aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/dtlb_base.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sparc64/kernel/dtlb_base.S
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/sparc64/kernel/dtlb_base.S')
-rw-r--r--arch/sparc64/kernel/dtlb_base.S113
1 files changed, 113 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
new file mode 100644
index 000000000000..ded2fed23fcc
--- /dev/null
+++ b/arch/sparc64/kernel/dtlb_base.S
@@ -0,0 +1,113 @@
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 */
56#define CREATE_VPTE_OFFSET1(r1, r2)
57#define CREATE_VPTE_OFFSET2(r1, r2) \
58 srax r1, 10, r2
59#define CREATE_VPTE_NOP nop
60#else
61#define CREATE_VPTE_OFFSET1(r1, r2) \
62 srax r1, PAGE_SHIFT, r2
63#define CREATE_VPTE_OFFSET2(r1, r2) \
64 sllx r2, 3, r2
65#define CREATE_VPTE_NOP
66#endif
67
68/* DTLB ** ICACHE line 1: Quick user TLB misses */
69 ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
70 andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus?
71from_tl1_trap:
72 rdpr %tl, %g5 ! For TL==3 test
73 CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
74 be,pn %xcc, 3f ! Yep, special processing
75 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
76 cmp %g5, 4 ! Last trap level?
77 be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
78 nop ! delay slot
79
80/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */
81 ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE
821: brgez,pn %g5, longpath ! Invalid, branch out
83 nop ! Delay-slot
849: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
85 retry ! Trap return
863: brlz,pt %g4, 9b ! Kernel virtual map?
87 xor %g2, %g4, %g5 ! Finish bit twiddles
88 ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc
89
90/* DTLB ** ICACHE line 3: winfixups+real_faults */
91longpath:
92 rdpr %pstate, %g5 ! Move into alternate globals
93 wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
94 rdpr %tl, %g4 ! See where we came from.
95 cmp %g4, 1 ! Is etrap/rtrap window fault?
96 mov TLB_TAG_ACCESS, %g4 ! Prepare for fault processing
97 ldxa [%g4] ASI_DMMU, %g5 ! Load faulting VA page
98 be,pt %xcc, sparc64_realfault_common ! Jump to normal fault handling
99 mov FAULT_CODE_DTLB, %g4 ! It was read from DTLB
100
101/* DTLB ** ICACHE line 4: Unused... */
102 ba,a,pt %xcc, winfix_trampoline ! Call window fixup code
103 nop
104 nop
105 nop
106 nop
107 nop
108 nop
109 CREATE_VPTE_NOP
110
111#undef CREATE_VPTE_OFFSET1
112#undef CREATE_VPTE_OFFSET2
113#undef CREATE_VPTE_NOP