arch/sparc/kernel/sun4v_tlb_miss.S

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/sun4v_tlb_miss.S

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/sun4v_tlb_miss.S
Extension
.S
Size
10836 bytes
Lines
438
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: arch/sparc
Status
atlas-only

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

.text
	.align	32

	/* Load ITLB fault information into VADDR and CTX, using BASE.  */
#define LOAD_ITLB_INFO(BASE, VADDR, CTX) \
	ldx	[BASE + HV_FAULT_I_ADDR_OFFSET], VADDR; \
	ldx	[BASE + HV_FAULT_I_CTX_OFFSET], CTX;

	/* Load DTLB fault information into VADDR and CTX, using BASE.  */
#define LOAD_DTLB_INFO(BASE, VADDR, CTX) \
	ldx	[BASE + HV_FAULT_D_ADDR_OFFSET], VADDR; \
	ldx	[BASE + HV_FAULT_D_CTX_OFFSET], CTX;

	/* DEST = (VADDR >> 22)
	 *
	 * Branch to ZERO_CTX_LABEL if context is zero.
	 */
#define	COMPUTE_TAG_TARGET(DEST, VADDR, CTX, ZERO_CTX_LABEL) \
	srlx	VADDR, 22, DEST; \
	brz,pn	CTX, ZERO_CTX_LABEL; \
	 nop;

	/* Create TSB pointer.  This is something like:
	 *
	 * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
	 * tsb_base = tsb_reg & ~0x7UL;
	 * tsb_index = ((vaddr >> HASH_SHIFT) & tsb_mask);
	 * tsb_ptr = tsb_base + (tsb_index * 16);
	 */
#define COMPUTE_TSB_PTR(TSB_PTR, VADDR, HASH_SHIFT, TMP1, TMP2) \
	and	TSB_PTR, 0x7, TMP1;			\
	mov	512, TMP2;				\
	andn	TSB_PTR, 0x7, TSB_PTR;			\
	sllx	TMP2, TMP1, TMP2;			\
	srlx	VADDR, HASH_SHIFT, TMP1;		\
	sub	TMP2, 1, TMP2;				\
	and	TMP1, TMP2, TMP1;			\
	sllx	TMP1, 4, TMP1;				\
	add	TSB_PTR, TMP1, TSB_PTR;

sun4v_itlb_miss:
	/* Load MMU Miss base into %g2.  */
	ldxa	[%g0] ASI_SCRATCHPAD, %g2
	
	/* Load UTSB reg into %g1.  */
	mov	SCRATCHPAD_UTSBREG1, %g1
	ldxa	[%g1] ASI_SCRATCHPAD, %g1

	LOAD_ITLB_INFO(%g2, %g4, %g5)
	COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_itlb_4v)
	COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)

	/* Load TSB tag/pte into %g2/%g3 and compare the tag.  */
	ldda	[%g1] ASI_QUAD_LDD_PHYS_4V, %g2
	cmp	%g2, %g6
	bne,a,pn %xcc, tsb_miss_page_table_walk
	 mov	FAULT_CODE_ITLB, %g3
	andcc	%g3, _PAGE_EXEC_4V, %g0
	be,a,pn	%xcc, tsb_do_fault
	 mov	FAULT_CODE_ITLB, %g3

	/* We have a valid entry, make hypervisor call to load
	 * I-TLB and return from trap.
	 *
	 * %g3:	PTE
	 * %g4:	vaddr
	 */
sun4v_itlb_load:
	ldxa	[%g0] ASI_SCRATCHPAD, %g6
	mov	%o0, %g1		! save %o0

Annotation

Implementation Notes