Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/usermode/usermode First pass of NetBSD/usermode's p...
details: https://anonhg.NetBSD.org/src/rev/2169f60c6543
branches: trunk
changeset: 768665:2169f60c6543
user: reinoud <reinoud%NetBSD.org@localhost>
date: Wed Aug 24 11:02:31 2011 +0000
description:
First pass of NetBSD/usermode's pmap.c cleanup:
* use thunk_malloc() for UVM space allocation releasing sbrk()
* make pmap.c 64 bit friendly for large page numbers
diffstat:
sys/arch/usermode/usermode/pmap.c | 129 ++++++++++++++++++-------------------
1 files changed, 64 insertions(+), 65 deletions(-)
diffs (289 lines):
diff -r dc4d3efd7b02 -r 2169f60c6543 sys/arch/usermode/usermode/pmap.c
--- a/sys/arch/usermode/usermode/pmap.c Wed Aug 24 10:59:10 2011 +0000
+++ b/sys/arch/usermode/usermode/pmap.c Wed Aug 24 11:02:31 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.25 2011/08/23 18:37:51 reinoud Exp $ */
+/* $NetBSD: pmap.c,v 1.26 2011/08/24 11:02:31 reinoud Exp $ */
/*-
* Copyright (c) 2011 Reinoud Zandijk <reinoud%NetBSD.org@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.25 2011/08/23 18:37:51 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.26 2011/08/24 11:02:31 reinoud Exp $");
#include "opt_memsize.h"
#include "opt_kmempages.h"
@@ -43,10 +43,10 @@
#include <uvm/uvm.h>
struct pv_entry {
- struct pv_entry *pv_next;
- pmap_t pv_pmap;
- int pv_ppn; /* physical page number */
- int pv_lpn; /* logical page number */
+ struct pv_entry *pv_next;
+ pmap_t pv_pmap;
+ uintptr_t pv_ppn; /* physical page number */
+ uintptr_t pv_lpn; /* logical page number */
vm_prot_t pv_prot; /* logical protection */
int pv_mmap_ppl; /* programmed protection */
uint8_t pv_vflags; /* per mapping flags */
@@ -71,8 +71,9 @@
static struct pmap pmap_kernel_store;
struct pmap * const kernel_pmap_ptr = &pmap_kernel_store;
-static char mem_name[20] = "";
-static int mem_fh;
+static char mem_name[20] = "";
+static int mem_fh;
+static void *mem_uvm; /* keeps all memory managed by UVM */
static int phys_npages = 0;
static int pm_nentries = 0;
@@ -84,17 +85,15 @@
void pmap_bootstrap(void);
static void pmap_page_activate(struct pv_entry *pv);
static void pv_update(struct pv_entry *pv);
-static void pmap_update_page(int ppn);
+static void pmap_update_page(uintptr_t ppn);
-static struct pv_entry *pv_get(pmap_t pmap, int ppn, int lpn);
+static struct pv_entry *pv_get(pmap_t pmap, uintptr_t ppn, uintptr_t lpn);
static struct pv_entry *pv_alloc(void);
static void pv_free(struct pv_entry *pv);
-//void pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva);
static void pmap_deferred_init(void);
/* exposed to signal handler */
vaddr_t kmem_k_start, kmem_k_end;
-vaddr_t kmem_data_start, kmem_data_end;
vaddr_t kmem_ext_start, kmem_ext_end;
vaddr_t kmem_user_start, kmem_user_end;
vaddr_t kmem_ext_cur_start, kmem_ext_cur_end;
@@ -106,13 +105,16 @@
ssize_t fpos, file_len;
ssize_t pv_fpos, pm_fpos;
ssize_t wlen;
- uint64_t pv_table_size;
- paddr_t free_start, free_end;
+ ssize_t kmem_len, user_len, barrier_len, uvm_len;
+ ssize_t pv_table_size;
+ vaddr_t free_start, free_end;
+ vaddr_t mpos;
paddr_t pa;
vaddr_t va;
+ uintptr_t pg;
void *addr;
char dummy;
- int pg, err;
+ int err;
extern void _init(void); /* start of kernel */
extern int etext; /* end of the kernel */
@@ -126,56 +128,52 @@
aprint_debug("1st end of data at %p\n", &end);
aprint_debug("CUR end data at %p\n", thunk_sbrk(0));
- /* calculate sections of the kernel (R+X) */
+ /* calculate memory lengths */
+ kmem_len = (physmem/2) * PAGE_SIZE;
+ user_len = MEMSIZE * 1024;
+ barrier_len = 2 * 1024 * 1024;
+
+ /* calculate kernel section (R-X) */
kmem_k_start = (vaddr_t) PAGE_SIZE * (atop(_init) );
kmem_k_end = (vaddr_t) PAGE_SIZE * (atop(&etext) + 1);
- /* read only section (for userland R, kernel RW) */
- kmem_data_start = (vaddr_t) PAGE_SIZE * (atop(&etext));
- kmem_data_end = (vaddr_t) PAGE_SIZE * (atop(&end) + 1);
- if (kmem_data_end > (vaddr_t) thunk_sbrk(0)) {
- aprint_debug("sbrk() has advanced, catching up\n");
- kmem_data_end = (vaddr_t) PAGE_SIZE * (atop(thunk_sbrk(0))+1);
- }
+ /* claim memory with 2 pages more */
+ uvm_len = kmem_len + barrier_len + user_len + barrier_len + 2*PAGE_SIZE;
+ mem_uvm = thunk_malloc(uvm_len);
+ /* make page aligned */
+ mpos = round_page((vaddr_t) mem_uvm) + PAGE_SIZE;
-#ifdef DIAGNOSTIC
- if (kmem_k_end >= kmem_data_start) {
- aprint_debug("end of kernel and kernel exec could clash\n");
- aprint_debug(" kmem_k_end = %p, kmem_data_start = %p\n",
- (void *) kmem_k_end, (void *) kmem_data_start);
- aprint_debug("fixing\n");
- }
-#endif
- /* on clash move RO segment so that all code is executable */
- if (kmem_k_end >= kmem_data_start)
- kmem_data_start = kmem_k_end;
+ /* calculate KVM section (RW-) */
+ kmem_ext_start = mpos;
+ mpos += kmem_len;
+ kmem_ext_end = mpos;
- /* claim an area for kernel data space growth (over dim) */
- kmem_ext_start = kmem_data_end;
- kmem_ext_end = kmem_ext_start + (physmem/2) * PAGE_SIZE;
+ /* low barrier (---) */
+ mpos += barrier_len;
- /* claim an area for userland */
- kmem_user_start = kmem_ext_end;
- kmem_user_end = kmem_user_start + 1024 * MEMSIZE;
+ /* claim an area for userland (---/R--/RW-/RWX) */
+ kmem_user_start = mpos;
+ mpos += user_len;
+ kmem_user_end = mpos;
/* TODO make a better user space size estimate */
- /* claim dummy space over all we need just to make fun of sbrk */
- addr = thunk_mmap((void*) kmem_data_end,
- kmem_user_end - kmem_data_end,
+ /* upper barrier (---) */
+ mpos += barrier_len;
+
+#if 0
+ /* protect complete UVM area (---) */
+ addr = thunk_mmap((void*) mem_uvm,
+ uvm_len,
PROT_NONE,
MAP_ANON | MAP_FIXED,
-1, 0);
- if (addr != (void *) kmem_data_end)
- panic("pmap_bootstrap: protection barrier failed\n");
-
- if (kmem_user_end < kmem_user_start)
- panic("pmap_bootstrap: to small memorysize specified");
+ if (addr != (void *) mem_uvm)
+ panic("pmap_bootstrap: uvm space protection barrier failed\n");
+#endif
aprint_debug("\nMemory summary\n");
aprint_debug("\tkmem_k_start\t%p\n", (void *) kmem_k_start);
aprint_debug("\tkmem_k_end\t%p\n", (void *) kmem_k_end);
- aprint_debug("\tkmem_data_start\t%p\n", (void *) kmem_data_start);
- aprint_debug("\tkmem_data_end\t%p\n", (void *) kmem_data_end);
aprint_debug("\tkmem_ext_start\t%p\n", (void *) kmem_ext_start);
aprint_debug("\tkmem_ext_end\t%p\n", (void *) kmem_ext_end);
aprint_debug("\tkmem_user_start\t%p\n", (void *) kmem_user_start);
@@ -204,9 +202,6 @@
err = thunk_mprotect((void *) kmem_k_start, kmem_k_end - kmem_k_start,
PROT_READ | PROT_EXEC);
assert(err == 0);
- err = thunk_mprotect((void *) kmem_k_end, kmem_data_end - kmem_k_end,
- PROT_READ | PROT_WRITE);
- assert(err == 0);
/* set up pv_table; bootstrap problem! */
fpos = 0;
@@ -216,7 +211,8 @@
phys_npages = (free_end - free_start) / PAGE_SIZE;
pv_table_size = round_page(phys_npages * sizeof(struct pv_entry));
aprint_debug("claiming %"PRIu64" KB of pv_table for "
- "%d pages of physical memory\n", pv_table_size/1024, phys_npages);
+ "%"PRIdPTR" pages of physical memory\n",
+ (uint64_t) pv_table_size/1024, (uintptr_t) phys_npages);
kmem_ext_cur_start = kmem_ext_start;
pv_fpos = fpos;
@@ -237,7 +233,7 @@
fpos += pv_table_size;
/* set up kernel pmap */
- pm_nentries = (kmem_user_end - kmem_k_start) / PAGE_SIZE;
+ pm_nentries = (kmem_user_end - kmem_ext_start) / PAGE_SIZE;
pm_entries_size = round_page(pm_nentries * sizeof(struct pv_entry *));
aprint_debug("pmap va->pa lookup table is %"PRIu64" KB for %d logical pages\n",
pm_entries_size/1024, pm_nentries);
@@ -381,7 +377,7 @@
}
static struct pv_entry *
-pv_get(pmap_t pmap, int ppn, int lpn)
+pv_get(pmap_t pmap, uintptr_t ppn, uintptr_t lpn)
{
struct pv_entry *pv;
@@ -398,7 +394,8 @@
}
}
/* Otherwise, allocate a new entry and link it in after the head. */
- printf("pv_get: multiple mapped page ppn %d, lpn %d\n", ppn, lpn);
+ printf("pv_get: multiple mapped page ppn %"PRIdPTR", lpn %"PRIdPTR"\n",
+ ppn, lpn);
assert(ppn < phys_npages);
assert(ppn >= 0);
panic("pv_get: multiple\n");
@@ -417,7 +414,7 @@
pmap_page_activate(struct pv_entry *pv)
{
paddr_t pa = pv->pv_ppn * PAGE_SIZE;
- vaddr_t va = pv->pv_lpn * PAGE_SIZE + kmem_k_start; /* XXX V->A make new var */
+ vaddr_t va = pv->pv_lpn * PAGE_SIZE + kmem_ext_start; /* XXX V->A make new var */
void *addr;
@@ -453,7 +450,7 @@
/* update mapping of a physical page */
static void
-pmap_update_page(int ppn)
+pmap_update_page(uintptr_t ppn)
{
struct pv_entry *pv;
@@ -468,12 +465,13 @@
static int
pmap_do_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, uint flags, int unmanaged)
{
- int ppn, lpn, s;
struct pv_entry *pv, *ppv;
+ uintptr_t ppn, lpn;
+ int s;
/* to page numbers */
ppn = atop(pa);
- lpn = atop(va - kmem_k_start); /* XXX V->A make new var */
+ lpn = atop(va - kmem_ext_start); /* XXX V->A make new var */
#ifdef DIAGNOSTIC
if ((va < kmem_k_start) || (va > kmem_user_end))
panic("pmap_do_enter: invalid va isued\n");
@@ -542,11 +540,11 @@
/* release the pv_entry for a mapping. Code derived also from hp300 pmap */
static void
-pv_release(pmap_t pmap, int ppn, int lpn)
+pv_release(pmap_t pmap, uintptr_t ppn, uintptr_t lpn)
{
struct pv_entry *pv, *npv;
-aprint_debug("pv_release ppn %d, lpn %d\n", ppn, lpn);
+aprint_debug("pv_release ppn %"PRIdPTR", lpn %"PRIdPTR"\n", ppn, lpn);
pv = &pv_table[ppn];
/*
* If it is the first entry on the list, it is actually
@@ -581,8 +579,9 @@
void
pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
{
- int slpn, elpn, lpn, s;
+ uintptr_t slpn, elpn, lpn;
struct pv_entry *pv;
+ int s;
aprint_debug("pmap_remove() called\n");
@@ -631,7 +630,7 @@
/* TODO protect against roque values */
aprint_debug("pmap_extract: extracting va %p\n", (void *) va);
- pv = pmap->pm_entries[atop(va - kmem_k_start)]; /* XXX V->A make new var */
+ pv = pmap->pm_entries[atop(va - kmem_ext_start)]; /* XXX V->A make new var */
if (pv == NULL)
return false;
Home |
Main Index |
Thread Index |
Old Index