aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/entry.S')
-rw-r--r--arch/sparc64/kernel/entry.S263
1 files changed, 47 insertions, 216 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 3e0badb820c5..11a848402fb1 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -30,164 +30,10 @@
30 .text 30 .text
31 .align 32 31 .align 32
32 32
33 .globl sparc64_vpte_patchme1
34 .globl sparc64_vpte_patchme2
35/*
36 * On a second level vpte miss, check whether the original fault is to the OBP
37 * range (note that this is only possible for instruction miss, data misses to
38 * obp range do not use vpte). If so, go back directly to the faulting address.
39 * This is because we want to read the tpc, otherwise we have no way of knowing
40 * the 8k aligned faulting address if we are using >8k kernel pagesize. This
41 * also ensures no vpte range addresses are dropped into tlb while obp is
42 * executing (see inherit_locked_prom_mappings() rant).
43 */
44sparc64_vpte_nucleus:
45 /* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
46 mov 0xf, %g5
47 sllx %g5, 28, %g5
48
49 /* Is addr >= LOW_OBP_ADDRESS? */
50 cmp %g4, %g5
51 blu,pn %xcc, sparc64_vpte_patchme1
52 mov 0x1, %g5
53
54 /* Load 0x100000000, which is HI_OBP_ADDRESS. */
55 sllx %g5, 32, %g5
56
57 /* Is addr < HI_OBP_ADDRESS? */
58 cmp %g4, %g5
59 blu,pn %xcc, obp_iaddr_patch
60 nop
61
62 /* These two instructions are patched by paginig_init(). */
63sparc64_vpte_patchme1:
64 sethi %hi(0), %g5
65sparc64_vpte_patchme2:
66 or %g5, %lo(0), %g5
67
68 /* With kernel PGD in %g5, branch back into dtlb_backend. */
69 ba,pt %xcc, sparc64_kpte_continue
70 andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */
71
72vpte_noent:
73 /* Restore previous TAG_ACCESS, %g5 is zero, and we will
74 * skip over the trap instruction so that the top level
75 * TLB miss handler will thing this %g5 value is just an
76 * invalid PTE, thus branching to full fault processing.
77 */
78 mov TLB_SFSR, %g1
79 stxa %g4, [%g1 + %g1] ASI_DMMU
80 done
81
82 .globl obp_iaddr_patch
83obp_iaddr_patch:
84 /* These two instructions patched by inherit_prom_mappings(). */
85 sethi %hi(0), %g5
86 or %g5, %lo(0), %g5
87
88 /* Behave as if we are at TL0. */
89 wrpr %g0, 1, %tl
90 rdpr %tpc, %g4 /* Find original faulting iaddr */
91 srlx %g4, 13, %g4 /* Throw out context bits */
92 sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */
93
94 /* Restore previous TAG_ACCESS. */
95 mov TLB_SFSR, %g1
96 stxa %g4, [%g1 + %g1] ASI_IMMU
97
98 /* Get PMD offset. */
99 srlx %g4, 23, %g6
100 and %g6, 0x7ff, %g6
101 sllx %g6, 2, %g6
102
103 /* Load PMD, is it valid? */
104 lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
105 brz,pn %g5, longpath
106 sllx %g5, 11, %g5
107
108 /* Get PTE offset. */
109 srlx %g4, 13, %g6
110 and %g6, 0x3ff, %g6
111 sllx %g6, 3, %g6
112
113 /* Load PTE. */
114 ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
115 brgez,pn %g5, longpath
116 nop
117
118 /* TLB load and return from trap. */
119 stxa %g5, [%g0] ASI_ITLB_DATA_IN
120 retry
121
122 .globl obp_daddr_patch
123obp_daddr_patch:
124 /* These two instructions patched by inherit_prom_mappings(). */
125 sethi %hi(0), %g5
126 or %g5, %lo(0), %g5
127
128 /* Get PMD offset. */
129 srlx %g4, 23, %g6
130 and %g6, 0x7ff, %g6
131 sllx %g6, 2, %g6
132
133 /* Load PMD, is it valid? */
134 lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
135 brz,pn %g5, longpath
136 sllx %g5, 11, %g5
137
138 /* Get PTE offset. */
139 srlx %g4, 13, %g6
140 and %g6, 0x3ff, %g6
141 sllx %g6, 3, %g6
142
143 /* Load PTE. */
144 ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
145 brgez,pn %g5, longpath
146 nop
147
148 /* TLB load and return from trap. */
149 stxa %g5, [%g0] ASI_DTLB_DATA_IN
150 retry
151
152/*
153 * On a first level data miss, check whether this is to the OBP range (note
154 * that such accesses can be made by prom, as well as by kernel using
155 * prom_getproperty on "address"), and if so, do not use vpte access ...
156 * rather, use information saved during inherit_prom_mappings() using 8k
157 * pagesize.
158 */
159kvmap:
160 /* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
161 mov 0xf, %g5
162 sllx %g5, 28, %g5
163
164 /* Is addr >= LOW_OBP_ADDRESS? */
165 cmp %g4, %g5
166 blu,pn %xcc, vmalloc_addr
167 mov 0x1, %g5
168
169 /* Load 0x100000000, which is HI_OBP_ADDRESS. */
170 sllx %g5, 32, %g5
171
172 /* Is addr < HI_OBP_ADDRESS? */
173 cmp %g4, %g5
174 blu,pn %xcc, obp_daddr_patch
175 nop
176
177vmalloc_addr:
178 /* If we get here, a vmalloc addr accessed, load kernel VPTE. */
179 ldxa [%g3 + %g6] ASI_N, %g5
180 brgez,pn %g5, longpath
181 nop
182
183 /* PTE is valid, load into TLB and return from trap. */
184 stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
185 retry
186
187 /* This is trivial with the new code... */ 33 /* This is trivial with the new code... */
188 .globl do_fpdis 34 .globl do_fpdis
189do_fpdis: 35do_fpdis:
190 sethi %hi(TSTATE_PEF), %g4 ! IEU0 36 sethi %hi(TSTATE_PEF), %g4
191 rdpr %tstate, %g5 37 rdpr %tstate, %g5
192 andcc %g5, %g4, %g0 38 andcc %g5, %g4, %g0
193 be,pt %xcc, 1f 39 be,pt %xcc, 1f
@@ -204,18 +50,18 @@ do_fpdis:
204 add %g0, %g0, %g0 50 add %g0, %g0, %g0
205 ba,a,pt %xcc, rtrap_clr_l6 51 ba,a,pt %xcc, rtrap_clr_l6
206 52
2071: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group 531: ldub [%g6 + TI_FPSAVED], %g5
208 wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles 54 wr %g0, FPRS_FEF, %fprs
209 andcc %g5, FPRS_FEF, %g0 ! IEU1 Group 55 andcc %g5, FPRS_FEF, %g0
210 be,a,pt %icc, 1f ! CTI 56 be,a,pt %icc, 1f
211 clr %g7 ! IEU0 57 clr %g7
212 ldx [%g6 + TI_GSR], %g7 ! Load Group 58 ldx [%g6 + TI_GSR], %g7
2131: andcc %g5, FPRS_DL, %g0 ! IEU1 591: andcc %g5, FPRS_DL, %g0
214 bne,pn %icc, 2f ! CTI 60 bne,pn %icc, 2f
215 fzero %f0 ! FPA 61 fzero %f0
216 andcc %g5, FPRS_DU, %g0 ! IEU1 Group 62 andcc %g5, FPRS_DU, %g0
217 bne,pn %icc, 1f ! CTI 63 bne,pn %icc, 1f
218 fzero %f2 ! FPA 64 fzero %f2
219 faddd %f0, %f2, %f4 65 faddd %f0, %f2, %f4
220 fmuld %f0, %f2, %f6 66 fmuld %f0, %f2, %f6
221 faddd %f0, %f2, %f8 67 faddd %f0, %f2, %f8
@@ -251,15 +97,17 @@ do_fpdis:
251 faddd %f0, %f2, %f4 97 faddd %f0, %f2, %f4
252 fmuld %f0, %f2, %f6 98 fmuld %f0, %f2, %f6
253 ldxa [%g3] ASI_DMMU, %g5 99 ldxa [%g3] ASI_DMMU, %g5
254cplus_fptrap_insn_1: 100 sethi %hi(sparc64_kern_sec_context), %g2
255 sethi %hi(0), %g2 101 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
256 stxa %g2, [%g3] ASI_DMMU 102 stxa %g2, [%g3] ASI_DMMU
257 membar #Sync 103 membar #Sync
258 add %g6, TI_FPREGS + 0xc0, %g2 104 add %g6, TI_FPREGS + 0xc0, %g2
259 faddd %f0, %f2, %f8 105 faddd %f0, %f2, %f8
260 fmuld %f0, %f2, %f10 106 fmuld %f0, %f2, %f10
261 ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-( 107 membar #Sync
108 ldda [%g1] ASI_BLK_S, %f32
262 ldda [%g2] ASI_BLK_S, %f48 109 ldda [%g2] ASI_BLK_S, %f48
110 membar #Sync
263 faddd %f0, %f2, %f12 111 faddd %f0, %f2, %f12
264 fmuld %f0, %f2, %f14 112 fmuld %f0, %f2, %f14
265 faddd %f0, %f2, %f16 113 faddd %f0, %f2, %f16
@@ -270,7 +118,6 @@ cplus_fptrap_insn_1:
270 fmuld %f0, %f2, %f26 118 fmuld %f0, %f2, %f26
271 faddd %f0, %f2, %f28 119 faddd %f0, %f2, %f28
272 fmuld %f0, %f2, %f30 120 fmuld %f0, %f2, %f30
273 membar #Sync
274 b,pt %xcc, fpdis_exit 121 b,pt %xcc, fpdis_exit
275 nop 122 nop
2762: andcc %g5, FPRS_DU, %g0 1232: andcc %g5, FPRS_DU, %g0
@@ -280,15 +127,17 @@ cplus_fptrap_insn_1:
280 fzero %f34 127 fzero %f34
281 ldxa [%g3] ASI_DMMU, %g5 128 ldxa [%g3] ASI_DMMU, %g5
282 add %g6, TI_FPREGS, %g1 129 add %g6, TI_FPREGS, %g1
283cplus_fptrap_insn_2: 130 sethi %hi(sparc64_kern_sec_context), %g2
284 sethi %hi(0), %g2 131 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
285 stxa %g2, [%g3] ASI_DMMU 132 stxa %g2, [%g3] ASI_DMMU
286 membar #Sync 133 membar #Sync
287 add %g6, TI_FPREGS + 0x40, %g2 134 add %g6, TI_FPREGS + 0x40, %g2
288 faddd %f32, %f34, %f36 135 faddd %f32, %f34, %f36
289 fmuld %f32, %f34, %f38 136 fmuld %f32, %f34, %f38
290 ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( 137 membar #Sync
138 ldda [%g1] ASI_BLK_S, %f0
291 ldda [%g2] ASI_BLK_S, %f16 139 ldda [%g2] ASI_BLK_S, %f16
140 membar #Sync
292 faddd %f32, %f34, %f40 141 faddd %f32, %f34, %f40
293 fmuld %f32, %f34, %f42 142 fmuld %f32, %f34, %f42
294 faddd %f32, %f34, %f44 143 faddd %f32, %f34, %f44
@@ -301,18 +150,18 @@ cplus_fptrap_insn_2:
301 fmuld %f32, %f34, %f58 150 fmuld %f32, %f34, %f58
302 faddd %f32, %f34, %f60 151 faddd %f32, %f34, %f60
303 fmuld %f32, %f34, %f62 152 fmuld %f32, %f34, %f62
304 membar #Sync
305 ba,pt %xcc, fpdis_exit 153 ba,pt %xcc, fpdis_exit
306 nop 154 nop
3073: mov SECONDARY_CONTEXT, %g3 1553: mov SECONDARY_CONTEXT, %g3
308 add %g6, TI_FPREGS, %g1 156 add %g6, TI_FPREGS, %g1
309 ldxa [%g3] ASI_DMMU, %g5 157 ldxa [%g3] ASI_DMMU, %g5
310cplus_fptrap_insn_3: 158 sethi %hi(sparc64_kern_sec_context), %g2
311 sethi %hi(0), %g2 159 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
312 stxa %g2, [%g3] ASI_DMMU 160 stxa %g2, [%g3] ASI_DMMU
313 membar #Sync 161 membar #Sync
314 mov 0x40, %g2 162 mov 0x40, %g2
315 ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( 163 membar #Sync
164 ldda [%g1] ASI_BLK_S, %f0
316 ldda [%g1 + %g2] ASI_BLK_S, %f16 165 ldda [%g1 + %g2] ASI_BLK_S, %f16
317 add %g1, 0x80, %g1 166 add %g1, 0x80, %g1
318 ldda [%g1] ASI_BLK_S, %f32 167 ldda [%g1] ASI_BLK_S, %f32
@@ -473,8 +322,8 @@ do_fptrap_after_fsr:
473 stx %g3, [%g6 + TI_GSR] 322 stx %g3, [%g6 + TI_GSR]
474 mov SECONDARY_CONTEXT, %g3 323 mov SECONDARY_CONTEXT, %g3
475 ldxa [%g3] ASI_DMMU, %g5 324 ldxa [%g3] ASI_DMMU, %g5
476cplus_fptrap_insn_4: 325 sethi %hi(sparc64_kern_sec_context), %g2
477 sethi %hi(0), %g2 326 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
478 stxa %g2, [%g3] ASI_DMMU 327 stxa %g2, [%g3] ASI_DMMU
479 membar #Sync 328 membar #Sync
480 add %g6, TI_FPREGS, %g2 329 add %g6, TI_FPREGS, %g2
@@ -495,45 +344,17 @@ cplus_fptrap_insn_4:
495 ba,pt %xcc, etrap 344 ba,pt %xcc, etrap
496 wr %g0, 0, %fprs 345 wr %g0, 0, %fprs
497 346
498cplus_fptrap_1:
499 sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
500
501 .globl cheetah_plus_patch_fpdis
502cheetah_plus_patch_fpdis:
503 /* We configure the dTLB512_0 for 4MB pages and the
504 * dTLB512_1 for 8K pages when in context zero.
505 */
506 sethi %hi(cplus_fptrap_1), %o0
507 lduw [%o0 + %lo(cplus_fptrap_1)], %o1
508
509 set cplus_fptrap_insn_1, %o2
510 stw %o1, [%o2]
511 flush %o2
512 set cplus_fptrap_insn_2, %o2
513 stw %o1, [%o2]
514 flush %o2
515 set cplus_fptrap_insn_3, %o2
516 stw %o1, [%o2]
517 flush %o2
518 set cplus_fptrap_insn_4, %o2
519 stw %o1, [%o2]
520 flush %o2
521
522 retl
523 nop
524
525 /* The registers for cross calls will be: 347 /* The registers for cross calls will be:
526 * 348 *
527 * DATA 0: [low 32-bits] Address of function to call, jmp to this 349 * DATA 0: [low 32-bits] Address of function to call, jmp to this
528 * [high 32-bits] MMU Context Argument 0, place in %g5 350 * [high 32-bits] MMU Context Argument 0, place in %g5
529 * DATA 1: Address Argument 1, place in %g6 351 * DATA 1: Address Argument 1, place in %g1
530 * DATA 2: Address Argument 2, place in %g7 352 * DATA 2: Address Argument 2, place in %g7
531 * 353 *
532 * With this method we can do most of the cross-call tlb/cache 354 * With this method we can do most of the cross-call tlb/cache
533 * flushing very quickly. 355 * flushing very quickly.
534 * 356 *
535 * Current CPU's IRQ worklist table is locked into %g1, 357 * Current CPU's IRQ worklist table is locked into %g6, don't touch.
536 * don't touch.
537 */ 358 */
538 .text 359 .text
539 .align 32 360 .align 32
@@ -1007,13 +828,14 @@ cheetah_plus_dcpe_trap_vector:
1007 nop 828 nop
1008 829
1009do_cheetah_plus_data_parity: 830do_cheetah_plus_data_parity:
1010 ba,pt %xcc, etrap 831 rdpr %pil, %g2
832 wrpr %g0, 15, %pil
833 ba,pt %xcc, etrap_irq
1011 rd %pc, %g7 834 rd %pc, %g7
1012 mov 0x0, %o0 835 mov 0x0, %o0
1013 call cheetah_plus_parity_error 836 call cheetah_plus_parity_error
1014 add %sp, PTREGS_OFF, %o1 837 add %sp, PTREGS_OFF, %o1
1015 ba,pt %xcc, rtrap 838 ba,a,pt %xcc, rtrap_irq
1016 clr %l6
1017 839
1018cheetah_plus_dcpe_trap_vector_tl1: 840cheetah_plus_dcpe_trap_vector_tl1:
1019 membar #Sync 841 membar #Sync
@@ -1037,13 +859,14 @@ cheetah_plus_icpe_trap_vector:
1037 nop 859 nop
1038 860
1039do_cheetah_plus_insn_parity: 861do_cheetah_plus_insn_parity:
1040 ba,pt %xcc, etrap 862 rdpr %pil, %g2
863 wrpr %g0, 15, %pil
864 ba,pt %xcc, etrap_irq
1041 rd %pc, %g7 865 rd %pc, %g7
1042 mov 0x1, %o0 866 mov 0x1, %o0
1043 call cheetah_plus_parity_error 867 call cheetah_plus_parity_error
1044 add %sp, PTREGS_OFF, %o1 868 add %sp, PTREGS_OFF, %o1
1045 ba,pt %xcc, rtrap 869 ba,a,pt %xcc, rtrap_irq
1046 clr %l6
1047 870
1048cheetah_plus_icpe_trap_vector_tl1: 871cheetah_plus_icpe_trap_vector_tl1:
1049 membar #Sync 872 membar #Sync
@@ -1076,6 +899,10 @@ do_dcpe_tl1:
1076 nop 899 nop
1077 wrpr %g1, %tl ! Restore original trap level 900 wrpr %g1, %tl ! Restore original trap level
1078do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ 901do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
902 sethi %hi(dcache_parity_tl1_occurred), %g2
903 lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1
904 add %g1, 1, %g1
905 stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)]
1079 /* Reset D-cache parity */ 906 /* Reset D-cache parity */
1080 sethi %hi(1 << 16), %g1 ! D-cache size 907 sethi %hi(1 << 16), %g1 ! D-cache size
1081 mov (1 << 5), %g2 ! D-cache line size 908 mov (1 << 5), %g2 ! D-cache line size
@@ -1122,6 +949,10 @@ do_icpe_tl1:
1122 nop 949 nop
1123 wrpr %g1, %tl ! Restore original trap level 950 wrpr %g1, %tl ! Restore original trap level
1124do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ 951do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
952 sethi %hi(icache_parity_tl1_occurred), %g2
953 lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1
954 add %g1, 1, %g1
955 stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)]
1125 /* Flush I-cache */ 956 /* Flush I-cache */
1126 sethi %hi(1 << 15), %g1 ! I-cache size 957 sethi %hi(1 << 15), %g1 ! I-cache size
1127 mov (1 << 5), %g2 ! I-cache line size 958 mov (1 << 5), %g2 ! I-cache line size