Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc Add support for large kernels by searching fo...
details: https://anonhg.NetBSD.org/src/rev/bf9f9c9b7511
branches: trunk
changeset: 543634:bf9f9c9b7511
user: pk <pk%NetBSD.org@localhost>
date: Sat Mar 01 13:01:55 2003 +0000
description:
Add support for large kernels by searching for a physical memory segment
to fit it in. As a bonus, the kernel is now also mapped to the virtual
address (i.e. KERNBASE) it is linked at.
diffstat:
sys/arch/sparc/include/loadfile_machdep.h | 4 +-
sys/arch/sparc/sparc/promlib.c | 37 ++++++-
sys/arch/sparc/stand/Makefile.buildboot | 4 +-
sys/arch/sparc/stand/boot/Makefile | 4 +-
sys/arch/sparc/stand/boot/boot.c | 127 ++++++++++++++++----
sys/arch/sparc/stand/boot/version | 3 +-
sys/arch/sparc/stand/common/mmu.c | 180 ++++++++++++++++++++++++++++++
sys/arch/sparc/stand/common/promdev.h | 7 +-
8 files changed, 330 insertions(+), 36 deletions(-)
diffs (truncated from 508 to 300 lines):
diff -r ba96ad411b4e -r bf9f9c9b7511 sys/arch/sparc/include/loadfile_machdep.h
--- a/sys/arch/sparc/include/loadfile_machdep.h Sat Mar 01 12:59:54 2003 +0000
+++ b/sys/arch/sparc/include/loadfile_machdep.h Sat Mar 01 13:01:55 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: loadfile_machdep.h,v 1.7 2002/12/08 14:36:55 uwe Exp $ */
+/* $NetBSD: loadfile_machdep.h,v 1.8 2003/03/01 13:01:55 pk Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
#define COUNT_KERNEL COUNT_ALL
#ifdef _STANDALONE
-#define LOADADDR(a) (((u_long)(a) & 0x07ffffff) + (u_long)offset)
+#define LOADADDR(a) (a)
#define ALIGNENTRY(a) ((u_long)(a))
#define READ(f, b, c) read((f), (void *)LOADADDR(b), (c))
#define BCOPY(s, d, c) memcpy((void *)LOADADDR(d), (void *)(s), (c))
diff -r ba96ad411b4e -r bf9f9c9b7511 sys/arch/sparc/sparc/promlib.c
--- a/sys/arch/sparc/sparc/promlib.c Sat Mar 01 12:59:54 2003 +0000
+++ b/sys/arch/sparc/sparc/promlib.c Sat Mar 01 13:01:55 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: promlib.c,v 1.16 2003/02/26 17:39:07 pk Exp $ */
+/* $NetBSD: promlib.c,v 1.17 2003/03/01 13:01:56 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -1168,6 +1168,10 @@
void
prom_init()
{
+#ifdef _STANDALONE
+ int node;
+ char *cp;
+#endif
if (CPU_ISSUN4) {
prom_init_oldmon();
@@ -1179,4 +1183,35 @@
*/
prom_init_opf();
}
+
+#ifdef _STANDALONE
+ /*
+ * Find out what type of machine we're running on.
+ *
+ * This process is actually started in srt0.S, which has discovered
+ * the minimal set of machine specific parameters for the 1st-level
+ * boot program (bootxx) to run. The page size has already been set
+ * and the CPU type is either CPU_SUN4 or CPU_SUN4C.
+ */
+
+ if (cputyp == CPU_SUN4)
+ return;
+
+ /*
+ * We have SUN4C, SUN4M or SUN4D.
+ * Use the PROM `compatible' property to determine which.
+ * Absence of the `compatible' property means `sun4c'.
+ */
+
+ node = prom_findroot();
+ cp = PROM_getpropstring(node, "compatible");
+ if (*cp == '\0' || strcmp(cp, "sun4c") == 0)
+ cputyp = CPU_SUN4C;
+ else if (strcmp(cp, "sun4m") == 0)
+ cputyp = CPU_SUN4M;
+ else if (strcmp(cp, "sun4d") == 0)
+ cputyp = CPU_SUN4D;
+ else
+ printf("Unknown CPU type (compatible=`%s')\n", cp);
+#endif /* _STANDALONE */
}
diff -r ba96ad411b4e -r bf9f9c9b7511 sys/arch/sparc/stand/Makefile.buildboot
--- a/sys/arch/sparc/stand/Makefile.buildboot Sat Mar 01 12:59:54 2003 +0000
+++ b/sys/arch/sparc/stand/Makefile.buildboot Sat Mar 01 13:01:55 2003 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.buildboot,v 1.18 2002/07/20 11:43:43 mrg Exp $
+# $NetBSD: Makefile.buildboot,v 1.19 2003/03/01 13:01:56 pk Exp $
#
# This file is for the sparc `boot' and `bootxx' only; it does not
# currently play well on a 64-bit system.
@@ -31,7 +31,7 @@
# flushing issues on Hypersparcs
RELOC_BOOTXX= 300000
-CPPFLAGS+= -D_STANDALONE -DSUN4 -DSUN4C -DHEAP_VARIABLE
+CPPFLAGS+= -D_STANDALONE -DSUN4 -DSUN4C -DSUN4M -DSUN4D -DHEAP_VARIABLE
CPPFLAGS+= -I. -I${.CURDIR}/../../.. -I${.CURDIR}/../../../..
CFLAGS= -O2
diff -r ba96ad411b4e -r bf9f9c9b7511 sys/arch/sparc/stand/boot/Makefile
--- a/sys/arch/sparc/stand/boot/Makefile Sat Mar 01 12:59:54 2003 +0000
+++ b/sys/arch/sparc/stand/boot/Makefile Sat Mar 01 13:01:55 2003 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.27 2001/12/04 18:54:34 thorpej Exp $
+# $NetBSD: Makefile,v 1.28 2003/03/01 13:01:56 pk Exp $
STRIPFLAG=
PROGSOURCE= boot.c net.c netif_sun.c conf.c openfirm.c bootinfo.c \
- prompatch.c vers.c
+ mmu.c prompatch.c vers.c
NEWVERSWHAT= "Secondary Boot"
FILES= boot.net ${RELOCS:S/^/boot./g}
CLEANFILES:= vers.c ${FILES}
diff -r ba96ad411b4e -r bf9f9c9b7511 sys/arch/sparc/stand/boot/boot.c
--- a/sys/arch/sparc/stand/boot/boot.c Sat Mar 01 12:59:54 2003 +0000
+++ b/sys/arch/sparc/stand/boot/boot.c Sat Mar 01 13:01:55 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: boot.c,v 1.14 2003/02/25 08:09:30 pk Exp $ */
+/* $NetBSD: boot.c,v 1.15 2003/03/01 13:01:56 pk Exp $ */
/*-
* Copyright (c) 1982, 1986, 1990, 1993
@@ -57,7 +57,10 @@
int netif_debug;
char fbuf[80], dbuf[128];
-u_long maxkernsize;
+paddr_t bstart, bend; /* physical start & end address of the boot program */
+
+int compatmode = 0; /* For loading older kernels */
+u_long loadaddrmask = -1UL;
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
@@ -104,10 +107,69 @@
return (v);
}
+static paddr_t getphysmem(u_long size)
+{
+ struct memarr *pmemarr; /* physical memory regions */
+ int npmemarr; /* number of entries in pmemarr */
+ struct memarr *mp;
+ int i;
+ extern char start[]; /* top of stack (see srt0.S) */
+
+ /*
+ * Find the physical memory area that's in use by the boot loader.
+ * Our stack grows down from label `start'; assume we need no more
+ * than 16K of stack space.
+ * The top of the boot loader is the next 4MB boundary.
+ */
+ if (pmap_extract((vaddr_t)start - (16*1024), &bstart) != 0)
+ return ((paddr_t)-1);
+
+ bend = roundup(bstart, 0x400000);
+
+ /*
+ * Get available physical memory from the prom.
+ */
+ npmemarr = prom_makememarr(NULL, 0, MEMARR_AVAILPHYS);
+ pmemarr = alloc(npmemarr*sizeof(struct memarr));
+ if (pmemarr == NULL)
+ return ((paddr_t)-1);
+ npmemarr = prom_makememarr(pmemarr, npmemarr, MEMARR_AVAILPHYS);
+
+ /*
+ * Find a suitable loading address.
+ */
+ for (mp = pmemarr, i = npmemarr; --i >= 0; mp++) {
+ paddr_t pa = (paddr_t)pmemarr[i].addr;
+ u_long len = (u_long)pmemarr[i].len;
+
+ /* Check whether it will fit in front of us */
+ if (pa < bstart && len >= size && (bstart - pa) >= size)
+ return (pa);
+
+ /* Skip the boot program memory */
+ if (pa < bend) {
+ if (len < bend - pa)
+ /* Not large enough */
+ continue;
+
+ /* Shrink this segment */
+ len -= bend - pa;
+ pa = bend;
+ }
+
+ /* Does it fit in the remainder of this segment? */
+ if (len >= size)
+ return (pa);
+ }
+ return ((paddr_t)-1);
+}
+
static int
loadk(char *kernel, u_long *marks)
{
int fd, error;
+ vaddr_t va;
+ paddr_t pa;
u_long size;
if ((fd = open(kernel, 0)) < 0)
@@ -118,15 +180,36 @@
goto out;
size = marks[MARK_END] - marks[MARK_START];
- if (size > maxkernsize) {
- printf("kernel too large: %lu"
- " (maximum kernel size is %lu)\n",
- marks[MARK_END] - marks[MARK_START],
- maxkernsize);
+
+ /* We want that leading 4K in front of the kernel image */
+ size += PROM_LOADADDR;
+ va = marks[MARK_START] - PROM_LOADADDR;
+
+ /* Extra space for bootinfo and kernel bootstrap */
+ size += 512 * 1024;
+
+ /* Get a physical load address */
+ pa = getphysmem(size);
+ if (pa == (paddr_t)-1) {
error = EFBIG;
goto out;
}
+ if (boothowto & AB_VERBOSE)
+ printf("Loading at physical address %lx\n", pa);
+ if (pmap_map(va, pa, size) != 0) {
+ error = EFAULT;
+ goto out;
+ }
+
+ /* XXX - to do: inspect kernel image and set compat mode */
+ if (compatmode) {
+ /* Double-map at VA 0 for compatibility; ignore errors */
+ if (pa + size < bstart)
+ (void)pmap_map(0, pa, size);
+ loadaddrmask = 0x07ffffffUL;
+ }
+
marks[MARK_START] = 0;
error = fdloadfile(fd, marks, LOAD_KERNEL);
out:
@@ -149,17 +232,8 @@
setheap((void *)ALIGN(end), (void *)0xffffffff);
}
#endif
- {
- /*
- * Find maximum the kernel size that we can handle.
- * Our stack grows down from label `start'; assume
- * we need no more that 16K of stack space.
- */
- extern char start[]; /* top of stack (see srt0.S) */
- maxkernsize = (u_long)start - (16*1024) - PROM_LOADADDR;
-
- }
prom_init();
+ mmu_init();
printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
@@ -228,21 +302,20 @@
}
}
- marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(int) - 1)) &
- (-sizeof(int));
+ marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(u_long) - 1)) &
+ (-sizeof(u_long));
arg = (prom_version() == PROM_OLDMON) ? (caddr_t)PROM_LOADADDR : romp;
- /* Should work with both a.out and ELF, but somehow ELF is busted */
- bootinfo = bi_init(marks[MARK_END]);
+ /* Setup boot info structure at the end of the kernel image */
+ bootinfo = bi_init(marks[MARK_END] & loadaddrmask);
- bi_sym.nsym = marks[MARK_NSYM];
- bi_sym.ssym = marks[MARK_SYM];
- bi_sym.esym = marks[MARK_END];
+ /* Add kernel symbols to bootinfo */
+ bi_sym.nsym = marks[MARK_NSYM] & loadaddrmask;
+ bi_sym.ssym = marks[MARK_SYM] & loadaddrmask;
+ bi_sym.esym = marks[MARK_END] & loadaddrmask;
bi_add(&bi_sym, BTINFO_SYMTAB, sizeof(bi_sym));
- /*
- * Add kernel path to bootinfo
- */
+ /* Add kernel path to bootinfo */
i = sizeof(struct btinfo_common) + strlen(kernel) + 1;
/* Impose limit (somewhat arbitrary) */
if (i < BOOTINFO_SIZE / 2) {
diff -r ba96ad411b4e -r bf9f9c9b7511 sys/arch/sparc/stand/boot/version
--- a/sys/arch/sparc/stand/boot/version Sat Mar 01 12:59:54 2003 +0000
+++ b/sys/arch/sparc/stand/boot/version Sat Mar 01 13:01:55 2003 +0000
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.16 2002/12/16 13:02:58 jdc Exp $
+$NetBSD: version,v 1.17 2003/03/01 13:01:56 pk Exp $
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important - make sure the entries are appended on end, last item
@@ -16,3 +16,4 @@
1.11: loadfile() update to avoid backwards seeks for ELF Program Headers.
Home |
Main Index |
Thread Index |
Old Index