summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2001-08-11 11:45:28 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2001-08-11 11:45:28 +0000
commit117e49e4fe673065b85ff3a47f437f8b43ff1baa (patch)
tree78d349044fe7cb8a12478770a454418f547cadbb /sys
parent7a180b0dffd8a6191dc39c284c4b43646bbe8ac6 (diff)
Some fixes from NetBSD.
Parts of the glue needed for page zeroing in the idle loop. More careful handling of ptp pages (should solve some problems, most notably with Intel 440GX+ motherboards).
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/i386/pmap.c72
-rw-r--r--sys/arch/i386/include/pmap.h10
2 files changed, 61 insertions, 21 deletions
diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c
index 3072006f1e5..022ff668013 100644
--- a/sys/arch/i386/i386/pmap.c
+++ b/sys/arch/i386/i386/pmap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pmap.c,v 1.43 2001/07/25 13:25:32 art Exp $ */
-/* $NetBSD: pmap.c,v 1.84 2000/02/21 02:01:24 chs Exp $ */
+/* $OpenBSD: pmap.c,v 1.44 2001/08/11 11:45:27 art Exp $ */
+/* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */
/*
*
@@ -991,7 +991,7 @@ pmap_init()
sizeof(char) * npages);
s = round_page(s); /* round up */
addr = (vaddr_t) uvm_km_zalloc(kernel_map, s);
- if (addr == NULL)
+ if (addr == 0)
panic("pmap_init: unable to allocate pv_heads");
/*
@@ -1023,7 +1023,7 @@ pmap_init()
pv_initpage = (struct pv_page *) uvm_km_alloc(kernel_map, NBPG);
if (pv_initpage == NULL)
panic("pmap_init: pv_initpage");
- pv_cachedva = NULL; /* a VA we have allocated but not used yet */
+ pv_cachedva = 0; /* a VA we have allocated but not used yet */
pv_nfpvents = 0;
(void) pmap_add_pvpage(pv_initpage, FALSE);
@@ -1158,10 +1158,10 @@ pmap_alloc_pvpage(pmap, mode)
*/
s = splimp(); /* must protect kmem_map/kmem_object with splimp! */
- if (pv_cachedva == NULL) {
+ if (pv_cachedva == 0) {
pv_cachedva = uvm_km_kmemalloc(kmem_map, uvmexp.kmem_object,
NBPG, UVM_KMF_TRYLOCK|UVM_KMF_VALLOC);
- if (pv_cachedva == NULL) {
+ if (pv_cachedva == 0) {
splx(s);
goto steal_one;
}
@@ -1199,7 +1199,7 @@ pmap_alloc_pvpage(pmap, mode)
pmap_kenter_pa(pv_cachedva, VM_PAGE_TO_PHYS(pg), VM_PROT_ALL);
pvpage = (struct pv_page *) pv_cachedva;
- pv_cachedva = NULL;
+ pv_cachedva = 0;
return(pmap_add_pvpage(pvpage, mode != ALLOCPV_NONEED));
steal_one:
@@ -1581,7 +1581,7 @@ pmap_alloc_ptp(pmap, pde_index, just_try)
struct vm_page *ptp;
ptp = uvm_pagealloc(&pmap->pm_obj, ptp_i2o(pde_index), NULL,
- UVM_PGA_USERESERVE);
+ UVM_PGA_USERESERVE|UVM_PGA_ZERO);
if (ptp == NULL) {
if (just_try)
return(NULL);
@@ -1589,12 +1589,13 @@ pmap_alloc_ptp(pmap, pde_index, just_try)
if (ptp == NULL) {
return (NULL);
}
+ /* stole one; zero it. */
+ pmap_zero_page(VM_PAGE_TO_PHYS(ptp));
}
/* got one! */
ptp->flags &= ~PG_BUSY; /* never busy */
ptp->wire_count = 1; /* no mappings yet */
- pmap_zero_page(VM_PAGE_TO_PHYS(ptp));
pmap->pm_pdir[pde_index] =
(pd_entry_t) (VM_PAGE_TO_PHYS(ptp) | PG_u | PG_RW | PG_V);
pmap->pm_stats.resident_count++; /* count PTP as resident */
@@ -2113,6 +2114,28 @@ pmap_zero_page(pa)
}
/*
+ * pmap_zero_page_uncached: the same, except uncached.
+ */
+
+void
+pmap_zero_page_uncached(pa)
+ paddr_t pa;
+{
+ simple_lock(&pmap_zero_page_lock);
+#ifdef DIAGNOSTIC
+ if (*zero_pte)
+ panic("pmap_zero_page_uncached: lock botch");
+#endif
+
+ *zero_pte = (pa & PG_FRAME) | PG_V | PG_RW | /* map in */
+ ((cpu_class != CPUCLASS_386) ? PG_N : 0);
+ memset(zerop, 0, NBPG); /* zero */
+ *zero_pte = 0; /* zap! */
+ pmap_update_pg((vaddr_t)zerop); /* flush TLB */
+ simple_unlock(&pmap_zero_page_lock);
+}
+
+/*
* pmap_copy_page: copy a page
*/
@@ -2219,7 +2242,8 @@ pmap_remove_ptes(pmap, pmap_rr, ptp, ptpva, startva, endva)
#ifdef DIAGNOSTIC
if (bank == -1)
panic("pmap_remove_ptes: unmanaged page marked "
- "PG_PVLIST");
+ "PG_PVLIST, va = 0x%lx, pa = 0x%lx",
+ startva, (u_long)(opte & PG_FRAME));
#endif
/* sync R/M bits */
@@ -2285,7 +2309,7 @@ pmap_remove_pte(pmap, ptp, pte, va)
if ((opte & PG_PVLIST) == 0) {
#ifdef DIAGNOSTIC
if (vm_physseg_find(i386_btop(opte & PG_FRAME), &off) != -1)
- panic("pmap_remove_ptes: managed page without "
+ panic("pmap_remove_pte: managed page without "
"PG_PVLIST for 0x%lx", va);
#endif
return(TRUE);
@@ -2294,7 +2318,9 @@ pmap_remove_pte(pmap, ptp, pte, va)
bank = vm_physseg_find(i386_btop(opte & PG_FRAME), &off);
#ifdef DIAGNOSTIC
if (bank == -1)
- panic("pmap_remove_pte: unmanaged page marked PG_PVLIST");
+ panic("pmap_remove_pte: unmanaged page marked "
+ "PG_PVLIST, va = 0x%lx, pa = 0x%lx", va,
+ (u_long)(opte & PG_FRAME));
#endif
/* sync R/M bits */
@@ -2721,7 +2747,7 @@ pmap_change_attrs(pg, setbits, clearbits)
for (pve = pvh->pvh_list; pve != NULL; pve = pve->pv_next) {
#ifdef DIAGNOSTIC
if (pve->pv_va >= uvm.pager_sva && pve->pv_va < uvm.pager_eva) {
- printf("pmap_change_attrs: found pager VA on pv_list");
+ printf("pmap_change_attrs: found pager VA on pv_list\n");
}
if (!pmap_valid_entry(pve->pv_pmap->pm_pdir[pdei(pve->pv_va)]))
panic("pmap_change_attrs: mapping without PTP "
@@ -2925,14 +2951,12 @@ pmap_unwire(pmap, va)
ptes[i386_btop(va)] &= ~PG_W;
pmap->pm_stats.wired_count--;
}
-#if 0
-#ifdef DIAGNOSITC
+#ifdef DIAGNOSTIC
else {
printf("pmap_unwire: wiring for pmap %p va 0x%lx "
"didn't change!\n", pmap, va);
}
#endif
-#endif
pmap_unmap_ptes(pmap); /* unlocks map */
}
#ifdef DIAGNOSTIC
@@ -3512,8 +3536,10 @@ pmap_enter(pmap, va, pa, prot, flags)
bank = vm_physseg_find(atop(pa), &off);
#ifdef DIAGNOSTIC
if (bank == -1)
- panic("pmap_enter: PG_PVLIST mapping "
- "with unmanaged page");
+ panic("pmap_enter: same pa PG_PVLIST "
+ "mapping with unmanaged page "
+ "pa = 0x%lx (0x%lx)", pa,
+ atop(pa));
#endif
pvh = &vm_physmem[bank].pmseg.pvhead[off];
simple_lock(&pvh->pvh_lock);
@@ -3539,7 +3565,8 @@ pmap_enter(pmap, va, pa, prot, flags)
#ifdef DIAGNOSTIC
if (bank == -1)
panic("pmap_enter: PG_PVLIST mapping with "
- "unmanaged page");
+ "unmanaged page "
+ "pa = 0x%lx (0x%lx)", pa, atop(pa));
#endif
pvh = &vm_physmem[bank].pmseg.pvhead[off];
simple_lock(&pvh->pvh_lock);
@@ -3660,6 +3687,7 @@ pmap_growkernel(maxkvaddr)
if (uvm_page_physget(&ptaddr) == FALSE)
panic("pmap_growkernel: out of memory");
+ pmap_zero_page(ptaddr);
kpm->pm_pdir[PDSLOT_KERN + nkpde] =
ptaddr | PG_RW | PG_V;
@@ -3675,6 +3703,12 @@ pmap_growkernel(maxkvaddr)
* INVOKED WHILE pmap_init() IS RUNNING!
*/
+ /*
+ * THIS *MUST* BE CODED SO AS TO WORK IN THE
+ * pmap_initialized == FALSE CASE! WE MAY BE
+ * INVOKED WHILE pmap_init() IS RUNNING!
+ */
+
if (pmap_alloc_ptp(kpm, PDSLOT_KERN + nkpde, FALSE) == NULL) {
panic("pmap_growkernel: alloc ptp failed");
}
diff --git a/sys/arch/i386/include/pmap.h b/sys/arch/i386/include/pmap.h
index 50b1c0dd352..1c5665ccbc6 100644
--- a/sys/arch/i386/include/pmap.h
+++ b/sys/arch/i386/include/pmap.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: pmap.h,v 1.14 2001/05/05 23:25:47 art Exp $ */
-/* $NetBSD: pmap.h,v 1.43 2000/02/11 07:00:13 thorpej Exp $ */
+/* $OpenBSD: pmap.h,v 1.15 2001/08/11 11:45:27 art Exp $ */
+/* $NetBSD: pmap.h,v 1.44 2000/04/24 17:18:18 thorpej Exp $ */
/*
*
@@ -413,6 +413,12 @@ vaddr_t reserve_dumppages __P((vaddr_t)); /* XXX: not a pmap fn */
#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */
/*
+ * Do idle page zero'ing uncached to avoid polluting the cache.
+ */
+void pmap_zero_page_uncached __P((paddr_t));
+#define PMAP_PAGEIDLEZERO(pa) pmap_zero_page_uncached((pa))
+
+/*
* inline functions
*/