summaryrefslogtreecommitdiff
path: root/sys/arch/powerpc
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-05-03 18:40:22 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-05-03 18:40:22 +0000
commiteedd5ea329da5b156cddc491df51010c67bc886a (patch)
tree8c7ebdc50e6de35ce0cc12de81e46c53bf0f358a /sys/arch/powerpc
parenta57f6a136dc1ecad3ef422187a576d421e348a95 (diff)
Implement pmap_steal_memory() on powerpc. With some help from art@.
Diffstat (limited to 'sys/arch/powerpc')
-rw-r--r--sys/arch/powerpc/include/pmap.h4
-rw-r--r--sys/arch/powerpc/powerpc/pmap.c84
2 files changed, 75 insertions, 13 deletions
diff --git a/sys/arch/powerpc/include/pmap.h b/sys/arch/powerpc/include/pmap.h
index ecfe25ce60f..1fad03dd0df 100644
--- a/sys/arch/powerpc/include/pmap.h
+++ b/sys/arch/powerpc/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.42 2006/05/29 21:50:09 deraadt Exp $ */
+/* $OpenBSD: pmap.h,v 1.43 2007/05/03 18:40:19 miod Exp $ */
/* $NetBSD: pmap.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */
/*-
@@ -140,6 +140,8 @@ int reserve_dumppages(caddr_t p);
void pmap_proc_iflush(struct proc *proc, vaddr_t va, vsize_t len);
#define pmap_unuse_final(p) /* nothing */
+#define PMAP_STEAL_MEMORY
+
#endif /* _KERNEL */
#endif /* _LOCORE */
#endif /* _POWERPC_PMAP_H_ */
diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c
index eb2687587d3..3ff0e4cab00 100644
--- a/sys/arch/powerpc/powerpc/pmap.c
+++ b/sys/arch/powerpc/powerpc/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.98 2007/04/13 18:12:16 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.99 2007/05/03 18:40:21 miod Exp $ */
/*
* Copyright (c) 2001, 2002 Dale Rahn.
@@ -717,7 +717,7 @@ _pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, int flags, int cache)
}
if (cache == PMAP_CACHE_DEFAULT) {
- if (pa < 0x80000000 || pmap_find_pvh(pa) != NULL)
+ if (pmap_find_pvh(pa) != NULL)
cache = PMAP_CACHE_WB; /* managed memory is cacheable */
else
cache = PMAP_CACHE_CI;
@@ -1465,6 +1465,72 @@ pmap_steal_avail(size_t size, int align)
size, align);
}
+/*
+ * Similar to pmap_steal_avail, but operating on vm_physmem since
+ * uvm_page_physload() has been called.
+ */
+vaddr_t
+pmap_steal_memory(vsize_t size, vaddr_t *start, vaddr_t *end)
+{
+ int segno;
+ u_int npg;
+ vaddr_t va;
+ paddr_t pa;
+ struct vm_physseg *seg;
+
+ size = round_page(size);
+ npg = atop(size);
+
+ for (segno = 0, seg = vm_physmem; segno < vm_nphysseg; segno++, seg++) {
+ if (seg->avail_end - seg->avail_start < npg)
+ continue;
+ /*
+ * We can only steal at an ``unused'' segment boundary,
+ * i.e. either at the start or at the end.
+ */
+ if (seg->avail_start == seg->start ||
+ seg->avail_end == seg->end)
+ break;
+ }
+ if (segno == vm_nphysseg)
+ va = 0;
+ else {
+ if (seg->avail_start == seg->start) {
+ pa = ptoa(seg->avail_start);
+ seg->avail_start += npg;
+ seg->start += npg;
+ } else {
+ pa = ptoa(seg->avail_end) - size;
+ seg->avail_end -= npg;
+ seg->end -= npg;
+ }
+ /*
+ * If all the segment has been consumed now, remove it.
+ * Note that the crash dump code still knows about it
+ * and will dump it correctly.
+ */
+ if (seg->start == seg->end) {
+ if (vm_nphysseg-- == 1)
+ panic("pmap_steal_memory: out of memory");
+ while (segno < vm_nphysseg) {
+ seg[0] = seg[1]; /* struct copy */
+ seg++;
+ segno++;
+ }
+ }
+
+ va = (vaddr_t)pa; /* 1:1 mapping */
+ bzero((void *)va, size);
+ }
+
+ if (start != NULL)
+ *start = VM_MIN_KERNEL_ADDRESS;
+ if (end != NULL)
+ *end = VM_MAX_KERNEL_ADDRESS;
+
+ return (va);
+}
+
void *msgbuf_addr;
/*
@@ -1610,6 +1676,10 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend)
pmap_attrib = pmap_steal_avail(sizeof(char) * npgs, 1);
pmap_avail_fixup();
for (mp = pmap_avail; mp->size; mp++) {
+ if (mp->start > 0x80000000)
+ continue;
+ if (mp->start + mp->size > 0x80000000)
+ mp->size = 0x80000000 - mp->start;
uvm_page_physload(atop(mp->start), atop(mp->start+mp->size),
atop(mp->start), atop(mp->start+mp->size),
VM_FREELIST_DEFAULT);
@@ -2089,16 +2159,6 @@ pmap_real_memory(paddr_t *start, vsize_t *size)
*size = 0;
}
-/*
- * How much virtual space is available to the kernel?
- */
-void
-pmap_virtual_space(vaddr_t *start, vaddr_t *end)
-{
- *start = VM_MIN_KERNEL_ADDRESS;
- *end = VM_MAX_KERNEL_ADDRESS;
-}
-
void
pmap_init()
{