arch/powerpc/mm/book3s32/hash_low.S

Source file repositories/reference/linux-study-clean/arch/powerpc/mm/book3s32/hash_low.S

File Facts

System
Linux kernel
Corpus path
arch/powerpc/mm/book3s32/hash_low.S
Extension
.S
Size
17935 bytes
Lines
607
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/export.h>
#include <linux/pgtable.h>
#include <linux/init.h>
#include <asm/reg.h>
#include <asm/page.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/feature-fixups.h>
#include <asm/code-patching-asm.h>

#ifdef CONFIG_PTE_64BIT
#define PTE_T_SIZE		8
#define PTE_FLAGS_OFFSET	4	/* offset of PTE flags, in bytes */
#else
#define PTE_T_SIZE		4
#define PTE_FLAGS_OFFSET	0
#endif

/*
 * Load a PTE into the hash table, if possible.
 * The address is in r4, and r3 contains required access flags:
 *   - For ISI: _PAGE_PRESENT | _PAGE_EXEC
 *   - For DSI: _PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE if a write.
 * r9 contains the SRR1 value, from which we use the MSR_PR bit.
 * SPRG_THREAD contains the physical address of the current task's thread.
 *
 * Returns to the caller if the access is illegal or there is no
 * mapping for the address.  Otherwise it places an appropriate PTE
 * in the hash table and returns from the exception.
 * Uses r0, r3 - r6, r8, r10, ctr, lr.
 */
	.text
_GLOBAL(hash_page)
#ifdef CONFIG_SMP
	lis	r8, (mmu_hash_lock - PAGE_OFFSET)@h
	ori	r8, r8, (mmu_hash_lock - PAGE_OFFSET)@l
	lis	r0,0x0fff
	b	10f
11:	lwz	r6,0(r8)
	cmpwi	0,r6,0
	bne	11b
10:	lwarx	r6,0,r8
	cmpwi	0,r6,0
	bne-	11b
	stwcx.	r0,0,r8
	bne-	10b
	isync
#endif
	/* Get PTE (linux-style) and check access */
	lis	r0, TASK_SIZE@h		/* check if kernel address */
	cmplw	0,r4,r0
	mfspr	r8,SPRN_SPRG_THREAD	/* current task's THREAD (phys) */
	lwz	r5,PGDIR(r8)		/* virt page-table root */
	blt+	112f			/* assume user more likely */
	lis	r5,swapper_pg_dir@ha	/* if kernel address, use */
	andi.	r0,r9,MSR_PR		/* Check usermode */
	addi	r5,r5,swapper_pg_dir@l	/* kernel page table */
#ifdef CONFIG_SMP
	bne-	.Lhash_page_out		/* return if usermode */
#else
	bnelr-
#endif
112:	tophys(r5, r5)
#ifndef CONFIG_PTE_64BIT
	rlwimi	r5,r4,12,20,29		/* insert top 10 bits of address */
	lwz	r8,0(r5)		/* get pmd entry */
	rlwinm.	r8,r8,0,0,19		/* extract address of pte page */
#else

Annotation

Implementation Notes