summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-02-13 14:07:31 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-02-13 14:07:31 +0000
commita39abfe300fee0e53216f744f86e1b2d36ee97c4 (patch)
treec7a741c0d6e2724811aaf2949f3ec07c9a195ca7
parente124446575d590a7ba2232d8ad8f2cbd1be155ca (diff)
Since the TLB handler exception code is now always a trampoline to branch
to the handler code in the kernel, we can use relative branches in it to make it a bit faster. Also, get rid of the tlbmiss handler and have both the tlb and xtlb refill exceptions branch to the xtlbmiss handler.
-rw-r--r--sys/arch/mips64/mips64/tlbhandler.S146
-rw-r--r--sys/arch/sgi/sgi/machdep.c10
2 files changed, 51 insertions, 105 deletions
diff --git a/sys/arch/mips64/mips64/tlbhandler.S b/sys/arch/mips64/mips64/tlbhandler.S
index ce2b0cdeceb..f1ee520ed40 100644
--- a/sys/arch/mips64/mips64/tlbhandler.S
+++ b/sys/arch/mips64/mips64/tlbhandler.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: tlbhandler.S,v 1.30 2010/02/01 05:26:17 miod Exp $ */
+/* $OpenBSD: tlbhandler.S,v 1.31 2010/02/13 14:07:30 miod Exp $ */
/*
* Copyright (c) 1995-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -47,19 +47,17 @@
.set noreorder /* Default reorder mode */
/*---------------------------------------------------------------- tlb_miss
- * Low level TLB exception handler. TLB and XTLB share some
- * code for the moment and is copied down at the same time.
- * This code must be PIC and not more than 64 instructions
- * for both TLB and XTLB handling or it will overflow the
- * available storage. If the startup code finds out that it
- * is larger, the trampoline code is copied instead of panicing.
+ * Low level TLB exception handler. TLB and XTLB code are
+ * identical at the moment.
+ * This code is not copied to the exception area, instead
+ * trampolines branching to the appropriate code are built.
*/
.set noat
#if defined(CPU_R5000) || defined(CPU_RM7000)
- .globl tlb_miss_err_r5k
- .ent tlb_miss_err_r5k, 0
-tlb_miss_err_r5k:
+ .globl xtlb_miss_err_r5k
+ .ent xtlb_miss_err_r5k, 0
+xtlb_miss_err_r5k:
/*
* R5000 errata: edge cases can trigger a TLB miss exception
* instead of an invalid TLB exception. Servicing the TLB miss
@@ -76,32 +74,36 @@ tlb_miss_err_r5k:
*/
tlbp
mfc0 k1, COP_0_TLB_INDEX
- bltz k1, tlb_miss # missing!
+ bltz k1, xtlb_miss # missing!
nop
- j k_tlb_inv
+ b k_tlb_inv
nop
- .end tlb_miss_err_r5k
+ .end xtlb_miss_err_r5k
#endif /* CPU_R5000 || CPU_RM7000 */
- .globl tlb_miss
- .ent tlb_miss, 0
-tlb_miss:
+ .globl xtlb_miss
+ .ent xtlb_miss, 0
+xtlb_miss:
+ dmfc0 k0, COP_0_BAD_VADDR
+ bltz k0, _k_miss # kernel address space
+ PTR_SRL k0, k0, SEGSHIFT
+ sltiu k1, k0, PMAP_SEGTABSIZE
+ beqz k1, _inv_seg # wrong if outside pm_segtab
+ nop
GET_CPU_INFO(k1, k0)
PTR_L k1, CI_CURPROCPADDR(k1)
dmfc0 k0, COP_0_BAD_VADDR
- bltz k0, _k_miss # kernel address space
- PTR_SRL k0, k0, SEGSHIFT - LOGREGSZ
+ PTR_SRL k0, k0, SEGSHIFT
+ PTR_SLL k0, k0, LOGREGSZ
PTR_L k1, PCB_SEGTAB(k1)
- andi k0, k0, (PMAP_SEGTABSIZE - 1) << LOGREGSZ
PTR_ADDU k1, k1, k0
PTR_L k1, 0(k1) # get pointer to page table
dmfc0 k0, COP_0_BAD_VADDR
PTR_SRL k0, k0, PGSHIFT - 2
andi k0, k0, ((NPTEPG/2) - 1) << 3
- beqz k1, _inv_seg # invalid segment map
- PTR_ADDU k1, k1, k0 # index into segment map
- lw k0, 0(k1) # get page PTE
-tlb_load:
+ beqz k1, _inv_seg
+ PTR_ADDU k1, k1, k0
+ lw k0, 0(k1)
lw k1, 4(k1)
dsll k0, k0, 34
dsrl k0, k0, 34
@@ -114,7 +116,7 @@ tlb_load:
nop
nop
tlbwr # update TLB
- nop
+ nop # RM7000 need 4 for JTLB usage.
nop
nop
nop
@@ -124,70 +126,36 @@ tlb_load:
dmtc0 k0, COP_0_DIAG
#endif
- eret # RM7000 need 4 for JTLB usage.
- .end tlb_miss
-
-/*---------------------------------------------------------------- xtlb_miss
- * Low level XTLB exception handler.
- */
-#if defined(CPU_R5000) || defined(CPU_RM7000)
- .globl xtlb_miss_err_r5k
- .ent xtlb_miss_err_r5k, 0
-xtlb_miss_err_r5k:
- /* See errata comments in tlb_miss above */
- tlbp
- mfc0 k1, COP_0_TLB_INDEX
- bltz k1, xtlb_miss # missing!
- nop
- j k_tlb_inv
- nop
- .end xtlb_miss_err_r5k
-#endif /* CPU_R5000 || CPU_RM7000 */
-
- .globl xtlb_miss
- .ent xtlb_miss, 0
-xtlb_miss:
- dmfc0 k0, COP_0_BAD_VADDR
- bltz k0, _k_miss # kernel address space
- PTR_SRL k0, k0, SEGSHIFT
- sltiu k1, k0, PMAP_SEGTABSIZE
- beqz k1, _inv_seg # wrong if outside pm_segtab
- nop
- GET_CPU_INFO(k1, k0)
- PTR_L k1, CI_CURPROCPADDR(k1)
- dmfc0 k0, COP_0_BAD_VADDR
- PTR_SRL k0, k0, SEGSHIFT
- PTR_SLL k0, k0, LOGREGSZ
- PTR_L k1, PCB_SEGTAB(k1)
- PTR_ADDU k1, k1, k0
- PTR_L k1, 0(k1) # get pointer to page table
- dmfc0 k0, COP_0_BAD_VADDR
- PTR_SRL k0, k0, PGSHIFT - 2
- andi k0, k0, ((NPTEPG/2) - 1) << 3
- beqz k1, _inv_seg
- PTR_ADDU k1, k1, k0
- b tlb_load # rest is same as 'tlb_miss'
- lw k0, 0(k1)
-
-_inv_seg:
- j tlb_miss_nopt # No page table for this segment.
- nop
+ eret
_k_miss:
- j k_tlb_miss # kernel tlbmiss.
+ b k_tlb_miss # kernel tlbmiss.
dmfc0 k0, COP_0_BAD_VADDR # must reload.
- .end xtlb_miss
- .globl tlb_miss_nopt
- .ent tlb_miss_nopt, 0
-tlb_miss_nopt:
+_inv_seg: # No page table for this segment.
mfc0 k0, COP_0_STATUS_REG
andi k0, SR_KSU_USER
bne k0, zero, go_u_general
nop
+ b go_k_general
+ nop
+
+go_k_general:
j k_general
nop
- .end tlb_miss_nopt
+go_u_general:
+#ifdef CPU_LOONGSON2
+ /*
+ * To work around a branch prediction issue on earlier LS2F
+ * chips, it is necessary to clear the BTB upon
+ * userland->kernel boundaries.
+ */
+ li k0, COP_0_DIAG_BTB_CLEAR | COP_0_DIAG_RAS_DISABLE
+ dmtc0 k0, COP_0_DIAG
+#endif
+ j u_general
+ nop
+ .end xtlb_miss
.set at
@@ -254,7 +222,7 @@ k_tlb_inv_odd:
dsrl k0, k0, 34
dmtc0 k0, COP_0_TLB_LO1 # save PTE entry
and k0, k0, PG_V # check for valid entry
- beq k0, zero, go_k_general # PTE invalid
+ beq k0, zero, go_k_general # PTE invalid
lw k0, -4(k1) # get even PTE entry
dsll k0, k0, 34
dsrl k0, k0, 34
@@ -363,24 +331,6 @@ sys_stk_chk:
PANIC("kernel stack overflow")
/*noreturn*/
-go_k_general:
- j k_general
- nop
-
-go_u_general:
-#ifdef CPU_LOONGSON2
- /*
- * To work around a branch prediction issue on earlier LS2F
- * chips, it is necessary to clear the BTB upon
- * userland->kernel boundaries.
- */
- li k0, COP_0_DIAG_BTB_CLEAR | COP_0_DIAG_RAS_DISABLE
- dmtc0 k0, COP_0_DIAG
-#endif
- j u_general
- nop
-
-
.data
1:
.asciiz "\rktlbmiss: PC %p RA %p ADR %p\nSR %p CR %p SP %p\n"
@@ -391,7 +341,7 @@ go_u_general:
.set at
END(k_tlb_miss)
-#if 0
+#if 0 /* currently unused */
/*---------------------------------------------------------------- tlb_write_i
* Write the given entry into the TLB at the given index.
*/
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index bae4b29b70c..8f5e6a7b042 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.98 2010/01/22 21:45:26 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.99 2010/02/13 14:07:30 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -144,7 +144,7 @@ mips_init(int argc, void *argv, caddr_t boot_esym)
char *cp;
int i;
u_int cputype;
- vaddr_t tlb_handler, xtlb_handler;
+ vaddr_t xtlb_handler;
extern char start[], edata[], end[];
extern char exception[], e_exception[];
extern char *hw_vendor;
@@ -466,24 +466,20 @@ mips_init(int argc, void *argv, caddr_t boot_esym)
* This is also necessary on RM52x0 and most RM7k/RM9k,
* and is a documented errata for these chips.
*/
- extern void tlb_miss_err_r5k;
extern void xtlb_miss_err_r5k;
- tlb_handler = (vaddr_t)&tlb_miss_err_r5k;
xtlb_handler = (vaddr_t)&xtlb_miss_err_r5k;
}
break;
#endif
default:
{
- extern void tlb_miss;
extern void xtlb_miss;
- tlb_handler = (vaddr_t)&tlb_miss;
xtlb_handler = (vaddr_t)&xtlb_miss;
}
break;
}
- build_trampoline(TLB_MISS_EXC_VEC, tlb_handler);
+ build_trampoline(TLB_MISS_EXC_VEC, xtlb_handler);
build_trampoline(XTLB_MISS_EXC_VEC, xtlb_handler);
/*