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));

Reply via email to