PERFORCE change 48381 for review
Juli Mallett
jmallett at FreeBSD.org
Sun Mar 7 16:23:51 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=48381
Change 48381 by jmallett at jmallett_oingo on 2004/03/07 16:23:32
Try to integ from alpha.
Affected files ...
.. //depot/projects/mips/sys/mips/mips/pmap.c#29 edit
Differences ...
==== //depot/projects/mips/sys/mips/mips/pmap.c#29 (text+ko) ====
@@ -44,7 +44,6 @@
* from: i386 Id: pmap.c,v 1.193 1998/04/19 15:22:48 bde Exp
* with some ideas from NetBSD's alpha pmap
* from: Alpha Id: pmap.c,v 1.122 2003/04/10 18:42:06 jhb Exp
- * $FreeBSD$
*/
/*
@@ -73,6 +72,9 @@
* and to when physical maps must be made correct.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -196,7 +198,6 @@
static void pmap_insert_entry(pmap_t pmap, vm_offset_t va,
vm_page_t mpte, vm_page_t m);
-
/*
* Routine: pmap_pte
* Function:
@@ -336,9 +337,41 @@
return (va);
}
-/*
- * A free function for the above.
- */
+void *
+uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
+{
+ static vm_pindex_t color;
+ vm_page_t m;
+ int pflags;
+ void *va;
+
+ *flags = UMA_SLAB_PRIV;
+
+ if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
+ pflags = VM_ALLOC_INTERRUPT;
+ else
+ pflags = VM_ALLOC_SYSTEM;
+
+ if (wait & M_ZERO)
+ pflags |= VM_ALLOC_ZERO;
+
+ for (;;) {
+ m = vm_page_alloc(NULL, color++, pflags | VM_ALLOC_NOOBJ);
+ if (m == NULL) {
+ if (wait & M_NOWAIT)
+ return (NULL);
+ else
+ VM_WAIT;
+ } else
+ break;
+ }
+
+ va = (void *)MIPS_PHYS_TO_KSEG0(m->phys_addr);
+ if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
+ bzero(va, PAGE_SIZE);
+ return (va);
+}
+
void
uma_small_free(void *mem, int size, u_int8_t flags)
{
@@ -677,7 +710,38 @@
pmap_pinit(pmap)
register struct pmap *pmap;
{
- pmap->pm_lev1 = kptmap; /* XXX */
+#if notyet
+ vm_page_t lev1pg;
+ int i;
+
+ /*
+ * allocate object for the ptes
+ */
+ if (pmap->pm_pteobj == NULL)
+ pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, NUSERLEV3MAPS + NUSERLEV2MAPS + 1);
+
+ /*
+ * allocate the page directory page
+ */
+ VM_OBJECT_LOCK(pmap->pm_pteobj);
+ lev1pg = vm_page_grab(pmap->pm_pteobj, NUSERLEV3MAPS + NUSERLEV2MAPS,
+ VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_WIRED);
+
+ vm_page_lock_queues();
+ vm_page_flag_clear(lev1pg, PG_BUSY);
+ lev1pg->valid = VM_PAGE_BITS_ALL;
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(pmap->pm_pteobj);
+
+ pmap->pm_lev1 = (pt_entry_t*) MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(lev1pg));
+ if ((lev1pg->flags & PG_ZERO) == 0)
+ bzero(pmap->pm_lev1, PAGE_SIZE);
+
+
+ /* install self-referential address mapping entry (not PG_ASM) */
+ pmap->pm_lev1[PTLEV1I] = pmap_phys_to_pte(VM_PAGE_TO_PHYS(lev1pg))
+ | PG_V | PG_KRE | PG_KWE;
+#endif
pmap->pm_ptphint = NULL;
pmap->pm_active = 0;
pmap->pm_asid = 0;
@@ -687,18 +751,9 @@
mtx_lock_spin(&allpmaps_lock);
LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
mtx_unlock_spin(&allpmaps_lock);
-}
-
-/*
- * Wire in kernel global address entries. To avoid a race condition
- * between pmap initialization and pmap_growkernel, this procedure
- * should be called after the vmspace is attached to the process
- * but before this pmap is activated.
- */
-void
-pmap_pinit2(pmap)
- struct pmap *pmap;
-{
+#if notyet
+ bcopy(PTlev1 + K1SEGLEV1I, pmap->pm_lev1 + K1SEGLEV1I, nklev2 * PTESIZE);
+#endif
}
/***************************************************
@@ -1147,7 +1202,37 @@
if (wired)
pmap->pm_stats.wired_count++;
- tlb_enter(pmap, va, pa, PG_V | (wired ? PG_W : 0));
+validate:
+ /*
+ * Now validate mapping with desired protection/wiring.
+ */
+ newpte = pmap_phys_to_pte(pa) | pte_prot(pmap, prot) | PG_V | managed;
+
+ if (managed) {
+ /*
+ * Set up referenced/modified emulation for the new
+ * mapping. Any old referenced/modified emulation
+ * results for the old mapping will have been recorded
+ * either in pmap_remove_pte() or above in the code
+ * which handles protection and/or wiring changes.
+ */
+ newpte |= (PG_FOR | PG_FOW | PG_FOE);
+ }
+
+ if (wired)
+ newpte |= PG_W;
+
+ /*
+ * if the mapping or permission bits are different, we need
+ * to update the pte.
+ */
+ if (origpte != newpte) {
+ *pte = newpte;
+ if (origpte)
+ pmap_invalidate_page(pmap, va);
+ if (prot & VM_PROT_EXECUTE)
+ alpha_pal_imb();
+ }
}
/*
@@ -1608,23 +1693,30 @@
*/
if ((*pte & PG_RO) == 0)
val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
- /*
- * Modified by someone
- */
- else if (m->dirty || pmap_is_modified(m))
- val |= MINCORE_MODIFIED_OTHER;
+ else {
+ /*
+ * Modified by someone
+ */
+ vm_page_lock_queues();
+ if (m->dirty || pmap_is_modified(m))
+ val |= MINCORE_MODIFIED_OTHER;
+ vm_page_unlock_queues();
+ }
/*
* Referenced by us
*/
if ((*pte & PG_D) == 0)
val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
-
- /*
- * Referenced by someone
- */
- else if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
- val |= MINCORE_REFERENCED_OTHER;
- vm_page_flag_set(m, PG_REFERENCED);
+ else {
+ /*
+ * Referenced by someone
+ */
+ vm_page_lock_queues();
+ if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
+ val |= MINCORE_REFERENCED_OTHER;
+ vm_page_flag_set(m, PG_REFERENCED);
+ }
+ vm_page_unlock_queues();
}
}
return val;
More information about the p4-projects
mailing list