summaryrefslogtreecommitdiff
path: root/arch/sparc64/kernel/sun4v_tlb_miss.S
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-09 16:12:22 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 01:12:05 -0800
commitaa9143b9719c07fb6f1f6207790c9c5086ae07e7 (patch)
tree74d56ecc53ed0542f200d6c6257c8f051095111c /arch/sparc64/kernel/sun4v_tlb_miss.S
parent12816ab38adddc9d7e9b3315d1739655dedc7c9f (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.S51
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:
ba,pt %xcc, sparc64_realfault_common
mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4
+ /* Called from trap table with &trap_block[smp_processor_id()] in
+ * %g5 and SCRATCHPAD_UTSBREG1 contents in %g1.
+ */
+sun4v_itsb_miss:
+ ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_ADDR_OFFSET], %g4
+ ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_I_CTX_OFFSET], %g5
+
+ srlx %g4, 22, %g7
+ sllx %g5, 48, %g6
+ or %g6, %g7, %g6
+ brz,pn %g5, kvmap_itlb_4v
+ nop
+
+ ba,pt %xcc, sun4v_tsb_miss_common
+ mov FAULT_CODE_ITLB, %g3
+
+ /* Called from trap table with &trap_block[smp_processor_id()] in
+ * %g5 and SCRATCHPAD_UTSBREG1 contents in %g1.
+ */
+sun4v_dtsb_miss:
+ ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_ADDR_OFFSET], %g4
+ ldx [%g5 + TRAP_PER_CPU_FAULT_INFO + HV_FAULT_D_CTX_OFFSET], %g5
+
+ srlx %g4, 22, %g7
+ sllx %g5, 48, %g6
+ or %g6, %g7, %g6
+ brz,pn %g5, kvmap_dtlb_4v
+ nop
+
+ mov FAULT_CODE_DTLB, %g3
+
+ /* Create TSB pointer into %g1. This is something like:
+ *
+ * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
+ * tsb_base = tsb_reg & ~0x7UL;
+ * tsb_index = ((vaddr >> PAGE_SHIFT) & tsb_mask);
+ * tsb_ptr = tsb_base + (tsb_index * 16);
+ */
+sun4v_tsb_miss_common:
+ and %g1, 0x7, %g2
+ andn %g1, 0x7, %g1
+ mov 512, %g7
+ sllx %g7, %g2, %g7
+ sub %g7, 1, %g7
+ srlx %g4, PAGE_SHIFT, %g2
+ and %g2, %g7, %g2
+ sllx %g2, 4, %g2
+ ba,pt %xcc, tsb_miss_page_table_walk
+ add %g1, %g2, %g1
+
+
#define BRANCH_ALWAYS 0x10680000
#define NOP 0x01000000
#define SUN4V_DO_PATCH(OLD, NEW) \