Date: Fri, 13 Oct 2006 14:07:17 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 107821 for review Message-ID: <200610131407.k9DE7H8v029890@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=107821 Change 107821 by gonzo@gonzo_hq on 2006/10/13 14:07:10 o Map user address space using a two level structure where virtual address bits 30..22 are used to index into a segment table which points to a page worth of PTEs (4096 page can hold 1024 PTEs). Bits 21..12 are then used to index a PTE which describes a page within a segment. The idea came from NetBSD MIPS pmap module. For kernel address space we still use direct-mapped memory map. Affected files ... .. //depot/projects/mips2/src/sys/mips/include/pmap.h#5 edit .. //depot/projects/mips2/src/sys/mips/include/vmparam.h#8 edit .. //depot/projects/mips2/src/sys/mips/mips/pmap.c#12 edit .. //depot/projects/mips2/src/sys/mips/mips/trap.c#9 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/include/pmap.h#5 (text+ko) ==== @@ -26,6 +26,81 @@ * $FreeBSD$ */ +/* $NetBSD: pmap.h,v 1.50 2006/02/16 20:17:14 perry Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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. + * + * @(#)pmap.h 8.1 (Berkeley) 6/10/93 + */ + +/* + * Copyright (c) 1987 Carnegie-Mellon University + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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. + * + * @(#)pmap.h 8.1 (Berkeley) 6/10/93 + */ + + + #ifndef _MACHINE_PMAP_H_ #define _MACHINE_PMAP_H_ @@ -38,12 +113,44 @@ struct pv_entry; +/* + * The user address space is 2Gb (0x0 - 0x80000000). + * User programs are laid out in memory as follows: + * address + * USRTEXT 0x00001000 + * USRDATA USRTEXT + text_size + * USRSTACK 0x7FFFFFFF + * + * The user address space is mapped using a two level structure where + * virtual address bits 30..22 are used to index into a segment table which + * points to a page worth of PTEs (4096 page can hold 1024 PTEs). + * Bits 21..12 are then used to index a PTE which describes a page within + * a segment. + * + * We use wired TLB entry #0 to keep thread's stack + * + */ + +#define MIPS_PMAP_SEGTABSIZE 512 +#define MIPS_PMAP_SEGSIZE 1024 + +struct segtab { + pt_entry_t *seg_tab[MIPS_PMAP_SEGTABSIZE]; +}; + +extern struct segtab *segbase; /* current segtab base */ + typedef struct pmap { struct pmap_statistics pm_stats; int pm_asid; int pm_asidgen; int pm_active; - pt_entry_t *pm_lev1; /* KVA of lev0map */ + union { + /* pointers to pages of PTEs */ + struct segtab *pm_segtab; + /* pointer to directly-mapped table of PTEs */ + pt_entry_t *pm_direct_map; + } pm_private; vm_object_t pm_pteobj; /* Container for pte's */ TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ struct vm_page *pm_ptphint; /* pmap ptp hint */ @@ -73,6 +180,7 @@ #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) +extern struct segtab * segtab_active; extern pmap_t kernel_pmap; extern vm_offset_t phys_avail[]; extern vm_offset_t virtual_avail; @@ -91,7 +199,4 @@ #endif /*!LOCORE*/ -#define NUSERLEV2MAPS (NPTEPG/2) -#define NUSERLEV3MAPS (NUSERLEV2MAPS << MIPS_PTSHIFT) - #endif /* !_MACHINE_PMAP_H_ */ ==== //depot/projects/mips2/src/sys/mips/include/vmparam.h#8 (text+ko) ==== @@ -113,6 +113,8 @@ /* virtual sizes (bytes) for various kernel submaps */ #define VM_KMEM_SIZE (16*1024*1024) /* XXX ??? */ - +#define NBSEG 0x400000 /* bytes/segment */ +#define SEGOFSET (NBSEG-1) /* byte offset into segment */ +#define SEGSHIFT 22 /* LOG2(NBSEG) */ #endif /* _MACHINE_VMPARAM_H_ */ ==== //depot/projects/mips2/src/sys/mips/mips/pmap.c#12 (text+ko) ==== @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1991 Regents of the University of California. * All rights reserved. * Copyright (c) 1994 John S. Dyson @@ -156,7 +156,7 @@ /* * Extract level 1, 2 and 3 page table indices from a va */ -#define PTMASK ((1 << MIPS_PTSHIFT) - 1) +#define PTMASK ((1 << PAGE_SHIFT) - 1) /* * Statically allocated kernel pmap @@ -177,6 +177,11 @@ void pmap_kremove(vm_offset_t); /* + * Active segtab. + */ +struct segtab * segtab_active; + +/* * Data for the ASID allocator */ static int pmap_maxasid; @@ -209,18 +214,20 @@ pmap_pte(pmap_t pmap, vm_offset_t va) { pt_entry_t *pte = NULL; - unsigned long lev1; - if (pmap != kernel_pmap && pmap) { + if (va < MIPS_KSEG0_START) { /* XXX Try to avoid TLB refills */ +#if 0 + unsigned long lev1; lev1 = (unsigned long)pmap->pm_lev1; lev1 = (unsigned long)tlb_pte_find(kptmap, lev1); lev1 = (unsigned long)MIPS_PTE_TO_PA(*(pt_entry_t *)lev1); - pte = tlb_pte_find( (pt_entry_t *)MIPS_PHYS_TO_KSEG0((pt_entry_t *)lev1), va); +#endif + panic("XXXMIPS: %s to implement", __func__); } else - pte = tlb_pte_find(kptmap, va); + pte = tlb_kern_pte_find(kptmap, va); return pte; } @@ -321,7 +328,7 @@ /* * Initialize the kernel pmap (which is statically allocated). */ - kernel_pmap->pm_lev1 = kptmap; + kernel_pmap->pm_private.pm_direct_map = kptmap; kernel_pmap->pm_active = ~0; kernel_pmap->pm_asid = 0; kernel_pmap->pm_asidgen = 1; @@ -698,7 +705,7 @@ struct pmap *pmap; { - pmap->pm_lev1 = kptmap; + pmap->pm_private.pm_direct_map = kptmap; pmap->pm_ptphint = NULL; pmap->pm_active = 0; pmap->pm_asid = 0; @@ -717,21 +724,18 @@ pmap_pinit(pmap) register struct pmap *pmap; { -#ifdef notyet vm_page_t lev1pg; - int i; /* * allocate object for the ptes */ if (pmap->pm_pteobj == NULL) - pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, NUSERLEV3MAPS + NUSERLEV2MAPS + 1); + pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, + MIPS_PMAP_SEGTABSIZE * MIPS_PMAP_SEGSIZE + 1); + VM_OBJECT_LOCK(pmap->pm_pteobj); - /* - * allocate the page directory page - */ - VM_OBJECT_LOCK(pmap->pm_pteobj); - lev1pg = vm_page_grab(pmap->pm_pteobj, NUSERLEV3MAPS + NUSERLEV2MAPS, + lev1pg = vm_page_grab(pmap->pm_pteobj, + MIPS_PMAP_SEGTABSIZE + MIPS_PMAP_SEGSIZE, VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_WIRED | VM_ALLOC_ZERO); vm_page_lock_queues(); @@ -740,22 +744,9 @@ vm_page_unlock_queues(); VM_OBJECT_UNLOCK(pmap->pm_pteobj); - pmap->pm_lev1 = (pt_entry_t*) MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(lev1pg)); - - /* install self-referential address mapping entry (not PG_ASM) */ - pmap->pm_lev1[PTLEV1I] = pmap_phys_to_pte(VM_PAGE_TO_PHYS(lev1pg)) - | PG_V | PG_KRE | PG_KWE; -#else - char *lev1pg; - - /* XXX */ - lev1pg = malloc(2097152, M_TEMP, M_WAITOK); - if (lev1pg == NULL) - panic("no lev1pg\n"); + pmap->pm_private.pm_segtab = + (struct segtab*) MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(lev1pg)); - pmap->pm_lev1 = (pt_entry_t*) lev1pg; -#endif - pmap->pm_ptphint = NULL; pmap->pm_active = 0; /* XXXMIPS: put proper asid generation here */ @@ -766,9 +757,6 @@ mtx_lock_spin(&allpmaps_lock); LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); mtx_unlock_spin(&allpmaps_lock); -#ifdef notyet - bcopy(PTlev1 + K1SEGLEV1I, pmap->pm_lev1 + K1SEGLEV1I, nklev2 * PTESIZE); -#endif } /* @@ -809,29 +797,27 @@ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) { n = TAILQ_NEXT(p, listq); panic("release p from pmap (%p, %p)", p, pmap); -#if 0 /* XXX */ - if (p->pindex >= NUSERLEV3MAPS) { + if (p->pindex >= MIPS_PMAP_SEGTABSIZE + MIPS_PMAP_SEGSIZE) { continue; } -#endif while (1) { - if (/*!pmap_release_free_page(pmap, p) &&*/ + if (/*!pmap_release_free_page(pmap, p) && */ (object->generation != curgeneration)) goto retry; } } for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) { n = TAILQ_NEXT(p, listq); -#if 0 /* XXX */ - if (p->pindex < NUSERLEV3MAPS) { + if (p->pindex < MIPS_PMAP_SEGTABSIZE + MIPS_PMAP_SEGSIZE) { /* can this happen? maybe panic */ goto retry; } - if (p->pindex >= NUSERLEV3MAPS + NUSERLEV2MAPS) { + + if (p->pindex >= MIPS_PMAP_SEGTABSIZE + MIPS_PMAP_SEGSIZE) { lev1pg = p; continue; } -#endif + while (1) { if (/*!pmap_release_free_page(pmap, p) &&*/ (object->generation != curgeneration)) @@ -1163,6 +1149,7 @@ return; va &= ~PAGE_MASK; + #ifdef PMAP_DIAGNOSTIC if (va > VM_MAX_KERNEL_ADDRESS) panic("pmap_enter: toobig"); @@ -1762,6 +1749,7 @@ atomic_clear_int(&pmap_active->pm_active, PCPU_GET(cpumask)); pmap_active = 0; + segtab_active = 0; } if (pmap->pm_asidgen != PCPU_GET(current_asidgen)) @@ -1770,6 +1758,7 @@ mips_wr_entryhi(pmap->pm_asid); pmap_active = pmap; + segtab_active = pmap->pm_private.pm_segtab; atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask)); critical_exit(); ==== //depot/projects/mips2/src/sys/mips/mips/trap.c#9 (text+ko) ==== @@ -136,7 +136,8 @@ if (va >= KERNBASE) { pt_entry_t *pte; - pte = tlb_pte_find(kernel_pmap->pm_lev1, va); + pte = tlb_kern_pte_find( + kernel_pmap->pm_private.pm_direct_map, va); if (!pte_valid(pte)) { map = kernel_map;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610131407.k9DE7H8v029890>