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