diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-09 19:12:22 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:05 -0500 |
commit | aa9143b9719c07fb6f1f6207790c9c5086ae07e7 (patch) | |
tree | 74d56ecc53ed0542f200d6c6257c8f051095111c /arch/sparc64/kernel/sun4v_tlb_miss.S | |
parent | 12816ab38adddc9d7e9b3315d1739655dedc7c9f (diff) |
[SPARC64]: Implement sun4v TSB miss handlers.
When we register a TSB with the hypervisor, so that it or hardware can
handle TLB misses and do the TSB walk for us, the hypervisor traps
down to these trap when it incurs a TSB miss.
Processing is simple, we load the missing virtual address and context,
and do a full page table walk.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/sun4v_tlb_miss.S')
-rw-r--r-- | arch/sparc64/kernel/sun4v_tlb_miss.S | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S index 58ea5dd8573c..b8678b5557aa 100644 --- a/arch/sparc64/kernel/sun4v_tlb_miss.S +++ b/arch/sparc64/kernel/sun4v_tlb_miss.S | |||
@@ -187,6 +187,57 @@ sun4v_dtlb_prot: | |||
187 | ba,pt %xcc, sparc64_realfault_common | 187 | ba,pt %xcc, sparc64_realfault_common |
188 | mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 | 188 | mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 |
189 | 189 | ||
190 | /* Called from trap table with &trap_block[smp_processor_id()] in | ||
191 | * %g5 and SCRATCHPAD_UTSBREG1 contents in %g1. | ||
192 | */ | ||
193 | 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 | ||
204 | mov FAULT_CODE_ITLB, %g3 | ||
205 | |||
206 | /* Called from trap table with &trap_block[smp_processor_id()] in | ||
207 | * %g5 and SCRATCHPAD_UTSBREG1 contents in %g1. | ||
208 | */ | ||
209 | 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 | ||
220 | |||
221 | /* Create TSB pointer into %g1. This is something like: | ||
222 | * | ||
223 | * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL; | ||
224 | * tsb_base = tsb_reg & ~0x7UL; | ||
225 | * tsb_index = ((vaddr >> PAGE_SHIFT) & tsb_mask); | ||
226 | * tsb_ptr = tsb_base + (tsb_index * 16); | ||
227 | */ | ||
228 | sun4v_tsb_miss_common: | ||
229 | and %g1, 0x7, %g2 | ||
230 | andn %g1, 0x7, %g1 | ||
231 | mov 512, %g7 | ||
232 | sllx %g7, %g2, %g7 | ||
233 | sub %g7, 1, %g7 | ||
234 | srlx %g4, PAGE_SHIFT, %g2 | ||
235 | and %g2, %g7, %g2 | ||
236 | sllx %g2, 4, %g2 | ||
237 | ba,pt %xcc, tsb_miss_page_table_walk | ||
238 | add %g1, %g2, %g1 | ||
239 | |||
240 | |||
190 | #define BRANCH_ALWAYS 0x10680000 | 241 | #define BRANCH_ALWAYS 0x10680000 |
191 | #define NOP 0x01000000 | 242 | #define NOP 0x01000000 |
192 | #define SUN4V_DO_PATCH(OLD, NEW) \ | 243 | #define SUN4V_DO_PATCH(OLD, NEW) \ |