diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-08-11 11:45:28 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-08-11 11:45:28 +0000 |
commit | 117e49e4fe673065b85ff3a47f437f8b43ff1baa (patch) | |
tree | 78d349044fe7cb8a12478770a454418f547cadbb /sys | |
parent | 7a180b0dffd8a6191dc39c284c4b43646bbe8ac6 (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.c | 72 | ||||
-rw-r--r-- | sys/arch/i386/include/pmap.h | 10 |
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 */ |