PERFORCE change 107821 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Fri Oct 13 07:07:36 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=107821
Change 107821 by gonzo at 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;
More information about the p4-projects
mailing list