diff options
author | David S. Miller <davem@davemloft.net> | 2011-08-05 03:53:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-08-05 03:53:57 -0400 |
commit | 9076d0e7e02b98f7a65df10d1956326c8d8ba61a (patch) | |
tree | ef7d3b694a7365ad8be871c2e892c7454c4b31c2 /arch/sparc/include/asm | |
parent | a61b582954183e93a3dc3a5cf6bfd2e2c3b40aba (diff) |
sparc: Access kernel TSB using physical addressing when possible.
On sun4v this is basically required since we point the hypervisor and
the TSB walking hardware at these tables using physical addressing
too.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/include/asm')
-rw-r--r-- | arch/sparc/include/asm/tsb.h | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 83c571d8c8a7..1a8afd1ad04f 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h | |||
@@ -133,29 +133,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
133 | sub TSB, 0x8, TSB; \ | 133 | sub TSB, 0x8, TSB; \ |
134 | TSB_STORE(TSB, TAG); | 134 | TSB_STORE(TSB, TAG); |
135 | 135 | ||
136 | #define KTSB_LOAD_QUAD(TSB, REG) \ | ||
137 | ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; | ||
138 | |||
139 | #define KTSB_STORE(ADDR, VAL) \ | ||
140 | stxa VAL, [ADDR] ASI_N; | ||
141 | |||
142 | #define KTSB_LOCK_TAG(TSB, REG1, REG2) \ | ||
143 | 99: lduwa [TSB] ASI_N, REG1; \ | ||
144 | sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ | ||
145 | andcc REG1, REG2, %g0; \ | ||
146 | bne,pn %icc, 99b; \ | ||
147 | nop; \ | ||
148 | casa [TSB] ASI_N, REG1, REG2;\ | ||
149 | cmp REG1, REG2; \ | ||
150 | bne,pn %icc, 99b; \ | ||
151 | nop; \ | ||
152 | |||
153 | #define KTSB_WRITE(TSB, TTE, TAG) \ | ||
154 | add TSB, 0x8, TSB; \ | ||
155 | stxa TTE, [TSB] ASI_N; \ | ||
156 | sub TSB, 0x8, TSB; \ | ||
157 | stxa TAG, [TSB] ASI_N; | ||
158 | |||
159 | /* Do a kernel page table walk. Leaves physical PTE pointer in | 136 | /* Do a kernel page table walk. Leaves physical PTE pointer in |
160 | * REG1. Jumps to FAIL_LABEL on early page table walk termination. | 137 | * REG1. Jumps to FAIL_LABEL on early page table walk termination. |
161 | * VADDR will not be clobbered, but REG2 will. | 138 | * VADDR will not be clobbered, but REG2 will. |
@@ -239,6 +216,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
239 | (KERNEL_TSB_SIZE_BYTES / 16) | 216 | (KERNEL_TSB_SIZE_BYTES / 16) |
240 | #define KERNEL_TSB4M_NENTRIES 4096 | 217 | #define KERNEL_TSB4M_NENTRIES 4096 |
241 | 218 | ||
219 | #define KTSB_PHYS_SHIFT 15 | ||
220 | |||
242 | /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL | 221 | /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL |
243 | * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries | 222 | * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries |
244 | * and the found TTE will be left in REG1. REG3 and REG4 must | 223 | * and the found TTE will be left in REG1. REG3 and REG4 must |
@@ -247,13 +226,22 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
247 | * VADDR and TAG will be preserved and not clobbered by this macro. | 226 | * VADDR and TAG will be preserved and not clobbered by this macro. |
248 | */ | 227 | */ |
249 | #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ | 228 | #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ |
250 | sethi %hi(swapper_tsb), REG1; \ | 229 | 661: sethi %hi(swapper_tsb), REG1; \ |
251 | or REG1, %lo(swapper_tsb), REG1; \ | 230 | or REG1, %lo(swapper_tsb), REG1; \ |
231 | .section .swapper_tsb_phys_patch, "ax"; \ | ||
232 | .word 661b; \ | ||
233 | .previous; \ | ||
234 | 661: nop; \ | ||
235 | .section .tsb_ldquad_phys_patch, "ax"; \ | ||
236 | .word 661b; \ | ||
237 | sllx REG1, KTSB_PHYS_SHIFT, REG1; \ | ||
238 | sllx REG1, KTSB_PHYS_SHIFT, REG1; \ | ||
239 | .previous; \ | ||
252 | srlx VADDR, PAGE_SHIFT, REG2; \ | 240 | srlx VADDR, PAGE_SHIFT, REG2; \ |
253 | and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ | 241 | and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ |
254 | sllx REG2, 4, REG2; \ | 242 | sllx REG2, 4, REG2; \ |
255 | add REG1, REG2, REG2; \ | 243 | add REG1, REG2, REG2; \ |
256 | KTSB_LOAD_QUAD(REG2, REG3); \ | 244 | TSB_LOAD_QUAD(REG2, REG3); \ |
257 | cmp REG3, TAG; \ | 245 | cmp REG3, TAG; \ |
258 | be,a,pt %xcc, OK_LABEL; \ | 246 | be,a,pt %xcc, OK_LABEL; \ |
259 | mov REG4, REG1; | 247 | mov REG4, REG1; |
@@ -263,12 +251,21 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
263 | * we can make use of that for the index computation. | 251 | * we can make use of that for the index computation. |
264 | */ | 252 | */ |
265 | #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ | 253 | #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ |
266 | sethi %hi(swapper_4m_tsb), REG1; \ | 254 | 661: sethi %hi(swapper_4m_tsb), REG1; \ |
267 | or REG1, %lo(swapper_4m_tsb), REG1; \ | 255 | or REG1, %lo(swapper_4m_tsb), REG1; \ |
256 | .section .swapper_4m_tsb_phys_patch, "ax"; \ | ||
257 | .word 661b; \ | ||
258 | .previous; \ | ||
259 | 661: nop; \ | ||
260 | .section .tsb_ldquad_phys_patch, "ax"; \ | ||
261 | .word 661b; \ | ||
262 | sllx REG1, KTSB_PHYS_SHIFT, REG1; \ | ||
263 | sllx REG1, KTSB_PHYS_SHIFT, REG1; \ | ||
264 | .previous; \ | ||
268 | and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ | 265 | and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ |
269 | sllx REG2, 4, REG2; \ | 266 | sllx REG2, 4, REG2; \ |
270 | add REG1, REG2, REG2; \ | 267 | add REG1, REG2, REG2; \ |
271 | KTSB_LOAD_QUAD(REG2, REG3); \ | 268 | TSB_LOAD_QUAD(REG2, REG3); \ |
272 | cmp REG3, TAG; \ | 269 | cmp REG3, TAG; \ |
273 | be,a,pt %xcc, OK_LABEL; \ | 270 | be,a,pt %xcc, OK_LABEL; \ |
274 | mov REG4, REG1; | 271 | mov REG4, REG1; |