Date: Tue, 19 Sep 2006 22:09:09 GMT From: Suleiman Souhlal <ssouhlal@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 106364 for review Message-ID: <200609192209.k8JM99Lw016482@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=106364 Change 106364 by ssouhlal@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*/) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609192209.k8JM99Lw016482>