Module Name: src
Committed By: uebayasi
Date: Mon Nov 22 03:20:57 UTC 2010
Modified Files:
src/sys/uvm [uebayasi-xip]: uvm_page.c
Log Message:
Start merging uvm_page_physload() and uvm_page_physload_device().
To generate a diff of this commit:
cvs rdiff -u -r1.153.2.68 -r1.153.2.69 src/sys/uvm/uvm_page.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.153.2.68 src/sys/uvm/uvm_page.c:1.153.2.69
--- src/sys/uvm/uvm_page.c:1.153.2.68 Sun Nov 21 15:27:36 2010
+++ src/sys/uvm/uvm_page.c Mon Nov 22 03:20:56 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.c,v 1.153.2.68 2010/11/21 15:27:36 uebayasi Exp $ */
+/* $NetBSD: uvm_page.c,v 1.153.2.69 2010/11/22 03:20:56 uebayasi Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.153.2.68 2010/11/21 15:27:36 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.153.2.69 2010/11/22 03:20:56 uebayasi Exp $");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -782,14 +782,38 @@
* => we are limited to VM_PHYSSEG_MAX physical memory segments
*/
+#define VM_PHYSSEG_PROT_READ UVM_PROT_READ /* 0x00000001 */
+#define VM_PHYSSEG_PROT_WRITE UVM_PROT_WRITE /* 0x00000002 */
+#define VM_PHYSSEG_PROT_EXEC UVM_PROT_EXEC /* 0x00000004 */
+#define VM_PHYSSEG_PROT_ALL UVM_PROT_ALL /* 0x00000007 */
+#define VM_PHYSSEG_PROT_MASK UVM_PROT_MASK /* 0x00000007 */
+#define VM_PHYSSEG_DEVICE 0x00010000
+
+void *
+uvm_page_physload1(paddr_t start, paddr_t end, paddr_t avail_start,
+ paddr_t avail_end, int free_list, int flags);
+static void
+uvm_page_physload_device1(struct vm_physseg *seg, paddr_t start, paddr_t end,
+ int flags);
+
void *
uvm_page_physload(paddr_t start, paddr_t end, paddr_t avail_start,
paddr_t avail_end, int free_list)
{
+
+ return uvm_page_physload1(start, end, avail_start, avail_end,
+ free_list, VM_PHYSSEG_PROT_ALL);
+}
+
+void *
+uvm_page_physload1(paddr_t start, paddr_t end, paddr_t avail_start,
+ paddr_t avail_end, int free_list, int flags)
+{
struct vm_physseg *seg;
int lcv;
- if (free_list >= VM_NFREELIST || free_list < VM_FREELIST_DEFAULT)
+ if (((flags & VM_PHYSSEG_DEVICE) == 0) &&
+ (free_list >= VM_NFREELIST || free_list < VM_FREELIST_DEFAULT))
panic("uvm_page_physload: bad free list %d", free_list);
seg = uvm_physseg_alloc(&vm_physmem_freelist, vm_physmem_ptrs,
@@ -798,6 +822,9 @@
seg->avail_start = avail_start;
seg->avail_end = avail_end;
+ seg->free_list = free_list;
+ seg->flags = flags;
+
/*
* check to see if this is a "preload" (i.e. uvm_page_init hasn't been
* called yet, so malloc is not available).
@@ -808,14 +835,29 @@
break;
}
if (lcv == vm_nphysmem) {
+ /* preload */
seg->pgs = NULL;
seg->endpg = NULL;
- seg->free_list = free_list;
+
+ if ((flags & VM_PHYSSEG_DEVICE) == 0) {
+ vm_nphysmem++;
+ } else {
+ panic("device physseg preload not supported!");
+ }
} else {
- panic("uvm_page_physload: "
- "tried to add RAM after uvm_page_init");
+ /* postload */
+ seg->pgs = kmem_zalloc(sizeof(struct vm_page) * (end - start),
+ KM_SLEEP);
+ KASSERT(seg->pgs != NULL);
+ seg->endpg = seg->pgs + (end - start);
+
+ if ((flags & VM_PHYSSEG_DEVICE) == 0) {
+ panic("memory physseg postload not supported!");
+ } else {
+ uvm_page_physload_device1(seg, start, end, flags);
+ vm_nphysdev++;
+ }
}
- vm_nphysmem++;
return seg;
}
@@ -834,15 +876,11 @@
uvm_page_physload_device(paddr_t start, paddr_t end, int prot, int flags)
{
struct vm_physseg *seg;
- int i;
seg = uvm_physseg_alloc(&vm_physdev_freelist, vm_physdev_ptrs,
vm_nphysdev, start, end);
KASSERT(seg != NULL);
- seg->prot = prot;
- seg->flags = flags;
-
/*
* Device page metadata initialization
* - Pages are not used for general purpose memory.
@@ -854,17 +892,29 @@
KM_SLEEP);
KASSERT(seg->pgs != NULL);
seg->endpg = seg->pgs + (end - start);
- seg->start = start;
- seg->end = end;
+
+ KASSERT((prot & ~UVM_PROT_ALL) == 0);
+ uvm_page_physload_device1(seg, start, end, prot | flags);
+ vm_nphysdev++;
+ return seg;
+}
+
+static void
+uvm_page_physload_device1(struct vm_physseg *seg, paddr_t start, paddr_t end,
+ int flags)
+{
+ const bool rdonly = (flags & UVM_PROT_MASK) == UVM_PROT_READ;
+ const int pg_flags = PG_CLEAN | PG_DEVICE |
+ ((rdonly) ? PG_RDONLY : 0);
+ int i;
for (i = 0; i < end - start; i++) {
struct vm_page *pg = seg->pgs + i;
paddr_t paddr = (start + i) << PAGE_SHIFT;
pg->phys_addr = paddr;
- pg->flags |= PG_CLEAN | PG_DEVICE;
- if (prot == VM_PROT_READ)
- pg->flags |= PG_RDONLY;
+ pg->flags = pg_flags;
+
#ifdef __HAVE_VM_PAGE_MD
VM_MDPAGE_INIT(&pg->mdpage, paddr);
#endif
@@ -880,9 +930,6 @@
pmap_physseg_init(seg);
#endif
#endif
-
- vm_nphysdev++;
- return seg;
}
void