diff options
Diffstat (limited to 'usr/src/psm/stand/boot/sparc')
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/boot.c | 108 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/boot_plat.c | 92 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/boot_plat.h | 19 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/boot_services.c | 713 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/bootflags.c | 57 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/bootops.c | 55 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/hsfsconf.c | 50 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/inetboot.c | 181 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/ramdisk.c | 861 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/ramdisk.h | 13 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c | 27 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/ufsconf.c | 57 | ||||
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/wanboot.c | 188 |
13 files changed, 665 insertions, 1756 deletions
diff --git a/usr/src/psm/stand/boot/sparc/common/boot.c b/usr/src/psm/stand/boot/sparc/common/boot.c deleted file mode 100644 index acfbad580b..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/boot.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/salib.h> -#include <sys/stat.h> -#include <sys/promif.h> -#include <sys/bootvfs.h> -#include <sys/boot_redirect.h> -#include "boot_plat.h" - -/* - * This implementation of bootprog() is used by all bootloaders except wanboot. - */ - -#define SUCCESS 0 -#define FAILURE -1 - -/* - * bpath is the boot device path buffer. - * bargs is the boot arguments buffer. - */ -/*ARGSUSED*/ -int -bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) -{ - boolean_t once = B_FALSE; - - systype = set_fstype(v2path, bpath); - -loop: - /* - * Beware: the following code may be executed twice, with different - * bpath's if we discover a redirection file. - */ - - if (verbosemode) { - printf("device path '%s'\n", bpath); - if (strcmp(bpath, v2path) != 0) - printf("client path '%s'\n", v2path); - } - - if (mountroot(bpath) != SUCCESS) - prom_panic("Could not mount filesystem."); - - /* - * kernname (default-name) might have changed if mountroot() called - * boot_nfs_mountroot(), and it called set_default_filename(). - */ - if (!user_specified_filename) - (void) strcpy(filename, kernname); - - if (verbosemode) - printf("standalone = `%s', args = `%s'\n", filename, bargs); - - set_client_bootargs(filename, bargs); - - if (!once && - (strcmp(systype, "ufs") == 0 || strcmp(systype, "hsfs") == 0)) { - char redirect[OBP_MAXPATHLEN]; - - post_mountroot(filename, redirect); - - /* - * If we return at all, it's because we discovered - * a redirection file - the 'redirect' string now contains - * the name of the disk slice we should be looking at. - * - * Unmount the filesystem, tweak the boot path and retry - * the whole operation one more time. - */ - closeall(1); - once = B_TRUE; - redirect_boot_path(bpath, redirect); - if (verbosemode) - printf("%sboot: using '%s'\n", systype, bpath); - - goto loop; - /*NOTREACHED*/ - } - - return (0); -} diff --git a/usr/src/psm/stand/boot/sparc/common/boot_plat.c b/usr/src/psm/stand/boot/sparc/common/boot_plat.c index ff1f0fe23b..9a9423cf1b 100644 --- a/usr/src/psm/stand/boot/sparc/common/boot_plat.c +++ b/usr/src/psm/stand/boot/sparc/common/boot_plat.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -81,7 +80,6 @@ int client_isLP64 = 1; /* SPARC clients are always LP64 */ * filename is the name of the standalone we're going to execute. */ char filename[MAXPATHLEN]; -char *cmd_line_default_path; char * const defname = "kernel/sparcv9/unix"; @@ -236,24 +234,6 @@ boot_open(char *pathname, void *arg) return (open(pathname, O_RDONLY)); } -static int -boot_isdir(char *pathname) -{ - int fd, retval; - struct stat sbuf; - - dprintf("trying '%s'\n", pathname); - if ((fd = open(pathname, O_RDONLY)) == -1) - return (0); - retval = 1; - if (fstat(fd, &sbuf) == -1) - retval = 0; - else if ((sbuf.st_mode & S_IFMT) != S_IFDIR) - retval = 0; - (void) close(fd); - return (retval); -} - /* * Open the given filename, expanding to it's * platform-dependent location if necessary. @@ -266,8 +246,6 @@ int openfile(char *filename) { static char *fullpath; - static char *iarch; - static char *orig_impl_arch_name; static int once; int fd; @@ -282,78 +260,16 @@ openfile(char *filename) if (mfg_name == NULL) mfg_name = get_mfg_name(); - /* - * If impl_arch_name was specified on the command line - * via the -I <arch> argument, remember the original value. - */ - if (impl_arch_name) { - orig_impl_arch_name = (char *) - kmem_alloc(strlen(impl_arch_name) + 1, 0); - (void) strcpy(orig_impl_arch_name, impl_arch_name); - } - fullpath = (char *)kmem_alloc(MAXPATHLEN, 0); - iarch = (char *)kmem_alloc(MAXPATHLEN, 0); } - /* - * impl_arch_name is exported as boot property, and is - * set according to the following algorithm, depending - * on the contents of the filesystem. - * XXX: This shouldn't be a side effect of openfile(). - * - * impl_arch_name table: - * - * root name default name neither name - * boot args found found found - * - * relative path root name fail fail - * absolute path root name default name empty - * -I arch arch arch arch - * - */ - - /* - * If the caller -specifies- an absolute pathname, then we just try to - * open it. (Mostly for booting non-kernel standalones.) - * - * In case this absolute pathname is the kernel, make sure that - * impl_arch_name (exported as a boot property) is set to some - * valid string value. - */ if (*filename == '/') { - if (orig_impl_arch_name == NULL) { - if (find_platform_dir(boot_isdir, iarch, 1) != 0) - impl_arch_name = iarch; - else - impl_arch_name = ""; - } (void) strcpy(fullpath, filename); fd = boot_open(fullpath, NULL); return (fd); } - /* - * If the -I flag has been used, impl_arch_name will - * be specified .. otherwise we ask find_platform_dir() to - * look for the existance of a directory for this platform name. - * Preserve the given impl-arch-name, because the 'kernel file' - * may be elsewhere. (impl-arch-name could be 'SUNW,Ultra-1', - * but the kernel file itself might be in the 'sun4u' directory). - * - * When booting any file by relative pathname this code fails - * if the platform-name dir doesn't exist unless some - * -I <iarch> argument has been given on the command line. - */ - if (orig_impl_arch_name == NULL) { - if (find_platform_dir(boot_isdir, iarch, 0) != 0) - impl_arch_name = iarch; - else - return (-1); - } - - fd = open_platform_file(filename, boot_open, NULL, fullpath, - orig_impl_arch_name); + fd = open_platform_file(filename, boot_open, NULL, fullpath); if (fd == -1) return (-1); diff --git a/usr/src/psm/stand/boot/sparc/common/boot_plat.h b/usr/src/psm/stand/boot/sparc/common/boot_plat.h index 99066f70bb..e6dffbedc4 100644 --- a/usr/src/psm/stand/boot/sparc/common/boot_plat.h +++ b/usr/src/psm/stand/boot/sparc/common/boot_plat.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,7 +35,6 @@ extern "C" { /* boot_plat.c */ -extern char *cmd_line_default_path; extern int verbosemode; extern char filename[]; extern char *const defname; @@ -52,21 +50,11 @@ extern void set_client_bootargs(const char *, const char *); extern boolean_t is_netdev(char *devpath); -/* boot_1275entry.c */ -extern int boot1275_entry_asm(void *); -extern void boot_fail_gracefully_asm(void); - - -/* boot_services.c */ -extern int boot1275_entry(void *); - - /* bootops.c */ extern struct bootops bootops; extern void setup_bootops(void); extern void update_memlist(char *, char *, struct memlist **); -extern void boot_fail_gracefully(void); /* @@ -81,7 +69,6 @@ extern char *mfg_name; extern char *impl_arch_name; extern char *bootp_response; extern char *boot_message; -extern char *cmd_line_default_path; extern int cache_state; extern uint64_t memlistextent; extern char *netdev_path; diff --git a/usr/src/psm/stand/boot/sparc/common/boot_services.c b/usr/src/psm/stand/boot/sparc/common/boot_services.c deleted file mode 100644 index 16a7acaebe..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/boot_services.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Definitions of interfaces that provide services from the secondary - * boot program to its clients (primarily unix, krtld and their successors.) - * This interface replaces the bootops (BOP) implementation as the interface - * to be called by boot clients. The BOP macros are still used to make the - * integration easier. - * - * The bootops vector is vestigial. - * - * The kern_* routines used to implement many of the services here - * are in the usr/src/stand/lib/ modules. - * - */ - -#include <sys/types.h> -#include <sys/bootconf.h> -#include <sys/reboot.h> -#include <sys/param.h> -#include <sys/varargs.h> -#include <sys/obpdefs.h> -#include <sys/promif.h> -#include <sys/salib.h> -#include <sys/stat.h> -#include <sys/bootvfs.h> - -extern void kern_killboot(void); -extern int bgetprop(struct bootops *, char *name, void *buf); -extern int bgetproplen(struct bootops *, char *name); -extern char *bnextprop(struct bootops *, char *prev); -extern caddr_t resalloc_virt(caddr_t virt, size_t size); - -static int boot1275_serviceavail(void *p); - -static struct boot_nm2svc *nm2svcp(char *name); - -/* - * Implementation of the "version" service. - * Return the compiled version number of this implementation of boot. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] Res0: returned version number - */ -static int boot_version = BO_VERSION; -static int -boot1275_getversion(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - args[3] = boot_int2cell(boot_version); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "open" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] filename string - * args[4] flags - * args[5] Res0: returned result - * - */ -static int -boot1275_open(void *p) -{ - int rc; - int flags; - char *name; - boot_cell_t *args = (boot_cell_t *)p; - - name = boot_cell2ptr(args[3]); - flags = boot_cell2int(args[4]); - rc = kern_open(name, flags); - args[5] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "read" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] boot-opened file descriptor - * args[4] client's buffer - * args[5] size of read request - * args[6] Res0: returned result - * - */ -static int -boot1275_read(void *p) -{ - int rc; - boot_cell_t *args = (boot_cell_t *)p; - - /* XXX use different routine to support larger I/O ? */ - int fd; - caddr_t buf; - size_t size; - - fd = boot_cell2int(args[3]); - buf = boot_cell2ptr(args[4]); - size = boot_cell2size(args[5]); - rc = kern_read(fd, buf, size); - args[6] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "seek" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] boot-opened file descriptor - * args[4] offset hi XXX just use one cell for offset? - * args[5] offset lo - * args[6] Res0: returned result - * - */ -static int -boot1275_seek(void *p) -{ - off_t rc; - int fd; - off_t hi, lo; - boot_cell_t *args = (boot_cell_t *)p; - - fd = boot_cell2int(args[3]); - hi = boot_cell2offt(args[4]); - lo = boot_cell2offt(args[5]); - rc = kern_lseek(fd, hi, lo); - args[6] = boot_offt2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "close" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] boot-opened file descriptor - * args[4] Res0: returned result - * - */ -static int -boot1275_close(void *p) -{ - int rc; - int fd; - boot_cell_t *args = (boot_cell_t *)p; - - fd = boot_cell2int(args[3]); - rc = kern_close(fd); - args[4] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "alloc" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual hint - * args[4] size to allocate - * args[5] alignment - * args[6] Res0: returned result - */ -static int -boot1275_alloc(void *p) -{ - caddr_t virthint, addr; - size_t size; - int align; - boot_cell_t *args = (boot_cell_t *)p; - - virthint = boot_cell2ptr(args[3]); - size = boot_cell2size(args[4]); - align = boot_cell2int(args[5]); - addr = kern_resalloc(virthint, size, align); - args[6] = boot_ptr2cell(addr); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "alloc_virt" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #arguments cells - * args[2] #result cells - * args[3] virtual address - * args[4] size to allocate - * args[5] Res0: returned result - */ -static int -boot1275_alloc_virt(void *p) -{ - caddr_t virt, addr; - size_t size; - boot_cell_t *args = (boot_cell_t *)p; - - virt = boot_cell2ptr(args[3]); - size = boot_cell2size(args[4]); - addr = resalloc_virt(virt, size); - args[5] = boot_ptr2cell(addr); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "free" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual addr - * args[4] size to free - * args[5] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_free(void *p) -{ - caddr_t virtaddr; - size_t size; - boot_cell_t *args = (boot_cell_t *)p; - - virtaddr = boot_cell2ptr(args[3]); - size = boot_cell2size(args[4]); - kern_resfree(virtaddr, size); - args[5] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "map" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual address - * args[4] space of phys addr - * args[5] phys addr - * args[6] size - * args[7] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_map(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - args[6] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "unmap" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual address - * args[4] size of chunk - * args[5] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_unmap(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - args[5] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "quiesce" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_quiesce(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - kern_killboot(); - args[3] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "getproplen" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] property name string - * args[4] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_getproplen(void *p) -{ - int rc; - char *name; - boot_cell_t *args = (boot_cell_t *)p; - - - name = boot_cell2ptr(args[3]); - rc = bgetproplen((struct bootops *)0, name); - args[4] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "getprop" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] property name string - * args[4] buffer pointer to hold value of the property - * args[5] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_getprop(void *p) -{ - int rc; - char *name; - void *buf; - boot_cell_t *args = (boot_cell_t *)p; - - - name = boot_cell2ptr(args[3]); - buf = boot_cell2ptr(args[4]); - rc = bgetprop((struct bootops *)0, name, buf); - args[5] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "putsarg" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] string to print (with '%*' format) - * args[4] 64-bit thing to print - * - * The bootops interface can only pass one additional - * argument. Abusing the format string can cause failures - * in interesting ways that could be hard to debug when - * an argument is pulled off the stack or dereferenced, - * so if the format string indicates more than one argument, - * we note the problem rather print garbage or panic. - */ -/*ARGSUSED*/ -static int -boot1275_putsarg(void *p) -{ - const char *string; - boot_cell_t *args = (boot_cell_t *)p; - const char *fmt; - int ells = 0; - int arg_is_ptr = 0; - int nargs = 0; - uint64_t arg; - - - string = boot_cell2ptr(args[3]); - arg = boot_cell2uint64(args[4]); - - /* - * We need to do the minimum printf-like stuff here to figure - * out the size of argument, if present. - */ - for (fmt = string; *fmt; fmt++) { - if (*fmt != '%') - continue; - if (*(++fmt) == '%') - continue; - - nargs++; - while (*fmt >= '0' && *fmt <= '9') - fmt++; - for (ells = 0; *fmt == 'l'; fmt++) - ells++; - - switch (*fmt) { - case 's': - case 'p': - arg_is_ptr = 1; - break; - } - } - - if (nargs > 1) { - printf("boot1275_putsarg: unsupported format: \"%s\"\n", - string); - } else if (arg_is_ptr) { - printf(string, (void *)arg); - } else { - switch (ells) { - case 0: - printf(string, (uint_t)arg); - break; - case 1: - printf(string, (ulong_t)arg); - break; - default: - printf(string, arg); - break; - } - } - - return (BOOT_SVC_OK); -} -/* - * Implementation of the "puts" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] string to print - */ -/*ARGSUSED*/ -static int -boot1275_puts(void *p) -{ - char *string; - boot_cell_t *args = (boot_cell_t *)p; - - - string = boot_cell2ptr(args[3]); - printf("%s", string); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "nextprop" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] previous property name string - * args[4] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_nextprop(void *p) -{ - char *name, *np; - boot_cell_t *args = (boot_cell_t *)p; - - name = boot_cell2ptr(args[3]); - np = bnextprop((struct bootops *)0, name); - args[4] = boot_ptr2cell(np); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "mount" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] pathname string - * args[4] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_mountroot(void *p) -{ - int rc; - char *name; - boot_cell_t *args = (boot_cell_t *)p; - - name = boot_cell2ptr(args[3]); - rc = kern_mountroot(name); - args[4] = boot_cell2int(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "unmount" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_unmountroot(void *p) -{ - int rc; - boot_cell_t *args = (boot_cell_t *)p; - - rc = kern_unmountroot(); - args[3] = boot_cell2int(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "fstat" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] fd - * args[4] client's stat structure - */ -int -boot1275_fstat(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - int fd = boot_cell2int(args[3]); - struct bootstat *st = boot_cell2ptr(args[4]); - int rc = kern_fstat(fd, st); - - args[5] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "interpret" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells (1) - * args[2] #result cells (0) - * args[3] string to interpret - */ -int -boot1275_interpret(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - char *str = boot_cell2ptr(args[3]); - - prom_interpret(str, 0, 0, 0, 0, 0); - - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "enter_mon" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells (0) - * args[2] #result cells (0) - */ -/*ARGSUSED*/ -int -boot1275_enter_mon(void *p) -{ - prom_enter_mon(); - - return (BOOT_SVC_OK); -} - -/* - * The lookup table akin to the old bootops vec - * for boot. Not part of the exported interface. - */ -static struct boot_nm2svc { - char *b_name; - int (*b_funcptr)(void *); - int b_svcversion; -} boot_nm2svc[] = { - { "version", boot1275_getversion, 1 }, - { "open", boot1275_open, 1 }, - { "read", boot1275_read, 1 }, - { "seek", boot1275_seek, 1 }, - { "close", boot1275_close, 1 }, - { "alloc", boot1275_alloc, 1 }, - { "alloc_virt", boot1275_alloc_virt, 1 }, - { "free", boot1275_free, 1 }, - { "map", boot1275_map, 1 }, - { "unmap", boot1275_unmap, 1 }, - { "quiesce", boot1275_quiesce, 1 }, - { "getproplen", boot1275_getproplen, 1 }, - { "getprop", boot1275_getprop, 1 }, - { "nextprop", boot1275_nextprop, 1 }, - { "mountroot", boot1275_mountroot, 1 }, - { "unmountroot", boot1275_unmountroot, 1 }, - { "serviceavail", boot1275_serviceavail, 1 }, - { "puts", boot1275_puts, 1 }, - { "putsarg", boot1275_putsarg, 1 }, - { "fstat", boot1275_fstat, 1 }, - { "interpret", boot1275_interpret, 1 }, - { "enter_mon", boot1275_enter_mon, 1 }, - { 0, 0, 0 } -}; - -static struct boot_nm2svc * -nm2svcp(char *name) -{ - struct boot_nm2svc *pnm2svc = &boot_nm2svc[0]; - - while (pnm2svc->b_name != 0) { - if (strcmp(pnm2svc->b_name, name)) - pnm2svc++; - else { - return (pnm2svc); - } - } - return (NULL); -} - -/* - * Implementation of the "serviceavail" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] name string of service to be tested for - * args[4] Res0: returned version number or 0 - */ -/*ARGSUSED*/ -static int -boot1275_serviceavail(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - char *name; - struct boot_nm2svc *pnm2svc; - int version = 0; /* 0 means service not avail */ - - name = boot_cell2ptr(args[3]); - pnm2svc = nm2svcp(name); - if (pnm2svc != 0) - version = pnm2svc->b_svcversion; - args[4] = boot_int2cell(version); - return (BOOT_SVC_OK); -} - -int -boot1275_entry(void *p) -{ - int rc = 0; - char *name; - int (*fp)(); - boot_cell_t *args = (boot_cell_t *)p; - struct boot_nm2svc *pnm2svc; - - name = boot_cell2ptr(args[0]); - pnm2svc = nm2svcp(name); - if (pnm2svc != NULL) { - fp = (int(*)())(pnm2svc->b_funcptr); - rc = (*fp)(args); - } else { - prom_printf("call to undefined service \"%s\"\n", name); - } - return (rc); -} diff --git a/usr/src/psm/stand/boot/sparc/common/bootflags.c b/usr/src/psm/stand/boot/sparc/common/bootflags.c index abb4573d24..f401f8ac57 100644 --- a/usr/src/psm/stand/boot/sparc/common/bootflags.c +++ b/usr/src/psm/stand/boot/sparc/common/bootflags.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,24 +37,19 @@ #include <util/getoptstr.h> #include "boot_plat.h" -static char impl_arch_buf[MAXNAMELEN]; static char default_path_buf[MAXPATHLEN]; char wanboot_arguments[OBP_MAXPATHLEN]; /* args following "-o" */ +char cmd_line_boot_archive[MAXPATHLEN]; + +boolean_t halt; + /* * Parse the boot arguments, adding the options found to the existing boothowto * value (if any) or other state. Then rewrite the buffer with arguments for * the standalone. * - * We assume that the buffer contains only the arguments (no preceeding - * filename or whitespace). We start interpreting flags, ignoring those used - * by the boot block (-H, -X, and -F filename) and acting on those intended - * for us (those documented in boot(1M) as well as some undocumented), and - * stop at unknown flags. Finally we reconstitute flags to be passed on to - * the standalone and the remaining arguments, excluding the first "--", to - * the beginning of the buffer, and return an integer representing our flags. - * * NOTE: boothowto may already have bits set when this function is called */ void @@ -67,8 +61,8 @@ bootflags(char *args, size_t argsz) char *np; size_t npres; int c; + char *cmd_line_default_path; - impl_arch_name = NULL; cmd_line_default_path = NULL; params.gos_opts = "HXF:VnI:D:advhko:"; @@ -77,11 +71,24 @@ bootflags(char *args, size_t argsz) while ((c = getoptstr(¶ms)) != -1) { switch (c) { /* - * Bootblock flags: ignore. + * Bootblock flags. */ case 'H': + halt = B_TRUE; + /*FALLTHRU*/ case 'X': + break; + case 'F': + if (params.gos_optarglen >= + sizeof (cmd_line_boot_archive)) { + printf("boot: -F argument too long. " + "Ignoring.\n"); + break; + } + (void) strncpy(cmd_line_boot_archive, + params.gos_optargp, params.gos_optarglen); + cmd_line_boot_archive[params.gos_optarglen] = '\0'; break; /* @@ -95,18 +102,6 @@ bootflags(char *args, size_t argsz) printf("Warning: boot will not enable cache\n"); break; - case 'I': - if (params.gos_optarglen >= sizeof (impl_arch_buf)) { - printf("boot: -I argument too long. " - "Ignoring.\n"); - break; - } - (void) strncpy(impl_arch_buf, params.gos_optargp, - params.gos_optarglen); - impl_arch_buf[params.gos_optarglen] = '\0'; - impl_arch_name = impl_arch_buf; - break; - case 'D': if (params.gos_optarglen >= sizeof (default_path_buf)) { printf("boot: -D argument too long. " @@ -160,8 +155,6 @@ bootflags(char *args, size_t argsz) */ switch (params.gos_last_opt) { case 'F': - /* -F is a bootblock flag, so ignore. */ - break; case 'I': case 'D': case 'o': @@ -271,4 +264,10 @@ done: */ if (cmd_line_default_path) set_default_filename(cmd_line_default_path); + + /* + * See if user wants to examine things + */ + if (halt == B_TRUE) + prom_enter_mon(); } diff --git a/usr/src/psm/stand/boot/sparc/common/bootops.c b/usr/src/psm/stand/boot/sparc/common/bootops.c index 662fcfaedc..10d7b87003 100644 --- a/usr/src/psm/stand/boot/sparc/common/bootops.c +++ b/usr/src/psm/stand/boot/sparc/common/bootops.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,17 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 1996-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" -/* - * Implementation of the vestigial bootops vector for platforms using the - * 1275-like boot interfaces. - */ - #include <sys/types.h> #include <sys/bootconf.h> #include <sys/param.h> @@ -51,38 +45,20 @@ static const int debug = 0; extern void closeall(int); -/* - * This is the number for this version of bootops, which is vestigial. - * Standalones that require the old bootops will look in bootops.bsys_version, - * see this number is higher than they expect and fail gracefully. - * They can make this "peek" successfully even if they are ILP32 programs. - */ -int boot_version = BO_VERSION; - struct bootops bootops; +static void +boot_fail(void) +{ + prom_panic("bootops is gone, it should not be called"); +} + void setup_bootops(void) { - /* sanity-check bsys_printf - old kernels need to fail with a message */ -#if !defined(lint) - if (offsetof(struct bootops, bsys_printf) != 60) { - printf("boot: bsys_printf is at offset 0x%lx instead of 60\n" - "boot: this will likely make old kernels die without " - "printing a message.\n", - offsetof(struct bootops, bsys_printf)); - } - /* sanity-check bsys_1275_call - if it moves, kernels cannot boot */ - if (offsetof(struct bootops, bsys_1275_call) != 24) { - printf("boot: bsys_1275_call is at offset 0x%lx instead of 24\n" - "boot: this will likely break the kernel\n", - offsetof(struct bootops, bsys_1275_call)); - } -#endif - bootops.bsys_version = boot_version; - bootops.bsys_1275_call = (uint64_t)boot1275_entry; - /* so old kernels die with a message */ - bootops.bsys_printf = (uint32_t)boot_fail_gracefully; + bootops.bsys_version = BO_VERSION; + bootops.bsys_1275_call = (uint64_t)boot_fail; + bootops.bsys_printf = (uint32_t)boot_fail; if (!memlistpage) /* paranoia runs rampant */ prom_panic("\nMemlistpage not setup yet."); @@ -204,10 +180,3 @@ kern_killboot(void) prom_enter_mon(); #endif } - -void -boot_fail_gracefully(void) -{ - prom_panic( - "mismatched version of /boot interface: new boot, old kernel"); -} diff --git a/usr/src/psm/stand/boot/sparc/common/hsfsconf.c b/usr/src/psm/stand/boot/sparc/common/hsfsconf.c deleted file mode 100644 index 2f71220391..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/hsfsconf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/param.h> -#include <sys/sysmacros.h> -#include <sys/stat.h> -#include <sys/bootvfs.h> - -/* HSFS Support */ -extern struct boot_fs_ops boot_hsfs_ops; - -struct boot_fs_ops *boot_fsw[] = { - &boot_hsfs_ops, -}; - -int boot_nfsw = sizeof (boot_fsw) / sizeof (boot_fsw[0]); -static char *fstype = "hsfs"; - -/*ARGSUSED*/ -char * -set_fstype(char *v2path, char *bpath) -{ - set_default_fs(fstype); - return (fstype); -} diff --git a/usr/src/psm/stand/boot/sparc/common/inetboot.c b/usr/src/psm/stand/boot/sparc/common/inetboot.c new file mode 100644 index 0000000000..13a61bb30f --- /dev/null +++ b/usr/src/psm/stand/boot/sparc/common/inetboot.c @@ -0,0 +1,181 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/fcntl.h> +#include <sys/obpdefs.h> +#include <sys/reboot.h> +#include <sys/promif.h> +#include <sys/stat.h> +#include <sys/bootvfs.h> +#include <sys/platnames.h> +#include <sys/salib.h> +#include <sys/elf.h> +#include <sys/link.h> +#include <sys/auxv.h> +#include <sys/boot_policy.h> +#include <sys/boot_redirect.h> +#include <sys/bootconf.h> +#include <sys/boot.h> +#include "boot_plat.h" +#include "ramdisk.h" + +#define SUCCESS 0 +#define FAILURE -1 + +#ifdef DEBUG +extern int debug = 0; +#else +static const int debug = 0; +#endif + +#define dprintf if (debug) printf + +char *def_boot_archive = "boot_archive"; +char *def_miniroot = "miniroot"; +extern char cmd_line_boot_archive[]; + +extern int openfile(char *filename); + +static int +read_and_boot_ramdisk(int fd) +{ + struct stat st; + caddr_t virt; + size_t size; + extern ssize_t xread(int, char *, size_t); + + if ((fstat(fd, &st) != 0) || + ((virt = create_ramdisk(RD_ROOTFS, st.st_size, NULL)) == NULL)) + return (-1); + + dprintf("reading boot archive ...\n"); + if ((size = xread(fd, (char *)virt, st.st_size)) != st.st_size) { + (void) printf("Error reading boot archive, bytes read = %ld, " + "filesize = %ld\n", (long)size, (long)st.st_size); + destroy_ramdisk(RD_ROOTFS); + return (-1); + } + + boot_ramdisk(RD_ROOTFS); + /* NOT REACHED */ + return (0); /* to make cc happy */ +} + + +static void +post_mountroot_nfs(void) +{ + int fd; + char *fn; + char tmpname[MAXPATHLEN]; + + for (;;) { + fn = NULL; + if (boothowto & RB_ASKNAME) { + fn = (cmd_line_boot_archive[0] != '\0') ? + cmd_line_boot_archive : def_boot_archive; + printf("Enter filename [%s]: ", fn); + (void) cons_gets(tmpname, sizeof (tmpname)); + if (tmpname[0] != '\0') + fn = tmpname; + } + + if (boothowto & RB_HALT) { + printf("Boot halted.\n"); + prom_enter_mon(); + } + + if (fn != NULL) + fd = openfile(fn); + else if (cmd_line_boot_archive[0] != '\0') { + fn = cmd_line_boot_archive; + fd = openfile(fn); + } else { + fn = def_boot_archive; + if ((fd = openfile(fn)) == FAILURE) { + fn = def_miniroot; + fd = openfile(fn); + } + } + + if (fd == FAILURE) { + if (fn != def_miniroot) + printf("cannot open %s\n", fn); + else + printf("cannot open neither %s nor %s\n", + def_boot_archive, def_miniroot); + } else { + /* + * this function does not return if successful. + */ + (void) read_and_boot_ramdisk(fd); + + printf("boot failed\n"); + (void) close(fd); + } + boothowto |= RB_ASKNAME; + } +} + + +/* + * bpath is the boot device path buffer. + * bargs is the boot arguments buffer. + */ +/*ARGSUSED*/ +int +bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) +{ + systype = set_fstype(v2path, bpath); + + if (verbosemode) { + printf("device path '%s'\n", bpath); + if (strcmp(bpath, v2path) != 0) + printf("client path '%s'\n", v2path); + } + + if (mountroot(bpath) != SUCCESS) + prom_panic("Could not mount filesystem."); + + /* + * kernname (default-name) might have changed if mountroot() called + * boot_nfs_mountroot(), and it called set_default_filename(). + */ + if (!user_specified_filename) + (void) strcpy(filename, kernname); + + if (verbosemode) + printf("standalone = `%s', args = `%s'\n", filename, bargs); + + set_client_bootargs(filename, bargs); + + post_mountroot_nfs(); + + return (1); +} diff --git a/usr/src/psm/stand/boot/sparc/common/ramdisk.c b/usr/src/psm/stand/boot/sparc/common/ramdisk.c index bba9f4b5d2..ee0116f3d0 100644 --- a/usr/src/psm/stand/boot/sparc/common/ramdisk.c +++ b/usr/src/psm/stand/boot/sparc/common/ramdisk.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,534 +33,400 @@ /* EXPORT DELETE END */ #include "ramdisk.h" -/* - * This is a chunk of Forth delivered by the OBP group. When loaded - * into OBP it creates a ramdisk device node whose functionality is - * defined in FWARC 2002/299. - * - * Note the %s in the line following " new-device" - this is where we - * plug the name of the node in. - */ -static const char ramdisk_fth[] = - -"headerless " - -"\" /\" find-package 0= if" -" .\" Can't find /\" abort " -"then push-package " - -"new-device" -" \" %s\" device-name" -" \" block\" encode-string \" device_type\" property" -/* CSTYLED */ +#include <sys/param.h> +#include <sys/fcntl.h> +#include <sys/obpdefs.h> +#include <sys/reboot.h> +#include <sys/promif.h> +#include <sys/stat.h> +#include <sys/bootvfs.h> +#include <sys/platnames.h> +#include <sys/salib.h> +#include <sys/elf.h> +#include <sys/link.h> +#include <sys/auxv.h> +#include <sys/boot_policy.h> +#include <sys/boot_redirect.h> +#include <sys/bootconf.h> +#include <sys/boot.h> +#include "boot_plat.h" + + +static char ramdisk_preamble_fth[] = + +": find-abort ( name$ -- ) " +" .\" Can't find \" type abort " +"; " + +": get-package ( pkg$ -- ph ) " +" 2dup find-package 0= if " +" find-abort " +" then ( pkg$ ph ) " +" nip nip ( ph ) " +"; " + +"\" /openprom/client-services\" get-package constant cif-ph " + +"instance defer cif-open ( dev$ -- ihandle|0 ) " +"instance defer cif-close ( ihandle -- ) " + +": find-cif-method ( adr,len -- acf ) " +" 2dup cif-ph find-method 0= if ( adr,len ) " +" find-abort " +" then ( adr,len acf ) " +" nip nip ( acf ) " +"; " + +"\" open\" find-cif-method to cif-open " +"\" close\" find-cif-method to cif-close " + +"0 value dev-ih " + +"d# 100 buffer: open-cstr " + +": dev-open ( dev$ -- okay? ) " +/* copy to C string for open */ +" 0 over open-cstr + c! " +" open-cstr swap move " +" open-cstr cif-open dup if " +" dup to dev-ih " +" then " +"; " + +": dev-close ( -- ) " +" dev-ih cif-close " +" 0 to dev-ih " +"; " + +": open-abort ( file$ -- ) " +" .\" Can't open \" type abort " +"; " +; + +static char ramdisk_fth[] = + +"\" /\" get-package push-package " + +"new-device " +" \" %s\" device-name " +" " +" \" block\" device-type " " \" SUNW,ramdisk\" encode-string \" compatible\" property" -" hex" - -" headerless" - -" 0 value mmu-ihandle" -" 0 value mem-ihandle" - -" : get-memory-ihandles" /* ( -- ) */ -" \" /chosen\" find-package drop dup \" mmu\" rot" -" get-package-property if" -" .\" Can't find chosen mmu property\" cr abort" -" then" -" decode-int to mmu-ihandle 2drop" -" \" memory\" rot get-package-property if" -" .\" Can't find chosen memory property\" cr abort" -" then" -" decode-int to mem-ihandle 2drop" -" ;" - -" : get-page-size" /* ( -- page-size ) */ -" mmu-ihandle ihandle>phandle \" page-size\" rot get-package-property" -" if h# 2000 else decode-int nip nip then " -" ;" - -" : get-mode" /* ( -- rw-mode ) */ -" here \" translate\" mmu-ihandle $call-method if" -" nip nip" -" else" -" h# 27" -" then" -" ;" - -" : 64>32bit-phys" /* ( 64bit.lo 64bit.hi -- 32bit.lo 32bit.hi ) */ -" drop xlsplit" -" ;" - -" : 32>64bit-phys" /* ( 32bit.lo 32bit.hi -- 64bit.lo 64bit.hi ) */ -" lxjoin 0" -" ;" - -" : phy-claim" /* ( size align -- base.lo base.hi 0 | error ) */ -" \" claim\" mem-ihandle ['] $call-method catch if" -" drop 2drop 2drop -1" -" else" -" 64>32bit-phys 0" -" then" -" ;" - -" : phy-release" /* ( phys.lo phys.hi size -- ) */ -" >r 32>64bit-phys r> \" release\" mem-ihandle $call-method" -" ;" - -" : vir-claim" /* ( [ virt ] size align -- base ) */ -" \" claim\" mmu-ihandle $call-method" -" ;" - -" : vir-release" /* ( virt size -- ) */ -" \" release\" mmu-ihandle $call-method" -" ;" - -" : vir-map" /* ( phys-lo phys-hi virt size mode -- ) */ -" >r >r >r 32>64bit-phys r> r> r>" -" \" map\" mmu-ihandle $call-method" -" ;" - -" : vir-unmap" /* ( virt size -- ) */ -" \" unmap\" mmu-ihandle $call-method" -" ;" -" headers" - -/* \ This structure represents a physical "chunk" of ramdisk memory */ -" struct" -" /l field >res-pa.lo" /* \ lower 32bits of physical address */ -" /l field >res-pa.hi" /* \ upper 32bits of physical address */ -" /l field >res-len.lo" /* \ lower 32bits of chunk size */ -" /l field >res-len.hi" /* \ upper 32bits of chunk size */ -" constant /res-entry" - -" 4 value max-res-entries" /* \ Max # of non-contig phys chunks */ - -" max-res-entries /res-entry *" /* \ size of resource buffer */ -" ( value ) buffer: my-resources" /* \ resource buffer label */ -" 0 value num-res-entries" /* \ current # of chunks allocated */ -" h# 10 constant label-size" /* \ size of disk-label buffer */ -" label-size instance buffer: my-label" /* \ for disk-label argument string */ - -" get-memory-ihandles" /* \ So we can claim/map/free memory */ -" get-page-size value pagesize" /* \ get virt pagesize from vmem node */ -" get-mode value mode" /* \ get mode to map virt memory with */ - -" 0 instance value window-mapped?" /* \ just in case for pa's near 0 */ -" 0 instance value window-pa" /* \ physical base of virtual window */ -" 0 instance value window-base" /* \ virtual window base */ -" h# 10000 constant window-size" /* \ virtual window size */ - -" 0 instance value filepos" /* \ file position marker */ -" -1 value new-disk?" /* \ need to alloc new resources? */ - -" 0 instance value offset-low" /* \ Offset to start of partition */ -" 0 instance value offset-high" /* \ For partition relative seeks */ -" 0 instance value label-package" /* \ ihandle for disk-label package */ - -" external" /* \ Because device_type = block */ - -" 0 value size" /* \ size of disk */ -" 0 value #blocks" /* \ size of disk / decimal 512 */ - -" headerless" - -" : round-up" /* ( n -- n' ) */ -" 1- tuck + swap invert and" -" ;" - -" : init-label-package" /* ( adr len -- okay? ) */ -" 0 to offset-high 0 to offset-low" -" \" disk-label\" $open-package to label-package" -" label-package if" -" 0 0 \" offset\" label-package $call-method" -" to offset-high to offset-low" -" true" -" else" -" .\" Can't open disk label package\" cr false" -" then" -" ;" - -" : res-entry-len" /* ( n -- 64bit-len | 0 ) \ Get length of chunk n */ -" dup num-res-entries > if" -" drop 0" -" else" -" /res-entry * my-resources +" -" dup >res-len.lo l@ swap >res-len.hi l@" -" lxjoin" -" then" -" ;" - -" : res-entry-pa" /* ( n -- 64bit-pa | 0 ) \ Get phys address of chunk n */ -" dup num-res-entries > if" /* ( n ) */ -" drop 0" /* ( 0 ) */ -" else" /* ( n ) */ -" /res-entry * my-resources +" /* ( chunk-adr ) */ -" dup >res-pa.lo l@ swap >res-pa.hi l@" /* ( pa.lo pa.hi ) */ -" lxjoin" /* ( 64bit-pa ) */ -" then" /* ( 64bit-pa ) */ -" ;" - -" : claim-window" /* ( -- ) \ Claim mem for virt window */ -" window-size pagesize vir-claim to window-base" -" ;" - -" : release-window" /* ( -- ) \ Free virt window memory */ -" window-base window-size" -" 2dup vir-unmap" -" vir-release" -" ;" - -" : map-window" /* ( 64bit-pa -- ) \ Map a physical address to the v-window */ -" dup to window-pa" -" xlsplit window-base window-size mode vir-map" -" -1 to window-mapped?" -" ;" - -" : unmap-window" /* ( -- ) \ Unmap the virtual window */ -" window-base window-size vir-unmap" -" 0 to window-mapped?" -" ;" - -" : in-window?" /* ( pa -- in-window? ) */ -" window-mapped? if" -" window-pa dup window-size + 1- between" -" else" -" drop 0" -" then" -" ;" - -" : window-left" /* ( offset -- space-left-in-window ) */ -" window-size mod" -" window-size swap -" -" ;" - -" : release-resources" /* ( -- ) \ release previously claimed phys addrs */ -" num-res-entries 0 2dup = if" /* ( res-entries 0 ) */ -" 2drop exit" /* ( ) */ -" then" /* ( res-entries 0 ) */ -" do" /* ( ) */ -" i res-entry-pa xlsplit" /* ( pa.lo pa.hi ) */ -" i res-entry-len phy-release" /* ( ) */ -" loop" /* ( ) */ -" 0 to num-res-entries" /* ( ) */ -" my-resources max-res-entries /res-entry * erase" /* ( ) */ -" ;" - -" : fill-entry" /* ( pa.lo pa.hi size.lo size.hi -- ) \ fill chunk buf */ -" num-res-entries /res-entry * my-resources +" -" tuck >res-len.hi l!" -" tuck >res-len.lo l!" -" tuck >res-pa.hi l!" -" >res-pa.lo l!" -" num-res-entries 1+ to num-res-entries" -" ;" - -/* \ First attempt to claim the whole ramdisk contiguously. */ -/* \ If that doesn't work, try to claim it in smaller chunks */ - -" : attempt-claim" /* ( size -- error? ) */ -" size 0 begin" /* ( next totcl ) */ -" over pagesize phy-claim if" /* ( next totcl ) */ -" swap 2 / window-size" /* ( totcl next' ) */ -" round-up swap" /* ( next' totcl ) */ -" else" /* ( next totcl pa.lo,hi ) */ -" 2over drop xlsplit" /* ( next totcl pa.lo,hi len.lo,hi ) */ -" fill-entry" /* ( next totcl ) */ -" over +" /* ( next totcl ) */ -" then" /* ( next totcl ) */ -" 2dup size - 0>=" /* ( next totcl next comp? ) */ -" swap size max-res-entries /" /* ( next totcl comp? next smallest ) */ -" - 0< or" /* ( next totcl ) */ -" until" /* ( next totcl ) */ -" nip size - 0< if -1 else 0 then" -" ;" - -" : claim-resources" /* ( -- error? ) */ -" attempt-claim if release-resources -1 else 0 then" -" ;" - -/* \ Given a 0-relative disk offset compute the proper physical address */ -" : offset>pa" /* ( disk-offset -- 64bit-pa error? ) */ -" 0 num-res-entries 0 do" /* ( disk-offset 0 ) */ -" i res-entry-len +" /* ( disk-offset len' ) */ -" 2dup - 0< if" /* ( disk-offset len' ) */ -" - i res-entry-len +" /* ( offset-into-pa ) \ briefly -ve */ -" i res-entry-pa + 0" /* ( pa 0 ) */ -" unloop exit" /* ( pa 0 ) */ -" then" /* ( disk-offset len' ) */ -" loop" /* ( disk-offset len' ) */ -" drop -1" /* ( offset error ) */ -" ;" - -/* \ Map the virtual window to the physical-address corresponding to the */ -/* \ given 0-relative disk offset */ -" : get-window" /* ( offset -- va len error? ) */ -" dup offset>pa if" /* ( offset pa ) */ -" -1" /* ( offset pa -1 ) */ -" else" /* ( offset pa ) */ -" dup in-window? 0= if" /* ( offset pa ) */ -" unmap-window" /* ( offset pa ) */ -" over window-size mod - map-window" /* ( offset ) */ -" else" -" drop" -" then" -" window-base over window-size mod +" /* ( offset va ) */ -" swap window-left 0" /* ( va len 0 ) */ -" then" /* ( va len error? ) */ -" ;" - -" headers" - -/* \ Write len1 bytes from src into va. */ -" : partial-write" /* ( src len0 va len1 -- len' ) */ -" rot min dup >r move r>" -" ;" - -/* \ Read len1 bytes from src into va. */ -" : partial-read" /* ( src len0 va len1 -- len' ) */ -" rot min dup >r >r swap r> move r>" -" ;" - -" defer operation ' partial-write is operation" - -/* \ Write or Read len given the src address. The block-operation word */ -/* \ determines the physical address that corresponds to the current file */ -/* \ position, and maps/unmaps the 64K virtual window */ -" : block-operation" /* ( src len acf -- len' ) */ -" is operation" -" 0 -rot begin" /* ( 0 src len ) */ -" dup 0>" /* ( len' src len more? ) */ -" while" /* ( len' src len ) */ -" 2dup filepos" /* ( len' src len src len filepos ) */ -" get-window if" /* ( len' src len src len va len ) */ -" 2drop 2drop 2drop exit" /* ( len' ) */ -" then" /* ( len src len src len va len ) */ -" operation" /* ( len src len len' ) */ -" dup filepos + to filepos" /* ( len src len len' ) */ -" >r r@ - rot r@ + rot r> + rot" /* ( len' src' len' ) */ -" repeat" /* ( len' src' len' ) */ -" 2drop" /* ( len' ) */ -" ;" - -" : range-bad?" /* ( adr -- range-bad? ) */ -" 0 size between 0=" -" ;" - -" : space-left" /* ( -- space-left ) */ -" size filepos -" -" ;" - -" : hex-number" /* ( adr,len -- true | n false ) */ -" base @ >r hex $number r> base !" -" ;" - -" : parse-size" /* ( $nums -- 64bit-size | 0 ) \ poss ',' seperated ints */ -" ascii , left-parse-string" /* ( $num $num ) */ -" hex-number if 2drop 0 exit then" /* ( $num n ) */ -" over 0= if nip nip exit then" /* ( $num n ) */ -" -rot hex-number if drop 0 exit then" /* ( hi lo ) */ -" swap lxjoin" -" ;" - -" : set-size" /* ( adr len -- error? ) */ -" parse-size dup 0= if" /* ( size ) */ -" drop -1" /* ( -1 ) */ -" else" /* ( size ) */ -" window-size round-up" /* ( size' ) */ -" dup to size" /* ( size' ) */ -" d# 512 / to #blocks" /* ( ) */ -" \" nolabel\" my-label pack" /* \ first open cannot have a label */ -" drop 0" /* ( 0 ) */ -" then" /* ( error? ) */ -" ;" - -" : $=" /* (s adr1 len1 adr2 len2 -- same? ) */ -" rot tuck <> if 3drop false exit then" /* ( adr1 adr2 len1 ) */ -" comp 0=" /* ( same? ) */ -" ;" - -" : is-label?" /* ( adr len -- is-label? ) \ $= "nolabel" or <a-z> */ -" dup 1 = if" /* ( adr len ) */ -" drop c@ ascii a ascii z between" /* ( is-label? ) */ -" else" /* ( adr len ) */ -" \" nolabel\" $=" /* ( is-label? ) */ -" then" /* ( is-label? ) */ -" ;" - -" : set-label" /* ( adr len -- error? ) */ -" my-label label-size erase" -" dup 1+ label-size > if" -" 2drop -1" -" else" -" my-label pack drop 0" -" then" -" ;" - -" : process-args" /* ( arg$ -- error? ) */ -" ascii = left-parse-string" /* ( value$ key$ ) */ -" new-disk? if" /* ( value$ key$ ) */ -" 2dup \" size\" $= if" /* ( value$ key$ ) */ -" 2drop set-size exit" /* ( error? ) */ -" then" /* ( value$ key$ ) */ -" else" /* ( value$ key$ ) */ -" 2dup is-label? if" /* ( value$ key$ ) */ -" 2swap 2drop set-label exit" /* ( error? ) */ -" then" /* ( value$ key$ ) */ -" then" /* ( value$ key$ ) */ -" .\" Inappropriate argument \" type cr 2drop -1" /* ( -1 ) */ -" ;" - -/* \ Publish the physical chunks that make up the ramdisk in the */ -/* \ existing property */ -" : create-existing-prop" /* ( -- ) */ -" 0 0 encode-bytes" /* ( adr 0 ) */ -" num-res-entries 0 do" /* ( adr 0 ) */ -" i /res-entry * my-resources + >r" /* ( adr len ) */ -" r@ >res-pa.hi l@ encode-int encode+" /* ( adr len ) */ -" r@ >res-pa.lo l@ encode-int encode+" /* ( adr len ) */ -" r@ >res-len.hi l@ encode-int encode+" /* ( adr len ) */ -" r> >res-len.lo l@ encode-int encode+" /* ( adr len ) */ -" loop" /* ( adr len ) */ -" \" existing\" property" /* ( ) */ -" ;" - -" external" - -" : read" /* ( adr,len -- len' ) */ -" space-left" /* ( adr len space-left ) */ -" min ['] partial-read" /* ( adr len' read-acf ) */ -" block-operation" /* ( len' ) */ -" ;" - -" : write" /* ( adr,len -- len' ) */ -" space-left" /* ( adr len space-left ) */ -" min ['] partial-write" /* ( adr len' write-acf ) */ -" block-operation" /* ( len' ) */ -" ;" - -" : seek" /* ( offset other -- error? ) */ -" offset-high + swap offset-low + swap drop" /* \ "other" arg unused */ -" dup 0< if" /* ( offset ) */ -" size +" /* ( offset' ) */ -" then" /* ( offset' ) */ -" 0 + dup range-bad? if" /* ( offset' ) */ -" drop -1" /* ( -1 ) */ -" else" /* ( offset' ) */ -" to filepos false" /* ( 0 ) */ -" then" /* ( error? ) */ -" ;" - -" : load" /* ( addr -- size ) */ -" \" load\" label-package $call-method" -" ;" - -" : offset" /* ( rel -- abs ) \ needed for device_type = block */ -" offset-low +" -" ;" - -/* \ release resources, initialize data, remove existing property */ -/* \ Can be called with no instance data */ -" : destroy" /* ( -- ) */ -" \" existing\" delete-property" -" 0 to size" -" -1 to new-disk?" -" release-resources" -" ;" - -" : open" /* ( -- flag ) */ -" my-args process-args if" -" 0 exit" /* \ unrecognized arguments */ -" then" -" new-disk? if" -" claim-resources if 0 exit then" /* \ can't claim */ -" create-existing-prop" /* \ advertise resources */ -" 0 to new-disk?" /* \ no longer a new-disk */ -" then" -" claim-window" /* \ claim virtual window */ -" my-label count init-label-package 0= if 0 exit then" -" -1" -" ;" - -" : close" /* ( -- ) */ -" window-base if " -" release-window" -" then" +" 0 instance value current-offset " +" " +" 0 value ramdisk-base-va " +" 0 value ramdisk-size " +" 0 value alloc-size " +" " +" : set-props " +" ramdisk-size encode-int \" size\" property " +" ramdisk-base-va encode-int \" address\" property " +" alloc-size encode-int \" alloc-size\" property " +" ; " +" set-props " +" " +" : current-va ( -- adr ) ramdisk-base-va current-offset + ; " +" " +" external " +" " +" : open ( -- okay? ) " +/* " .\" ramdisk-open\" cr " */ +" true " +" ; " +" " +" : close ( -- ) " +" ; " +" " +" : seek ( off.low off.high -- error? ) " +/* " 2dup .\" ramdisk-seek: \" .x .x " */ +" drop dup ramdisk-size > if " +/* " .\" fail\" cr " */ +" drop true exit ( failed ) " +" then " +" to current-offset false ( succeeded ) " +/* " .\" OK\" cr " */ " ; " +" " +" : read ( addr len -- actual-len ) " +/* " 2dup .\" ramdisk-read: \" .x .x " */ +" dup current-offset + ( addr len new-off ) " +" dup ramdisk-size > if " +" ramdisk-size - - ( addr len' ) " +" ramdisk-size ( addr len new-off ) " +" then -rot ( new-off addr len ) " +" tuck current-va -rot move ( new-off len ) " +" swap to current-offset ( len ) " +/* " dup .x cr " */ +" ; " +" " +" : create ( alloc-sz base size -- ) " +" to ramdisk-size " +" to ramdisk-base-va " +" to alloc-size " +" set-props " +" ; " +" " "finish-device " +"pop-package " + +"\" /%s\" 2dup dev-open 0= if " +" open-abort " +"then 2drop " + +/* %x %x %x will be replaced by alloc-sz, base, size respectively */ +"h# %x h# %x h# %x ( alloc-sz base size ) " +"\" create\" dev-ih $call-method ( ) " +"dev-close " + +; + +char ramdisk_bootable[] = + +"\" /chosen\" get-package push-package " +" \" nfs\" encode-string \" fstype\" property " +" \" /%s\" encode-string \" bootarchive\" property " +"pop-package " + +" h# %x d# 512 + to load-base init-program " +; + +#define BOOT_ARCHIVE_ALLOC_SIZE (32 * 1024 * 1024) /* 32 MB */ +#define BOOTFS_VIRT ((caddr_t)0x50f00000) +#define ROOTFS_VIRT ((caddr_t)0x51000000) + +struct ramdisk_attr { + char *rd_name; + caddr_t rd_base; + size_t rd_size; +} ramdisk_attr[] = { + RD_BOOTFS, BOOTFS_VIRT, 0, + RD_ROOTFS, ROOTFS_VIRT, 0, + 0 +}; + +static struct ramdisk_attr * +ramdisk_lookup(char *ramdisk_name) +{ + int i; -"pop-package" + for (i = 0; ramdisk_attr[i].rd_name != 0; i++) { + if (strcmp(ramdisk_name, ramdisk_attr[i].rd_name) == 0) { + return (&ramdisk_attr[i]); + } + } + return (NULL); +} -; /* end of ramdisk_fth[] initialization */ +static void +ramdisk_free_mem(caddr_t addr, size_t size) +{ + caddr_t end_addr; + for (end_addr = addr + size; addr < end_addr; + addr += BOOT_ARCHIVE_ALLOC_SIZE) { + prom_free(addr, MIN(BOOT_ARCHIVE_ALLOC_SIZE, end_addr - addr)); + } +} /* - * Create an actual ramdisk instance. + * Allocate memory for ramdisk image. */ -static void -create_ramdisk_node(const char *ramdisk_name) +static caddr_t +ramdisk_alloc_mem(caddr_t addr, size_t size) +{ + caddr_t virt = addr; + caddr_t end_addr; + + for (end_addr = virt + size; virt < end_addr; + virt += BOOT_ARCHIVE_ALLOC_SIZE) { + if (prom_alloc(virt, + MIN(BOOT_ARCHIVE_ALLOC_SIZE, end_addr - virt), + 1) == NULL) { + ramdisk_free_mem(addr, virt - addr); + return (NULL); + } + } + return (addr); +} + +caddr_t +create_ramdisk(char *ramdisk_name, size_t size, char **devpath) { char *fth_buf; size_t buf_size; + struct ramdisk_attr *rdp; + char tdevpath[80]; + caddr_t virt; + static int need_preamble = 1; + + /* + * lookup ramdisk name. + */ + if ((rdp = ramdisk_lookup(ramdisk_name)) == NULL) + prom_panic("invalid ramdisk name"); + + virt = rdp->rd_base; + + /* + * Allocate memory. + */ + size = roundup(size, PAGESIZE); + if (ramdisk_alloc_mem(virt, size) == NULL) + prom_panic("can't alloc ramdisk memory"); + + rdp->rd_size = size; - buf_size = sizeof (ramdisk_fth) + strlen(ramdisk_name); + if (need_preamble) { + prom_interpret(ramdisk_preamble_fth, 0, 0, 0, 0, 0); + need_preamble = 0; + } + + /* + * add some space to the size to accommodate a few words in the + * snprintf() below. + */ + buf_size = sizeof (ramdisk_fth) + 80; fth_buf = bkmem_alloc(buf_size); - if (fth_buf == NULL) { + if (fth_buf == NULL) prom_panic("unable to allocate Forth buffer for ramdisk"); - } - (void) snprintf(fth_buf, buf_size, ramdisk_fth, ramdisk_name); + (void) snprintf(fth_buf, buf_size, ramdisk_fth, + ramdisk_name, ramdisk_name, + BOOT_ARCHIVE_ALLOC_SIZE, virt, size); prom_interpret(fth_buf, 0, 0, 0, 0, 0); - bkmem_free(fth_buf, buf_size); + + if (devpath != NULL) { + (void) snprintf(tdevpath, sizeof (tdevpath), "/%s:nolabel", + ramdisk_name); + *devpath = strdup(tdevpath); + } + + return (virt); } -int -create_ramdisk(const char *ramdisk_name, size_t size, char **device_path) +void +destroy_ramdisk(char *ramdisk_name) { - static int first_time = 1; - char buf[OBP_MAXPATHLEN]; - ihandle_t ih; + struct ramdisk_attr *rdp; /* - * Ensure that size is a multiple of page size (rounded up). + * lookup ramdisk name. */ - size = ptob(btopr(size)); + if ((rdp = ramdisk_lookup(ramdisk_name)) == NULL) + prom_panic("invalid ramdisk name"); -/* EXPORT DELETE START */ - bootlog("wanboot", BOOTLOG_VERBOSE, "Creating ramdisk, size=0x%lx", - size); -/* EXPORT DELETE END */ - - if (strcmp(ramdisk_name, RD_ROOTFS) == 0 || - strcmp(ramdisk_name, RD_BOOTFS) == 0) { + ramdisk_free_mem(rdp->rd_base, rdp->rd_size); + rdp->rd_size = 0; +} - if (first_time) { - first_time = 0; +/* + * change cwp! to drop in the 2nd word of (init-program) - really + * init-c-stack, but that word has no header. + * (you are not expected to undertsnad this) + */ +char obpfix[] = "' drop ' cwp! ' (init-program) >body ta1+ token@ (patch"; +char obpver[OBP_MAXPROPNAME]; +const char badver[] = "OBP 4.27."; - create_ramdisk_node(RD_ROOTFS); - create_ramdisk_node(RD_BOOTFS); - } - (void) snprintf(buf, sizeof (buf), "/%s:nolabel", ramdisk_name); - *device_path = strdup(buf); +void +boot_ramdisk(char *ramdisk_name) +{ + char *fth_buf; + size_t buf_size; + struct ramdisk_attr *rdp; + void do_sg_go(void); - if (*device_path != NULL) { - (void) snprintf(buf, sizeof (buf), "/%s:size=%x,%x", - ramdisk_name, - (uint32_t)(size >> 32), (uint32_t)size); + /* + * OBP revs 4.27.0 to 4.27.8 started using + * windowed regs for the forth kernel, but + * init-program still blindly 0'd %cwp, which + * causes predictably disaterous consequences + * when called with %cwp != 0. + * + * We detect and fix this here + */ + if (prom_version_name(obpver, OBP_MAXPROPNAME) != -1 && + strncmp(obpver, badver, sizeof (badver) - 1) == 0) { + char ch = obpver[sizeof (badver) - 1]; - if ((ih = prom_open(buf)) != 0) { - return (ih); - } + if (ch >= '0' && ch <= '8') { + prom_interpret(obpfix, 0, 0, 0, 0, 0); } } -/* EXPORT DELETE START */ - bootlog("wanboot", BOOTLOG_CRIT, "Cannot create ramdisk \"%s\"", - ramdisk_name); -/* EXPORT DELETE END */ - prom_panic("create_ramdisk: fatal error"); - /* NOTREACHED */ + /* close all open devices */ + closeall(1); + + /* + * lookup ramdisk name. + */ + if ((rdp = ramdisk_lookup(ramdisk_name)) == NULL) + prom_panic("invalid ramdisk name"); + + /* + * add some space to the size to accommodate a few words in the + * snprintf() below. + */ + buf_size = sizeof (ramdisk_bootable) + 80; + + fth_buf = bkmem_alloc(buf_size); + if (fth_buf == NULL) + prom_panic("unable to allocate Forth buffer for ramdisk"); + + (void) snprintf(fth_buf, buf_size, ramdisk_bootable, + ramdisk_name, rdp->rd_base); + + prom_interpret(fth_buf, 0, 0, 0, 0, 0); + + /* + * Ugh Serengeti proms don't execute C programs + * in init-program, and 'go' doesn't work when + * launching a second C program (inetboot itself + * was launched as the 1st C program). Nested fcode + * programs work, but that doesn't help the kernel. + */ + do_sg_go(); +} + +void +do_sg_go() +{ + pnode_t chosen = prom_chosennode(); + Elf64_Ehdr *ehdr; + Elf64_Addr entry; + uint32_t eadr; + extern int is_sg; + extern caddr_t sg_addr; + extern size_t sg_len; + + if (!is_sg) + prom_panic("do_sg_go"); + + /* + * The ramdisk bootblk left a pointer to the elf image + * in 'elfheader-address' Use it to find the kernel's + * entry point. + */ + if (prom_getprop(chosen, "elfheader-address", (caddr_t)&eadr) == -1) + prom_panic("no elf header property"); + ehdr = (Elf64_Ehdr *)(uintptr_t)eadr; + if (ehdr->e_machine != EM_SPARCV9) + prom_panic("bad ELF header"); + entry = ehdr->e_entry; + + /* + * free extra bootmem + */ + prom_free(sg_addr, sg_len); + + /* + * Use pre-newboot's exitto64() to launch the kernel + */ + exitto64((int (*)())entry, NULL); + prom_panic("exitto returned"); } diff --git a/usr/src/psm/stand/boot/sparc/common/ramdisk.h b/usr/src/psm/stand/boot/sparc/common/ramdisk.h index 77eb021a11..561b210f75 100644 --- a/usr/src/psm/stand/boot/sparc/common/ramdisk.h +++ b/usr/src/psm/stand/boot/sparc/common/ramdisk.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,9 +38,11 @@ extern "C" { * Ramdisk names */ #define RD_BOOTFS "ramdisk-bootfs" -#define RD_ROOTFS "ramdisk-rootfs" +#define RD_ROOTFS "ramdisk-root" -extern int create_ramdisk(const char *, size_t, char **); +extern caddr_t create_ramdisk(char *, size_t, char **); +extern void destroy_ramdisk(char *); +extern void boot_ramdisk(char *); #ifdef __cplusplus } diff --git a/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c b/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c index 707c7ff5c2..a68c6d0d47 100644 --- a/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c +++ b/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -104,6 +103,15 @@ static caddr_t free_addr[N_FREELIST]; static caddr_t top_bootmem = MAPPEDMEM_MINTOP; static caddr_t top_resvmem, scratchresvp; +/* + * with newboot, boot goes away when it launches the client, + * so we can safely extend bootmem on sg, and give it back + * before we die. + */ +int is_sg; +caddr_t sg_addr; +size_t sg_len; + static int impl_name(char *buf, size_t bufsz) { @@ -212,8 +220,13 @@ resalloc_init(void) * but we don't have the ability to check for the firmware version here. */ if (strcmp(iarch, "SUNW,Sun-Fire") == 0 || - strcmp(iarch, "SUNW,Netra-T12") == 0) - return; + strcmp(iarch, "SUNW,Netra-T12") == 0) { + is_sg = 1; + sg_addr = MAPPEDMEM_MINTOP; + sg_len = MAPPEDMEM_FULLTOP - MAPPEDMEM_MINTOP; + if (prom_alloc(sg_addr, sg_len, 1) != sg_addr) + prom_panic("can't extend sg bootmem"); + } top_bootmem = MAPPEDMEM_FULLTOP; @@ -264,7 +277,7 @@ resalloc(enum RESOURCES type, size_t bytes, caddr_t virthint, int align) if (vaddr == (caddr_t)virthint) return (vaddr); printf("Alloc of 0x%lx bytes at 0x%p refused.\n", - bytes, (void *)virthint); + bytes, (void *)virthint); return ((caddr_t)0); /*NOTREACHED*/ diff --git a/usr/src/psm/stand/boot/sparc/common/ufsconf.c b/usr/src/psm/stand/boot/sparc/common/ufsconf.c deleted file mode 100644 index 5d0195e5f3..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/ufsconf.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/param.h> -#include <sys/sysmacros.h> -#include <sys/obpdefs.h> -#include <sys/stat.h> -#include <sys/bootvfs.h> -#include <sys/bootdebug.h> -#include <sys/promif.h> -#include <sys/salib.h> -#include "boot_plat.h" - -/* - * filesystem switch table, UFS - */ -extern struct boot_fs_ops boot_ufs_ops; -struct boot_fs_ops *boot_fsw[] = { - &boot_ufs_ops, -}; - -int boot_nfsw = sizeof (boot_fsw) / sizeof (boot_fsw[0]); -int nfs_readsize = 0; - -static char *ufsname = "ufs"; - -/* ARGSUSED */ -char * -set_fstype(char *v2path, char *bpath) -{ - set_default_fs(ufsname); - return (ufsname); -} diff --git a/usr/src/psm/stand/boot/sparc/common/wanboot.c b/usr/src/psm/stand/boot/sparc/common/wanboot.c index 236746d9f6..2c8121f7a6 100644 --- a/usr/src/psm/stand/boot/sparc/common/wanboot.c +++ b/usr/src/psm/stand/boot/sparc/common/wanboot.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -77,7 +76,8 @@ /* * Experimentation has shown that an 8K download buffer is optimal */ -static char buffer[8192]; +#define HTTP_XFER_SIZE 8192 +static char buffer[HTTP_XFER_SIZE]; bc_handle_t bc_handle; @@ -428,7 +428,7 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) lenstr = http_get_header_value(handle, CONTENT_LENGTH); if (lenstr == NULL) { bootlog("wanboot", BOOTLOG_ALERT, - "%s: error getting digest length", what); + "%s: error getting digest length", what); return (1); } digest_size = (size_t)strtol(lenstr, NULL, 10); @@ -439,8 +439,8 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) */ if (digest_size != HMAC_DIGEST_LEN) { bootlog("wanboot", BOOTLOG_CRIT, - "%s: error validating response - invalid digest size", - what); + "%s: error validating response - invalid digest size", + what); return (-1); } @@ -449,7 +449,7 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) */ if (read_bytes(handle, (char *)sdigest, digest_size) != 0) { bootlog("wanboot", BOOTLOG_ALERT, - "%s: error reading digest", what); + "%s: error reading digest", what); return (1); } @@ -469,7 +469,7 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) * 1 = HTTP download error */ static int -write_msg_to_ramdisk(const char *what, int fd, http_handle_t handle, +write_msg_to_ramdisk(const char *what, caddr_t addr, http_handle_t handle, size_t ramdisk_size, off_t *offset, SHA1_CTX *sha) { int len; @@ -497,13 +497,14 @@ write_msg_to_ramdisk(const char *what, int fd, http_handle_t handle, "Continuing read of %s file system (%ld kB)", what, ramdisk_size / 1024); } - for (ret = 0; ret == 0 && *offset < ramdisk_size; *offset += len) { + for (ret = 0; ret == 0 && *offset < ramdisk_size; + *offset += len, addr += len) { nleft = ramdisk_size - *offset; if (nleft > sizeof (buffer)) nleft = sizeof (buffer); - len = http_read_body(handle, buffer, nleft); + len = http_read_body(handle, addr, nleft); if (len <= 0) { print_errors("http_read_body", handle); /* @@ -517,13 +518,7 @@ write_msg_to_ramdisk(const char *what, int fd, http_handle_t handle, ret = 1; } if (sha != NULL) { - HMACUpdate(sha, (uchar_t *)buffer, (size_t)len); - } - if (prom_write(fd, buffer, (size_t)len, 0, 0) != (ssize_t)len) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: write to ramdisk failed", what); - ret = -1; - continue; + HMACUpdate(sha, (uchar_t *)addr, (size_t)len); } if (bootlog_progress == bootlog_message_interval) { bootlog("wanboot", BOOTLOG_PROGRESS, @@ -790,10 +785,10 @@ establish_http_connection(const char *what, http_handle_t *handlep, if ((offset == 0 && resp->code != 200) || (offset != 0 && resp->code != 206)) { bootlog("wanboot", BOOTLOG_ALERT, - "%s: Request returned code %d", what, resp->code); + "%s: Request returned code %d", what, resp->code); if (resp->statusmsg != NULL && resp->statusmsg[0] != '\0') bootlog("wanboot", BOOTLOG_ALERT, - "%s", resp->statusmsg); + "%s", resp->statusmsg); http_free_respinfo(resp); (void) http_srv_close(*handlep); return (1); @@ -929,7 +924,7 @@ get_miniinfo(const url_t *server_url, size_t *mini_size, } if ((ret = process_miniinfo(handle, mini_size, - sdigest)) > 0) { + sdigest)) > 0) { if (!wanboot_retry(++retry_cnt, retry_max)) { (void) http_srv_close(handle); break; @@ -985,10 +980,10 @@ process_miniroot(http_handle_t handle, hash_type_t htype, { static SHA1_CTX sha; static size_t miniroot_size; - static int fd = -1; + static caddr_t miniroot_vaddr = NULL; int ret; - if (fd == -1) { + if (miniroot_vaddr == NULL) { if (htype == HASH_HMAC_SHA1) { bootlog("wanboot", BOOTLOG_INFO, "%s: Authentication will use HMAC-SHA1", MINIROOT); @@ -997,23 +992,14 @@ process_miniroot(http_handle_t handle, hash_type_t htype, miniroot_size = length; - fd = create_ramdisk(RD_ROOTFS, miniroot_size, devpath); + miniroot_vaddr = create_ramdisk(RD_ROOTFS, miniroot_size, + devpath); } - if (prom_seek(fd, *offset) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", MINIROOT); - return (-1); - } + miniroot_vaddr += *offset; - if ((ret = write_msg_to_ramdisk(MINIROOT, fd, handle, miniroot_size, - offset, (htype == HASH_NONE) ? NULL : &sha)) != 0) { - if (ret < 0) { - /* - * Reentry not supported. - */ - (void) prom_close(fd); - } + if ((ret = write_msg_to_ramdisk(MINIROOT, miniroot_vaddr, handle, + miniroot_size, offset, (htype == HASH_NONE) ? NULL : &sha)) != 0) { return (ret); } @@ -1021,8 +1007,6 @@ process_miniroot(http_handle_t handle, hash_type_t htype, HMACFinal(&sha, g_hash_key, WANBOOT_HMAC_KEY_SIZE, cdigest); } - (void) prom_close(fd); - return (0); } @@ -1177,9 +1161,8 @@ encr_fini(encr_type_t etype, void *eh) } /* - * This routine is called by process_wanbootfs() to read the encrypted - * file system from ramdisk and decrypt it. This routine will rewrite - * the file system back to ramdisk in place. The method of decryption + * This routine is called by process_wanbootfs() to decrypt the encrypted + * file system from ramdisk in place. The method of decryption * (algorithm) will have already been determined by process_wanbootfs() * and the cbc_handle passed to this routine will already have been * initialized appropriately. @@ -1189,45 +1172,13 @@ encr_fini(encr_type_t etype, void *eh) * 0 = Success */ static int -decrypt_wanbootfs(int fd, cbc_handle_t *ch, uint8_t *iv, - size_t block_size, size_t wanbootfs_size) +decrypt_wanbootfs(caddr_t addr, cbc_handle_t *ch, uint8_t *iv, + size_t wanbootfs_size) { - size_t total; - size_t len; - size_t nleft; - size_t max_read_size; - - max_read_size = (sizeof (buffer) / block_size) * block_size; - for (total = 0; total < wanbootfs_size; total += len) { - if (prom_seek(fd, total) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", WANBOOTFS); - return (-1); - } - nleft = wanbootfs_size - total; - if (nleft > max_read_size) - nleft = max_read_size; - len = prom_read(fd, buffer, nleft, 0, 0); - if (len != nleft) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_read error", WANBOOTFS); - return (-1); - } - if (!cbc_decrypt(ch, (uint8_t *)buffer, len, iv)) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: cbc decrypt error", WANBOOTFS); - return (-1); - } - if (prom_seek(fd, total) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", WANBOOTFS); - return (-1); - } - if (prom_write(fd, buffer, len, 0, 0) != len) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_write error", WANBOOTFS); - return (-1); - } + if (!cbc_decrypt(ch, (uint8_t *)addr, wanbootfs_size, iv)) { + bootlog("wanboot", BOOTLOG_CRIT, + "%s: cbc decrypt error", WANBOOTFS); + return (-1); } return (0); } @@ -1279,7 +1230,7 @@ process_wanbootfs(http_handle_t handle, char **devpath, size_t wanbootfs_size; size_t block_size; off_t offset; - static int fd = -1; + static caddr_t bootfs_vaddr = NULL; int ret; switch (hash_type) { @@ -1371,25 +1322,16 @@ process_wanbootfs(http_handle_t handle, char **devpath, * the already existing ramdisk and seek back to the * beginning of the file. */ - if (fd == -1) { - fd = create_ramdisk(RD_BOOTFS, wanbootfs_size, devpath); + if (bootfs_vaddr == NULL) { + bootfs_vaddr = create_ramdisk(RD_BOOTFS, wanbootfs_size, + devpath); } offset = 0; - if (prom_seek(fd, offset) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", WANBOOTFS); - return (-1); - } - if ((ret = write_msg_to_ramdisk(WANBOOTFS, fd, handle, wanbootfs_size, - &offset, (hash_type == HASH_NONE) ? NULL : &sha)) != 0) { - if (ret < 0) { - /* - * Reentry not supported. - */ - (void) prom_close(fd); - } + if ((ret = write_msg_to_ramdisk(WANBOOTFS, bootfs_vaddr, handle, + wanbootfs_size, &offset, (hash_type == HASH_NONE) ? NULL : &sha)) + != 0) { return (ret); } @@ -1401,18 +1343,14 @@ process_wanbootfs(http_handle_t handle, char **devpath, * If encrypted, then decrypt it. */ if (encr_type != ENCR_NONE) { - ret = decrypt_wanbootfs(fd, &ch, iv, block_size, - wanbootfs_size); + ret = decrypt_wanbootfs(bootfs_vaddr, &ch, iv, wanbootfs_size); if (ret != 0) { encr_fini(encr_type, eh); - (void) prom_close(fd); return (-1); } encr_fini(encr_type, eh); } - (void) prom_close(fd); - return (read_digest(WANBOOTFS, handle, sdigest)); } @@ -1472,7 +1410,7 @@ get_wanbootfs(const url_t *server_url) bzero(cdigest, sizeof (cdigest)); do { if ((ret = establish_http_connection(WANBOOTFS, &handle, - &req_url, 0)) < 0) { + &req_url, 0)) < 0) { break; } else if (ret > 0) { if (wanboot_retry(++retry_cnt, retry_max)) { @@ -1483,7 +1421,7 @@ get_wanbootfs(const url_t *server_url) } if ((ret = process_wanbootfs(handle, &devpath, - cdigest, sdigest)) > 0) { + cdigest, sdigest)) > 0) { if (!wanboot_retry(++retry_cnt, retry_max)) { (void) http_srv_close(handle); break; @@ -1498,7 +1436,7 @@ get_wanbootfs(const url_t *server_url) * Validate the computed digest against the one received. */ if (ret != 0 || - !verify_digests(WANBOOTFS, cdigest, sdigest)) { + !verify_digests(WANBOOTFS, cdigest, sdigest)) { bootlog("wanboot", BOOTLOG_CRIT, "The wanboot file system download aborted"); return (-1); @@ -1530,7 +1468,7 @@ get_wanbootfs(const url_t *server_url) */ if ((fd = open(WANBOOTFS_NONCE_FILE, O_RDONLY)) == -1) { bootlog("wanboot", BOOTLOG_CRIT, - "No nonce found in the wanboot file system"); + "No nonce found in the wanboot file system"); bootlog("wanboot", BOOTLOG_CRIT, "The wanboot file system download aborted"); return (-1); @@ -1540,7 +1478,7 @@ get_wanbootfs(const url_t *server_url) bcmp(nonce, buf, NONCELEN) != 0) { (void) close(fd); bootlog("wanboot", BOOTLOG_CRIT, - "Invalid nonce found in the wanboot file system"); + "Invalid nonce found in the wanboot file system"); bootlog("wanboot", BOOTLOG_CRIT, "The wanboot file system download aborted"); return (-1); @@ -1633,7 +1571,7 @@ init_netdev(char *bpath) * * - The wanboot miniroot is downloaded over http/https into the rootfs * ramdisk. The bootfs filesystem is unmounted, and the rootfs filesystem - * is mounted. + * is booted. */ /* EXPORT DELETE END */ /*ARGSUSED*/ @@ -1723,39 +1661,7 @@ bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) */ (void) unmountroot(); - /* - * Mount the miniroot. - */ - if (determine_fstype_and_mountroot(miniroot_path) != VFS_SUCCESS) { - bootlog("wanboot", BOOTLOG_CRIT, - "Could not mount miniroot filesystem"); - return (-1); - } - bootlog("wanboot", BOOTLOG_VERBOSE, "The miniroot has been mounted"); - - v2path = "/ramdisk-rootfs:a"; - bootlog("wanboot", BOOTLOG_VERBOSE, "device path '%s'", v2path); - - /* - * kernname (default-name) might have changed if mountroot() called - * boot_nfs_mountroot(), and it called set_default_filename(). - */ - if (! user_specified_filename) - (void) strcpy(filename, kernname); - - bootlog("wanboot", BOOTLOG_VERBOSE, - "standalone = `%s', args = `%s'", filename, bargs); - - set_client_bootargs(filename, bargs); - - /* - * We're done with the mac interface that was initialized by - * mac_init() inside init_netdev(). - */ - mac_fini(); - - bootconf_end(&bc_handle); - bootinfo_end(); + boot_ramdisk(RD_ROOTFS); /* EXPORT DELETE END */ return (0); |
