PERFORCE change 106364 for review

Suleiman Souhlal ssouhlal at FreeBSD.org
Tue Sep 19 15:09:18 PDT 2006


http://perforce.freebsd.org/chv.cgi?CH=106364

Change 106364 by ssouhlal at ssouhlal-maho on 2006/09/19 22:08:40

	Make TLB Refill and TLB Invalid exceptions work for userland and 
	when the PTE hasn't been filled in yet.
	Needs more work (exceptions in general do).

Affected files ...

.. //depot/projects/mips2/src/sys/mips/mips/exception.S#10 edit
.. //depot/projects/mips2/src/sys/mips/mips/trap.c#6 edit

Differences ...

==== //depot/projects/mips2/src/sys/mips/mips/exception.S#10 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/mips2/src/sys/mips/mips/exception.S#9 $
+ * $P4: //depot/projects/mips2/src/sys/mips/mips/exception.S#10 $
  */
 
 #include "opt_ddb.h"
@@ -202,6 +202,45 @@
 	.set noat
 
 	mfc0	k0, MIPS_COP_0_BAD_VADDR
+	nop
+	bltz	k0, 5f
+	nop
+
+	/* Userland */
+6:
+	/* XXX We should switch stack elsewhere. */
+	subu	sp, sp, TF_SIZE
+	lw	k1, PC_CURTHREAD(t2)
+	lw	k1, TD_KSTACK(k1)
+	subu	k1, k1, TF_SIZE
+
+	la	k0, 4f
+	j	exception_save_registers
+	nop
+
+	move	sp, k1
+
+4:	mfc0    a1, MIPS_COP_0_CAUSE
+	mfc0    a2, MIPS_COP_0_BAD_VADDR
+	jal     trap
+	move	a0, k1
+
+	move	k1, sp
+	jal	exception_restore_registers
+	nop
+
+	addu	sp, sp, TF_SIZE
+	eret
+5:
+	j	kernfault
+
+VEND(TLBMissVector)
+	.data
+2:	.asciiz "TLBMissVector"
+	.text
+
+
+kernfault:
 	/*
 	 * Shift right logical to get a page index, but leaving
 	 * enough bits to index an array of 64 bit values, plus
@@ -241,9 +280,36 @@
 	nop
 
 	tlbp
-    
+
+	mfc0	k1, MIPS_COP_0_BAD_VADDR
+	srl	k1, PAGE_SHIFT
+	andi	k1, k1, 1
+	bne	k1, zero, 2f
+	nop
+
+	mfc0	k1, MIPS_COP_0_TLB_LO0
+	b	3f
+	nop
+2:
+	mfc0	k1, MIPS_COP_0_TLB_LO1
+	nop
+3:	
+	andi	k1, 2
+	bne	k1, zero, 4f
+	nop
+	/*
+	 * The PTE that triggered the fault is not valid. We need to do a
+	 * "real" page fault.
+	 *
+	 * XXX Maybe we should just ignore the fact that it's not valid here
+	 * and just let the TLB Invalid Exception (vector 0x80000180) handler
+	 * deal with it.
+	 */
+	j	6b
+	nop
+
+4:
 	mfc0	k0, MIPS_COP_0_TLB_INDEX
-	nop
 	bltz	k0, 1f
 	nop
 
@@ -253,14 +319,9 @@
 1:
 
 	tlbwr
+
 	eret
-
 	.set at
-VEND(TLBMissVector)
-	.data
-2:	.asciiz "TLBMissVector"
-	.text
-
 
 
 LEAF(XTLBMissVector)

==== //depot/projects/mips2/src/sys/mips/mips/trap.c#6 (text+ko) ====

@@ -36,6 +36,9 @@
 #include <vm/vm.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_param.h>
+#include <vm/vm_extern.h>
 
 #include <machine/cpu.h>
 #include <machine/frame.h>
@@ -95,9 +98,13 @@
 void
 trap(struct trapframe *retf, u_int cause, void *badvaddr)
 {
+	vm_offset_t va;
+	vm_map_t map;
+	struct thread *td;
 	struct trapframe *tf;
 	struct trap_identifier *tid;
 	int code, kernelmode;
+	int ftype, error;
 
 	platform_trap_enter();
 
@@ -118,6 +125,41 @@
 		/* XXX Kernel only. */
 		tlb_modified(badvaddr);
 		goto done;
+	case TrTLBL:
+	case TrTLBS:
+		va = trunc_page(badvaddr);
+		td = curthread;
+
+		if (va >= KERNBASE) {
+			pt_entry_t *pte;
+			pte = tlb_pte_find(kernel_pmap->pm_lev1, va);
+
+			if (!pte_valid(pte)) {
+				map = kernel_map;
+				goto heavy;
+			}
+
+			if ((va >> PAGE_SHIFT) & 1)
+				tlb_update(va, pte[-1], pte[0]);
+			else
+				tlb_update(va, pte[0], pte[1]);
+			goto done;
+		} else
+			map = &td->td_proc->p_vmspace->vm_map;
+
+heavy:
+		if (code == TrTLBL)
+			ftype = VM_PROT_READ;
+		else
+			ftype = VM_PROT_WRITE;
+		error = vm_fault(map, va, ftype,
+		    (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL);
+
+		if (error == KERN_SUCCESS)
+			goto done;
+		if (kernelmode)
+			break;
+		/* XXX send signal */
 	case TrAdEL:
 	case TrDBE:
 		if (trap_error == -1/* && trap_addr == badvaddr*/) {


More information about the p4-projects mailing list