Module Name: src
Committed By: martin
Date: Thu Jan 3 09:40:56 UTC 2013
Modified Files:
src/sys/arch/sparc64/include: param.h vmparam.h
src/sys/arch/sparc64/sparc64: pmap.c
Log Message:
Rearange VA layout for 64 bit kernels, as suggested by Lars Heidieker:
move the dynamic kernel memory past 4GB (basically unlimiting it) and
use the now freed address range past kernel data upto 2GB for modules.
To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/arch/sparc64/include/param.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/sparc64/include/vmparam.h
cvs rdiff -u -r1.278 -r1.279 src/sys/arch/sparc64/sparc64/pmap.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/arch/sparc64/include/param.h
diff -u src/sys/arch/sparc64/include/param.h:1.50 src/sys/arch/sparc64/include/param.h:1.51
--- src/sys/arch/sparc64/include/param.h:1.50 Sat Mar 10 07:54:17 2012
+++ src/sys/arch/sparc64/include/param.h Thu Jan 3 09:40:55 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.50 2012/03/10 07:54:17 nakayama Exp $ */
+/* $NetBSD: param.h,v 1.51 2013/01/03 09:40:55 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -123,7 +123,7 @@ extern int nbpg, pgofset, pgshift;
* 0x00000000f0100000. It also uses some space around 0x00000000fff00000 to
* map in device registers. The rest is pretty much ours to play with.
*
- * The kernel starts at KERNBASE. Here's they layout. We use macros to set
+ * The kernel starts at KERNBASE. Here's the layout. We use macros to set
* the addresses so we can relocate everything easily. We use 4MB locked TTEs
* to map in the kernel text and data segments. Any extra pages are recycled,
* so they can potentially be double-mapped. This shouldn't really be a
@@ -132,8 +132,8 @@ extern int nbpg, pgofset, pgshift;
*
* 0x0000000000000000: 64K NFO page zero
* 0x0000000000010000: Userland or PROM
- * KERNBASE: 4MB kernel text and read only data
- * This is mapped in the ITLB and
+ * KERNBASE: 4MB (or multiple thereof) kernel text and read only
+ * data. This is mapped in the ITLB and
* Read-Only in the DTLB
* KERNBASE+0x400000: 4MB kernel data and BSS -- not in ITLB
* Contains context table, kernel pmap,
@@ -141,8 +141,11 @@ extern int nbpg, pgofset, pgshift;
* KERNBASE+0x800000: Unmapped page -- redzone
* KERNBASE+0x802000: Process 0 stack and u-area
* KERNBASE+0x806000: 2 pages for pmap_copy_page and /dev/mem
- * KERNBASE+0x80a000: Start of kernel VA segment
- * KERNEND: End of kernel VA segment
+ *
+ * For 32 bit kernels:
+ * KERNBASE+0x80a000: Start of kernel VA segment
+ * KERNEND: End of kernel VA segment
+ *
* KERNEND+0x02000: Auxreg_va (unused?)
* KERNEND+0x04000: TMPMAP_VA (unused?)
* KERNEND+0x06000: message buffer.
@@ -154,6 +157,10 @@ extern int nbpg, pgofset, pgshift;
* KERNEND+0x022000: IODEV_BASE -- begin mapping IO devices here.
* 0x00000000f0000000: IODEV_END -- end of device mapping space.
*
+ * For 64 bit kernels:
+ * 0x100000000: Start of kernel VA segment (theoretically upto
+ * the VA hole)
+ *
*/
#define KERNBASE 0x001000000 /* start of kernel virtual space */
#define KERNEND 0x0e0000000 /* end of kernel virtual space */
@@ -195,12 +202,20 @@ extern int nbpg, pgofset, pgshift;
/*
* Minimum size of the kernel kmem_arena in PAGE_SIZE-sized
* logical pages.
+ * For 32bit kernels:
* Maximum of 2.5GB on sparc64 (it must fit into KERNEND - KERNBASE, and also
* leave space in the kernel_map for other allocations).
+ * For 64bit kernels:
+ * Unlimited. (Practically there is a limit, we use VA starting at 4GB upto
+ * the VA-hole, but let us call this unlimited for now.)
*/
#define NKMEMPAGES_MIN_DEFAULT ((64 * 1024 * 1024) >> PAGE_SHIFT)
+#ifdef __arch64__
+#define NKMEMPAGES_MAX_UNLIMITED
+#else
#undef NKMEMPAGES_MAX_UNLIMITED
#define NKMEMPAGES_MAX_DEFAULT ((2048UL * 1024 * 1024) >> PAGE_SHIFT)
+#endif
#ifdef _KERNEL
#ifndef _LOCORE
Index: src/sys/arch/sparc64/include/vmparam.h
diff -u src/sys/arch/sparc64/include/vmparam.h:1.32 src/sys/arch/sparc64/include/vmparam.h:1.33
--- src/sys/arch/sparc64/include/vmparam.h:1.32 Sun Nov 14 13:33:23 2010
+++ src/sys/arch/sparc64/include/vmparam.h Thu Jan 3 09:40:55 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.32 2010/11/14 13:33:23 uebayasi Exp $ */
+/* $NetBSD: vmparam.h,v 1.33 2013/01/03 09:40:55 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -161,7 +161,12 @@
#define VM_MAXUSER_ADDRESS32 ((vaddr_t)(0x00000000ffffffffL&~PGOFSET))
#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)KERNBASE)
+#ifdef __arch64__
+#define VM_KERNEL_MEM_VA_START ((vaddr_t)0x100000000UL)
+#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)0x000007ffffffffffUL)
+#else
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)KERNEND)
+#endif
#define VM_PHYSSEG_MAX 32 /* up to 32 segments */
#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
Index: src/sys/arch/sparc64/sparc64/pmap.c
diff -u src/sys/arch/sparc64/sparc64/pmap.c:1.278 src/sys/arch/sparc64/sparc64/pmap.c:1.279
--- src/sys/arch/sparc64/sparc64/pmap.c:1.278 Sun Mar 25 02:31:00 2012
+++ src/sys/arch/sparc64/sparc64/pmap.c Thu Jan 3 09:40:55 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.278 2012/03/25 02:31:00 mrg Exp $ */
+/* $NetBSD: pmap.c,v 1.279 2013/01/03 09:40:55 martin Exp $ */
/*
*
* Copyright (C) 1996-1999 Eduardo Horvath.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.278 2012/03/25 02:31:00 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.279 2013/01/03 09:40:55 martin Exp $");
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
#define HWREF
@@ -1175,15 +1175,24 @@ pmap_bootstrap(u_long kernelstart, u_lon
#ifdef MODULAR
/*
- * Reserve 16 MB of VA for module loading. Right now our full
- * GENERIC kernel is about 13 MB, so this looks good enough.
- * If we make this bigger, we should adjust the KERNEND and
- * associated defines in param.h.
- */
+ * For 32bit kernels:
+ * Reserve 16 MB of VA for module loading. Right now our full
+ * GENERIC kernel is about 13 MB, so this looks good enough.
+ * For 64bit kernels:
+ * We can use all the space left before the special addresses,
+ * but leave 2 pages at vmmap alone (see pmap_virtual_space)
+ * and another red zone page.
+ */
+#ifdef __arch64__
+ module_start = vmmap + 3*PAGE_SIZE;
+ module_end = 0x08000000; /* keep all modules within 2GB */
+ KASSERT(module_end < KERNEND); /* of kernel text */
+#else
module_start = vmmap;
vmmap += 16 * 1024*1024;
module_end = vmmap;
#endif
+#endif
/*
* Set up bounds of allocatable memory for vmstat et al.
@@ -1325,11 +1334,23 @@ pmap_virtual_space(vaddr_t *start, vaddr
{
/*
- * Reserve one segment for kernel virtual memory
+ * Reserve one segment for kernel virtual memory.
+ */
+#ifdef __arch64__
+ /*
+ * On 64 bit kernels, start it beyound firmware, so
+ * we are basically unrestricted.
+ */
+ *start = kbreak = VM_KERNEL_MEM_VA_START;
+ *end = VM_MAX_KERNEL_ADDRESS;
+#else
+ /*
+ * Reserve two pages for pmap_copy_page && /dev/mem, but otherwise
+ * end it beyound the iospace and other special fixed addresses.
*/
- /* Reserve two pages for pmap_copy_page && /dev/mem */
*start = kbreak = (vaddr_t)(vmmap + 2*PAGE_SIZE);
*end = VM_MAX_KERNEL_ADDRESS;
+#endif
BDPRINTF(PDB_BOOT1, ("pmap_virtual_space: %x-%x\n", *start, *end));
}
@@ -1349,9 +1370,9 @@ pmap_growkernel(vaddr_t maxkvaddr)
struct pmap *pm = pmap_kernel();
paddr_t pa;
- if (maxkvaddr >= KERNEND) {
+ if (maxkvaddr >= VM_MAX_KERNEL_ADDRESS) {
printf("WARNING: cannot extend kernel pmap beyond %p to %p\n",
- (void *)KERNEND, (void *)maxkvaddr);
+ (void *)VM_MAX_KERNEL_ADDRESS, (void *)maxkvaddr);
return (kbreak);
}
DPRINTF(PDB_GROW, ("pmap_growkernel(%lx...%lx)\n", kbreak, maxkvaddr));