| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* $Id: dtlb_base.S,v 1.17 2001/10/11 22:33:52 davem Exp $ | 
|  | 2 | * dtlb_base.S:	Front end to DTLB miss replacement strategy. | 
|  | 3 | *              This is included directly into the trap table. | 
|  | 4 | * | 
|  | 5 | * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com) | 
|  | 6 | * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz) | 
|  | 7 | */ | 
|  | 8 |  | 
|  | 9 | #include <asm/pgtable.h> | 
|  | 10 | #include <asm/mmu.h> | 
|  | 11 |  | 
|  | 12 | /* %g1	TLB_SFSR	(%g1 + %g1 == TLB_TAG_ACCESS) | 
|  | 13 | * %g2	(KERN_HIGHBITS | KERN_LOWBITS) | 
|  | 14 | * %g3  VPTE base	(0xfffffffe00000000)	Spitfire/Blackbird (44-bit VA space) | 
|  | 15 | *			(0xffe0000000000000)	Cheetah		   (64-bit VA space) | 
|  | 16 | * %g7	__pa(current->mm->pgd) | 
|  | 17 | * | 
|  | 18 | * The VPTE base value is completely magic, but note that | 
|  | 19 | * few places in the kernel other than these TLB miss | 
|  | 20 | * handlers know anything about the VPTE mechanism or | 
|  | 21 | * how it works (see VPTE_SIZE, TASK_SIZE and PTRS_PER_PGD). | 
|  | 22 | * Consider the 44-bit VADDR Ultra-I/II case as an example: | 
|  | 23 | * | 
|  | 24 | * VA[0 :  (1<<43)] produce VPTE index [%g3                        :   0] | 
|  | 25 | * VA[0 : -(1<<43)] produce VPTE index [%g3-(1<<(43-PAGE_SHIFT+3)) : %g3] | 
|  | 26 | * | 
|  | 27 | * For Cheetah's 64-bit VADDR space this is: | 
|  | 28 | * | 
|  | 29 | * VA[0 :  (1<<63)] produce VPTE index [%g3                        :   0] | 
|  | 30 | * VA[0 : -(1<<63)] produce VPTE index [%g3-(1<<(63-PAGE_SHIFT+3)) : %g3] | 
|  | 31 | * | 
|  | 32 | * If you're paying attention you'll notice that this means half of | 
|  | 33 | * the VPTE table is above %g3 and half is below, low VA addresses | 
|  | 34 | * map progressively upwards from %g3, and high VA addresses map | 
|  | 35 | * progressively upwards towards %g3.  This trick was needed to make | 
|  | 36 | * the same 8 instruction handler work both for Spitfire/Blackbird's | 
|  | 37 | * peculiar VA space hole configuration and the full 64-bit VA space | 
|  | 38 | * one of Cheetah at the same time. | 
|  | 39 | */ | 
|  | 40 |  | 
|  | 41 | /* Ways we can get here: | 
|  | 42 | * | 
|  | 43 | * 1) Nucleus loads and stores to/from PA-->VA direct mappings. | 
|  | 44 | * 2) Nucleus loads and stores to/from vmalloc() areas. | 
|  | 45 | * 3) User loads and stores. | 
|  | 46 | * 4) User space accesses by nucleus at tl0 | 
|  | 47 | */ | 
|  | 48 |  | 
|  | 49 | #if PAGE_SHIFT == 13 | 
|  | 50 | /* | 
|  | 51 | * To compute vpte offset, we need to do ((addr >> 13) << 3), | 
|  | 52 | * which can be optimized to (addr >> 10) if bits 10/11/12 can | 
|  | 53 | * be guaranteed to be 0 ... mmu_context.h does guarantee this | 
|  | 54 | * by only using 10 bits in the hwcontext value. | 
|  | 55 | */ | 
| David S. Miller | c9c1083 | 2005-10-12 12:22:46 -0700 | [diff] [blame] | 56 | #define CREATE_VPTE_OFFSET1(r1, r2) nop | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 | #define CREATE_VPTE_OFFSET2(r1, r2) \ | 
|  | 58 | srax	r1, 10, r2 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 | #else | 
|  | 60 | #define CREATE_VPTE_OFFSET1(r1, r2) \ | 
|  | 61 | srax	r1, PAGE_SHIFT, r2 | 
|  | 62 | #define CREATE_VPTE_OFFSET2(r1, r2) \ | 
|  | 63 | sllx	r2, 3, r2 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 64 | #endif | 
|  | 65 |  | 
|  | 66 | /* DTLB ** ICACHE line 1: Quick user TLB misses		*/ | 
| David S. Miller | c9c1083 | 2005-10-12 12:22:46 -0700 | [diff] [blame] | 67 | mov		TLB_SFSR, %g1 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 68 | ldxa		[%g1 + %g1] ASI_DMMU, %g4	! Get TAG_ACCESS | 
|  | 69 | andcc		%g4, TAG_CONTEXT_BITS, %g0	! From Nucleus? | 
|  | 70 | from_tl1_trap: | 
|  | 71 | rdpr		%tl, %g5			! For TL==3 test | 
|  | 72 | CREATE_VPTE_OFFSET1(%g4, %g6)			! Create VPTE offset | 
| David S. Miller | 2a7e299 | 2005-09-21 18:50:51 -0700 | [diff] [blame] | 73 | be,pn		%xcc, kvmap			! Yep, special processing | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 74 | CREATE_VPTE_OFFSET2(%g4, %g6)			! Create VPTE offset | 
|  | 75 | cmp		%g5, 4				! Last trap level? | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 |  | 
|  | 77 | /* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses	*/ | 
| David S. Miller | c9c1083 | 2005-10-12 12:22:46 -0700 | [diff] [blame] | 78 | be,pn		%xcc, longpath			! Yep, cannot risk VPTE miss | 
|  | 79 | nop						! delay slot | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 80 | ldxa		[%g3 + %g6] ASI_S, %g5		! Load VPTE | 
|  | 81 | 1:	brgez,pn	%g5, longpath			! Invalid, branch out | 
|  | 82 | nop						! Delay-slot | 
|  | 83 | 9:	stxa		%g5, [%g0] ASI_DTLB_DATA_IN	! Reload TLB | 
|  | 84 | retry						! Trap return | 
| David S. Miller | 2a7e299 | 2005-09-21 18:50:51 -0700 | [diff] [blame] | 85 | nop | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 |  | 
|  | 87 | /* DTLB ** ICACHE line 3: winfixups+real_faults		*/ | 
|  | 88 | longpath: | 
|  | 89 | rdpr		%pstate, %g5			! Move into alternate globals | 
|  | 90 | wrpr		%g5, PSTATE_AG|PSTATE_MG, %pstate | 
|  | 91 | rdpr		%tl, %g4			! See where we came from. | 
|  | 92 | cmp		%g4, 1				! Is etrap/rtrap window fault? | 
|  | 93 | mov		TLB_TAG_ACCESS, %g4		! Prepare for fault processing | 
|  | 94 | ldxa		[%g4] ASI_DMMU, %g5		! Load faulting VA page | 
|  | 95 | be,pt		%xcc, sparc64_realfault_common	! Jump to normal fault handling | 
|  | 96 | mov		FAULT_CODE_DTLB, %g4		! It was read from DTLB | 
|  | 97 |  | 
|  | 98 | /* DTLB ** ICACHE line 4: Unused...	*/ | 
|  | 99 | ba,a,pt		%xcc, winfix_trampoline		! Call window fixup code | 
|  | 100 | nop | 
|  | 101 | nop | 
|  | 102 | nop | 
|  | 103 | nop | 
|  | 104 | nop | 
|  | 105 | nop | 
| David S. Miller | c9c1083 | 2005-10-12 12:22:46 -0700 | [diff] [blame] | 106 | nop | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 107 |  | 
|  | 108 | #undef CREATE_VPTE_OFFSET1 | 
|  | 109 | #undef CREATE_VPTE_OFFSET2 |