diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-10 18:39:51 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:15 -0500 |
commit | 12eaa328f9fb2d3fcb5afb682c762690d05a3cd8 (patch) | |
tree | cce4e68b971757010a3e0bbf035fc65a381a3cd4 | |
parent | 18397944642cbca7fcd4a109b43ed5b4652e95b9 (diff) |
[SPARC64]: Use ASI_SCRATCHPAD address 0x0 properly.
This is where the virtual address of the fault status
area belongs.
To set it up we don't make a hypervisor call, instead
we call OBP's SUNW,set-trap-table with the real address
of the fault status area as the second argument. And
right before that call we write the virtual address into
ASI_SCRATCHPAD vaddr 0x0.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/head.S | 29 | ||||
-rw-r--r-- | arch/sparc64/kernel/sun4v_ivec.S | 28 | ||||
-rw-r--r-- | arch/sparc64/kernel/sun4v_tlb_miss.S | 162 | ||||
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 29 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 22 | ||||
-rw-r--r-- | arch/sparc64/prom/misc.c | 5 | ||||
-rw-r--r-- | include/asm-sparc64/cpudata.h | 26 | ||||
-rw-r--r-- | include/asm-sparc64/oplib.h | 1 | ||||
-rw-r--r-- | include/asm-sparc64/ttable.h | 34 |
9 files changed, 144 insertions, 192 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index d048f0dfd423..f581f0e917f7 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -521,11 +521,36 @@ setup_trap_table: | |||
521 | wrpr %g0, 15, %pil | 521 | wrpr %g0, 15, %pil |
522 | 522 | ||
523 | /* Make the firmware call to jump over to the Linux trap table. */ | 523 | /* Make the firmware call to jump over to the Linux trap table. */ |
524 | call prom_set_trap_table | 524 | sethi %hi(is_sun4v), %o0 |
525 | lduw [%o0 + %lo(is_sun4v)], %o0 | ||
526 | brz,pt %o0, 1f | ||
527 | nop | ||
528 | |||
529 | TRAP_LOAD_TRAP_BLOCK(%g2, %g3) | ||
530 | add %g2, TRAP_PER_CPU_FAULT_INFO, %g2 | ||
531 | stxa %g2, [%g0] ASI_SCRATCHPAD | ||
532 | |||
533 | /* Compute physical address: | ||
534 | * | ||
535 | * paddr = kern_base + (mmfsa_vaddr - KERNBASE) | ||
536 | */ | ||
537 | sethi %hi(KERNBASE), %g3 | ||
538 | sub %g2, %g3, %g2 | ||
539 | sethi %hi(kern_base), %g3 | ||
540 | ldx [%g3 + %lo(kern_base)], %g3 | ||
541 | add %g2, %g3, %o1 | ||
542 | |||
543 | call prom_set_trap_table_sun4v | ||
544 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
545 | |||
546 | ba,pt %xcc, 2f | ||
547 | nop | ||
548 | |||
549 | 1: call prom_set_trap_table | ||
525 | sethi %hi(sparc64_ttable_tl0), %o0 | 550 | sethi %hi(sparc64_ttable_tl0), %o0 |
526 | 551 | ||
527 | /* Start using proper page size encodings in ctx register. */ | 552 | /* Start using proper page size encodings in ctx register. */ |
528 | sethi %hi(sparc64_kern_pri_context), %g3 | 553 | 2: sethi %hi(sparc64_kern_pri_context), %g3 |
529 | ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 | 554 | ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 |
530 | 555 | ||
531 | mov PRIMARY_CONTEXT, %g1 | 556 | mov PRIMARY_CONTEXT, %g1 |
diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S index d9d442017d3d..c0367ef7e098 100644 --- a/arch/sparc64/kernel/sun4v_ivec.S +++ b/arch/sparc64/kernel/sun4v_ivec.S | |||
@@ -22,11 +22,8 @@ sun4v_cpu_mondo: | |||
22 | nop | 22 | nop |
23 | 23 | ||
24 | /* Get &trap_block[smp_processor_id()] into %g3. */ | 24 | /* Get &trap_block[smp_processor_id()] into %g3. */ |
25 | __GET_CPUID(%g1) | 25 | ldxa [%g0] ASI_SCRATCHPAD, %g3 |
26 | sethi %hi(trap_block), %g3 | 26 | sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 |
27 | sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g7 | ||
28 | or %g3, %lo(trap_block), %g3 | ||
29 | add %g3, %g7, %g3 | ||
30 | 27 | ||
31 | /* Get CPU mondo queue base phys address into %g7. */ | 28 | /* Get CPU mondo queue base phys address into %g7. */ |
32 | ldx [%g3 + TRAP_PER_CPU_CPU_MONDO_PA], %g7 | 29 | ldx [%g3 + TRAP_PER_CPU_CPU_MONDO_PA], %g7 |
@@ -74,11 +71,8 @@ sun4v_dev_mondo: | |||
74 | nop | 71 | nop |
75 | 72 | ||
76 | /* Get &trap_block[smp_processor_id()] into %g3. */ | 73 | /* Get &trap_block[smp_processor_id()] into %g3. */ |
77 | __GET_CPUID(%g1) | 74 | ldxa [%g0] ASI_SCRATCHPAD, %g3 |
78 | sethi %hi(trap_block), %g3 | 75 | sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 |
79 | sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g7 | ||
80 | or %g3, %lo(trap_block), %g3 | ||
81 | add %g3, %g7, %g3 | ||
82 | 76 | ||
83 | /* Get DEV mondo queue base phys address into %g5. */ | 77 | /* Get DEV mondo queue base phys address into %g5. */ |
84 | ldx [%g3 + TRAP_PER_CPU_DEV_MONDO_PA], %g5 | 78 | ldx [%g3 + TRAP_PER_CPU_DEV_MONDO_PA], %g5 |
@@ -143,11 +137,8 @@ sun4v_res_mondo: | |||
143 | nop | 137 | nop |
144 | 138 | ||
145 | /* Get &trap_block[smp_processor_id()] into %g3. */ | 139 | /* Get &trap_block[smp_processor_id()] into %g3. */ |
146 | __GET_CPUID(%g1) | 140 | ldxa [%g0] ASI_SCRATCHPAD, %g3 |
147 | sethi %hi(trap_block), %g3 | 141 | sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 |
148 | sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g7 | ||
149 | or %g3, %lo(trap_block), %g3 | ||
150 | add %g3, %g7, %g3 | ||
151 | 142 | ||
152 | /* Get RES mondo queue base phys address into %g5. */ | 143 | /* Get RES mondo queue base phys address into %g5. */ |
153 | ldx [%g3 + TRAP_PER_CPU_RESUM_MONDO_PA], %g5 | 144 | ldx [%g3 + TRAP_PER_CPU_RESUM_MONDO_PA], %g5 |
@@ -251,11 +242,8 @@ sun4v_nonres_mondo: | |||
251 | nop | 242 | nop |
252 | 243 | ||
253 | /* Get &trap_block[smp_processor_id()] into %g3. */ | 244 | /* Get &trap_block[smp_processor_id()] into %g3. */ |
254 | __GET_CPUID(%g1) | 245 | ldxa [%g0] ASI_SCRATCHPAD, %g3 |
255 | sethi %hi(trap_block), %g3 | 246 | sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 |
256 | sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g7 | ||
257 | or %g3, %lo(trap_block), %g3 | ||
258 | add %g3, %g7, %g3 | ||
259 | 247 | ||
260 | /* Get RES mondo queue base phys address into %g5. */ | 248 | /* Get RES mondo queue base phys address into %g5. */ |
261 | ldx [%g3 + TRAP_PER_CPU_NONRESUM_MONDO_PA], %g5 | 249 | ldx [%g3 + TRAP_PER_CPU_NONRESUM_MONDO_PA], %g5 |
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S index c408b05a5f0a..f6222623de38 100644 --- a/arch/sparc64/kernel/sun4v_tlb_miss.S +++ b/arch/sparc64/kernel/sun4v_tlb_miss.S | |||
@@ -7,26 +7,20 @@ | |||
7 | .align 32 | 7 | .align 32 |
8 | 8 | ||
9 | sun4v_itlb_miss: | 9 | sun4v_itlb_miss: |
10 | /* Load CPU ID into %g3. */ | 10 | /* Load MMU Miss base into %g2. */ |
11 | mov SCRATCHPAD_CPUID, %g1 | 11 | ldxa [%g0] ASI_SCRATCHPAD, %g3 |
12 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | ||
13 | 12 | ||
14 | /* Load UTSB reg into %g1. */ | 13 | /* Load UTSB reg into %g1. */ |
15 | ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1 | 14 | mov SCRATCHPAD_UTSBREG1, %g1 |
16 | 15 | ldxa [%g1] ASI_SCRATCHPAD, %g1 | |
17 | /* Load &trap_block[smp_processor_id()] into %g2. */ | ||
18 | sethi %hi(trap_block), %g2 | ||
19 | or %g2, %lo(trap_block), %g2 | ||
20 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
21 | add %g2, %g3, %g2 | ||
22 | 16 | ||
23 | /* Create a TAG TARGET, "(vaddr>>22) | (ctx << 48)", in %g6. | 17 | /* Create a TAG TARGET, "(vaddr>>22) | (ctx << 48)", in %g6. |
24 | * Branch if kernel TLB miss. The kernel TSB and user TSB miss | 18 | * Branch if kernel TLB miss. The kernel TSB and user TSB miss |
25 | * code wants the missing virtual address in %g4, so that value | 19 | * code wants the missing virtual address in %g4, so that value |
26 | * cannot be modified through the entirety of this handler. | 20 | * cannot be modified through the entirety of this handler. |
27 | */ | 21 | */ |
28 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_ADDR_OFFSET], %g4 | 22 | ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4 |
29 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_CTX_OFFSET], %g5 | 23 | ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5 |
30 | srlx %g4, 22, %g3 | 24 | srlx %g4, 22, %g3 |
31 | sllx %g5, 48, %g6 | 25 | sllx %g5, 48, %g6 |
32 | or %g6, %g3, %g6 | 26 | or %g6, %g3, %g6 |
@@ -90,26 +84,20 @@ sun4v_itlb_load: | |||
90 | retry | 84 | retry |
91 | 85 | ||
92 | sun4v_dtlb_miss: | 86 | sun4v_dtlb_miss: |
93 | /* Load CPU ID into %g3. */ | 87 | /* Load MMU Miss base into %g2. */ |
94 | mov SCRATCHPAD_CPUID, %g1 | 88 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
95 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | ||
96 | 89 | ||
97 | /* Load UTSB reg into %g1. */ | 90 | /* Load UTSB reg into %g1. */ |
91 | mov SCRATCHPAD_UTSBREG1, %g1 | ||
98 | ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1 | 92 | ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1 |
99 | 93 | ||
100 | /* Load &trap_block[smp_processor_id()] into %g2. */ | ||
101 | sethi %hi(trap_block), %g2 | ||
102 | or %g2, %lo(trap_block), %g2 | ||
103 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
104 | add %g2, %g3, %g2 | ||
105 | |||
106 | /* Create a TAG TARGET, "(vaddr>>22) | (ctx << 48)", in %g6. | 94 | /* Create a TAG TARGET, "(vaddr>>22) | (ctx << 48)", in %g6. |
107 | * Branch if kernel TLB miss. The kernel TSB and user TSB miss | 95 | * Branch if kernel TLB miss. The kernel TSB and user TSB miss |
108 | * code wants the missing virtual address in %g4, so that value | 96 | * code wants the missing virtual address in %g4, so that value |
109 | * cannot be modified through the entirety of this handler. | 97 | * cannot be modified through the entirety of this handler. |
110 | */ | 98 | */ |
111 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | 99 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 |
112 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | 100 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 |
113 | srlx %g4, 22, %g3 | 101 | srlx %g4, 22, %g3 |
114 | sllx %g5, 48, %g6 | 102 | sllx %g5, 48, %g6 |
115 | or %g6, %g3, %g6 | 103 | or %g6, %g3, %g6 |
@@ -169,17 +157,10 @@ sun4v_dtlb_load: | |||
169 | retry | 157 | retry |
170 | 158 | ||
171 | sun4v_dtlb_prot: | 159 | sun4v_dtlb_prot: |
172 | /* Load CPU ID into %g3. */ | 160 | /* Load MMU Miss base into %g2. */ |
173 | mov SCRATCHPAD_CPUID, %g1 | 161 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
174 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | ||
175 | 162 | ||
176 | /* Load &trap_block[smp_processor_id()] into %g2. */ | 163 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5 |
177 | sethi %hi(trap_block), %g2 | ||
178 | or %g2, %lo(trap_block), %g2 | ||
179 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
180 | add %g2, %g3, %g2 | ||
181 | |||
182 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g5 | ||
183 | rdpr %tl, %g1 | 164 | rdpr %tl, %g1 |
184 | cmp %g1, 1 | 165 | cmp %g1, 1 |
185 | bgu,pn %xcc, winfix_trampoline | 166 | bgu,pn %xcc, winfix_trampoline |
@@ -187,35 +168,17 @@ sun4v_dtlb_prot: | |||
187 | ba,pt %xcc, sparc64_realfault_common | 168 | ba,pt %xcc, sparc64_realfault_common |
188 | mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 | 169 | mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 |
189 | 170 | ||
190 | /* Called from trap table with &trap_block[smp_processor_id()] in | 171 | /* Called from trap table with TAG TARGET placed into |
191 | * %g5 and SCRATCHPAD_UTSBREG1 contents in %g1. | 172 | * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1. |
192 | */ | 173 | */ |
193 | sun4v_itsb_miss: | 174 | sun4v_itsb_miss: |
194 | ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_ADDR_OFFSET], %g4 | ||
195 | ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_CTX_OFFSET], %g5 | ||
196 | |||
197 | srlx %g4, 22, %g7 | ||
198 | sllx %g5, 48, %g6 | ||
199 | or %g6, %g7, %g6 | ||
200 | brz,pn %g5, kvmap_itlb_4v | ||
201 | nop | ||
202 | |||
203 | ba,pt %xcc, sun4v_tsb_miss_common | 175 | ba,pt %xcc, sun4v_tsb_miss_common |
204 | mov FAULT_CODE_ITLB, %g3 | 176 | mov FAULT_CODE_ITLB, %g3 |
205 | 177 | ||
206 | /* Called from trap table with &trap_block[smp_processor_id()] in | 178 | /* Called from trap table with TAG TARGET placed into |
207 | * %g5 and SCRATCHPAD_UTSBREG1 contents in %g1. | 179 | * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1. |
208 | */ | 180 | */ |
209 | sun4v_dtsb_miss: | 181 | sun4v_dtsb_miss: |
210 | ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | ||
211 | ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | ||
212 | |||
213 | srlx %g4, 22, %g7 | ||
214 | sllx %g5, 48, %g6 | ||
215 | or %g6, %g7, %g6 | ||
216 | brz,pn %g5, kvmap_dtlb_4v | ||
217 | nop | ||
218 | |||
219 | mov FAULT_CODE_DTLB, %g3 | 182 | mov FAULT_CODE_DTLB, %g3 |
220 | 183 | ||
221 | /* Create TSB pointer into %g1. This is something like: | 184 | /* Create TSB pointer into %g1. This is something like: |
@@ -239,15 +202,10 @@ sun4v_tsb_miss_common: | |||
239 | 202 | ||
240 | /* Instruction Access Exception, tl0. */ | 203 | /* Instruction Access Exception, tl0. */ |
241 | sun4v_iacc: | 204 | sun4v_iacc: |
242 | mov SCRATCHPAD_CPUID, %g1 | 205 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
243 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | 206 | ldx [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3 |
244 | sethi %hi(trap_block), %g2 | 207 | ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4 |
245 | or %g2, %lo(trap_block), %g2 | 208 | ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5 |
246 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
247 | add %g2, %g3, %g2 | ||
248 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_TYPE_OFFSET], %g3 | ||
249 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_ADDR_OFFSET], %g4 | ||
250 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_CTX_OFFSET], %g5 | ||
251 | sllx %g3, 16, %g3 | 209 | sllx %g3, 16, %g3 |
252 | or %g5, %g3, %g5 | 210 | or %g5, %g3, %g5 |
253 | ba,pt %xcc, etrap | 211 | ba,pt %xcc, etrap |
@@ -260,15 +218,10 @@ sun4v_iacc: | |||
260 | 218 | ||
261 | /* Instruction Access Exception, tl1. */ | 219 | /* Instruction Access Exception, tl1. */ |
262 | sun4v_iacc_tl1: | 220 | sun4v_iacc_tl1: |
263 | mov SCRATCHPAD_CPUID, %g1 | 221 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
264 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | 222 | ldx [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3 |
265 | sethi %hi(trap_block), %g2 | 223 | ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4 |
266 | or %g2, %lo(trap_block), %g2 | 224 | ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5 |
267 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
268 | add %g2, %g3, %g2 | ||
269 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_TYPE_OFFSET], %g3 | ||
270 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_ADDR_OFFSET], %g4 | ||
271 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_CTX_OFFSET], %g5 | ||
272 | sllx %g3, 16, %g3 | 225 | sllx %g3, 16, %g3 |
273 | or %g5, %g3, %g5 | 226 | or %g5, %g3, %g5 |
274 | ba,pt %xcc, etraptl1 | 227 | ba,pt %xcc, etraptl1 |
@@ -281,15 +234,10 @@ sun4v_iacc_tl1: | |||
281 | 234 | ||
282 | /* Data Access Exception, tl0. */ | 235 | /* Data Access Exception, tl0. */ |
283 | sun4v_dacc: | 236 | sun4v_dacc: |
284 | mov SCRATCHPAD_CPUID, %g1 | 237 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
285 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | 238 | ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3 |
286 | sethi %hi(trap_block), %g2 | 239 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 |
287 | or %g2, %lo(trap_block), %g2 | 240 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 |
288 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
289 | add %g2, %g3, %g2 | ||
290 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_TYPE_OFFSET], %g3 | ||
291 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | ||
292 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | ||
293 | sllx %g3, 16, %g3 | 241 | sllx %g3, 16, %g3 |
294 | or %g5, %g3, %g5 | 242 | or %g5, %g3, %g5 |
295 | ba,pt %xcc, etrap | 243 | ba,pt %xcc, etrap |
@@ -302,15 +250,10 @@ sun4v_dacc: | |||
302 | 250 | ||
303 | /* Data Access Exception, tl1. */ | 251 | /* Data Access Exception, tl1. */ |
304 | sun4v_dacc_tl1: | 252 | sun4v_dacc_tl1: |
305 | mov SCRATCHPAD_CPUID, %g1 | 253 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
306 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | 254 | ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3 |
307 | sethi %hi(trap_block), %g2 | 255 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 |
308 | or %g2, %lo(trap_block), %g2 | 256 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 |
309 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
310 | add %g2, %g3, %g2 | ||
311 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_TYPE_OFFSET], %g3 | ||
312 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | ||
313 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | ||
314 | sllx %g3, 16, %g3 | 257 | sllx %g3, 16, %g3 |
315 | or %g5, %g3, %g5 | 258 | or %g5, %g3, %g5 |
316 | ba,pt %xcc, etraptl1 | 259 | ba,pt %xcc, etraptl1 |
@@ -323,15 +266,10 @@ sun4v_dacc_tl1: | |||
323 | 266 | ||
324 | /* Memory Address Unaligned. */ | 267 | /* Memory Address Unaligned. */ |
325 | sun4v_mna: | 268 | sun4v_mna: |
326 | mov SCRATCHPAD_CPUID, %g1 | 269 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
327 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | ||
328 | sethi %hi(trap_block), %g2 | ||
329 | or %g2, %lo(trap_block), %g2 | ||
330 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
331 | add %g2, %g3, %g2 | ||
332 | mov HV_FAULT_TYPE_UNALIGNED, %g3 | 270 | mov HV_FAULT_TYPE_UNALIGNED, %g3 |
333 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | 271 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 |
334 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | 272 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 |
335 | sllx %g3, 16, %g3 | 273 | sllx %g3, 16, %g3 |
336 | or %g5, %g3, %g5 | 274 | or %g5, %g3, %g5 |
337 | 275 | ||
@@ -359,15 +297,10 @@ sun4v_privact: | |||
359 | 297 | ||
360 | /* Unaligned ldd float, tl0. */ | 298 | /* Unaligned ldd float, tl0. */ |
361 | sun4v_lddfmna: | 299 | sun4v_lddfmna: |
362 | mov SCRATCHPAD_CPUID, %g1 | 300 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
363 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | 301 | ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3 |
364 | sethi %hi(trap_block), %g2 | 302 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 |
365 | or %g2, %lo(trap_block), %g2 | 303 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 |
366 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
367 | add %g2, %g3, %g2 | ||
368 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_TYPE_OFFSET], %g3 | ||
369 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | ||
370 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | ||
371 | sllx %g3, 16, %g3 | 304 | sllx %g3, 16, %g3 |
372 | or %g5, %g3, %g5 | 305 | or %g5, %g3, %g5 |
373 | ba,pt %xcc, etrap | 306 | ba,pt %xcc, etrap |
@@ -380,15 +313,10 @@ sun4v_lddfmna: | |||
380 | 313 | ||
381 | /* Unaligned std float, tl0. */ | 314 | /* Unaligned std float, tl0. */ |
382 | sun4v_stdfmna: | 315 | sun4v_stdfmna: |
383 | mov SCRATCHPAD_CPUID, %g1 | 316 | ldxa [%g0] ASI_SCRATCHPAD, %g2 |
384 | ldxa [%g1] ASI_SCRATCHPAD, %g3 | 317 | ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3 |
385 | sethi %hi(trap_block), %g2 | 318 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 |
386 | or %g2, %lo(trap_block), %g2 | 319 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 |
387 | sllx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 | ||
388 | add %g2, %g3, %g2 | ||
389 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_TYPE_OFFSET], %g3 | ||
390 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4 | ||
391 | ldx [%g2 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5 | ||
392 | sllx %g3, 16, %g3 | 320 | sllx %g3, 16, %g3 |
393 | or %g5, %g3, %g5 | 321 | or %g5, %g3, %g5 |
394 | ba,pt %xcc, etrap | 322 | ba,pt %xcc, etrap |
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index c476f5b321fb..88382200c7b8 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -389,10 +389,35 @@ after_lock_tlb: | |||
389 | or %o1, PSTATE_IE, %o1 | 389 | or %o1, PSTATE_IE, %o1 |
390 | wrpr %o1, 0, %pstate | 390 | wrpr %o1, 0, %pstate |
391 | 391 | ||
392 | call prom_set_trap_table | 392 | sethi %hi(is_sun4v), %o0 |
393 | lduw [%o0 + %lo(is_sun4v)], %o0 | ||
394 | brz,pt %o0, 1f | ||
395 | nop | ||
396 | |||
397 | TRAP_LOAD_TRAP_BLOCK(%g2, %g3) | ||
398 | add %g2, TRAP_PER_CPU_FAULT_INFO, %g2 | ||
399 | stxa %g2, [%g0] ASI_SCRATCHPAD | ||
400 | |||
401 | /* Compute physical address: | ||
402 | * | ||
403 | * paddr = kern_base + (mmfsa_vaddr - KERNBASE) | ||
404 | */ | ||
405 | sethi %hi(KERNBASE), %g3 | ||
406 | sub %g2, %g3, %g2 | ||
407 | sethi %hi(kern_base), %g3 | ||
408 | ldx [%g3 + %lo(kern_base)], %g3 | ||
409 | add %g2, %g3, %o1 | ||
410 | |||
411 | call prom_set_trap_table_sun4v | ||
412 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
413 | |||
414 | ba,pt %xcc, 2f | ||
415 | nop | ||
416 | |||
417 | 1: call prom_set_trap_table | ||
393 | sethi %hi(sparc64_ttable_tl0), %o0 | 418 | sethi %hi(sparc64_ttable_tl0), %o0 |
394 | 419 | ||
395 | call smp_callin | 420 | 2: call smp_callin |
396 | nop | 421 | nop |
397 | call cpu_idle | 422 | call cpu_idle |
398 | mov 0, %o0 | 423 | mov 0, %o0 |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 7faba33202a9..88eb6f6be562 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -1109,24 +1109,6 @@ static void __init tsb_phys_patch(void) | |||
1109 | } | 1109 | } |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* Register this cpu's fault status area with the hypervisor. */ | ||
1113 | void __cpuinit sun4v_register_fault_status(void) | ||
1114 | { | ||
1115 | register unsigned long func asm("%o5"); | ||
1116 | register unsigned long arg0 asm("%o0"); | ||
1117 | int cpu = hard_smp_processor_id(); | ||
1118 | struct trap_per_cpu *tb = &trap_block[cpu]; | ||
1119 | unsigned long pa; | ||
1120 | |||
1121 | pa = kern_base + ((unsigned long) tb - KERNBASE); | ||
1122 | func = HV_FAST_MMU_FAULT_AREA_CONF; | ||
1123 | arg0 = pa; | ||
1124 | __asm__ __volatile__("ta %4" | ||
1125 | : "=&r" (func), "=&r" (arg0) | ||
1126 | : "0" (func), "1" (arg0), | ||
1127 | "i" (HV_FAST_TRAP)); | ||
1128 | } | ||
1129 | |||
1130 | /* paging_init() sets up the page tables */ | 1112 | /* paging_init() sets up the page tables */ |
1131 | 1113 | ||
1132 | extern void cheetah_ecache_flush_init(void); | 1114 | extern void cheetah_ecache_flush_init(void); |
@@ -1147,10 +1129,8 @@ void __init paging_init(void) | |||
1147 | tlb_type == hypervisor) | 1129 | tlb_type == hypervisor) |
1148 | tsb_phys_patch(); | 1130 | tsb_phys_patch(); |
1149 | 1131 | ||
1150 | if (tlb_type == hypervisor) { | 1132 | if (tlb_type == hypervisor) |
1151 | sun4v_patch_tlb_handlers(); | 1133 | sun4v_patch_tlb_handlers(); |
1152 | sun4v_register_fault_status(); | ||
1153 | } | ||
1154 | 1134 | ||
1155 | /* Find available physical memory... */ | 1135 | /* Find available physical memory... */ |
1156 | read_obp_memory("available", &pavail[0], &pavail_ents); | 1136 | read_obp_memory("available", &pavail[0], &pavail_ents); |
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 87f5cfce23bb..713cbac5f9bf 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c | |||
@@ -136,6 +136,11 @@ void prom_set_trap_table(unsigned long tba) | |||
136 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); | 136 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); |
137 | } | 137 | } |
138 | 138 | ||
139 | void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa) | ||
140 | { | ||
141 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(2, 0), tba, mmfsa); | ||
142 | } | ||
143 | |||
139 | int prom_get_mmu_ihandle(void) | 144 | int prom_get_mmu_ihandle(void) |
140 | { | 145 | { |
141 | int node, ret; | 146 | int node, ret; |
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 338b0ca5b519..5a970f5ed9bd 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h | |||
@@ -156,13 +156,16 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | |||
156 | nop; \ | 156 | nop; \ |
157 | .previous; | 157 | .previous; |
158 | 158 | ||
159 | /* Clobbers TMP, current address space PGD phys address into DEST. */ | 159 | #define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ |
160 | #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ | ||
161 | __GET_CPUID(TMP) \ | 160 | __GET_CPUID(TMP) \ |
162 | sethi %hi(trap_block), DEST; \ | 161 | sethi %hi(trap_block), DEST; \ |
163 | sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ | 162 | sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ |
164 | or DEST, %lo(trap_block), DEST; \ | 163 | or DEST, %lo(trap_block), DEST; \ |
165 | add DEST, TMP, DEST; \ | 164 | add DEST, TMP, DEST; \ |
165 | |||
166 | /* Clobbers TMP, current address space PGD phys address into DEST. */ | ||
167 | #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ | ||
168 | TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ | ||
166 | ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; | 169 | ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; |
167 | 170 | ||
168 | /* Clobbers TMP, loads local processor's IRQ work area into DEST. */ | 171 | /* Clobbers TMP, loads local processor's IRQ work area into DEST. */ |
@@ -175,11 +178,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | |||
175 | 178 | ||
176 | /* Clobbers TMP, loads DEST with current thread info pointer. */ | 179 | /* Clobbers TMP, loads DEST with current thread info pointer. */ |
177 | #define TRAP_LOAD_THREAD_REG(DEST, TMP) \ | 180 | #define TRAP_LOAD_THREAD_REG(DEST, TMP) \ |
178 | __GET_CPUID(TMP) \ | 181 | TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ |
179 | sethi %hi(trap_block), DEST; \ | 182 | ldx [DEST + TRAP_PER_CPU_THREAD], DEST; |
180 | sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ | ||
181 | or DEST, %lo(trap_block), DEST; \ | ||
182 | ldx [DEST + TMP], DEST; | ||
183 | 183 | ||
184 | /* Given the current thread info pointer in THR, load the per-cpu | 184 | /* Given the current thread info pointer in THR, load the per-cpu |
185 | * area base of the current processor into DEST. REG1, REG2, and REG3 are | 185 | * area base of the current processor into DEST. REG1, REG2, and REG3 are |
@@ -201,13 +201,13 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | |||
201 | 201 | ||
202 | #else | 202 | #else |
203 | 203 | ||
204 | #define __GET_CPUID(REG) \ | 204 | #define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ |
205 | mov 0, REG; | 205 | sethi %hi(trap_block), DEST; \ |
206 | or DEST, %lo(trap_block), DEST; \ | ||
206 | 207 | ||
207 | /* Uniprocessor versions, we know the cpuid is zero. */ | 208 | /* Uniprocessor versions, we know the cpuid is zero. */ |
208 | #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ | 209 | #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ |
209 | sethi %hi(trap_block), DEST; \ | 210 | TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ |
210 | or DEST, %lo(trap_block), DEST; \ | ||
211 | ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; | 211 | ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; |
212 | 212 | ||
213 | #define TRAP_LOAD_IRQ_WORK(DEST, TMP) \ | 213 | #define TRAP_LOAD_IRQ_WORK(DEST, TMP) \ |
@@ -215,8 +215,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | |||
215 | or DEST, %lo(__irq_work), DEST; | 215 | or DEST, %lo(__irq_work), DEST; |
216 | 216 | ||
217 | #define TRAP_LOAD_THREAD_REG(DEST, TMP) \ | 217 | #define TRAP_LOAD_THREAD_REG(DEST, TMP) \ |
218 | sethi %hi(trap_block), DEST; \ | 218 | TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ |
219 | ldx [DEST + %lo(trap_block)], DEST; | 219 | ldx [DEST + TRAP_PER_CPU_THREAD], DEST; |
220 | 220 | ||
221 | /* No per-cpu areas on uniprocessor, so no need to load DEST. */ | 221 | /* No per-cpu areas on uniprocessor, so no need to load DEST. */ |
222 | #define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) | 222 | #define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) |
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index 2ea545b931b0..ce5066ef2dd0 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h | |||
@@ -338,6 +338,7 @@ int cpu_find_by_mid(int mid, int *prom_node); | |||
338 | 338 | ||
339 | /* Client interface level routines. */ | 339 | /* Client interface level routines. */ |
340 | extern void prom_set_trap_table(unsigned long tba); | 340 | extern void prom_set_trap_table(unsigned long tba); |
341 | extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa); | ||
341 | 342 | ||
342 | extern long p1275_cmd(const char *, long, ...); | 343 | extern long p1275_cmd(const char *, long, ...); |
343 | 344 | ||
diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 972f913709a3..6bb86a7a5b42 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h | |||
@@ -180,25 +180,25 @@ | |||
180 | #define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl) | 180 | #define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl) |
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | #define SUN4V_ITSB_MISS \ | 183 | #define SUN4V_ITSB_MISS \ |
184 | mov SCRATCHPAD_CPUID, %g1; \ | 184 | ldxa [%g0] ASI_SCRATCHPAD, %g2; \ |
185 | ldxa [%g1] ASI_SCRATCHPAD, %g2; \ | 185 | ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4; \ |
186 | ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1;\ | 186 | ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5; \ |
187 | sethi %hi(trap_block), %g5; \ | 187 | srlx %g4, 22, %g7; \ |
188 | sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2; \ | 188 | sllx %g5, 48, %g6; \ |
189 | or %g5, %lo(trap_block), %g5; \ | 189 | brz,pn %g5, kvmap_itlb_4v; \ |
190 | ba,pt %xcc, sun4v_itsb_miss; \ | 190 | or %g6, %g7, %g6; \ |
191 | add %g5, %g2, %g5; | 191 | ba,a,pt %xcc, sun4v_itsb_miss; |
192 | 192 | ||
193 | #define SUN4V_DTSB_MISS \ | 193 | #define SUN4V_DTSB_MISS \ |
194 | mov SCRATCHPAD_CPUID, %g1; \ | 194 | ldxa [%g0] ASI_SCRATCHPAD, %g2; \ |
195 | ldxa [%g1] ASI_SCRATCHPAD, %g2; \ | 195 | ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \ |
196 | ldxa [%g1 + %g1] ASI_SCRATCHPAD, %g1;\ | 196 | ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \ |
197 | sethi %hi(trap_block), %g5; \ | 197 | srlx %g4, 22, %g7; \ |
198 | sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2; \ | 198 | sllx %g5, 48, %g6; \ |
199 | or %g5, %lo(trap_block), %g5; \ | 199 | brz,pn %g5, kvmap_dtlb_4v; \ |
200 | ba,pt %xcc, sun4v_dtsb_miss; \ | 200 | or %g6, %g7, %g6; \ |
201 | add %g5, %g2, %g5; | 201 | ba,a,pt %xcc, sun4v_dtsb_miss; |
202 | 202 | ||
203 | /* Before touching these macros, you owe it to yourself to go and | 203 | /* Before touching these macros, you owe it to yourself to go and |
204 | * see how arch/sparc64/kernel/winfixup.S works... -DaveM | 204 | * see how arch/sparc64/kernel/winfixup.S works... -DaveM |