Date: Tue, 3 Jun 2003 00:14:19 -0700 (PDT) From: Juli Mallett <jmallett@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 32463 for review Message-ID: <200306030714.h537EJKT046915@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=32463 Change 32463 by jmallett@jmallett_dalek on 2003/06/03 00:14:11 Fill in VCED handler. Fill in fake interrupt handler (panic). Write something for when we encounter a bad PTE: return to panic. Fill in a cheap attempt at handling 64-bit TLB misses. Fill in a return to panic for 32-bit TLB misses. Clarify that the SP needs fixed up after restoring registers, not before. Pass in the trapframe for restoring registers based on sp, don't rely on a0 being the same. And finally, finish filling up the generic exception vector (0 bytes free) by putting in some code to switch the ExcCode value. Maybe NetBSD's idea of a jump table isn't so bad, but it makes PIC worse. Affected files ... .. //depot/projects/mips/sys/mips/mips/exception.S#4 edit Differences ... ==== //depot/projects/mips/sys/mips/mips/exception.S#4 (text+ko) ==== @@ -12,7 +12,10 @@ #include "opt_ddb.h" #include <machine/asm.h> +#include <machine/cache_r4k.h> #include <machine/cpuregs.h> +#include <machine/param.h> +#include <machine/pte.h> #include "assym.s" @@ -38,6 +41,45 @@ */ LEAF(ExceptionVector) .set noat + /* + * Interrupts are fast. Let everything else go through trap(). + */ + mfc0 k0, MIPS_COP_0_CAUSE + li k1, 31 << 2 + and k0, k1 + beq k0, zero, Interrupt + nop + + /* + * If all the bits were set, it's 31, it's VCED, so go there. + */ + bne k0, k1, 1f + nop + + J VCED + /* No BDSlot, save space by just pulling in the next insn. */ + +1: + /* + * Except stuff the TLB handler really wants. (TLB exceptions + * that are not TLBMod, that goes through trap() and into pmap.) + * This means that if this is one, or has bits outside of the + * three lowest set, we need to go ahead. Otherwise, switch to + * the TLB miss handler. + */ + li k1, 1 << 2 + beq k1, k0, 1f + nop + + li k1, ~(3 << 2) + and k1, k0 + bne k1, zero, 1f + nop + + j XTLBMissVector + nop + +1: dsubu sp, sp, TF_SIZE dla k0, 1f j exception_save_registers @@ -66,6 +108,7 @@ move a0, k1 jal exception_restore_registers + nop daddu sp, sp, TF_SIZE eret .set at @@ -90,6 +133,7 @@ move a0, k1 jal exception_restore_registers + move a0, sp daddu sp, sp, TF_SIZE eret .set at @@ -97,19 +141,110 @@ LEAF(TLBMissVector) .set noat - j ExceptionVector - nop + dla a0, 1f + dla k0, panic + dmtc0 k0, MIPS_COP_0_EXC_PC + eret .set at VEND(TLBMissVector) + .data +1: .asciiz "32-bit TLB miss!?\n" + .text +/* + * XXX kernel only. For now that makes sense. + */ LEAF(XTLBMissVector) .set noat - j ExceptionVector + dmfc0 k0, MIPS_COP_0_BAD_VADDR + li k1, MIPS_XKSEG_START + subu k0, k1 + /* + * Shift right logical to get a page index, but leaving + * enough bits to index an array of 64 bit values. + */ + dsrl k0, PAGE_SHIFT - 3 + dla k1, kptmap + /* + * Find the page table, and index it. + */ + ld k1, 0(k1) + addu k1, k0 + ld k0, 0(k1) /* Even PTE. */ + andi k0, PG_V /* Check validity. */ + beq k0, zero, 1f /* Invalid. */ + nop + /* + * Valid PTE. Write the pair. + */ + ld k0, 0(k1) /* Even PTE. */ + ld k1, 8(k1) /* Odd PTE. */ + /* + * Write TLB entry. + */ + mtc0 k0, MIPS_COP_0_TLB_LO0 + nop + mtc0 k1, MIPS_COP_0_TLB_LO1 + nop + tlbwr + nop + nop + eret +1: j BadPTE nop .set at VEND(XTLBMissVector) /* + * Yell about a bogus PTE, at 0(k1). + */ +ENTRY(BadPTE) + .set noat + dmfc0 a3, MIPS_COP_0_BAD_VADDR + move a1, k1 + ld a2, 0(k1) + dla a0, 1f + dla k0, panic + dmtc0 k0, MIPS_COP_0_EXC_PC + eret + .set at +END(BadPTE) + .data +1: .asciiz "Bad PTE at %p (%16lx), badvaddr %lx" + .text + +/* + * Handle an interrupt. Return into panic, for now. + */ +LEAF(Interrupt) + .set noat + mfc0 k1, MIPS_COP_0_CAUSE + dla k0, panic + dmtc0 k0, MIPS_COP_0_EXC_PC + dla a0, 1f + move a1, k1 + eret + .set at +END(Interrupt) + .data +1: .asciiz "Interrupt, cause: %lx\n" + .text + +/* + * Handle VCED. + */ +LEAF(VCED) + .set noat + dmfc0 k0, MIPS_COP_0_BAD_VADDR + li k1, -16 + and k0, k1 + cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) + cache (CACHE_R4K_D | CACHEOP_R4K_HIT_INV), 0(k0) + eret + .set at +END(VCED) + +/* * Restore registers from a trapframe pointed to in k1, returning to ra * that is passed in, and kept in k0. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200306030714.h537EJKT046915>