diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-02-13 14:07:31 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-02-13 14:07:31 +0000 |
commit | a39abfe300fee0e53216f744f86e1b2d36ee97c4 (patch) | |
tree | c7a741c0d6e2724811aaf2949f3ec07c9a195ca7 | |
parent | e124446575d590a7ba2232d8ad8f2cbd1be155ca (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.S | 146 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/machdep.c | 10 |
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); /* |