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/* %g1 TLB_SFSR (%g1 + %g1 == TLB_TAG_ACCESS) 10 * %g2 (KERN_HIGHBITS | KERN_LOWBITS) 11 * %g3 VPTE base (0xfffffffe00000000) Spitfire/Blackbird (44-bit VA space) 12 * (0xffe0000000000000) Cheetah (64-bit VA space) 13 * %g7 __pa(current->mm->pgd) 14 * 15 * The VPTE base value is completely magic, but note that 16 * few places in the kernel other than these TLB miss 17 * handlers know anything about the VPTE mechanism or 18 * how it works (see VPTE_SIZE, TASK_SIZE and PTRS_PER_PGD). 19 * Consider the 44-bit VADDR Ultra-I/II case as an example: 20 * 21 * VA[0 : (1<<43)] produce VPTE index [%g3 : 0] 22 * VA[0 : -(1<<43)] produce VPTE index [%g3-(1<<(43-PAGE_SHIFT+3)) : %g3] 23 * 24 * For Cheetah's 64-bit VADDR space this is: 25 * 26 * VA[0 : (1<<63)] produce VPTE index [%g3 : 0] 27 * VA[0 : -(1<<63)] produce VPTE index [%g3-(1<<(63-PAGE_SHIFT+3)) : %g3] 28 * 29 * If you're paying attention you'll notice that this means half of 30 * the VPTE table is above %g3 and half is below, low VA addresses 31 * map progressively upwards from %g3, and high VA addresses map 32 * progressively upwards towards %g3. This trick was needed to make 33 * the same 8 instruction handler work both for Spitfire/Blackbird's 34 * peculiar VA space hole configuration and the full 64-bit VA space 35 * one of Cheetah at the same time. 36 */ 37 38/* Ways we can get here: 39 * 40 * 1) Nucleus loads and stores to/from PA-->VA direct mappings. 41 * 2) Nucleus loads and stores to/from vmalloc() areas. 42 * 3) User loads and stores. 43 * 4) User space accesses by nucleus at tl0 44 */ 45 46#if PAGE_SHIFT == 13 47/* 48 * To compute vpte offset, we need to do ((addr >> 13) << 3), 49 * which can be optimized to (addr >> 10) if bits 10/11/12 can 50 * be guaranteed to be 0 ... mmu_context.h does guarantee this 51 * by only using 10 bits in the hwcontext value. 52 */ 53#define CREATE_VPTE_OFFSET1(r1, r2) 54#define CREATE_VPTE_OFFSET2(r1, r2) \ 55 srax r1, 10, r2 56#define CREATE_VPTE_NOP nop 57#else 58#define CREATE_VPTE_OFFSET1(r1, r2) \ 59 srax r1, PAGE_SHIFT, r2 60#define CREATE_VPTE_OFFSET2(r1, r2) \ 61 sllx r2, 3, r2 62#define CREATE_VPTE_NOP 63#endif 64 65/* DTLB ** ICACHE line 1: Quick user TLB misses */ 66 ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS 67 andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus? 68 mov 1, %g5 ! For TL==3 test 69from_tl1_trap: 70 CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset 71 be,pn %xcc, 3f ! Yep, special processing 72 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset 73 cmp %g5, 4 ! Last trap level? 74 be,pn %xcc, longpath ! Yep, cannot risk VPTE miss 75 nop ! delay slot 76 77/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */ 78 ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE 791: brgez,pn %g5, longpath ! Invalid, branch out 80 nop ! Delay-slot 819: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB 82 retry ! Trap return 833: brlz,pt %g4, 9b ! Kernel virtual map? 84 xor %g2, %g4, %g5 ! Finish bit twiddles 85 ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc 86 87/* DTLB ** ICACHE line 3: winfixups+real_faults */ 88longpath: 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 106 CREATE_VPTE_NOP 107 108#undef CREATE_VPTE_OFFSET1 109#undef CREATE_VPTE_OFFSET2 110#undef CREATE_VPTE_NOP 111