From owner-p4-projects@FreeBSD.ORG Tue Sep 19 22:09:18 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E9CEA16A47B; Tue, 19 Sep 2006 22:09:17 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AB05616A403 for ; Tue, 19 Sep 2006 22:09:17 +0000 (UTC) (envelope-from ssouhlal@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1D09D43D7E for ; Tue, 19 Sep 2006 22:09:09 +0000 (GMT) (envelope-from ssouhlal@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8JM997R016485 for ; Tue, 19 Sep 2006 22:09:09 GMT (envelope-from ssouhlal@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8JM99Lw016482 for perforce@freebsd.org; Tue, 19 Sep 2006 22:09:09 GMT (envelope-from ssouhlal@freebsd.org) Date: Tue, 19 Sep 2006 22:09:09 GMT Message-Id: <200609192209.k8JM99Lw016482@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to ssouhlal@freebsd.org using -f From: Suleiman Souhlal To: Perforce Change Reviews Cc: Subject: PERFORCE change 106364 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Sep 2006 22:09:18 -0000 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 #include #include +#include +#include +#include #include #include @@ -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*/) {