Subject: cacheable page tables
To: None <port-arm@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: port-arm
Date: 08/21/2002 22:03:38
--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

In a continuing effort to squeeze more performance out of some XScale-based
I/O processors, today I looked at making the page tables cacheable.  This
turned out to be remarkably easy, save the PT-PT, which is potentially
accessed from more than one address.

While this did not have quite as much performance impact as I would have
liked (the bottleneck I was seeing was _bus_dmamap_load_buffer(), which
was doing un-cached memory access to get the physical address of a buffer).
It did, however, make some improvement, and so I think it's worth checking
in (and _bus_dmamap_load_buffer() did get faster).

The implementation here has room for more improvement -- there are some
places where it could write-back a chunk of PTEs where it currently only
writes-back one at a time.  I also would like to figure out how to deal
with the PT-PT, as making that cacheable would speed up fork/exit.[*]

[*] Actually I already sped up the fork path by using a pool_cache for
the PT-PT, which saves having to duplicate the kernel mappings each time
(they're cached in constructed form) -- but the exit patch currently has
to bzero the bottom half of the PT-PT, and this is done as uncached access
as well.

Attached is the patch against a bleeding-edge -current.  I've booted
it on IQ80321 and Shark ... the changes to machdep code are basically
mechanical.

I'm going to let this ferment overnight, and check it in in the morning,
and then work on improving it some more tomorrow.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=ptp-cache

Index: acorn32/acorn32/rpc_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/acorn32/acorn32/rpc_machdep.c,v
retrieving revision 1.40
diff -c -r1.40 rpc_machdep.c
*** acorn32/acorn32/rpc_machdep.c	2002/08/22 01:13:53	1.40
--- acorn32/acorn32/rpc_machdep.c	2002/08/22 04:09:53
***************
*** 777,800 ****
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (KERNEL_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_KERNEL].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_NOCACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
  	    kernel_ptpt.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (VMEM_VBASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_VMEM].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_NOCACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE+ (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_NOCACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) {
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	}
  
  	/* Map the vector page. */
--- 777,800 ----
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (KERNEL_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_KERNEL].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_CACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
  	    kernel_ptpt.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (VMEM_VBASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_VMEM].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_CACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE+ (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_CACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) {
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	}
  
  	/* Map the vector page. */
Index: arm/arm32/pmap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/arm/arm32/pmap.c,v
retrieving revision 1.112
diff -c -r1.112 pmap.c
*** arm/arm32/pmap.c	2002/08/22 01:13:55	1.112
--- arm/arm32/pmap.c	2002/08/22 04:09:57
***************
*** 340,346 ****
  
  struct l1pt *pmap_alloc_l1pt __P((void));
  static __inline void pmap_map_in_l1 __P((struct pmap *pmap, vaddr_t va,
!      vaddr_t l2pa, boolean_t));
  
  static pt_entry_t *pmap_map_ptes __P((struct pmap *));
  static void pmap_unmap_ptes __P((struct pmap *));
--- 340,346 ----
  
  struct l1pt *pmap_alloc_l1pt __P((void));
  static __inline void pmap_map_in_l1 __P((struct pmap *pmap, vaddr_t va,
!      vaddr_t l2pa, int));
  
  static pt_entry_t *pmap_map_ptes __P((struct pmap *));
  static void pmap_unmap_ptes __P((struct pmap *));
***************
*** 420,425 ****
--- 420,437 ----
  	return (FALSE);
  }
  
+ #define	PTE_SYNC_CURRENT(pmap, pte)			\
+ do {							\
+ 	if (pmap_is_curpmap((pmap)))			\
+ 		PTE_SYNC((pte));			\
+ } while (/*CONSTCOND*/0)
+ 
+ #define	PTE_SYNC_RANGE_CURRENT(pmap, pte, cnt)		\
+ do {							\
+ 	if (pmap_is_curpmap((pmap)))			\
+ 		PTE_SYNC_RANGE((pte), (cnt));		\
+ } while (/*CONSTCOND*/0)
+ 
  /*
   * p v _ e n t r y   f u n c t i o n s
   */
***************
*** 903,910 ****
   * the given pmap to cover a chunk of virtual address space starting from the
   * address specified.
   */
  static __inline void
! pmap_map_in_l1(struct pmap *pmap, vaddr_t va, paddr_t l2pa, boolean_t selfref)
  {
  	vaddr_t ptva;
  
--- 915,925 ----
   * the given pmap to cover a chunk of virtual address space starting from the
   * address specified.
   */
+ #define	PMAP_PTP_SELFREF	0x01
+ #define	PMAP_PTP_CACHEABLE	0x02
+ 
  static __inline void
! pmap_map_in_l1(struct pmap *pmap, vaddr_t va, paddr_t l2pa, int flags)
  {
  	vaddr_t ptva;
  
***************
*** 919,927 ****
  	cpu_dcache_wb_range((vaddr_t) &pmap->pm_pdir[ptva + 0], 16);
  
  	/* Map the page table into the page table area. */
! 	if (selfref)
  		*((pt_entry_t *)(pmap->pm_vptpt + ptva)) = L2_S_PROTO | l2pa |
! 		    L2_S_PROT(PTE_KERNEL, VM_PROT_READ|VM_PROT_WRITE);
  }
  
  #if 0
--- 934,943 ----
  	cpu_dcache_wb_range((vaddr_t) &pmap->pm_pdir[ptva + 0], 16);
  
  	/* Map the page table into the page table area. */
! 	if (flags & PMAP_PTP_SELFREF)
  		*((pt_entry_t *)(pmap->pm_vptpt + ptva)) = L2_S_PROTO | l2pa |
! 		    L2_S_PROT(PTE_KERNEL, VM_PROT_READ|VM_PROT_WRITE) |
! 		    ((flags & PMAP_PTP_CACHEABLE) ? pte_l2_s_cache_mode : 0);
  }
  
  #if 0
***************
*** 1446,1452 ****
  	    (L1_TABLE_SIZE - KERNEL_PD_SIZE), KERNEL_PD_SIZE);
  
  	/* Wire in this page table */
! 	pmap_map_in_l1(pmap, PTE_BASE, pmap->pm_pptpt, TRUE);
  
  	pt->pt_flags &= ~PTFLAG_CLEAN;	/* L1 is dirty now */
  
--- 1462,1468 ----
  	    (L1_TABLE_SIZE - KERNEL_PD_SIZE), KERNEL_PD_SIZE);
  
  	/* Wire in this page table */
! 	pmap_map_in_l1(pmap, PTE_BASE, pmap->pm_pptpt, PMAP_PTP_SELFREF);
  
  	pt->pt_flags &= ~PTFLAG_CLEAN;	/* L1 is dirty now */
  
***************
*** 1600,1605 ****
--- 1616,1625 ----
  	simple_lock(&pmap->pm_obj.vmobjlock);
  	while ((page = TAILQ_FIRST(&pmap->pm_obj.memq)) != NULL) {
  		KASSERT((page->flags & PG_BUSY) == 0);
+ 		if (PMAP_PTP_CACHEABLE)
+ 			cpu_dcache_inv_range(
+ 			    trunc_page((vaddr_t) vtopte(page->offset)),
+ 			    PAGE_SIZE);
  		page->wire_count = 0;
  		uvm_pagefree(page);
  	}
***************
*** 1796,1801 ****
--- 1816,1822 ----
  	 */
  	*cdst_pte = L2_S_PROTO | phys |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) | pte_l2_s_cache_mode;
+ 	PTE_SYNC(cdst_pte);
  	cpu_tlb_flushD_SE(cdstp);
  	cpu_cpwait();
  	bzero_page(cdstp);
***************
*** 1823,1828 ****
--- 1844,1850 ----
  	*cdst_pte = L2_S_PROTO | phys |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) |
  	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);	/* mini-data */
+ 	PTE_SYNC(cdst_pte);
  	cpu_tlb_flushD_SE(cdstp);
  	cpu_cpwait();
  	bzero_page(cdstp);
***************
*** 1857,1862 ****
--- 1879,1885 ----
  	 */
  	*cdst_pte = L2_S_PROTO | phys |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) | pte_l2_s_cache_mode;
+ 	PTE_SYNC(cdst_pte);
  	cpu_tlb_flushD_SE(cdstp);
  	cpu_cpwait();
  
***************
*** 1921,1928 ****
--- 1944,1953 ----
  	 */
  	*csrc_pte = L2_S_PROTO | src |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ) | pte_l2_s_cache_mode;
+ 	PTE_SYNC(csrc_pte);
  	*cdst_pte = L2_S_PROTO | dst |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) | pte_l2_s_cache_mode;
+ 	PTE_SYNC(cdst_pte);
  	cpu_tlb_flushD_SE(csrcp);
  	cpu_tlb_flushD_SE(cdstp);
  	cpu_cpwait();
***************
*** 1964,1972 ****
--- 1989,1999 ----
  	*csrc_pte = L2_S_PROTO | src |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ) |
  	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);	/* mini-data */
+ 	PTE_SYNC(csrc_pte);
  	*cdst_pte = L2_S_PROTO | dst |
  	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) |
  	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);	/* mini-data */
+ 	PTE_SYNC(cdst_pte);
  	cpu_tlb_flushD_SE(csrcp);
  	cpu_tlb_flushD_SE(cdstp);
  	cpu_cpwait();
***************
*** 2232,2237 ****
--- 2259,2266 ----
  			    || kpmap == npv->pv_pmap) && 
  			    (npv->pv_flags & PVF_NC) == 0) {
  				ptes[arm_btop(npv->pv_va)] &= ~L2_S_CACHE_MASK;
+ 				PTE_SYNC_CURRENT(pmap,
+ 				    &ptes[arm_btop(npv->pv_va)]);
   				npv->pv_flags |= PVF_NC;
  				/*
  				 * If this page needs flushing from the
***************
*** 2265,2270 ****
--- 2294,2301 ----
  			    (npv->pv_flags & PVF_NC)) {
  				ptes[arm_btop(npv->pv_va)] |=
  				    pte_l2_s_cache_mode;
+ 				PTE_SYNC_CURRENT(pmap,
+ 				    &ptes[arm_btop(npv->pv_va)]);
  				npv->pv_flags &= ~PVF_NC;
  			}
  		}
***************
*** 2331,2342 ****
  	/* Now loop along */
  	while (sva < eva) {
  		/* Check if we can move to the next PDE (l1 chunk) */
! 		if (!(sva & L2_ADDR_BITS))
  			if (!pmap_pde_page(pmap_pde(pmap, sva))) {
  				sva += L1_S_SIZE;
  				pte += arm_btop(L1_S_SIZE);
  				continue;
  			}
  
  		/* We've found a valid PTE, so this page of PTEs has to go. */
  		if (pmap_pte_v(pte)) {
--- 2362,2374 ----
  	/* Now loop along */
  	while (sva < eva) {
  		/* Check if we can move to the next PDE (l1 chunk) */
! 		if ((sva & L2_ADDR_BITS) == 0) {
  			if (!pmap_pde_page(pmap_pde(pmap, sva))) {
  				sva += L1_S_SIZE;
  				pte += arm_btop(L1_S_SIZE);
  				continue;
  			}
+ 		}
  
  		/* We've found a valid PTE, so this page of PTEs has to go. */
  		if (pmap_pte_v(pte)) {
***************
*** 2376,2384 ****
--- 2408,2420 ----
  				 */
  				for (cnt = 0; cnt < PMAP_REMOVE_CLEAN_LIST_SIZE; cnt++) {
  					*cleanlist[cnt].pte = 0;
+ 					if (pmap_active)
+ 						PTE_SYNC(cleanlist[cnt].pte);
  					pmap_pte_delref(pmap, cleanlist[cnt].va);
  				}
  				*pte = 0;
+ 				if (pmap_active)
+ 					PTE_SYNC(pte);
  				pmap_pte_delref(pmap, sva);
  				cleanlist_idx++;
  			} else {
***************
*** 2388,2393 ****
--- 2424,2431 ----
  				 * and we won't need to do it again
  				 */
  				*pte = 0;
+ 				if (pmap_active)
+ 					PTE_SYNC(pte);
  				pmap_pte_delref(pmap, sva);
  			}
  
***************
*** 2421,2426 ****
--- 2459,2465 ----
  				cpu_idcache_wbinv_range(cleanlist[cnt].va,
  				    NBPG);
  				*cleanlist[cnt].pte = 0;
+ 				PTE_SYNC(cleanlist[cnt].pte);
  				cpu_tlb_flushID_SE(cleanlist[cnt].va);
  			} else
  				*cleanlist[cnt].pte = 0;
***************
*** 2498,2503 ****
--- 2537,2543 ----
  #endif
  
  		*pte = 0;
+ 		PTE_SYNC_CURRENT(pmap, pte);
  		pmap_pte_delref(pmap, pv->pv_va);
  
  		npv = pv->pv_next;
***************
*** 2586,2591 ****
--- 2626,2632 ----
  		flush = 1;
  
  		*pte &= ~L2_S_PROT_W;		/* clear write bit */
+ 		PTE_SYNC_CURRENT(pmap, pte);	/* XXXJRT optimize */
  
  		/* Clear write flag */
  		if ((pg = PHYS_TO_VM_PAGE(pmap_pte_pa(pte))) != NULL) {
***************
*** 2806,2811 ****
--- 2847,2853 ----
  		npte &= ~L2_XSCALE_T_TEX(TEX_XSCALE_X);
  #endif
  	ptes[arm_btop(va)] = npte;
+ 	PTE_SYNC_CURRENT(pmap, &ptes[arm_btop(va)]);
  
  	if (pg != NULL) {
  		simple_lock(&pg->mdpage.pvh_slock);
***************
*** 3111,3118 ****
  		simple_lock(&pmap->pm_obj.vmobjlock);
  	}
      
! 	pmap_map_in_l1(p->p_vmspace->vm_map.pmap, APTE_BASE, pmap->pm_pptpt,
! 	    FALSE);
  	cpu_tlb_flushD();
  	cpu_cpwait();
  	return (pt_entry_t *)APTE_BASE;
--- 3153,3160 ----
  		simple_lock(&pmap->pm_obj.vmobjlock);
  	}
      
! 	pmap_map_in_l1(p->p_vmspace->vm_map.pmap, APTE_BASE,
! 	    pmap->pm_pptpt, 0);
  	cpu_tlb_flushD();
  	cpu_cpwait();
  	return (pt_entry_t *)APTE_BASE;
***************
*** 3255,3262 ****
  		if (npte != opte) {
  			ptes[arm_btop(va)] = npte;
  			/* Flush the TLB entry if a current pmap. */
! 			if (pmap_is_curpmap(pv->pv_pmap))
  				cpu_tlb_flushID_SE(pv->pv_va);
  		}
  
  		pmap_unmap_ptes(pv->pv_pmap);		/* unlocks pmap */
--- 3297,3306 ----
  		if (npte != opte) {
  			ptes[arm_btop(va)] = npte;
  			/* Flush the TLB entry if a current pmap. */
! 			if (pmap_is_curpmap(pv->pv_pmap)) {
! 				PTE_SYNC(&ptes[arm_btop(va)]);
  				cpu_tlb_flushID_SE(pv->pv_va);
+ 			}
  		}
  
  		pmap_unmap_ptes(pv->pv_pmap);		/* unlocks pmap */
***************
*** 3391,3396 ****
--- 3435,3441 ----
  	 */
  	ptes[arm_btop(va)] =
  	    (ptes[arm_btop(va)] & ~L2_TYPE_MASK) | L2_S_PROTO | L2_S_PROT_W;
+ 	PTE_SYNC(&ptes[arm_btop(va)]);
  	PDEBUG(0, printf("->(%08x)\n", ptes[arm_btop(va)]));
  
  	simple_unlock(&pg->mdpage.pvh_slock);
***************
*** 3449,3454 ****
--- 3494,3500 ----
  	pg->mdpage.pvh_attrs |= PVF_REF;
  
  	ptes[arm_btop(va)] = (ptes[arm_btop(va)] & ~L2_TYPE_MASK) | L2_S_PROTO;
+ 	PTE_SYNC(&ptes[arm_btop(va)]);
  	PDEBUG(0, printf("->(%08x)\n", ptes[arm_btop(va)]));
  
  	simple_unlock(&pg->mdpage.pvh_slock);
***************
*** 3546,3552 ****
  	/* got one! */
  	ptp->flags &= ~PG_BUSY;	/* never busy */
  	ptp->wire_count = 1;	/* no mappings yet */
! 	pmap_map_in_l1(pmap, va, VM_PAGE_TO_PHYS(ptp), TRUE);
  	pmap->pm_stats.resident_count++;	/* count PTP as resident */
  	pmap->pm_ptphint = ptp;
  	return (ptp);
--- 3592,3599 ----
  	/* got one! */
  	ptp->flags &= ~PG_BUSY;	/* never busy */
  	ptp->wire_count = 1;	/* no mappings yet */
! 	pmap_map_in_l1(pmap, va, VM_PAGE_TO_PHYS(ptp),
! 	    PMAP_PTP_SELFREF | PMAP_PTP_CACHEABLE);
  	pmap->pm_stats.resident_count++;	/* count PTP as resident */
  	pmap->pm_ptphint = ptp;
  	return (ptp);
***************
*** 3588,3594 ****
  			pmap_zero_page(ptaddr);
  
  			/* map this page in */
! 			pmap_map_in_l1(kpm, pmap_curmaxkvaddr, ptaddr, TRUE);
  
  			/* count PTP as resident */
  			kpm->pm_stats.resident_count++;
--- 3635,3642 ----
  			pmap_zero_page(ptaddr);
  
  			/* map this page in */
! 			pmap_map_in_l1(kpm, pmap_curmaxkvaddr, ptaddr,
! 			    PMAP_PTP_SELFREF | PMAP_PTP_CACHEABLE);
  
  			/* count PTP as resident */
  			kpm->pm_stats.resident_count++;
***************
*** 3608,3614 ****
  		simple_lock(&pmaps_lock);
  		LIST_FOREACH(pm, &pmaps, pm_list) {
  			pmap_map_in_l1(pm, pmap_curmaxkvaddr,
! 			    VM_PAGE_TO_PHYS(ptp), TRUE); 
  		}
  
  		/* Invalidate the PTPT cache. */
--- 3656,3663 ----
  		simple_lock(&pmaps_lock);
  		LIST_FOREACH(pm, &pmaps, pm_list) {
  			pmap_map_in_l1(pm, pmap_curmaxkvaddr,
! 			    VM_PAGE_TO_PHYS(ptp),
! 			    PMAP_PTP_SELFREF | PMAP_PTP_CACHEABLE); 
  		}
  
  		/* Invalidate the PTPT cache. */
Index: arm/include/arm32/pmap.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/arm/include/arm32/pmap.h,v
retrieving revision 1.57
diff -c -r1.57 pmap.h
*** arm/include/arm32/pmap.h	2002/08/22 01:13:55	1.57
--- arm/include/arm32/pmap.h	2002/08/22 04:09:58
***************
*** 231,237 ****
  #define vtophys(va) \
  	((*vtopte(va) & L2_S_FRAME) | ((vaddr_t) (va) & L2_S_OFFSET))
  
! #if 0 /* Not yet... */
  #define	PTE_SYNC(pte) \
  	cpu_dcache_wb_range((vaddr_t)(pte), sizeof(pt_entry_t))
  
--- 231,237 ----
  #define vtophys(va) \
  	((*vtopte(va) & L2_S_FRAME) | ((vaddr_t) (va) & L2_S_OFFSET))
  
! #if 1 /* Not yet... */
  #define	PTE_SYNC(pte) \
  	cpu_dcache_wb_range((vaddr_t)(pte), sizeof(pt_entry_t))
  
Index: cats/cats/cats_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/cats/cats/cats_machdep.c,v
retrieving revision 1.33
diff -c -r1.33 cats_machdep.c
*** cats/cats/cats_machdep.c	2002/08/21 18:34:31	1.33
--- cats/cats/cats_machdep.c	2002/08/22 04:10:00
***************
*** 632,638 ****
  		    PTE_BASE + ((KERNEL_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_KERNEL + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
--- 632,638 ----
  		    PTE_BASE + ((KERNEL_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_KERNEL + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
***************
*** 641,653 ****
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  
  	/* Map the vector page. */
  	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
--- 641,653 ----
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  
  	/* Map the vector page. */
  	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
Index: hpcarm/hpcarm/hpc_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcarm/hpcarm/hpc_machdep.c,v
retrieving revision 1.53
diff -c -r1.53 hpc_machdep.c
*** hpcarm/hpcarm/hpc_machdep.c	2002/08/22 01:13:57	1.53
--- hpcarm/hpcarm/hpc_machdep.c	2002/08/22 04:10:02
***************
*** 589,605 ****
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (KERNEL_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_KERNEL].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) {
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	}
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
--- 589,605 ----
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (KERNEL_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_KERNEL].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) {
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	}
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
***************
*** 607,613 ****
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (SAIPIO_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_IO].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_NOCACHE);
  
  	/* Map the vector page. */
  	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
--- 607,613 ----
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (SAIPIO_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_IO].pv_pa, VM_PROT_READ|VM_PROT_WRITE,
! 	    PTE_CACHE);
  
  	/* Map the vector page. */
  	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
Index: netwinder/netwinder/netwinder_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/netwinder/netwinder/netwinder_machdep.c,v
retrieving revision 1.35
diff -c -r1.35 netwinder_machdep.c
*** netwinder/netwinder/netwinder_machdep.c	2002/08/21 18:34:33	1.35
--- netwinder/netwinder/netwinder_machdep.c	2002/08/22 04:10:03
***************
*** 617,623 ****
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (KERNEL_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_KERNEL].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
  	    kernel_ptpt.pv_pa,
--- 617,623 ----
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (KERNEL_BASE >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_KERNEL].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
  	    kernel_ptpt.pv_pa,
***************
*** 625,637 ****
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  
  	/* Map the vector page. */
  	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
--- 625,637 ----
  	pmap_map_entry(l1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    kernel_pt_table[KERNEL_PT_SYS].pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
  		pmap_map_entry(l1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE +
  		    (loop * 0x00400000)) >> (PGSHIFT-2)),
  		    kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  
  	/* Map the vector page. */
  	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
Index: shark/ofw/ofw.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/shark/ofw/ofw.c,v
retrieving revision 1.19
diff -c -r1.19 ofw.c
*** shark/ofw/ofw.c	2002/08/22 01:13:58	1.19
--- shark/ofw/ofw.c	2002/08/22 04:10:04
***************
*** 1464,1475 ****
  	pmap_map_entry(L1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    proc0_pt_sys.pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	for (i = 0; i < KERNEL_IMG_PTS; i++)
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((KERNEL_BASE + i * 0x00400000) >> (PGSHIFT-2)),
  		    proc0_pt_kernel[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	pmap_map_entry(L1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
  	    proc0_pt_pte.pv_pa,
--- 1464,1475 ----
  	pmap_map_entry(L1pagetable,
  	    PTE_BASE + (0x00000000 >> (PGSHIFT-2)),
  	    proc0_pt_sys.pv_pa,
! 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	for (i = 0; i < KERNEL_IMG_PTS; i++)
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((KERNEL_BASE + i * 0x00400000) >> (PGSHIFT-2)),
  		    proc0_pt_kernel[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	pmap_map_entry(L1pagetable,
  	    PTE_BASE + (PTE_BASE >> (PGSHIFT-2)),
  	    proc0_pt_pte.pv_pa,
***************
*** 1478,1494 ****
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE + i * 0x00400000)
  		    >> (PGSHIFT-2)), proc0_pt_vmdata[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	for (i = 0; i < KERNEL_OFW_PTS; i++)
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((OFW_VIRT_BASE + i * 0x00400000)
  		    >> (PGSHIFT-2)), proc0_pt_ofw[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  	for (i = 0; i < KERNEL_IO_PTS; i++)
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((IO_VIRT_BASE + i * 0x00400000)
  		    >> (PGSHIFT-2)), proc0_pt_io[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
  
  	/* update the top of the kernel VM */
  	pmap_curmaxkvaddr =
--- 1478,1494 ----
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((KERNEL_VM_BASE + i * 0x00400000)
  		    >> (PGSHIFT-2)), proc0_pt_vmdata[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	for (i = 0; i < KERNEL_OFW_PTS; i++)
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((OFW_VIRT_BASE + i * 0x00400000)
  		    >> (PGSHIFT-2)), proc0_pt_ofw[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  	for (i = 0; i < KERNEL_IO_PTS; i++)
  		pmap_map_entry(L1pagetable,
  		    PTE_BASE + ((IO_VIRT_BASE + i * 0x00400000)
  		    >> (PGSHIFT-2)), proc0_pt_io[i].pv_pa,
! 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
  
  	/* update the top of the kernel VM */
  	pmap_curmaxkvaddr =

--82I3+IH0IqGh5yIs--