diff --git a/sys/arch/macppc/include/vmparam.h b/sys/arch/macppc/include/vmparam.h index 462d97232b19..b507c046c90f 100644 --- a/sys/arch/macppc/include/vmparam.h +++ b/sys/arch/macppc/include/vmparam.h @@ -1,106 +1,3 @@ -/* $NetBSD: vmparam.h,v 1.21 2002/12/10 05:14:29 thorpej Exp $ */ +/* $NetBSD: vmparam.h,v 1.22 2003/02/02 21:22:11 matt Exp $ */ -/*- - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef OLDPMAP #include -#define _MACHINE_VMPARAM_H_ -#endif - -#ifndef _MACHINE_VMPARAM_H_ -#define _MACHINE_VMPARAM_H_ - -#define USRSTACK VM_MAXUSER_ADDRESS - -#ifndef MAXTSIZ -#define MAXTSIZ (64*1024*1024) /* max text size */ -#endif - -#ifndef DFLDSIZ -#define DFLDSIZ (128*1024*1024) /* default data size */ -#endif - -#ifndef MAXDSIZ -#define MAXDSIZ (1*1024*1024*1024) /* max data size */ -#endif - -#ifndef DFLSSIZ -#define DFLSSIZ (2*1024*1024) /* default stack size */ -#endif - -#ifndef MAXSSIZ -#define MAXSSIZ (32*1024*1024) /* max stack size */ -#endif - -/* - * Size of shared memory map - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 -#endif - -/* - * Size of User Raw I/O map - */ -#define USRIOSIZE 1024 - -/* - * Would like to have MAX addresses = 0, but this doesn't (currently) work - */ -#define VM_MIN_ADDRESS ((vaddr_t)0) -#define VM_MAXUSER_ADDRESS ((vaddr_t)0x7ffff000) -#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS -#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)(KERNEL_SR << ADDR_SR_SHFT)) -#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + SEGMENT_LENGTH - 1) - -/* XXX max. amount of KVM to be used by buffers. */ -#ifndef VM_MAX_KERNEL_BUF -#define VM_MAX_KERNEL_BUF (SEGMENT_LENGTH / 2) -#endif - -#define VM_PHYS_SIZE (USRIOSIZE * NBPG) - -#define __HAVE_PMAP_PHYSSEG - -struct pmap_physseg { - struct pv_entry *pvent; - char *attrs; -}; - -#define VM_PHYSSEG_MAX 16 /* 1? */ -#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH -#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ - -#define VM_NFREELIST 1 -#define VM_FREELIST_DEFAULT 0 - -#endif /* _MACHINE_VMPARAM_H_ */ diff --git a/sys/arch/ofppc/include/vmparam.h b/sys/arch/ofppc/include/vmparam.h index c445efc8e6e7..b409749e4375 100644 --- a/sys/arch/ofppc/include/vmparam.h +++ b/sys/arch/ofppc/include/vmparam.h @@ -1,112 +1,4 @@ -/* $NetBSD: vmparam.h,v 1.19 2002/12/10 05:14:31 thorpej Exp $ */ +/* $NetBSD: vmparam.h,v 1.20 2003/02/02 21:22:11 matt Exp $ */ -/*- - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef OLDPMAP #define USER_SR 11 #include -#define _MACHINE_VMPARAM_H_ -#endif - -#ifndef _MACHINE_VMPARAM_H_ -#define _MACHINE_VMPARAM_H_ - -#define USRSTACK VM_MAXUSER_ADDRESS - -#ifndef MAXTSIZ -#define MAXTSIZ (16*1024*1024) /* max text size */ -#endif - -#ifndef DFLDSIZ -#define DFLDSIZ (16*1024*1024) /* default data size */ -#endif - -#ifndef MAXDSIZ -#define MAXDSIZ (512*1024*1024) /* max data size */ -#endif - -#ifndef DFLSSIZ -#define DFLSSIZ (1*1024*1024) /* default stack size */ -#endif - -#ifndef MAXSSIZ -#define MAXSSIZ (32*1024*1024) /* max stack size */ -#endif - -/* - * Size of shared memory map - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 -#endif - -/* - * Size of User Raw I/O map - */ -#define USRIOSIZE 1024 - -/* - * Would like to have MAX addresses = 0, but this doesn't (currently) work - */ -#define VM_MIN_ADDRESS ((vaddr_t)0) -#define VM_MAXUSER_ADDRESS ((vaddr_t)0xfffff000) -#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS -#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)(KERNEL_SR << ADDR_SR_SHFT)) -#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + SEGMENT_LENGTH - 1) - -/* XXX max. amount of KVM to be used by buffers. */ -#ifndef VM_MAX_KERNEL_BUF -#define VM_MAX_KERNEL_BUF (SEGMENT_LENGTH / 2) -#endif - -/* - * Override the default pager_map size, there's not enough KVA. - */ -#define PAGER_MAP_SIZE (4 * 1024 * 1024) - -#define VM_PHYS_SIZE (USRIOSIZE * NBPG) - -#define __HAVE_PMAP_PHYSSEG - -struct pmap_physseg { - struct pv_entry *pvent; - char *attrs; -}; - -#define VM_PHYSSEG_MAX 32 -#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH -#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ - -#define VM_NFREELIST 1 -#define VM_FREELIST_DEFAULT 0 - -#endif /* _MACHINE_VMPARAM_H_ */ diff --git a/sys/arch/pmppc/include/vmparam.h b/sys/arch/pmppc/include/vmparam.h index 9238b8b67afb..0e72333a1e93 100644 --- a/sys/arch/pmppc/include/vmparam.h +++ b/sys/arch/pmppc/include/vmparam.h @@ -1,102 +1,3 @@ -/* $NetBSD: vmparam.h,v 1.2 2002/12/10 05:14:32 thorpej Exp $ */ +/* $NetBSD: vmparam.h,v 1.3 2003/02/02 21:22:12 matt Exp $ */ -#ifndef OLDPMAP #include -#else -/*- - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MACHINE_VMPARAM_H_ -#define _MACHINE_VMPARAM_H_ - -#define USRSTACK VM_MAXUSER_ADDRESS - -#ifndef MAXTSIZ -#define MAXTSIZ (64*1024*1024) /* max text size */ -#endif - -#ifndef DFLDSIZ -#define DFLDSIZ (128*1024*1024) /* default data size */ -#endif - -#ifndef MAXDSIZ -#define MAXDSIZ (1*1024*1024*1024) /* max data size */ -#endif - -#ifndef DFLSSIZ -#define DFLSSIZ (2*1024*1024) /* default stack size */ -#endif - -#ifndef MAXSSIZ -#define MAXSSIZ (32*1024*1024) /* max stack size */ -#endif - -/* - * Size of shared memory map - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 -#endif - -/* - * Size of User Raw I/O map - */ -#define USRIOSIZE 1024 - -/* - * Would like to have MAX addresses = 0, but this doesn't (currently) work - */ -#define VM_MIN_ADDRESS ((vaddr_t)0) -#define VM_MAXUSER_ADDRESS ((vaddr_t)0xfffff000) -#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS -#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)(KERNEL_SR << ADDR_SR_SHFT)) -#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + SEGMENT_LENGTH - 1) - -#define VM_PHYS_SIZE (USRIOSIZE * NBPG) - -#define __HAVE_PMAP_PHYSSEG - -#ifndef _LOCORE -struct pmap_physseg { - struct pv_entry *pvent; - char *attrs; -}; -#endif - -#define VM_PHYSSEG_MAX 32 -#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH -#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ - -#define VM_NFREELIST 1 -#define VM_FREELIST_DEFAULT 0 - -#endif /* _MACHINE_VMPARAM_H_ */ -#endif diff --git a/sys/arch/powerpc/conf/files.powerpc b/sys/arch/powerpc/conf/files.powerpc index 4dcbd7cdda03..df692405b450 100644 --- a/sys/arch/powerpc/conf/files.powerpc +++ b/sys/arch/powerpc/conf/files.powerpc @@ -1,4 +1,4 @@ -# $NetBSD: files.powerpc,v 1.43 2003/02/02 20:43:22 matt Exp $ +# $NetBSD: files.powerpc,v 1.44 2003/02/02 21:22:12 matt Exp $ defflag opt_altivec.h ALTIVEC K_ALTIVEC defflag opt_openpic.h OPENPIC OPENPIC_SERIAL_MODE @@ -15,7 +15,7 @@ file arch/powerpc/powerpc/ipkdb_glue.c ipkdb file arch/powerpc/powerpc/kgdb_machdep.c kgdb file arch/powerpc/powerpc/mem.c file arch/powerpc/powerpc/openpic.c openpic -file arch/powerpc/powerpc/pmap_subr.c ppc_mpc6xx & !oldpmap +file arch/powerpc/powerpc/pmap_subr.c ppc_mpc6xx file arch/powerpc/powerpc/powerpc_machdep.c file arch/powerpc/powerpc/process_machdep.c file arch/powerpc/powerpc/setfault.S @@ -46,9 +46,8 @@ file arch/powerpc/ibm4xx/intr.c ppc_ibm4xx file arch/powerpc/mpc6xx/altivec.c ppc_mpc6xx & altivec file arch/powerpc/mpc6xx/cpu_subr.c ppc_mpc6xx file arch/powerpc/mpc6xx/mpc6xx_machdep.c ppc_mpc6xx -file arch/powerpc/mpc6xx/pmap.c ppc_mpc6xx & !oldpmap +file arch/powerpc/mpc6xx/pmap.c ppc_mpc6xx file arch/powerpc/powerpc/fpu.c ppc_mpc6xx -file arch/powerpc/powerpc/pmap.c ppc_mpc6xx & oldpmap file arch/powerpc/powerpc/trap.c ppc_mpc6xx # Binary compatibility with previous NetBSD releases (COMPAT_XX) diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c deleted file mode 100644 index f616e3a8459d..000000000000 --- a/sys/arch/powerpc/powerpc/pmap.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* $NetBSD: pmap.c,v 1.51 2003/01/18 06:23:33 thorpej Exp $ */ - -/* - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -pte_t *ptable; -int ptab_cnt; -u_int ptab_mask; -#define HTABSIZE (ptab_cnt * 64) - -struct pte_ovfl { - LIST_ENTRY(pte_ovfl) po_list; /* Linked list of overflow entries */ - struct pte po_pte; /* PTE for this mapping */ -}; - -LIST_HEAD(pte_ovtab, pte_ovfl) *potable; /* Overflow entries for ptable */ - -struct pmap kernel_pmap_; - -int physmem; -static int npgs; -static u_int nextavail; -#ifndef MSGBUFADDR -extern paddr_t msgbuf_paddr; -#endif - -static struct mem_region *mem, *avail; - -/* - * This is a cache of referenced/modified bits. - * Bits herein are shifted by ATTRSHFT. - */ -static char *pmap_attrib; -#define ATTRSHFT 4 - -struct pv_entry { - struct pv_entry *pv_next; /* Linked list of mappings */ - int pv_idx; /* Index into ptable */ - vaddr_t pv_va; /* virtual address of mapping */ -}; - -struct pv_entry *pv_table; - -struct pv_page; -struct pv_page_info { - LIST_ENTRY(pv_page) pgi_list; - struct pv_entry *pgi_freelist; - int pgi_nfree; -}; -#define NPVPPG ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry)) -struct pv_page { - struct pv_page_info pvp_pgi; - struct pv_entry pvp_pv[NPVPPG]; -}; -LIST_HEAD(pv_page_list, pv_page) pv_page_freelist; -int pv_nfree; -int pv_pcnt; -static struct pv_entry *pmap_alloc_pv __P((void)); -static void pmap_free_pv __P((struct pv_entry *)); -void pmap_pinit __P((pmap_t)); -void pmap_release __P((pmap_t)); - -struct po_page; -struct po_page_info { - LIST_ENTRY(po_page) pgi_list; - struct vm_page *pgi_page; - LIST_HEAD(po_freelist, pte_ovfl) pgi_freelist; - int pgi_nfree; -}; -#define NPOPPG ((NBPG - sizeof(struct po_page_info)) / sizeof(struct pte_ovfl)) -struct po_page { - struct po_page_info pop_pgi; - struct pte_ovfl pop_po[NPOPPG]; -}; -LIST_HEAD(po_page_list, po_page) po_page_freelist; -int po_nfree; -int po_pcnt; -static struct pte_ovfl *poalloc __P((void)); -static void pofree __P((struct pte_ovfl *, int)); - -static u_int usedsr[NPMAPS / sizeof(u_int) / 8]; - -static int pmap_initialized; - -static inline void tlbie __P((vaddr_t)); -static inline void tlbsync __P((void)); -static inline void tlbia __P((void)); -static inline int ptesr __P((sr_t *, vaddr_t)); -static inline int pteidx __P((sr_t, vaddr_t)); -static inline int ptematch __P((pte_t *, sr_t, vaddr_t, int)); -static inline struct pv_entry *pa_to_pv __P((paddr_t)); -static inline char *pa_to_attr __P((paddr_t)); -static int pte_insert __P((int, pte_t *)); -int pmap_pte_spill __P((struct pmap *, vaddr_t)); /* Called from trap.c */ -static inline int pmap_enter_pv __P((int, vaddr_t, paddr_t)); -static void pmap_remove_pv __P((int, vaddr_t, paddr_t, struct pte *)); -static pte_t *pte_find __P((struct pmap *, vaddr_t)); - -/* - * These small routines may have to be replaced, - * if/when we support processors other that the 604. - */ -static inline void -tlbie(ea) - vaddr_t ea; -{ - asm volatile ("tlbie %0" :: "r"(ea)); -} - -static inline void -tlbsync() -{ - asm volatile ("sync; tlbsync; sync"); -} - -static void -tlbia() -{ - vaddr_t i; - - asm volatile ("sync"); - for (i = 0; i < (vaddr_t)0x00040000; i += 0x00001000) - tlbie(i); - tlbsync(); -} - -static inline int -ptesr(sr, addr) - sr_t *sr; - vaddr_t addr; -{ - return sr[(u_int)addr >> ADDR_SR_SHFT]; -} - -static inline int -pteidx(sr, addr) - sr_t sr; - vaddr_t addr; -{ - int hash; - - hash = (sr & SR_VSID) ^ (((u_int)addr & ADDR_PIDX) >> ADDR_PIDX_SHFT); - return hash & ptab_mask; -} - -static inline int -ptematch(ptp, sr, va, which) - pte_t *ptp; - sr_t sr; - vaddr_t va; - int which; -{ - return ptp->pte_hi - == (((sr & SR_VSID) << PTE_VSID_SHFT) - | (((u_int)va >> ADDR_API_SHFT) & PTE_API) - | which); -} - -static inline struct pv_entry * -pa_to_pv(pa) - paddr_t pa; -{ - int bank, pg; - - bank = vm_physseg_find(atop(pa), &pg); - if (bank == -1) - return NULL; - return &vm_physmem[bank].pmseg.pvent[pg]; -} - -static inline char * -pa_to_attr(pa) - paddr_t pa; -{ - int bank, pg; - - bank = vm_physseg_find(atop(pa), &pg); - if (bank == -1) - return NULL; - return &vm_physmem[bank].pmseg.attrs[pg]; -} - -/* - * Try to insert page table entry *pt into the ptable at idx. - * - * Note: *pt mustn't have PTE_VALID set. - * This is done here as required by Book III, 4.12. - */ -static int -pte_insert(idx, pt) - int idx; - pte_t *pt; -{ - pte_t *ptp; - int i; - - /* - * First try primary hash. - */ - for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) - if (!(ptp->pte_hi & PTE_VALID)) { - *ptp = *pt; - ptp->pte_hi &= ~PTE_HID; - asm volatile ("sync"); - ptp->pte_hi |= PTE_VALID; - return 1; - } - idx ^= ptab_mask; - for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) - if (!(ptp->pte_hi & PTE_VALID)) { - *ptp = *pt; - ptp->pte_hi |= PTE_HID; - asm volatile ("sync"); - ptp->pte_hi |= PTE_VALID; - return 1; - } - return 0; -} - -/* - * Spill handler. - * - * Tries to spill a page table entry from the overflow area. - * Note that this routine runs in real mode on a separate stack, - * with interrupts disabled. - */ -int -pmap_pte_spill(pm, addr) - struct pmap *pm; - vaddr_t addr; -{ - int idx, i; - sr_t sr; - struct pte_ovfl *po; - pte_t ps; - pte_t *pt; - - idx = pteidx(ptesr(pm->pm_sr, addr), addr); - for (po = potable[idx].lh_first; po; po = po->po_list.le_next) - if (ptematch(&po->po_pte, sr, addr, 0)) { - /* - * Now found an entry to be spilled into the real ptable. - */ - if (pte_insert(idx, &po->po_pte)) { - LIST_REMOVE(po, po_list); - pofree(po, 0); - return 1; - } - /* - * Have to substitute some entry. Use the primary hash for this. - * - * Use low bits of timebase as random generator - */ - asm ("mftb %0" : "=r"(i)); - pt = ptable + idx * 8 + (i & 7); - pt->pte_hi &= ~PTE_VALID; - ps = *pt; - asm volatile ("sync"); - tlbie(addr); - tlbsync(); - *pt = po->po_pte; - asm volatile ("sync"); - pt->pte_hi |= PTE_VALID; - po->po_pte = ps; - if (ps.pte_hi & PTE_HID) { - /* - * We took an entry that was on the alternate hash - * chain, so move it to it's original chain. - */ - po->po_pte.pte_hi &= ~PTE_HID; - LIST_REMOVE(po, po_list); - LIST_INSERT_HEAD(potable + (idx ^ ptab_mask), - po, po_list); - } - return 1; - } - return 0; -} - -/* - * This is called during initppc, before the system is really initialized. - */ -void -pmap_bootstrap(kernelstart, kernelend) - u_int kernelstart, kernelend; -{ - struct mem_region *mp, *mp1; - int cnt, i; - u_int s, e, sz; - - /* - * Get memory. - */ - mem_regions(&mem, &avail); - for (mp = mem; mp->size; mp++) - physmem += btoc(mp->size); - - /* - * Count the number of available entries. - */ - for (cnt = 0, mp = avail; mp->size; mp++) - cnt++; - - /* - * Page align all regions. - * Non-page aligned memory isn't very interesting to us. - * Also, sort the entries for ascending addresses. - */ - kernelstart &= ~PGOFSET; - kernelend = (kernelend + PGOFSET) & ~PGOFSET; - for (mp = avail; mp->size; mp++) { - s = mp->start; - e = mp->start + mp->size; - /* - * Check whether this region holds all of the kernel. - */ - if (s < kernelstart && e > kernelend) { - avail[cnt].start = kernelend; - avail[cnt++].size = e - kernelend; - e = kernelstart; - } - /* - * Look whether this regions starts within the kernel. - */ - if (s >= kernelstart && s < kernelend) { - if (e <= kernelend) - goto empty; - s = kernelend; - } - /* - * Now look whether this region ends within the kernel. - */ - if (e > kernelstart && e <= kernelend) { - if (s >= kernelstart) - goto empty; - e = kernelstart; - } - /* - * Now page align the start and size of the region. - */ - s = round_page(s); - e = trunc_page(e); - if (e < s) - e = s; - sz = e - s; - /* - * Check whether some memory is left here. - */ - if (sz == 0) { - empty: - memmove(mp, mp + 1, - (cnt - (mp - avail)) * sizeof *mp); - cnt--; - mp--; - continue; - } - /* - * Do an insertion sort. - */ - npgs += btoc(sz); - for (mp1 = avail; mp1 < mp; mp1++) - if (s < mp1->start) - break; - if (mp1 < mp) { - memmove(mp1 + 1, mp1, (char *)mp - (char *)mp1); - mp1->start = s; - mp1->size = sz; - } else { - mp->start = s; - mp->size = sz; - } - } - - /* - * The PEM recommends that the total number of PTEGs should be - * at least 1/2 of the number of physical pages. - */ -#ifdef HTABENTS - ptab_cnt = HTABENTS; -#else - ptab_cnt = (physmem + 1) / 2; - - /* The minimum is 1024 PTEGs. */ - if (ptab_cnt < 1024) - ptab_cnt = 1024; - - /* Round up to power of 2. */ - asm ("cntlzw %0,%1" : "=r"(i) : "r"(ptab_cnt - 1)); - ptab_cnt = 1 << (32 - i); -#endif - - /* - * Find suitably aligned memory for HTAB. - */ - for (mp = avail; mp->size; mp++) { - s = roundup(mp->start, HTABSIZE) - mp->start; - if (mp->size < s + HTABSIZE) - continue; - ptable = (pte_t *)(mp->start + s); - if (mp->size == s + HTABSIZE) { - if (s) - mp->size = s; - else { - memmove(mp, mp + 1, - (cnt - (mp - avail)) * sizeof *mp); - mp = avail; - } - break; - } - if (s != 0) { - memmove(mp + 1, mp, - (cnt - (mp - avail)) * sizeof *mp); - mp++->size = s; - cnt++; - } - mp->start += s + HTABSIZE; - mp->size -= s + HTABSIZE; - break; - } - if (!mp->size) - panic("not enough memory?"); - - npgs -= btoc(HTABSIZE); - memset((void *)ptable, 0, HTABSIZE); - ptab_mask = ptab_cnt - 1; - - /* - * We cannot do pmap_steal_memory here, - * since we don't run with translation enabled yet. - */ - s = sizeof(struct pte_ovtab) * ptab_cnt; - sz = round_page(s); - for (mp = avail; mp->size; mp++) - if (mp->size >= sz) - break; - if (!mp->size) - panic("not enough memory?"); - - npgs -= btoc(sz); - potable = (struct pte_ovtab *)mp->start; - mp->size -= sz; - mp->start += sz; - if (mp->size <= 0) - memmove(mp, mp + 1, (cnt - (mp - avail)) * sizeof *mp); - for (i = 0; i < ptab_cnt; i++) - LIST_INIT(potable + i); - LIST_INIT(&pv_page_freelist); - -#ifndef MSGBUFADDR - /* - * allow for msgbuf - */ - sz = round_page(MSGBUFSIZE); - mp = NULL; - for (mp1 = avail; mp1->size; mp1++) - if (mp1->size >= sz) - mp = mp1; - if (mp == NULL) - panic("not enough memory?"); - - npgs -= btoc(sz); - msgbuf_paddr = mp->start + mp->size - sz; - mp->size -= sz; - if (mp->size <= 0) - memmove(mp, mp + 1, (cnt - (mp - avail)) * sizeof *mp); -#endif - - for (mp = avail; mp->size; mp++) - uvm_page_physload(atop(mp->start), atop(mp->start + mp->size), - atop(mp->start), atop(mp->start + mp->size), - VM_FREELIST_DEFAULT); - - /* - * Initialize kernel pmap and hardware. - */ -#if NPMAPS >= KERNEL_SEGMENT / 16 - usedsr[KERNEL_SEGMENT / 16 / (sizeof usedsr[0] * 8)] - |= 1 << ((KERNEL_SEGMENT / 16) % (sizeof usedsr[0] * 8)); -#endif - for (i = 0; i < 16; i++) { - pmap_kernel()->pm_sr[i] = EMPTY_SEGMENT; - asm volatile ("mtsrin %0,%1" - :: "r"(EMPTY_SEGMENT), "r"(i << ADDR_SR_SHFT)); - } - pmap_kernel()->pm_sr[KERNEL_SR] = KERNEL_SEGMENT; - asm volatile ("mtsr %0,%1" - :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT)); - asm volatile ("sync; mtsdr1 %0; isync" - :: "r"((u_int)ptable | (ptab_mask >> 10))); - tlbia(); - nextavail = avail->start; -} - -/* - * Restrict given range to physical memory - */ -void -pmap_real_memory(start, size) - paddr_t *start; - psize_t *size; -{ - struct mem_region *mp; - - for (mp = mem; mp->size; mp++) { - if (*start + *size > mp->start - && *start < mp->start + mp->size) { - if (*start < mp->start) { - *size -= mp->start - *start; - *start = mp->start; - } - if (*start + *size > mp->start + mp->size) - *size = mp->start + mp->size - *start; - return; - } - } - *size = 0; -} - -/* - * Initialize anything else for pmap handling. - * Called during vm_init(). - */ -void -pmap_init() -{ - struct pv_entry *pv; - vsize_t sz; - vaddr_t addr; - int i, s; - int bank; - char *attr; - - sz = (vsize_t)((sizeof(struct pv_entry) + 1) * npgs); - sz = round_page(sz); - /* XXXCDC: ABSOLUTELY WRONG! uvm_km_zalloc() _CAN_ - return 0 if out of VM */ - addr = uvm_km_zalloc(kernel_map, sz); - s = splvm(); - pv = pv_table = (struct pv_entry *)addr; - for (i = npgs; --i >= 0;) - pv++->pv_idx = -1; - LIST_INIT(&pv_page_freelist); - pmap_attrib = (char *)pv; - memset(pv, 0, npgs); - - pv = pv_table; - attr = pmap_attrib; - for (bank = 0; bank < vm_nphysseg; bank++) { - sz = vm_physmem[bank].end - vm_physmem[bank].start; - vm_physmem[bank].pmseg.pvent = pv; - vm_physmem[bank].pmseg.attrs = attr; - pv += sz; - attr += sz; - } - - pmap_initialized = 1; - splx(s); -} - -/* - * How much virtual space is available to the kernel? - */ -void -pmap_virtual_space(start, end) - vaddr_t *start, *end; -{ - /* - * Reserve one segment for kernel virtual memory - */ - *start = (vaddr_t)(KERNEL_SR << ADDR_SR_SHFT); - *end = *start + SEGMENT_LENGTH; -} - -/* - * Create and return a physical map. - */ -struct pmap * -pmap_create() -{ - struct pmap *pm; - - pm = (struct pmap *)malloc(sizeof *pm, M_VMPMAP, M_WAITOK); - memset((caddr_t)pm, 0, sizeof *pm); - pmap_pinit(pm); - return pm; -} - -/* - * Initialize a preallocated and zeroed pmap structure. - */ -void -pmap_pinit(pm) - struct pmap *pm; -{ - int i, j; - - /* - * Allocate some segment registers for this pmap. - */ - pm->pm_refs = 1; - for (i = 0; i < sizeof usedsr / sizeof usedsr[0]; i++) - if (usedsr[i] != 0xffffffff) { - j = ffs(~usedsr[i]) - 1; - usedsr[i] |= 1 << j; - pm->pm_sr[0] = (i * sizeof usedsr[0] * 8 + j) * 16; - for (i = 1; i < 16; i++) - pm->pm_sr[i] = pm->pm_sr[i - 1] + 1; - return; - } - panic("out of segments"); -} - -/* - * Add a reference to the given pmap. - */ -void -pmap_reference(pm) - struct pmap *pm; -{ - pm->pm_refs++; -} - -/* - * Retire the given pmap from service. - * Should only be called if the map contains no valid mappings. - */ -void -pmap_destroy(pm) - struct pmap *pm; -{ - if (--pm->pm_refs == 0) { - pmap_release(pm); - free((caddr_t)pm, M_VMPMAP); - } -} - -/* - * Release any resources held by the given physical map. - * Called when a pmap initialized by pmap_pinit is being released. - */ -void -pmap_release(pm) - struct pmap *pm; -{ - int i, j; - - if (!pm->pm_sr[0]) - panic("pmap_release"); - i = pm->pm_sr[0] / 16; - j = i % (sizeof usedsr[0] * 8); - i /= sizeof usedsr[0] * 8; - usedsr[i] &= ~(1 << j); -} - -/* - * Copy the range specified by src_addr/len - * from the source map to the range dst_addr/len - * in the destination map. - * - * This routine is only advisory and need not do anything. - */ -void -pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) - struct pmap *dst_pmap, *src_pmap; - vaddr_t dst_addr, src_addr; - vsize_t len; -{ -} - -/* - * Garbage collects the physical map system for - * pages which are no longer used. - * Success need not be guaranteed -- that is, there - * may well be pages which are not referenced, but - * others may be collected. - * Called by the pageout daemon when pages are scarce. - */ -void -pmap_collect(pm) - struct pmap *pm; -{ -} - -/* - * Fill the given physical page with zeroes. - */ -void -pmap_zero_page(pa) - paddr_t pa; -{ -#if 0 - memset((caddr_t)pa, 0, NBPG); -#else - int i; - - for (i = NBPG/CACHELINESIZE; i > 0; i--) { - __asm __volatile ("dcbz 0,%0" :: "r"(pa)); - pa += CACHELINESIZE; - } -#endif -} - -/* - * Copy the given physical source page to its destination. - */ -void -pmap_copy_page(src, dst) - paddr_t src, dst; -{ - memcpy((caddr_t)dst, (caddr_t)src, NBPG); -} - -static struct pv_entry * -pmap_alloc_pv() -{ - struct pv_page *pvp; - struct pv_entry *pv; - int i; - - if (pv_nfree == 0) { - if (!(pvp = (struct pv_page *)uvm_km_zalloc(kernel_map, NBPG))) - panic("pmap_alloc_pv: uvm_km_zalloc() failed"); - pv_pcnt++; - pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1]; - for (i = NPVPPG - 2; --i >= 0; pv++) - pv->pv_next = pv + 1; - pv->pv_next = 0; - pv_nfree += pvp->pvp_pgi.pgi_nfree = NPVPPG - 1; - LIST_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list); - pv = pvp->pvp_pv; - } else { - pv_nfree--; - pvp = pv_page_freelist.lh_first; - if (--pvp->pvp_pgi.pgi_nfree <= 0) - LIST_REMOVE(pvp, pvp_pgi.pgi_list); - pv = pvp->pvp_pgi.pgi_freelist; - pvp->pvp_pgi.pgi_freelist = pv->pv_next; - } - return pv; -} - -static void -pmap_free_pv(pv) - struct pv_entry *pv; -{ - struct pv_page *pvp; - - pvp = (struct pv_page *)trunc_page((vaddr_t)pv); - switch (++pvp->pvp_pgi.pgi_nfree) { - case 1: - LIST_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list); - default: - pv->pv_next = pvp->pvp_pgi.pgi_freelist; - pvp->pvp_pgi.pgi_freelist = pv; - pv_nfree++; - break; - case NPVPPG: - pv_nfree -= NPVPPG - 1; - pv_pcnt--; - LIST_REMOVE(pvp, pvp_pgi.pgi_list); - uvm_km_free(kernel_map, (vaddr_t)pvp, NBPG); - break; - } -} - -/* - * We really hope that we don't need overflow entries - * before the VM system is initialized! XXX - */ -static struct pte_ovfl * -poalloc() -{ - struct po_page *pop; - struct pte_ovfl *po; - struct vm_page *mem; - int i; - - if (!pmap_initialized) - panic("poalloc"); - - if (po_nfree == 0) { - /* - * Since we cannot use maps for potable allocation, - * we have to steal some memory from the VM system. XXX - */ - mem = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE); - po_pcnt++; - pop = (struct po_page *)VM_PAGE_TO_PHYS(mem); - pop->pop_pgi.pgi_page = mem; - LIST_INIT(&pop->pop_pgi.pgi_freelist); - for (i = NPOPPG - 1, po = pop->pop_po + 1; --i >= 0; po++) - LIST_INSERT_HEAD(&pop->pop_pgi.pgi_freelist, po, po_list); - po_nfree += pop->pop_pgi.pgi_nfree = NPOPPG - 1; - LIST_INSERT_HEAD(&po_page_freelist, pop, pop_pgi.pgi_list); - po = pop->pop_po; - } else { - po_nfree--; - pop = po_page_freelist.lh_first; - if (--pop->pop_pgi.pgi_nfree <= 0) - LIST_REMOVE(pop, pop_pgi.pgi_list); - po = pop->pop_pgi.pgi_freelist.lh_first; - LIST_REMOVE(po, po_list); - } - return po; -} - -static void -pofree(po, freepage) - struct pte_ovfl *po; - int freepage; -{ - struct po_page *pop; - - pop = (struct po_page *)trunc_page((vaddr_t)po); - switch (++pop->pop_pgi.pgi_nfree) { - case NPOPPG: - if (!freepage) - break; - po_nfree -= NPOPPG - 1; - po_pcnt--; - LIST_REMOVE(pop, pop_pgi.pgi_list); - uvm_pagefree(pop->pop_pgi.pgi_page); - return; - case 1: - LIST_INSERT_HEAD(&po_page_freelist, pop, pop_pgi.pgi_list); - default: - break; - } - LIST_INSERT_HEAD(&pop->pop_pgi.pgi_freelist, po, po_list); - po_nfree++; -} - -/* - * This returns whether this is the first mapping of a page. - */ -static inline int -pmap_enter_pv(pteidx, va, pa) - int pteidx; - vaddr_t va; - paddr_t pa; -{ - struct pv_entry *pv, *npv; - int s, first; - - if (!pmap_initialized) - return 0; - - s = splvm(); - - pv = pa_to_pv(pa); - if ((first = pv->pv_idx) == -1) { - /* - * No entries yet, use header as the first entry. - */ - pv->pv_va = va; - pv->pv_idx = pteidx; - pv->pv_next = NULL; - } else { - /* - * There is at least one other VA mapping this page. - * Place this entry after the header. - */ - npv = pmap_alloc_pv(); - npv->pv_va = va; - npv->pv_idx = pteidx; - npv->pv_next = pv->pv_next; - pv->pv_next = npv; - } - splx(s); - return first; -} - -static void -pmap_remove_pv(pteidx, va, pa, pte) - int pteidx; - vaddr_t va; - paddr_t pa; - struct pte *pte; -{ - struct pv_entry *pv, *npv; - char *attr; - - /* - * First transfer reference/change bits to cache. - */ - attr = pa_to_attr(pa); - if (attr == NULL) - return; - *attr |= (pte->pte_lo & (PTE_REF | PTE_CHG)) >> ATTRSHFT; - - /* - * Remove from the PV table. - */ - pv = pa_to_pv(pa); - - /* - * If it is the first entry on the list, it is actually - * in the header and we must copy the following entry up - * to the header. Otherwise we must search the list for - * the entry. In either case we free the now unused entry. - */ - if (pteidx == pv->pv_idx && va == pv->pv_va) { - npv = pv->pv_next; - if (npv) { - *pv = *npv; - pmap_free_pv(npv); - } else - pv->pv_idx = -1; - } else { - for (; (npv = pv->pv_next) != NULL; pv = npv) - if (pteidx == npv->pv_idx && va == npv->pv_va) - break; - if (npv) { - pv->pv_next = npv->pv_next; - pmap_free_pv(npv); - } -#ifdef DIAGNOSTIC - else - panic("pmap_remove_pv: not on list"); -#endif - } -} - -/* - * Insert physical page at pa into the given pmap at virtual address va. - */ -int -pmap_enter(pm, va, pa, prot, flags) - struct pmap *pm; - vaddr_t va; - paddr_t pa; - vm_prot_t prot; - int flags; -{ - sr_t sr; - int idx, s; - pte_t pte; - struct pte_ovfl *po; - int managed; - struct mem_region *mp; - - /* - * Have to remove any existing mapping first. - */ - pmap_remove(pm, va, va + NBPG); - - /* - * Compute the HTAB index. - */ - idx = pteidx(sr = ptesr(pm->pm_sr, va), va); - /* - * Construct the PTE. - * - * Note: Don't set the valid bit for correct operation of tlb update. - */ - pte.pte_hi = ((sr & SR_VSID) << PTE_VSID_SHFT) - | ((va & ADDR_PIDX) >> ADDR_API_SHFT); - pte.pte_lo = (pa & PTE_RPGN) | PTE_M | PTE_I | PTE_G; - - managed = 0; - if (vm_physseg_find(atop(pa), NULL) != -1) - managed = 1; - for (mp = mem; mp->size; mp++) { - if (pa >= mp->start && pa < mp->start + mp->size) { - pte.pte_lo &= ~(PTE_I | PTE_G); - break; - } - } - if (prot & VM_PROT_WRITE) - pte.pte_lo |= PTE_RW; - else - pte.pte_lo |= PTE_RO; - - /* - * Now record mapping for later back-translation. - */ - if (pmap_initialized && managed) - if (pmap_enter_pv(idx, va, pa)) { - /* - * Flush the real memory from the cache. - */ - if (prot & VM_PROT_EXECUTE) - __syncicache((void *)pa, NBPG); - } - - s = splvm(); - pm->pm_stats.resident_count++; - /* - * Try to insert directly into HTAB. - */ - if (pte_insert(idx, &pte)) { - splx(s); - return 0; - } - - /* - * Have to allocate overflow entry. - * - * Note, that we must use real addresses for these. - */ - po = poalloc(); - po->po_pte = pte; - LIST_INSERT_HEAD(potable + idx, po, po_list); - splx(s); - - return 0; -} - -void -pmap_kenter_pa(va, pa, prot) - vaddr_t va; - paddr_t pa; - vm_prot_t prot; -{ - struct pmap *pm = pmap_kernel(); - sr_t sr; - int idx, s; - pte_t pte; - struct pte_ovfl *po; - struct mem_region *mp; - - /* - * Have to remove any existing mapping first. - */ - pmap_kremove(va, NBPG); - - /* - * Compute the HTAB index. - */ - idx = pteidx(sr = ptesr(pm->pm_sr, va), va); - /* - * Construct the PTE. - * - * Note: Don't set the valid bit for correct operation of tlb update. - */ - pte.pte_hi = ((sr & SR_VSID) << PTE_VSID_SHFT) - | ((va & ADDR_PIDX) >> ADDR_API_SHFT); - pte.pte_lo = (pa & PTE_RPGN) | PTE_M | PTE_I | PTE_G; - - for (mp = mem; mp->size; mp++) { - if (pa >= mp->start && pa < mp->start + mp->size) { - pte.pte_lo &= ~(PTE_I | PTE_G); - break; - } - } - if (prot & VM_PROT_WRITE) - pte.pte_lo |= PTE_RW; - else - pte.pte_lo |= PTE_RO; - - s = splvm(); - pm->pm_stats.resident_count++; - /* - * Try to insert directly into HTAB. - */ - if (pte_insert(idx, &pte)) { - splx(s); - return; - } - - /* - * Have to allocate overflow entry. - * - * Note, that we must use real addresses for these. - */ - po = poalloc(); - po->po_pte = pte; - LIST_INSERT_HEAD(potable + idx, po, po_list); - splx(s); -} - -/* - * Remove the given range of mapping entries. - */ -void -pmap_remove(pm, va, endva) - struct pmap *pm; - vaddr_t va, endva; -{ - int idx, i, s; - sr_t sr; - pte_t *ptp; - struct pte_ovfl *po, *npo; - - s = splvm(); - while (va < endva) { - idx = pteidx(sr = ptesr(pm->pm_sr, va), va); - for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) - if (ptematch(ptp, sr, va, PTE_VALID)) { - pmap_remove_pv(idx, va, ptp->pte_lo, ptp); - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(va); - tlbsync(); - pm->pm_stats.resident_count--; - goto next; - } - for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) - if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) { - pmap_remove_pv(idx, va, ptp->pte_lo, ptp); - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(va); - tlbsync(); - pm->pm_stats.resident_count--; - goto next; - } - for (po = potable[idx].lh_first; po; po = npo) { - npo = po->po_list.le_next; - if (ptematch(&po->po_pte, sr, va, 0)) { - pmap_remove_pv(idx, va, po->po_pte.pte_lo, - &po->po_pte); - LIST_REMOVE(po, po_list); - pofree(po, 1); - pm->pm_stats.resident_count--; - goto next; - } - } - next: - va += NBPG; - } - splx(s); -} - -void -pmap_kremove(va, len) - vaddr_t va; - vsize_t len; -{ - struct pmap *pm = pmap_kernel(); - vaddr_t endva = va + len; - int idx, i, s; - sr_t sr; - pte_t *ptp; - struct pte_ovfl *po, *npo; - - s = splvm(); - while (va < endva) { - idx = pteidx(sr = ptesr(pm->pm_sr, va), va); - for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) - if (ptematch(ptp, sr, va, PTE_VALID)) { - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(va); - tlbsync(); - pm->pm_stats.resident_count--; - goto next; - } - for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) - if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) { - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(va); - tlbsync(); - pm->pm_stats.resident_count--; - goto next; - } - for (po = potable[idx].lh_first; po; po = npo) { - npo = po->po_list.le_next; - if (ptematch(&po->po_pte, sr, va, 0)) { - LIST_REMOVE(po, po_list); - pofree(po, 1); - pm->pm_stats.resident_count--; - goto next; - } - } - next: - va += NBPG; - } - splx(s); -} - -static pte_t * -pte_find(pm, va) - struct pmap *pm; - vaddr_t va; -{ - int idx, i; - sr_t sr; - pte_t *ptp; - struct pte_ovfl *po; - - idx = pteidx(sr = ptesr(pm->pm_sr, va), va); - for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) - if (ptematch(ptp, sr, va, PTE_VALID)) - return ptp; - for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) - if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) - return ptp; - for (po = potable[idx].lh_first; po; po = po->po_list.le_next) - if (ptematch(&po->po_pte, sr, va, 0)) - return &po->po_pte; - return 0; -} - -/* - * Get the physical page address for the given pmap/virtual address. - */ -boolean_t -pmap_extract(pm, va, pap) - struct pmap *pm; - vaddr_t va; - paddr_t *pap; -{ - pte_t *ptp; - int s = splvm(); - - if (!(ptp = pte_find(pm, va))) { - splx(s); - return (FALSE); - } - *pap = (ptp->pte_lo & PTE_RPGN) | (va & ADDR_POFF); - splx(s); - return (TRUE); -} - -/* - * Lower the protection on the specified range of this pmap. - * - * There are only two cases: either the protection is going to 0, - * or it is going to read-only. - */ -void -pmap_protect(pm, sva, eva, prot) - struct pmap *pm; - vaddr_t sva, eva; - vm_prot_t prot; -{ - pte_t *ptp; - int valid, s; - - if (prot & VM_PROT_READ) { - s = splvm(); - while (sva < eva) { - if ((ptp = pte_find(pm, sva)) != NULL) { - valid = ptp->pte_hi & PTE_VALID; - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(sva); - tlbsync(); - ptp->pte_lo &= ~PTE_PP; - ptp->pte_lo |= PTE_RO; - asm volatile ("sync"); - ptp->pte_hi |= valid; - } - sva += NBPG; - } - splx(s); - return; - } - pmap_remove(pm, sva, eva); -} - -boolean_t -ptemodify(pg, mask, val) - struct vm_page *pg; - u_int mask; - u_int val; -{ - paddr_t pa = VM_PAGE_TO_PHYS(pg); - struct pv_entry *pv; - pte_t *ptp; - struct pte_ovfl *po; - int i, s; - char *attr; - int rv; - - /* - * First modify bits in cache. - */ - attr = pa_to_attr(pa); - if (attr == NULL) - return FALSE; - - rv = *attr & (mask >> ATTRSHFT); - *attr &= ~mask >> ATTRSHFT; - *attr |= val >> ATTRSHFT; - - pv = pa_to_pv(pa); - if (pv->pv_idx < 0) - return rv != 0; - - s = splvm(); - for (; pv; pv = pv->pv_next) { - for (ptp = ptable + pv->pv_idx * 8, i = 8; --i >= 0; ptp++) - if ((ptp->pte_hi & PTE_VALID) - && (ptp->pte_lo & PTE_RPGN) == pa) { - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(pv->pv_va); - tlbsync(); - rv |= ptp->pte_lo & mask; - ptp->pte_lo &= ~mask; - ptp->pte_lo |= val; - asm volatile ("sync"); - ptp->pte_hi |= PTE_VALID; - } - for (ptp = ptable + (pv->pv_idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) - if ((ptp->pte_hi & PTE_VALID) - && (ptp->pte_lo & PTE_RPGN) == pa) { - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(pv->pv_va); - tlbsync(); - rv |= ptp->pte_lo & mask; - ptp->pte_lo &= ~mask; - ptp->pte_lo |= val; - asm volatile ("sync"); - ptp->pte_hi |= PTE_VALID; - } - for (po = potable[pv->pv_idx].lh_first; po; po = po->po_list.le_next) - if ((po->po_pte.pte_lo & PTE_RPGN) == pa) { - rv |= ptp->pte_lo & mask; - po->po_pte.pte_lo &= ~mask; - po->po_pte.pte_lo |= val; - } - } - splx(s); - return rv != 0; -} - -int -ptebits(pg, bit) - struct vm_page *pg; - int bit; -{ - struct pv_entry *pv; - pte_t *ptp; - struct pte_ovfl *po; - int i, s, bits = 0; - char *attr; - paddr_t pa = VM_PAGE_TO_PHYS(pg); - - /* - * First try the cache. - */ - attr = pa_to_attr(pa); - if (attr == NULL) - return 0; - bits |= (*attr << ATTRSHFT) & bit; - if (bits == bit) - return bits; - - pv = pa_to_pv(pa); - if (pv->pv_idx < 0) - return 0; - - s = splvm(); - for (; pv; pv = pv->pv_next) { - for (ptp = ptable + pv->pv_idx * 8, i = 8; --i >= 0; ptp++) - if ((ptp->pte_hi & PTE_VALID) - && (ptp->pte_lo & PTE_RPGN) == pa) { - bits |= ptp->pte_lo & bit; - if (bits == bit) { - splx(s); - return bits; - } - } - for (ptp = ptable + (pv->pv_idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) - if ((ptp->pte_hi & PTE_VALID) - && (ptp->pte_lo & PTE_RPGN) == pa) { - bits |= ptp->pte_lo & bit; - if (bits == bit) { - splx(s); - return bits; - } - } - for (po = potable[pv->pv_idx].lh_first; po; po = po->po_list.le_next) - if ((po->po_pte.pte_lo & PTE_RPGN) == pa) { - bits |= po->po_pte.pte_lo & bit; - if (bits == bit) { - splx(s); - return bits; - } - } - } - splx(s); - return bits; -} - -/* - * Lower the protection on the specified physical page. - * - * There are only two cases: either the protection is going to 0, - * or it is going to read-only. - */ -void -pmap_page_protect(pg, prot) - struct vm_page *pg; - vm_prot_t prot; -{ - paddr_t pa = VM_PAGE_TO_PHYS(pg); - vaddr_t va; - pte_t *ptp; - struct pte_ovfl *po, *npo; - int i, s, idx; - struct pv_entry *pv; - - pa &= ~ADDR_POFF; - if (prot & VM_PROT_READ) { - ptemodify(pg, PTE_PP, PTE_RO); - return; - } - - pv = pa_to_pv(pa); - if (pv == NULL) - return; - - s = splvm(); - while (pv->pv_idx >= 0) { - idx = pv->pv_idx; - va = pv->pv_va; - for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) - if ((ptp->pte_hi & PTE_VALID) - && (ptp->pte_lo & PTE_RPGN) == pa) { - pmap_remove_pv(idx, va, pa, ptp); - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(va); - tlbsync(); - goto next; - } - for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) - if ((ptp->pte_hi & PTE_VALID) - && (ptp->pte_lo & PTE_RPGN) == pa) { - pmap_remove_pv(idx, va, pa, ptp); - ptp->pte_hi &= ~PTE_VALID; - asm volatile ("sync"); - tlbie(va); - tlbsync(); - goto next; - } - for (po = potable[idx].lh_first; po; po = npo) { - npo = po->po_list.le_next; - if ((po->po_pte.pte_lo & PTE_RPGN) == pa) { - pmap_remove_pv(idx, va, pa, &po->po_pte); - LIST_REMOVE(po, po_list); - pofree(po, 1); - goto next; - } - } -next: - } - splx(s); -} - -/* - * Activate the address space for the specified process. If the process - * is the current process, load the new MMU context. - */ -void -pmap_activate(l) - struct lwp *l; -{ - struct pcb *pcb = &l->l_addr->u_pcb; - pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap, rpm; - int psl, i, seg; - - /* - * XXX Normally performed in cpu_fork(). - */ - if (pcb->pcb_pm != pmap) { - pcb->pcb_pm = pmap; - (void) pmap_extract(pmap_kernel(), (vaddr_t)pcb->pcb_pm, - (paddr_t *)&pcb->pcb_pmreal); - } - - if (l == curlwp) { - /* Disable interrupts while switching. */ - __asm __volatile("mfmsr %0" : "=r"(psl) :); - psl &= ~PSL_EE; - __asm __volatile("mtmsr %0" :: "r"(psl)); - - /* Store pointer to new current pmap. */ - curpm = pcb->pcb_pmreal; - - /* - * Set new segment registers. We use the pmap's real - * address to avoid accessibility problems. - */ - rpm = pcb->pcb_pmreal; - for (i = 0; i < 16; i++) { - /* Do not reload the kernel segment register. */ - if (i == KERNEL_SR) continue; - - seg = rpm->pm_sr[i]; - __asm __volatile("mtsrin %0,%1" - :: "r"(seg), "r"(i << ADDR_SR_SHFT)); - } - - /* Interrupts are OK again. */ - psl |= PSL_EE; - __asm __volatile("mtmsr %0" :: "r"(psl)); - } -} - -/* - * Deactivate the specified process's address space. - */ -void -pmap_deactivate(l) - struct lwp *l; -{ -} - -/* - * Synchronize caches corresponding to [addr, addr+len) in p. - */ -void -pmap_procwr(p, va, len) - struct proc *p; - vaddr_t va; - size_t len; -{ - paddr_t pa; - - (void) pmap_extract(p->p_vmspace->vm_map.pmap, va, &pa); - __syncicache((void *)pa, len); -} diff --git a/sys/arch/prep/include/vmparam.h b/sys/arch/prep/include/vmparam.h index 53f84399b967..59aaae42f06d 100644 --- a/sys/arch/prep/include/vmparam.h +++ b/sys/arch/prep/include/vmparam.h @@ -1,113 +1,4 @@ -/* $NetBSD: vmparam.h,v 1.10 2002/12/10 05:14:32 thorpej Exp $ */ +/* $NetBSD: vmparam.h,v 1.11 2003/02/02 21:22:13 matt Exp $ */ -#ifndef OLDPMAP #define USER_SR 11 #include -#else -/*- - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MACHINE_VMPARAM_H_ -#define _MACHINE_VMPARAM_H_ - -#define USRSTACK VM_MAXUSER_ADDRESS - -#ifndef MAXTSIZ -#define MAXTSIZ (16*1024*1024) /* max text size */ -#endif - -#ifndef DFLDSIZ -#define DFLDSIZ (32*1024*1024) /* default data size */ -#endif - -#ifndef MAXDSIZ -#define MAXDSIZ (512*1024*1024) /* max data size */ -#endif - -#ifndef DFLSSIZ -#define DFLSSIZ (1*1024*1024) /* default stack size */ -#endif - -#ifndef MAXSSIZ -#define MAXSSIZ (32*1024*1024) /* max stack size */ -#endif - -/* - * Size of shared memory map - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 -#endif - -/* - * Size of User Raw I/O map - */ -#define USRIOSIZE 1024 - -/* - * Would like to have MAX addresses = 0, but this doesn't (currently) work - */ -#define VM_MIN_ADDRESS ((vaddr_t)0) -#define VM_MAXUSER_ADDRESS ((vaddr_t)0xfffff000) -#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS -#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)(KERNEL_SR << ADDR_SR_SHFT)) -#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + SEGMENT_LENGTH - 1) - -/* XXX max. amount of KVM to be used by buffers. */ -#ifndef VM_MAX_KERNEL_BUF -#define VM_MAX_KERNEL_BUF (SEGMENT_LENGTH * 7 / 10) -#endif - -/* - * Override the default pager_map size, there's not enough KVA. - */ -#define PAGER_MAP_SIZE (4 * 1024 * 1024) - -#define VM_PHYS_SIZE (USRIOSIZE * NBPG) - -#define __HAVE_PMAP_PHYSSEG - -#ifndef _LOCORE -struct pmap_physseg { - struct pv_entry *pvent; - char *attrs; -}; -#endif /* _LOCORE */ - -#define VM_PHYSSEG_MAX 32 -#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH -#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ - -#define VM_NFREELIST 1 -#define VM_FREELIST_DEFAULT 0 - -#endif /* _MACHINE_VMPARAM_H_ */ -#endif diff --git a/sys/arch/sandpoint/include/vmparam.h b/sys/arch/sandpoint/include/vmparam.h index 0fa21c899998..7493e7d3f583 100644 --- a/sys/arch/sandpoint/include/vmparam.h +++ b/sys/arch/sandpoint/include/vmparam.h @@ -1,102 +1,3 @@ -/* $NetBSD: vmparam.h,v 1.9 2002/12/10 05:14:32 thorpej Exp $ */ +/* $NetBSD: vmparam.h,v 1.10 2003/02/02 21:22:13 matt Exp $ */ -#ifndef OLDPMAP #include -#else -/*- - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MACHINE_VMPARAM_H_ -#define _MACHINE_VMPARAM_H_ - -#define USRSTACK VM_MAXUSER_ADDRESS - -#ifndef MAXTSIZ -#define MAXTSIZ (64*1024*1024) /* max text size */ -#endif - -#ifndef DFLDSIZ -#define DFLDSIZ (128*1024*1024) /* default data size */ -#endif - -#ifndef MAXDSIZ -#define MAXDSIZ (1*1024*1024*1024) /* max data size */ -#endif - -#ifndef DFLSSIZ -#define DFLSSIZ (2*1024*1024) /* default stack size */ -#endif - -#ifndef MAXSSIZ -#define MAXSSIZ (32*1024*1024) /* max stack size */ -#endif - -/* - * Size of shared memory map - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 -#endif - -/* - * Size of User Raw I/O map - */ -#define USRIOSIZE 1024 - -/* - * Would like to have MAX addresses = 0, but this doesn't (currently) work - */ -#define VM_MIN_ADDRESS ((vaddr_t)0) -#define VM_MAXUSER_ADDRESS ((vaddr_t)0xfffff000) -#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS -#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)(KERNEL_SR << ADDR_SR_SHFT)) -#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + SEGMENT_LENGTH - 1) - -#define VM_PHYS_SIZE (USRIOSIZE * NBPG) - -#define __HAVE_PMAP_PHYSSEG - -#ifndef _LOCORE -struct pmap_physseg { - struct pv_entry *pvent; - char *attrs; -}; -#endif - -#define VM_PHYSSEG_MAX 32 -#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH -#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ - -#define VM_NFREELIST 1 -#define VM_FREELIST_DEFAULT 0 - -#endif /* _MACHINE_VMPARAM_H_ */ -#endif