summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/m88k/m88k/pmap.c44
-rw-r--r--sys/arch/m88k/m88k/trap.c59
2 files changed, 57 insertions, 46 deletions
diff --git a/sys/arch/m88k/m88k/pmap.c b/sys/arch/m88k/m88k/pmap.c
index f3346e70fff..9cd3eff5968 100644
--- a/sys/arch/m88k/m88k/pmap.c
+++ b/sys/arch/m88k/m88k/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.34 2007/11/20 21:48:17 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.35 2007/11/20 21:53:25 miod Exp $ */
/*
* Copyright (c) 2001-2004, Miodrag Vallat
* Copyright (c) 1998-2001 Steve Murphree, Jr.
@@ -172,6 +172,7 @@ void pmap_remove_all(struct vm_page *);
void pmap_changebit(struct vm_page *, int, int);
boolean_t pmap_unsetbit(struct vm_page *, int);
boolean_t pmap_testbit(struct vm_page *, int);
+int pmap_set_modify(pmap_t, vaddr_t);
/*
* quick PTE field checking macros
@@ -2540,3 +2541,44 @@ pmap_proc_iflush(struct proc *p, vaddr_t va, vsize_t len)
len -= count;
}
}
+
+#ifdef M88110
+#include <machine/m88110.h>
+int
+pmap_set_modify(pmap_t pmap, vaddr_t va)
+{
+ pt_entry_t *pte;
+ paddr_t pa;
+ vm_page_t pg;
+ pv_entry_t pvl;
+
+ pte = pmap_pte(pmap, va);
+#ifdef DEBUG
+ if (pte == NULL)
+ panic("NULL pte on write fault??");
+#endif
+
+ /* Not a first write to a writable page */
+ if ((*pte & (PG_M | PG_RO)) != 0)
+ return (FALSE);
+
+ /* Mark the page as dirty */
+ *pte |= PG_M;
+ pa = *pte & PG_FRAME;
+ pg = PHYS_TO_VM_PAGE(pa);
+#ifdef DIAGNOSTIC
+ if (pg == NULL)
+ panic("Write fault to unmanaged page %p", pa);
+#endif
+
+ pvl = pg_to_pvh(pg);
+ pvl->pv_flags |= PG_M_U;
+
+ if (pmap == kernel_pmap)
+ set_dcmd(CMMU_DCMD_INV_SATC);
+ else
+ set_dcmd(CMMU_DCMD_INV_UATC);
+
+ return (TRUE);
+}
+#endif
diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c
index 51380a6ae91..fb496a51372 100644
--- a/sys/arch/m88k/m88k/trap.c
+++ b/sys/arch/m88k/m88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.44 2007/11/20 21:48:58 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.45 2007/11/20 21:53:25 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -193,8 +193,6 @@ m88100_trap(u_int type, struct trapframe *frame)
#endif
int sig = 0;
- extern struct vm_map *kernel_map;
-
uvmexp.traps++;
if ((p = curproc) == NULL)
p = &proc0;
@@ -592,10 +590,8 @@ m88110_trap(u_int type, struct trapframe *frame)
u_int psr;
#endif
int sig = 0;
- pt_entry_t *pte;
- extern struct vm_map *kernel_map;
- extern pt_entry_t *pmap_pte(pmap_t, vaddr_t);
+ extern int pmap_set_modify(pmap_t, vaddr_t);
uvmexp.traps++;
if ((p = curproc) == NULL)
@@ -746,7 +742,6 @@ m88110_trap(u_int type, struct trapframe *frame)
map = kernel_map;
if (frame->tf_dsr & (CMMU_DSR_SI | CMMU_DSR_PI)) {
- frame->tf_dsr &= ~CMMU_DSR_WE; /* undefined */
/*
* On a segment or a page fault, call uvm_fault() to
* resolve the fault.
@@ -759,7 +754,7 @@ m88110_trap(u_int type, struct trapframe *frame)
KERNEL_UNLOCK();
return;
}
- }
+ } else
if (frame->tf_dsr & CMMU_DSR_WE) { /* write fault */
/*
* This could be a write protection fault or an
@@ -771,28 +766,19 @@ m88110_trap(u_int type, struct trapframe *frame)
* modified and valid bits to determine if this
* indeed a real write fault. XXX smurph
*/
- pte = pmap_pte(map->pmap, va);
-#ifdef DEBUG
- if (pte == NULL) {
- KERNEL_UNLOCK();
- panic("NULL pte on write fault??");
- }
-#endif
- if (!(*pte & PG_M) && !(*pte & PG_RO)) {
- /* Set modified bit and try the write again. */
+ if (pmap_set_modify(map->pmap, va)) {
#ifdef TRAPDEBUG
- printf("Corrected kernel write fault, map %x pte %x\n",
- map->pmap, *pte);
+ printf("Corrected kernel write fault, pmap %p va %p\n",
+ map->pmap, va);
#endif
- *pte |= PG_M;
KERNEL_UNLOCK();
return;
-#if 1 /* shouldn't happen */
+#if 0 /* shouldn't happen */
} else {
/* must be a real wp fault */
#ifdef TRAPDEBUG
- printf("Uncorrected kernel write fault, map %x pte %x\n",
- map->pmap, *pte);
+ printf("Uncorrected kernel write fault, pmap %p va %p\n",
+ map->pmap, va);
#endif
if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
p->p_addr->u_pcb.pcb_onfault = 0;
@@ -896,33 +882,16 @@ m88110_user_fault:
* modified and valid bits to determine if this
* indeed a real write fault. XXX smurph
*/
- pte = pmap_pte(vm_map_pmap(map), va);
-#ifdef DEBUG
- if (pte == NULL) {
- panic("NULL pte on write fault??");
- }
-#endif
- if (!(*pte & PG_M) && !(*pte & PG_RO)) {
- /*
- * Set modified bit and try the
- * write again.
- */
+ if (pmap_set_modify(map->pmap, va)) {
#ifdef TRAPDEBUG
- printf("Corrected userland write fault, map %x pte %x\n",
- map->pmap, *pte);
+ printf("Corrected userland write fault, pmap %p va %p\n",
+ map->pmap, va);
#endif
- *pte |= PG_M;
- /*
- * invalidate ATCs to force
- * table search
- */
- set_dcmd(CMMU_DCMD_INV_UATC);
- result = 0;
} else {
/* must be a real wp fault */
#ifdef TRAPDEBUG
- printf("Uncorrected userland write fault, map %x pte %x\n",
- map->pmap, *pte);
+ printf("Uncorrected userland write fault, pmap %p va %p\n",
+ map->pmap, va);
#endif
result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
p->p_addr->u_pcb.pcb_onfault = pcb_onfault;