diff options
Diffstat (limited to 'usr/src/psm/stand/boot/sparc/common/bootprop.c')
| -rw-r--r-- | usr/src/psm/stand/boot/sparc/common/bootprop.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/usr/src/psm/stand/boot/sparc/common/bootprop.c b/usr/src/psm/stand/boot/sparc/common/bootprop.c new file mode 100644 index 0000000000..dcc69fa593 --- /dev/null +++ b/usr/src/psm/stand/boot/sparc/common/bootprop.c @@ -0,0 +1,263 @@ +/* + * 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/types.h> +#include <sys/promif.h> +#include <sys/bootconf.h> +#include <sys/salib.h> +#include <sys/boot.h> +#include "boot_plat.h" + +char *v2path, *kernname, *systype; +char *my_own_name = "boot"; +char v2args_buf[V2ARGS_BUF_SZ]; +char *v2args = v2args_buf; +char *mfg_name; +char *impl_arch_name; +char *bootp_response; +char *module_path; +int cache_state; +uint64_t memlistextent; /* replacement for old member of bootops */ + +/* These are the various memory lists */ +struct memlist *pfreelistp, /* physmem available */ + *vfreelistp, /* virtmem available */ + *pinstalledp; /* physmem installed */ + +char *boot_message; + +char *netdev_path; + +/* + * Support new boot properties "boot-start" and "boot-end" for + * Freeze/Thaw project. + */ +caddr_t start_addr, end_addr; + +#define BOOT_BADPROP -1 +#define BOOT_SUCCESS 0 +#define BOOT_FAILURE -1 +#define NIL 0 + +#define strequal(p, q) (strcmp((p), (q)) == 0) + + +/* + * This routine is used by stand/lib/$PROC/libnfs.a in case it comes up with a + * default filename, and by bootflags() if a default filename is specified in + * the boot arguments. + */ +void +set_default_filename(char *filename) +{ + kernname = filename; +} + + +static const struct bplist { + char *name; + void *val; + uint_t size; +} bprop_tab[] = { + "boot-args", &v2args, 0, + "boot-path", &v2path, 0, + "fstype", &systype, 0, + "whoami", &my_own_name, 0, + "mfg-name", &mfg_name, 0, + "impl-arch-name", &impl_arch_name, 0, + "module-path", &module_path, 0, + "virt-avail", &vfreelistp, 0, + "phys-avail", &pfreelistp, 0, + "phys-installed", &pinstalledp, 0, + "default-name", &kernname, 0, + "extent", &memlistextent, sizeof (memlistextent), + "vac", &vac, sizeof (vac), + "cache-on?", &cache_state, sizeof (int), + "memory-update", 0, 0, + "boot-start", &start_addr, sizeof (start_addr), + "boot-end", &scratchmemp, sizeof (scratchmemp), + "boot-message", &boot_message, 0, + "bootp-response", &bootp_response, 0, + "netdev-path", &netdev_path, 0, + 0, 0, 0 +}; + +/* + * These routines implement the boot getprop interface. + * They are designed to mimic the corresponding devr_{getprop,getproplen} + * functions. + * The assumptions is that the basic property is an unsigned int. Other + * types (including lists) are special cases. + */ + +/*ARGSUSED*/ +int +bgetproplen(struct bootops *bop, char *name) +{ + int size = 0; + struct bplist *p; + struct memlist *ml; + + /* this prop has side effects only. No length. */ + if (strequal(name, "memory-update")) + return (BOOT_SUCCESS); + + for (p = (struct bplist *)bprop_tab; p->name != (char *)0; p++) { + + /* got a linked list? */ + if ((strequal(name, "virt-avail") && strequal(name, p->name)) || + (strequal(name, "phys-avail") && strequal(name, p->name)) || + (strequal(name, "phys-installed") && + strequal(name, p->name))) { + + for (ml = *((struct memlist **)p->val); + ml != NIL; + ml = ml->next) + + /* + * subtract out the ptrs for our local + * linked list. The application will + * only see an array. + */ + size += (int)(sizeof (struct memlist) - + 2*sizeof (struct memlist *)); + return (size); + + } else if (strequal(name, p->name)) { + + /* if we already know the size, return it */ + if (p->size != 0) + return (p->size); + else { + if (*((char **)p->val) == NIL) + return (0); /* NULL is allowed */ + + /* don't forget the null termination */ + return (strlen(*((char **)p->val)) + 1); + } + } + } + printf("Property (%s) not supported by %s\n", name, my_own_name); + return (BOOT_BADPROP); +} + +/*ARGSUSED*/ +int +bgetprop(struct bootops *bop, char *name, void *buf) +{ + struct bplist *p; + struct memlist *ml; + + if (strequal(name, "memory-update")) { +/* + * dprintf("bgetprop: updating memlists.\n"); + */ + update_memlist("virtual-memory", "available", &vfreelistp); + update_memlist("memory", "available", &pfreelistp); + return (BOOT_SUCCESS); + } + + if (strequal(name, "boot-start")) { + start_addr = (caddr_t)_start; + bcopy((char *)(&start_addr), buf, sizeof (start_addr)); + return (BOOT_SUCCESS); + } + + if (strequal(name, "boot-end")) { + /* + * The true end of boot should be scratchmemp, + * boot gets its dynamic memory from the scratchmem + * which is the first 4M of the physical memory, + * and they are mapped 1:1. + */ + end_addr = scratchmemp; + bcopy((char *)(&end_addr), buf, sizeof (scratchmemp)); + return (BOOT_SUCCESS); + } + + for (p = (struct bplist *)bprop_tab; p->name != (char *)0; p++) { + + /* gotta linked list? */ + if ((strequal(name, "virt-avail") && strequal(name, p->name)) || + (strequal(name, "phys-avail") && strequal(name, p->name)) || + (strequal(name, "phys-installed") && + strequal(name, p->name))) { + + u_longlong_t *t = buf; + + for (ml = *((struct memlist **)p->val); + ml != NIL; + ml = ml->next) { + + /* copy out into an array */ + *t++ = ml->address; + *t++ = ml->size; + } + return (BOOT_SUCCESS); + } else if (strequal(name, p->name)) { + if (p->size != 0) { + bcopy(p->val, buf, p->size); + } else { + (void) strcpy((char *)buf, *((char **)p->val)); + } + return (BOOT_SUCCESS); + } + } + return (BOOT_FAILURE); +} + +/* + * If the user wants the first property in the list, he passes in a + * null string. The routine will always return a ptr to the name of the + * next prop, except when there are no more props. In that case, it will + * return a null string. + */ + +/*ARGSUSED*/ +char * +bnextprop(struct bootops *bop, char *prev) +{ + struct bplist *p; + + /* user wants the firstprop */ + if (*prev == 0) + return (bprop_tab->name); + + for (p = (struct bplist *)bprop_tab; p->name != (char *)0; p++) { + + if (strequal(prev, p->name)) + /* + * if prev is the last valid prop, + * we will return our terminator (0). + */ + return ((++p)->name); + + + } + return ((char *)0); +} |
