Import 2.3.18pre1
[davej-history.git] / arch / sparc64 / kernel / dtlb_base.S
blob71e5b14d77d7df073d3a8043134cf35c1fc0a366
1 /* $Id: dtlb_base.S,v 1.4 1998/06/15 16:59:30 jj 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@dm.cobaltmicro.com)
6  * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz)
7  */
9 #define TAG_CONTEXT_BITS        0x3ff
10 #define VPTE_SHIFT              (PAGE_SHIFT - 3)
11 #define KERN_HIGHBITS           ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
12 #define KERN_LOWBITS            (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
13 #define KERN_LOWBITS_IO         (_PAGE_E | _PAGE_P | _PAGE_W)
14 #define KERN_IOBITS             (KERN_LOWBITS ^ KERN_LOWBITS_IO)
16 /* %g1  TLB_SFSR        (%g1 + %g1 == TLB_TAG_ACCESS)
17  * %g2  (KERN_HIGHBITS | KERN_LOWBITS)
18  * %g3  VPTE base       (0xfffffffe00000000)    Spitfire/Blackbird (44-bit VA space)
19  *                      (0xffe0000000000000)    Cheetah            (64-bit VA space)
20  * %g7  __pa(current->mm->pgd)
21  *
22  * The VPTE base value is completely magic, but note that
23  * nothing else in the kernel other than these TLB miss
24  * handlers know anything about the VPTE mechanism or
25  * how it works.  Consider the 44-bit VADDR Ultra-I/II
26  * case as an example:
27  *
28  * VA[0 :  (1<<43)] produce VPTE index [%g3                        :   0]
29  * VA[0 : -(1<<43)] produce VPTE index [%g3-(1<<(43-PAGE_SHIFT+3)) : %g3]
30  *
31  * For Cheetah's 64-bit VADDR space this is:
32  *
33  * VA[0 :  (1<<63)] produce VPTE index [%g3                        :   0]
34  * VA[0 : -(1<<63)] produce VPTE index [%g3-(1<<(63-PAGE_SHIFT+3)) : %g3]
35  *
36  * If you're paying attention you'll notice that this means half of
37  * the VPTE table is above %g3 and half is below, low VA addresses
38  * map progressively upwards from %g3, and high VA addresses map
39  * progressively downwards from %g3.  This trick was needed to make
40  * the same 8 instruction handler work both for Spitfire/Blackbird's
41  * peculiar VA space hole configuration and the full 64-bit VA space
42  * one of Cheetah at the same time.
43  */
45 /* Ways we can get here:
46  *
47  * 1) Nucleus loads and stores to/from PA-->VA direct mappings.
48  * 2) Nucleus loads and stores to/from vmalloc() areas.
49  * 3) User loads and stores.
50  * 4) User space accesses by nucleus at tl0
51  */
53 /* DTLB ** ICACHE line 1: Quick user TLB misses         */
54         ldxa            [%g1 + %g1] ASI_DMMU, %g4       ! Get TAG_ACCESS
55         andcc           %g4, TAG_CONTEXT_BITS, %g0      ! From Nucleus?
56         be,pn           %xcc, 3f                        ! Yep, special processing
57          srax           %g4, VPTE_SHIFT, %g6            ! Create VPTE offset
58         ldxa            [%g3 + %g6] ASI_S, %g5          ! Load VPTE
59 1:      brlz,pt         %g5, 2f                         ! Valid, load into TLB
60          and            %g5, (_PAGE_PRESENT|_PAGE_READ), %g4    ! Mask readable bits
61         ba,a,pt         %xcc, 4f                        ! Invalid, branch out
63 /* DTLB ** ICACHE line 2: Quick kernel TLB misses       */
64 3:      brgez,a,pn      %g4, 1b                         ! Kernel virtual map?
65          ldxa           [%g3 + %g6] ASI_N, %g5          ! Yep, load k-vpte
66         srlx            %g4, 40, %g5                    ! Else compute phys-kpte
67         andcc           %g5, 1, %g0                     ! I/O area?
68         be,pt           %xcc, 2f                        ! Nope, go and load TLB
69          xor            %g2, %g4, %g5                   ! Finish bit twiddles
70         ba,pt           %xcc, 2f                        ! Yes, I/O space, back back
71          xor            %g5, (KERN_IOBITS), %g5         ! After set E, clear CP/CV
73 /* DTLB ** ICACHE line 3: winfixups+real_faults         */
74 4:      cmp             %g4, (_PAGE_PRESENT|_PAGE_READ) ! Readable page?
75         be,pn           %xcc, 5f                        ! Yep, refbit update
76          sllx           %g1, 60, %g4                    ! Get valid bit
77         rdpr            %pstate, %g5                    ! Move into alternate globals
78         wrpr            %g5, PSTATE_AG|PSTATE_MG, %pstate
79         rdpr            %tl, %g4                        ! See where we came from.
80         cmp             %g4, 1                          ! Is etrap/rtrap window fault?
81         mov             TLB_TAG_ACCESS, %g4             ! Prepare for fault processing
83 /* DTLB ** ICACHE line 4: padding               */
84         be,pt           %xcc, sparc64_realfault_common  ! Jump to normal fault handling
85          ldxa           [%g4] ASI_DMMU, %g5             ! And load faulting VA page
86         ba,a,pt         %xcc, winfix_trampoline         ! Call window fixup code
87 5:      or              %g5, _PAGE_ACCESSED, %g5        ! Indicate reference
88         or              %g5, %g4, %g5                   ! Set valid
89         stxa            %g5, [%g3 + %g6] ASI_S          ! Update PTE table (cant trap)
90 2:      stxa            %g5, [%g0] ASI_DTLB_DATA_IN     ! Reload TLB
91         retry                                           ! Trap return
93 #undef TAG_CONTEXT_BITS
94 #undef VPTE_SHIFT
95 #undef KERN_HIGHBITS
96 #undef KERN_LOWBITS
97 #undef KERN_LOWBITS_IO
98 #undef KERN_IOBITS