Skip site navigation (1)Skip section navigation (2)
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>