diff options
Diffstat (limited to 'stand')
768 files changed, 15621 insertions, 11884 deletions
diff --git a/stand/Makefile b/stand/Makefile index 1597f6832c07..f5ce6ca3db71 100644 --- a/stand/Makefile +++ b/stand/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <src.opts.mk> # For amd64 we have to build 32 and 64 bit versions of things. For @@ -39,9 +37,7 @@ INTERP_DEPENDS+= lua .include <bsd.arch.inc.mk> S.${MK_EFI}+= efi -.if ${MK_FDT} != "no" S.${MK_LOADER_KBOOT}+= kboot -.endif S.${MK_LOADER_UBOOT}+= uboot .if defined(LIB32LIST) @@ -68,6 +64,7 @@ SUBDIR_DEPEND_${MACHINE}+= libofw SUBDIR+=${_x} .if defined(LIB32LIST) && ${LIB32LIST:M${_x}} SUBDIR+=${_x}32 +INTERP_DEPENDS+=${_x}32 .endif .if ${_x} != "libsa" SUBDIR_DEPEND_${_x}+= libsa @@ -94,3 +91,8 @@ SUBDIR_DEPEND_uboot+= fdt SUBDIR_PARALLEL= yes .include <bsd.subdir.mk> + +# Simplified way to build-test the most important build combinations for the +# loader. +universe: + sh ${SRCTOP}/tools/boot/universe.sh diff --git a/stand/Makefile.amd64 b/stand/Makefile.amd64 index 9ee3649071b2..48e5136ec33f 100644 --- a/stand/Makefile.amd64 +++ b/stand/Makefile.amd64 @@ -1,5 +1,3 @@ -# $FreeBSD$ - S.yes+= userboot S.yes+= i386 diff --git a/stand/Makefile.inc b/stand/Makefile.inc index aa7cfa14542f..5d55c4e4a16f 100644 --- a/stand/Makefile.inc +++ b/stand/Makefile.inc @@ -1,5 +1,6 @@ -# $FreeBSD$ - SUBDIR_PARALLEL= yes +# Firmware may not be able to handle branch protection failures +MK_BRANCH_PROTECTION= no + .include "defs.mk" diff --git a/stand/arm64/Makefile b/stand/arm64/Makefile index d4c9667d6b13..eb7a92885d77 100644 --- a/stand/arm64/Makefile +++ b/stand/arm64/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - NO_OBJ=t .include <bsd.subdir.mk> diff --git a/stand/arm64/libarm64/cache.c b/stand/arm64/libarm64/cache.c index 105e08cb4257..7b74f584ffe3 100644 --- a/stand/arm64/libarm64/cache.c +++ b/stand/arm64/libarm64/cache.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2014 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Semihalf under * the sponsorship of the FreeBSD Foundation. @@ -26,16 +25,12 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <machine/armreg.h> #include <machine/atomic.h> #include <stand.h> -#include <efi.h> #include "bootstrap.h" #include "cache.h" diff --git a/stand/arm64/libarm64/cache.h b/stand/arm64/libarm64/cache.h index 5e560c4d578d..76e641b8115a 100644 --- a/stand/arm64/libarm64/cache.h +++ b/stand/arm64/libarm64/cache.h @@ -1,6 +1,5 @@ /*- * Copyright (c) 2014 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Semihalf under * the sponsorship of the FreeBSD Foundation. @@ -24,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _CACHE_H_ diff --git a/stand/common/Makefile.depend b/stand/common/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/common/Makefile.depend +++ b/stand/common/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/common/bcache.c b/stand/common/bcache.c index 88dee8c7ce2d..f4805cbaa715 100644 --- a/stand/common/bcache.c +++ b/stand/common/bcache.c @@ -25,10 +25,7 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> #include <sys/param.h> -__FBSDID("$FreeBSD$"); - /* * Simple hashed block cache */ diff --git a/stand/common/boot.c b/stand/common/boot.c index 06f604f595df..e0775c0fca26 100644 --- a/stand/common/boot.c +++ b/stand/common/boot.c @@ -24,16 +24,14 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Loading modules, booting the system */ #include <stand.h> -#include <sys/reboot.h> #include <sys/boot.h> +#include <sys/kenv.h> +#include <sys/reboot.h> #include <string.h> #include "bootstrap.h" @@ -161,7 +159,7 @@ command_autoboot(int argc, char *argv[]) * we haven't tried already, try now. */ void -autoboot_maybe() +autoboot_maybe(void) { char *cp; @@ -321,14 +319,14 @@ getbootfile(int try) int getrootmount(char *rootdev) { - char lbuf[128], *cp, *ep, *dev, *fstyp, *options; + char lbuf[KENV_MVALLEN], *cp, *ep, *dev, *fstyp, *options; int fd, error; if (getenv("vfs.root.mountfrom") != NULL) return(0); error = 1; - sprintf(lbuf, "%s/etc/fstab", rootdev); + snprintf(lbuf, sizeof(lbuf), "%s/etc/fstab", rootdev); if ((fd = open(lbuf, O_RDONLY)) < 0) goto notfound; @@ -382,7 +380,7 @@ getrootmount(char *rootdev) *cp = 0; options = strdup(ep); /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */ - sprintf(lbuf, "%s:%s", fstyp, dev); + snprintf(lbuf, sizeof(lbuf), "%s:%s", fstyp, dev); setenv("vfs.root.mountfrom", lbuf, 0); /* Don't override vfs.root.mountfrom.options if it is already set */ diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h index 9c62a49b0da7..17887919089c 100644 --- a/stand/common/bootstrap.h +++ b/stand/common/bootstrap.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _BOOTSTRAP_H_ @@ -52,10 +50,12 @@ extern char command_errbuf[COMMAND_ERRBUFSZ]; void interact(void); void interp_emit_prompt(void); int interp_builtin_cmd(int argc, char *argv[]); +bool interp_has_builtin_cmd(const char *cmd); /* Called by interp.c for interp_*.c embedded interpreters */ int interp_include(const char *); /* Execute commands from filename */ -void interp_init(void); /* Initialize interpreater */ +void interp_preinit(void); /* Initialize interpreater execution engine */ +void interp_init(void); /* Initialize interpreater and run main script */ int interp_run(const char *); /* Run a single command */ /* interp_backslash.c */ @@ -181,6 +181,7 @@ extern int isapnp_readport; * Version information */ extern char bootprog_info[]; +extern unsigned bootprog_rev; /* * Interpreter information @@ -200,6 +201,7 @@ struct file_metadata { size_t md_size; uint16_t md_type; + vm_offset_t md_addr; /* Valid after copied to kernel space */ struct file_metadata *md_next; char md_data[1]; /* data are immediately appended */ }; @@ -228,7 +230,7 @@ struct kernel_module struct preloaded_file { char *f_name; /* file name */ - char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */ + char *f_type; /* verbose file type, eg 'elf kernel', 'pnptable', etc. */ char *f_args; /* arguments for the file */ /* metadata that will be placed in the module directory */ struct file_metadata *f_metadata; @@ -237,10 +239,10 @@ struct preloaded_file size_t f_size; /* file size */ struct kernel_module *f_modules; /* list of modules if any */ struct preloaded_file *f_next; /* next file */ -#ifdef __amd64__ +#if defined(__amd64__) || (defined(__i386__) && defined(EFI)) bool f_kernphys_relocatable; #endif -#if defined(__i386__) +#if defined(__i386__) && !defined(EFI) bool f_tg_kernel_support; #endif }; @@ -269,7 +271,7 @@ void unload(void); struct preloaded_file *file_alloc(void); struct preloaded_file *file_findfile(const char *name, const char *type); struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type); -struct preloaded_file *file_loadraw(const char *name, char *type, int insert); +struct preloaded_file *file_loadraw(const char *name, const char *type, int insert); void file_discard(struct preloaded_file *fp); void file_addmetadata(struct preloaded_file *, int, size_t, void *); int file_addmodule(struct preloaded_file *, char *, int, @@ -280,6 +282,7 @@ int tslog_init(void); int tslog_publish(void); vm_offset_t build_font_module(vm_offset_t); +vm_offset_t build_splash_module(vm_offset_t); /* MI module loaders */ #ifdef __elfN @@ -323,7 +326,8 @@ SET_DECLARE(Xcommand_set, struct bootblk_command); * The intention of the architecture switch is to provide a convenient * encapsulation of the interface between the bootstrap MI and MD code. * MD code may selectively populate the switch at runtime based on the - * actual configuration of the target system. + * actual configuration of the target system, though some routines are + * mandatory. */ struct arch_switch { @@ -348,14 +352,6 @@ struct arch_switch void (*arch_isaoutb)(int port, int value); /* - * Interface to adjust the load address according to the "object" - * being loaded. - */ - uint64_t (*arch_loadaddr)(u_int type, void *data, uint64_t addr); -#define LOAD_ELF 1 /* data points to the ELF header. */ -#define LOAD_RAW 2 /* data points to the file name. */ - - /* * Interface to inform MD code about a loaded (ELF) segment. This * can be used to flush caches and/or set up translations. */ @@ -370,53 +366,17 @@ struct arch_switch /* Return the hypervisor name/type or NULL if not virtualized. */ const char *(*arch_hypervisor)(void); - - /* For kexec-type loaders, get ksegment structure */ - void (*arch_kexec_kseg_get)(int *nseg, void **kseg); }; extern struct arch_switch archsw; /* This must be provided by the MD code, but should it be in the archsw? */ void delay(int delay); -void dev_cleanup(void); - -/* - * nvstore API. - */ -typedef int (nvstore_getter_cb_t)(void *, const char *, void **); -typedef int (nvstore_setter_cb_t)(void *, int, const char *, - const void *, size_t); -typedef int (nvstore_setter_str_cb_t)(void *, const char *, const char *, - const char *); -typedef int (nvstore_unset_cb_t)(void *, const char *); -typedef int (nvstore_print_cb_t)(void *, void *); -typedef int (nvstore_iterate_cb_t)(void *, int (*)(void *, void *)); - -typedef struct nvs_callbacks { - nvstore_getter_cb_t *nvs_getter; - nvstore_setter_cb_t *nvs_setter; - nvstore_setter_str_cb_t *nvs_setter_str; - nvstore_unset_cb_t *nvs_unset; - nvstore_print_cb_t *nvs_print; - nvstore_iterate_cb_t *nvs_iterate; -} nvs_callbacks_t; - -int nvstore_init(const char *, nvs_callbacks_t *, void *); -int nvstore_fini(const char *); -void *nvstore_get_store(const char *); -int nvstore_print(void *); -int nvstore_get_var(void *, const char *, void **); -int nvstore_set_var(void *, int, const char *, void *, size_t); -int nvstore_set_var_from_string(void *, const char *, const char *, - const char *); -int nvstore_unset_var(void *, const char *); +int setprint_delay(struct env_var *ev, int flags, const void *value); /* common code to set currdev variable. */ -extern int mount_currdev(struct env_var *, int, const void *); - -#ifndef CTASSERT -#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") -#endif +int gen_setcurrdev(struct env_var *ev, int flags, const void *value); +int mount_currdev(struct env_var *, int, const void *); +void set_currdev(const char *devname); #endif /* !_BOOTSTRAP_H_ */ diff --git a/stand/common/commands.c b/stand/common/commands.c index 0d21ed44c681..19452047a0ca 100644 --- a/stand/common/commands.c +++ b/stand/common/commands.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> @@ -123,7 +120,6 @@ help_emitsummary(char *topic, char *subtopic, char *desc) return (pager_output("\n")); } - static int command_help(int argc, char *argv[]) { @@ -132,7 +128,8 @@ command_help(int argc, char *argv[]) char *topic, *subtopic, *t, *s, *d; /* page the help text from our load path */ - snprintf(buf, sizeof(buf), "%s/boot/loader.help", getenv("loaddev")); + snprintf(buf, sizeof(buf), "%s/boot/%s", getenv("loaddev"), + HELP_FILENAME); if ((hfd = open(buf, O_RDONLY)) < 0) { printf("Verbose help not available, " "use '?' to list commands\n"); @@ -232,7 +229,7 @@ command_commandlist(int argc __unused, char *argv[] __unused) { struct bootblk_command **cmdp; int res; - char name[20]; + char name[23]; res = 0; pager_open(); @@ -241,9 +238,10 @@ command_commandlist(int argc __unused, char *argv[] __unused) if (res) break; if ((*cmdp)->c_name != NULL && (*cmdp)->c_desc != NULL) { - snprintf(name, sizeof(name), " %-15s ", + snprintf(name, sizeof(name), " %-20s", (*cmdp)->c_name); pager_output(name); + pager_output(" "); pager_output((*cmdp)->c_desc); res = pager_output("\n"); } @@ -293,6 +291,63 @@ command_show(int argc, char *argv[]) return (CMD_OK); } +#ifdef LOADER_VERIEXEC +static int +is_restricted_var(const char *var) +{ + /* + * We impose restrictions if input is not verified + * allowing for exceptions. + * These entries should include the '=' + */ + const char *allowed[] = { + "boot_function=", + "boot_phase=", + "boot_recover_cli=", + "boot_recover_volume=", + "boot_safe=", + "boot_set=", + "boot_single=", + "boot_verbose=", + NULL, + }; + const char *restricted[] = { + "boot", + "init", + "loader.ve.", + "rootfs", + "secur", + "vfs.", + NULL, + }; + const char **cp; + int ok = -1; + +#ifdef LOADER_VERIEXEC_TESTING + printf("Checking: %s\n", var); +#endif + for (cp = restricted; *cp; cp++) { + if (strncmp(var, *cp, strlen(*cp)) == 0) { + ok = 0; + break; + } + } + if (!ok) { + /* + * Check for exceptions. + * These should match up to '='. + */ + for (cp = allowed; *cp; cp++) { + if (strncmp(var, *cp, strlen(*cp)) == 0) { + ok = 1; + break; + } + } + } + return (ok == 0); +} +#endif + COMMAND_SET(set, "set", "set a variable", command_set); static int @@ -305,32 +360,14 @@ command_set(int argc, char *argv[]) return (CMD_ERROR); } else { #ifdef LOADER_VERIEXEC - /* - * Impose restrictions if input is not verified - */ - const char *restricted[] = { - "boot", - "init", - "loader.ve.", - "rootfs", - "secur", - "vfs.", - NULL, - }; - const char **cp; int ves; ves = ve_status_get(-1); if (ves == VE_UNVERIFIED_OK) { -#ifdef LOADER_VERIEXEC_TESTING - printf("Checking: %s\n", argv[1]); -#endif - for (cp = restricted; *cp; cp++) { - if (strncmp(argv[1], *cp, strlen(*cp)) == 0) { - printf("Ignoring restricted variable: %s\n", - argv[1]); - return (CMD_OK); - } + if (is_restricted_var(argv[1])) { + printf("Ignoring restricted variable: %s\n", + argv[1]); + return (CMD_OK); } } #endif @@ -353,6 +390,18 @@ command_unset(int argc, char *argv[]) command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } else { +#ifdef LOADER_VERIEXEC + int ves; + + ves = ve_status_get(-1); + if (ves == VE_UNVERIFIED_OK) { + if (is_restricted_var(argv[1])) { + printf("Ignoring restricted variable: %s\n", + argv[1]); + return (CMD_OK); + } + } +#endif if ((err = unsetenv(argv[1])) != 0) { command_errmsg = strerror(err); return (CMD_ERROR); @@ -576,3 +625,12 @@ command_readtest(int argc, char *argv[]) } COMMAND_SET(readtest, "readtest", "Time a file read", command_readtest); + +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return (CMD_OK); +} + +COMMAND_SET(quit, "quit", "exit the loader", command_quit); diff --git a/stand/common/console.c b/stand/common/console.c index 0e8afb477ee8..65ab7ffad622 100644 --- a/stand/common/console.c +++ b/stand/common/console.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <stand.h> #include <string.h> @@ -47,6 +44,8 @@ static int twiddle_set(struct env_var *ev, int flags, const void *value); #endif int module_verbose = MODULE_VERBOSE; +static uint32_t print_delay_usec = 0; + static int module_verbose_set(struct env_var *ev, int flags, const void *value) { @@ -69,6 +68,23 @@ module_verbose_set(struct env_var *ev, int flags, const void *value) } /* + * Hook to set the print delay + */ +int +setprint_delay(struct env_var *ev, int flags, const void *value) +{ + char *end; + int usec = strtol(value, &end, 10); + + if (*(char *)value == '\0' || *end != '\0') + return (EINVAL); + if (usec < 0) + return (EINVAL); + print_delay_usec = usec; + return (0); +} + +/* * Detect possible console(s) to use. If preferred console(s) have been * specified, mark them as active. Else, mark the first probed console * as active. Also create the console variable. @@ -181,6 +197,10 @@ putchar(int c) (C_PRESENTOUT | C_ACTIVEOUT)) consoles[cons]->c_out(c); } + + /* Pause after printing newline character if a print delay is set */ + if (print_delay_usec != 0 && c == '\n') + delay(print_delay_usec); } /* @@ -238,7 +258,7 @@ cons_check(const char *string) if (*curpos != '\0') { cons = cons_find(curpos); if (cons == -1) { - printf("console %s is invalid!\n", curpos); + printf("console %s is unavailable\n", curpos); failed++; } else { found++; @@ -251,7 +271,7 @@ cons_check(const char *string) if (found == 0) printf("no valid consoles!\n"); - if (found == 0 || failed != 0) { + if (found == 0 && failed != 0) { printf("Available consoles:\n"); for (cons = 0; consoles[cons] != NULL; cons++) printf(" %s\n", consoles[cons]->c_name); diff --git a/stand/common/dev_net.c b/stand/common/dev_net.c index 70b571047d56..d1c48d40691a 100644 --- a/stand/common/dev_net.c +++ b/stand/common/dev_net.c @@ -29,9 +29,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /*- * This module implements a "raw device" interface suitable for * use by the stand-alone I/O library NFS code. This interface @@ -50,9 +47,10 @@ __FBSDID("$FreeBSD$"); * for use by the NFS open code (NFS/lookup). */ -#include <machine/stdarg.h> #include <sys/param.h> #include <sys/socket.h> +#include <sys/stdarg.h> + #include <net/if.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -68,8 +66,8 @@ __FBSDID("$FreeBSD$"); #include "dev_net.h" #include "bootstrap.h" -#ifdef NETIF_DEBUG -int debug = 0; +#ifndef NETPROTO_DEFAULT +# define NETPROTO_DEFAULT NET_NFS #endif static char *netdev_name; @@ -86,15 +84,15 @@ static int net_print(int); static int net_getparams(int sock); struct devsw netdev = { - "net", - DEVT_NET, - net_init, - net_strategy, - net_open, - net_close, - noioctl, - net_print, - net_cleanup + .dv_name = "net", + .dv_type = DEVT_NET, + .dv_init = net_init, + .dv_strategy = net_strategy, + .dv_open = net_open, + .dv_close = net_close, + .dv_ioctl = noioctl, + .dv_print = net_print, + .dv_cleanup = net_cleanup, }; static struct uri_scheme { @@ -145,11 +143,8 @@ net_open(struct open_file *f, ...) return (ENXIO); } netdev_name = strdup(devname); -#ifdef NETIF_DEBUG - if (debug) - printf("%s: netif_open() succeeded\n", - __func__); -#endif + DEBUG_PRINTF(1,("%s: netif_open() succeeded %#x\n", + __func__, rootip.s_addr)); } /* * If network params were not set by netif_open(), try to get @@ -191,6 +186,7 @@ net_open(struct open_file *f, ...) setenv("boot.netif.mtu", mtu, 1); } + DEBUG_PRINTF(1,("%s: netproto=%d\n", __func__, netproto)); } netdev_opens++; dev->d_opendata = &netdev_sock; @@ -202,10 +198,7 @@ net_close(struct open_file *f) { struct devdesc *dev; -#ifdef NETIF_DEBUG - if (debug) - printf("%s: opens=%d\n", __func__, netdev_opens); -#endif + DEBUG_PRINTF(2,("%s: opens=%d\n", __func__, netdev_opens)); dev = f->f_devdata; dev->d_opendata = NULL; @@ -218,10 +211,7 @@ net_cleanup(void) { if (netdev_sock >= 0) { -#ifdef NETIF_DEBUG - if (debug) - printf("%s: calling netif_close()\n", __func__); -#endif + DEBUG_PRINTF(1,("%s: calling netif_close()\n", __func__)); rootip.s_addr = 0; free(netdev_name); netif_close(netdev_sock); @@ -273,10 +263,7 @@ net_getparams(int sock) bootp(sock); if (myip.s_addr != 0) goto exit; -#ifdef NETIF_DEBUG - if (debug) - printf("%s: BOOTP failed, trying RARP/RPC...\n", __func__); -#endif + DEBUG_PRINTF(1,("%s: BOOTP failed, trying RARP/RPC...\n", __func__)); #endif /* @@ -294,10 +281,7 @@ net_getparams(int sock) printf("%s: bootparam/whoami RPC failed\n", __func__); return (EIO); } -#ifdef NETIF_DEBUG - if (debug) - printf("%s: client name: %s\n", __func__, hostname); -#endif + DEBUG_PRINTF(1,("%s: client name: %s\n", __func__, hostname)); /* * Ignore the gateway from whoami (unreliable). @@ -311,16 +295,12 @@ net_getparams(int sock) } if (smask) { netmask = smask; -#ifdef NETIF_DEBUG - if (debug) - printf("%s: subnet mask: %s\n", __func__, - intoa(netmask)); -#endif + DEBUG_PRINTF(1,("%s: subnet mask: %s\n", __func__, + intoa(netmask))); } -#ifdef NETIF_DEBUG - if (gateip.s_addr && debug) - printf("%s: net gateway: %s\n", __func__, inet_ntoa(gateip)); -#endif + if (gateip.s_addr) + DEBUG_PRINTF(1,("%s: net gateway: %s\n", __func__, + inet_ntoa(gateip))); /* Get the root server and pathname. */ if (bp_getfile(sock, "root", &rootip, rootpath)) { @@ -328,15 +308,13 @@ net_getparams(int sock) return (EIO); } exit: - if ((rootaddr = net_parse_rootpath()) != INADDR_NONE) + if ((rootaddr = net_parse_rootpath()) != htonl(INADDR_NONE)) rootip.s_addr = rootaddr; -#ifdef NETIF_DEBUG - if (debug) { - printf("%s: server addr: %s\n", __func__, inet_ntoa(rootip)); - printf("%s: server path: %s\n", __func__, rootpath); - } -#endif + DEBUG_PRINTF(1,("%s: proto: %d\n", __func__, netproto)); + DEBUG_PRINTF(1,("%s: server addr: %s\n", __func__, inet_ntoa(rootip))); + DEBUG_PRINTF(1,("%s: server port: %d\n", __func__, rootport)); + DEBUG_PRINTF(1,("%s: server path: %s\n", __func__, rootpath)); return (0); } @@ -371,11 +349,17 @@ net_print(int verbose) return (ret); } +bool +is_tftp(void) +{ + return (netproto == NET_TFTP); +} + /* * Parses the rootpath if present * * The rootpath format can be in the form - * <scheme>://ip/path + * <scheme>://ip[:port]/path * <scheme>:/path * * For compatibility with previous behaviour it also accepts as an NFS scheme @@ -390,10 +374,10 @@ net_print(int verbose) uint32_t net_parse_rootpath(void) { - n_long addr = htonl(INADDR_NONE); + n_long addr = 0; size_t i; char ip[FNAME_SIZE]; - char *ptr, *val; + char *ptr, *portp, *val; netproto = NET_NONE; @@ -408,10 +392,12 @@ net_parse_rootpath(void) ptr = rootpath; /* Fallback for compatibility mode */ if (netproto == NET_NONE) { - netproto = NET_NFS; + netproto = NETPROTO_DEFAULT; (void)strsep(&ptr, ":"); if (ptr != NULL) { addr = inet_addr(rootpath); + DEBUG_PRINTF(1,("rootpath=%s addr=%#x\n", + rootpath, addr)); bcopy(ptr, rootpath, strlen(ptr) + 1); } } else { @@ -419,16 +405,21 @@ net_parse_rootpath(void) if (*ptr == '/') { /* we are in the form <scheme>://, we do expect an ip */ ptr++; - /* - * XXX when http will be there we will need to check for - * a port, but right now we do not need it yet - */ + portp = val = strchr(ptr, ':'); + if (val != NULL) { + val++; + rootport = strtol(val, NULL, 10); + } val = strchr(ptr, '/'); if (val != NULL) { + if (portp == NULL) + portp = val; snprintf(ip, sizeof(ip), "%.*s", - (int)((uintptr_t)val - (uintptr_t)ptr), + (int)(portp - ptr), ptr); addr = inet_addr(ip); + DEBUG_PRINTF(1,("ip=%s addr=%#x\n", + ip, addr)); bcopy(val, rootpath, strlen(val) + 1); } } else { @@ -436,6 +427,7 @@ net_parse_rootpath(void) bcopy(ptr, rootpath, strlen(ptr) + 1); } } - + if (addr == 0) + addr = htonl(INADDR_NONE); return (addr); } diff --git a/stand/common/dev_net.h b/stand/common/dev_net.h index 995b67241de8..189508854dc5 100644 --- a/stand/common/dev_net.h +++ b/stand/common/dev_net.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _BOOT_DEV_NET_H_ diff --git a/stand/common/devopen.c b/stand/common/devopen.c index 8fd2c1796555..a50334ba61e3 100644 --- a/stand/common/devopen.c +++ b/stand/common/devopen.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> @@ -63,9 +60,7 @@ devopen(struct open_file *f, const char *fname, const char **file) * pw if needed), this will attach the geli code to the open_file by * replacing f->f_dev and f_devdata with pointers to a geli_devdesc. */ - if (f->f_dev->dv_type == DEVT_DISK) { - geli_probe_and_attach(f); - } + geli_probe_and_attach(f); #endif return (0); diff --git a/stand/common/disk.c b/stand/common/disk.c index 733b7b0d57e7..c1650f0fa1ec 100644 --- a/stand/common/disk.c +++ b/stand/common/disk.c @@ -25,15 +25,13 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/disk.h> #include <sys/queue.h> #include <stand.h> #include <stdarg.h> #include <bootstrap.h> #include <part.h> +#include <assert.h> #include "disk.h" @@ -385,12 +383,14 @@ disk_close(struct disk_devdesc *dev) return (0); } -char* -disk_fmtdev(struct disk_devdesc *dev) +char * +disk_fmtdev(struct devdesc *vdev) { + struct disk_devdesc *dev = (struct disk_devdesc *)vdev; static char buf[128]; char *cp; + assert(vdev->d_dev->dv_type == DEVT_DISK); cp = buf + sprintf(buf, "%s%d", dev->dd.d_dev->dv_name, dev->dd.d_unit); if (dev->d_slice > D_SLICENONE) { #ifdef LOADER_GPT_SUPPORT @@ -410,13 +410,14 @@ disk_fmtdev(struct disk_devdesc *dev) } int -disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path) +disk_parsedev(struct devdesc **idev, const char *devspec, const char **path) { int unit, slice, partition; const char *np; char *cp; + struct disk_devdesc *dev; - np = devspec; + np = devspec + 4; /* Skip the leading 'disk' */ unit = -1; /* * If there is path/file info after the device info, then any missing @@ -467,9 +468,13 @@ disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path) if (*cp != '\0' && *cp != ':') return (EINVAL); + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return (ENOMEM); dev->dd.d_unit = unit; dev->d_slice = slice; dev->d_partition = partition; + *idev = &dev->dd; if (path != NULL) *path = (*cp == '\0') ? cp: cp + 1; return (0); diff --git a/stand/common/disk.h b/stand/common/disk.h index 83109981e0a8..fa47ceaed6bd 100644 --- a/stand/common/disk.h +++ b/stand/common/disk.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -97,11 +95,6 @@ struct disk_devdesc { uint64_t d_offset; }; -enum disk_ioctl { - IOCTL_GET_BLOCKS, - IOCTL_GET_BLOCK_SIZE -}; - /* * Parse disk metadata and initialise dev->d_offset. */ @@ -116,7 +109,8 @@ extern int ptblread(void *, void *, size_t, uint64_t); * Print information about slices on a disk. */ extern int disk_print(struct disk_devdesc *, char *, int); -extern char* disk_fmtdev(struct disk_devdesc *); -extern int disk_parsedev(struct disk_devdesc *, const char *, const char **); +extern int disk_parsedev(struct devdesc **, const char *, const char **); + +char *disk_fmtdev(struct devdesc *vdev); #endif /* _DISK_H */ diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c index b80e9c565944..659bf8540422 100644 --- a/stand/common/gfx_fb.c +++ b/stand/common/gfx_fb.c @@ -25,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -84,12 +82,14 @@ * from VGA colors to console colors, while we are reading RGB data. */ -#include <sys/cdefs.h> #include <sys/param.h> #include <stand.h> #include <teken.h> #include <gfx_fb.h> #include <sys/font.h> +#include <sys/splash.h> +#include <sys/linker.h> +#include <sys/module.h> #include <sys/stdint.h> #include <sys/endian.h> #include <pnglite.h> @@ -102,6 +102,8 @@ #include <vbe.h> #endif +#include "modinfo.h" + /* VGA text mode does use bold font. */ #if !defined(VGA_8X16_FONT) #define VGA_8X16_FONT "/boot/fonts/8x16b.fnt" @@ -159,6 +161,14 @@ static const int vga_to_cons_colors[NCOLORS] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +/* + * It is reported very slow console draw in some systems. + * in order to exclude buggy gop->Blt(), we want option + * to use direct draw to framebuffer and avoid gop->Blt. + * Can be toggled with "gop" command. + */ +bool ignore_gop_blt = false; + struct text_pixel *screen_buffer; #if defined(EFI) static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GlyphBuffer; @@ -182,6 +192,7 @@ gfx_framework_init(void) * Setup font list to have builtin font. */ (void) insert_font(NULL, FONT_BUILTIN); + gfx_interp_ref(); /* Draw in the gfx interpreter for this thing */ } static uint8_t * @@ -221,6 +232,69 @@ gfx_parse_mode_str(char *str, int *x, int *y, int *depth) return (true); } +/* + * Returns true if we set the color from pre-existing environment, false if + * just used existing defaults. + */ +static bool +gfx_fb_evalcolor(const char *envname, teken_color_t *cattr, + ev_sethook_t sethook, ev_unsethook_t unsethook) +{ + const char *ptr; + char env[10]; + int eflags = EV_VOLATILE | EV_NOKENV; + bool from_env = false; + + ptr = getenv(envname); + if (ptr != NULL) { + *cattr = strtol(ptr, NULL, 10); + + /* + * If we can't unset the value, then it's probably hooked + * properly and we can just carry on. Otherwise, we want to + * reinitialize it so that we can hook it for the console that + * we're resetting defaults for. + */ + if (unsetenv(envname) != 0) + return (true); + from_env = true; + + /* + * If we're carrying over an existing value, we *do* want that + * to propagate to the kenv. + */ + eflags &= ~EV_NOKENV; + } + + snprintf(env, sizeof(env), "%d", *cattr); + env_setenv(envname, eflags, env, sethook, unsethook); + + return (from_env); +} + +void +gfx_fb_setcolors(teken_attr_t *attr, ev_sethook_t sethook, + ev_unsethook_t unsethook) +{ + const char *ptr; + bool need_setattr = false; + + /* + * On first run, we setup an environment hook to process any color + * changes. If the env is already set, we pick up fg and bg color + * values from the environment. + */ + if (gfx_fb_evalcolor("teken.fg_color", &attr->ta_fgcolor, + sethook, unsethook)) + need_setattr = true; + if (gfx_fb_evalcolor("teken.bg_color", &attr->ta_bgcolor, + sethook, unsethook)) + need_setattr = true; + + if (need_setattr) + teken_set_defattr(&gfx_state.tg_teken, attr); +} + static uint32_t rgb_color_map(uint8_t index, uint32_t rmax, int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset) @@ -792,7 +866,7 @@ gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation, * done as they are provided by protocols that disappear when exit * boot services. */ - if (gop != NULL && boot_services_active) { + if (!ignore_gop_blt && gop != NULL && boot_services_active) { tpl = BS->RaiseTPL(TPL_NOTIFY); switch (BltOperation) { case GfxFbBltVideoFill: @@ -990,6 +1064,8 @@ gfx_fb_fill(void *arg, const teken_rect_t *r, teken_char_t c, teken_pos_t p; struct text_pixel *row; + TSENTER(); + /* remove the cursor */ if (state->tg_cursor_visible) gfx_fb_cursor_draw(state, &state->tg_cursor, false); @@ -1015,6 +1091,8 @@ gfx_fb_fill(void *arg, const teken_rect_t *r, teken_char_t c, c = teken_get_cursor(&state->tg_teken); gfx_fb_cursor_draw(state, c, true); } + + TSEXIT(); } static void @@ -1190,7 +1268,7 @@ gfx_fb_copy_line(teken_gfx_t *state, int ncol, teken_pos_t *s, teken_pos_t *d) screen_buffer[doffset + x] = screen_buffer[soffset + x]; if (mark) { /* update end point */ - sr.tr_end.tp_col = s->tp_col + x;; + sr.tr_end.tp_col = s->tp_col + x; } else { /* set up new rectangle */ mark = true; @@ -2039,7 +2117,8 @@ gfx_get_ppi(void) * not smaller than calculated size value. */ static vt_font_bitmap_data_t * -gfx_get_font(void) +gfx_get_font(teken_unit_t rows, teken_unit_t cols, teken_unit_t height, + teken_unit_t width) { unsigned ppi, size; vt_font_bitmap_data_t *font = NULL; @@ -2062,6 +2141,14 @@ gfx_get_font(void) size = roundup(size * 2, 10) / 10; STAILQ_FOREACH(fl, &fonts, font_next) { + /* + * Skip too large fonts. + */ + font = fl->font_data; + if (height / font->vfbd_height < rows || + width / font->vfbd_width < cols) + continue; + next = STAILQ_NEXT(fl, font_next); /* @@ -2069,7 +2156,6 @@ gfx_get_font(void) * we have our font. Make sure, it actually is loaded. */ if (next == NULL || next->font_data->vfbd_height < size) { - font = fl->font_data; if (font->vfbd_font == NULL || fl->font_flags == FONT_RELOAD) { if (fl->font_load != NULL && @@ -2078,6 +2164,7 @@ gfx_get_font(void) } break; } + font = NULL; } return (font); @@ -2108,7 +2195,7 @@ set_font(teken_unit_t *rows, teken_unit_t *cols, teken_unit_t h, teken_unit_t w) } if (font == NULL) - font = gfx_get_font(); + font = gfx_get_font(*rows, *cols, h, w); if (font != NULL) { *rows = height / font->vfbd_height; @@ -2920,3 +3007,133 @@ gfx_get_edid_resolution(struct vesa_edid_info *edid, edid_res_list_t *res) } return (!TAILQ_EMPTY(res)); } + +vm_offset_t +build_font_module(vm_offset_t addr) +{ + vt_font_bitmap_data_t *bd; + struct vt_font *fd; + struct preloaded_file *fp; + size_t size; + uint32_t checksum; + int i; + struct font_info fi; + struct fontlist *fl; + uint64_t fontp; + + if (STAILQ_EMPTY(&fonts)) + return (addr); + + /* We can't load first */ + if ((file_findfile(NULL, NULL)) == NULL) { + printf("Can not load font module: %s\n", + "the kernel is not loaded"); + return (addr); + } + + /* helper pointers */ + bd = NULL; + STAILQ_FOREACH(fl, &fonts, font_next) { + if (gfx_state.tg_font.vf_width == fl->font_data->vfbd_width && + gfx_state.tg_font.vf_height == fl->font_data->vfbd_height) { + /* + * Kernel does have better built in font. + */ + if (fl->font_flags == FONT_BUILTIN) + return (addr); + + bd = fl->font_data; + break; + } + } + if (bd == NULL) + return (addr); + fd = bd->vfbd_font; + + fi.fi_width = fd->vf_width; + checksum = fi.fi_width; + fi.fi_height = fd->vf_height; + checksum += fi.fi_height; + fi.fi_bitmap_size = bd->vfbd_uncompressed_size; + checksum += fi.fi_bitmap_size; + + size = roundup2(sizeof (struct font_info), 8); + for (i = 0; i < VFNT_MAPS; i++) { + fi.fi_map_count[i] = fd->vf_map_count[i]; + checksum += fi.fi_map_count[i]; + size += fd->vf_map_count[i] * sizeof (struct vfnt_map); + size += roundup2(size, 8); + } + size += bd->vfbd_uncompressed_size; + + fi.fi_checksum = -checksum; + + fp = file_findfile(NULL, md_kerntype); + if (fp == NULL) + panic("can't find kernel file"); + + fontp = addr; + addr += archsw.arch_copyin(&fi, addr, sizeof (struct font_info)); + addr = roundup2(addr, 8); + + /* Copy maps. */ + for (i = 0; i < VFNT_MAPS; i++) { + if (fd->vf_map_count[i] != 0) { + addr += archsw.arch_copyin(fd->vf_map[i], addr, + fd->vf_map_count[i] * sizeof (struct vfnt_map)); + addr = roundup2(addr, 8); + } + } + + /* Copy the bitmap. */ + addr += archsw.arch_copyin(fd->vf_bytes, addr, fi.fi_bitmap_size); + + /* Looks OK so far; populate control structure */ + file_addmetadata(fp, MODINFOMD_FONT, sizeof(fontp), &fontp); + return (addr); +} + +vm_offset_t +build_splash_module(vm_offset_t addr) +{ + struct preloaded_file *fp; + struct splash_info si; + const char *splash; + png_t png; + uint64_t splashp; + int error; + + /* We can't load first */ + if ((file_findfile(NULL, NULL)) == NULL) { + printf("Can not load splash module: %s\n", + "the kernel is not loaded"); + return (addr); + } + + fp = file_findfile(NULL, md_kerntype); + if (fp == NULL) + panic("can't find kernel file"); + + splash = getenv("splash"); + if (splash == NULL) + return (addr); + + /* Parse png */ + if ((error = png_open(&png, splash)) != PNG_NO_ERROR) { + return (addr); + } + + si.si_width = png.width; + si.si_height = png.height; + si.si_depth = png.bpp; + splashp = addr; + addr += archsw.arch_copyin(&si, addr, sizeof (struct splash_info)); + addr = roundup2(addr, 8); + + /* Copy the bitmap. */ + addr += archsw.arch_copyin(png.image, addr, png.png_datalen); + + printf("Loading splash ok\n"); + file_addmetadata(fp, MODINFOMD_SPLASH, sizeof(splashp), &splashp); + return (addr); +} diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h index f5747e065daf..d12bcd76b7fa 100644 --- a/stand/common/gfx_fb.h +++ b/stand/common/gfx_fb.h @@ -24,8 +24,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _GFX_FB_H @@ -279,10 +277,13 @@ void gfx_fb_bezier(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, int gfx_fb_putimage(png_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); bool gfx_parse_mode_str(char *, int *, int *, int *); +void gfx_fb_setcolors(teken_attr_t *, ev_sethook_t, ev_unsethook_t); void term_image_display(teken_gfx_t *, const teken_rect_t *); void reset_font_flags(void); +void gfx_interp_ref(void); + #ifdef __cplusplus } #endif diff --git a/stand/common/gfx_fb_stub.c b/stand/common/gfx_fb_stub.c deleted file mode 100644 index e212bd2daa12..000000000000 --- a/stand/common/gfx_fb_stub.c +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * Copyright 2021 Toomas Soome <tsoome@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Generic gfx stubs. - */ - -#include <sys/types.h> -#include <pnglite.h> -#include "bootstrap.h" -#include "gfx_fb.h" - -font_list_t fonts = STAILQ_HEAD_INITIALIZER(fonts); -teken_gfx_t gfx_state = { 0 }; - -void -gfx_fb_setpixel(uint32_t x __unused, uint32_t y __unused) -{ -} - -void -gfx_fb_drawrect(uint32_t x1 __unused, uint32_t y1 __unused, - uint32_t x2 __unused, uint32_t y2 __unused, uint32_t fill __unused) -{ -} - -void -gfx_term_drawrect(uint32_t x1 __unused, uint32_t y1 __unused, - uint32_t x2 __unused, uint32_t y2 __unused) -{ -} - -void -gfx_fb_line(uint32_t x0 __unused, uint32_t y0 __unused, - uint32_t x1 __unused, uint32_t y1 __unused, uint32_t w __unused) -{ -} - -void -gfx_fb_bezier(uint32_t x0 __unused, uint32_t y0 __unused, - uint32_t x1 __unused, uint32_t y1 __unused, uint32_t x2 __unused, - uint32_t y2 __unused, uint32_t w __unused) -{ -} - -int -gfx_fb_putimage(png_t *png __unused, uint32_t ux1 __unused, - uint32_t uy1 __unused, uint32_t ux2 __unused, uint32_t uy2 __unused, - uint32_t flags __unused) -{ - return (1); -} diff --git a/stand/common/install.c b/stand/common/install.c index ea6eaaa7cebc..d07c4c6fc620 100644 --- a/stand/common/install.c +++ b/stand/common/install.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/socket.h> #include <net/if.h> @@ -140,7 +137,9 @@ read_metatags(int fd) } *p++ = '\0'; - if (strcmp(tag, "KERNEL") == 0) + if (strncmp(tag, "ENV_", 4) == 0) + setenv(&tag[4], val, 1); + else if (strcmp(tag, "KERNEL") == 0) error = setpath(&inst_kernel, val); else if (strcmp(tag, "MODULES") == 0) error = setmultipath(&inst_modules, val); @@ -215,6 +214,7 @@ install(char *pkgname) if (i == 4 && !strncasecmp(pkgname, "tftp", i)) { devname = "net0"; devnamelen = 4; + netproto = NET_TFTP; proto = &tftp_fsops; } else if (i == 4 && !strncasecmp(pkgname, "file", i)) { currdev = getenv("currdev"); diff --git a/stand/common/interp.c b/stand/common/interp.c index ab68694d61b7..e1fa4f9582ac 100644 --- a/stand/common/interp.c +++ b/stand/common/interp.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Simple commandline interpreter, toplevel and misc. * @@ -37,8 +34,14 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include "bootstrap.h" +#ifdef LOADER_VERIEXEC +#include <verify_file.h> +#endif + #define MAXARGS 20 /* maximum number of arguments allowed */ +const char * volatile interp_identifier; + /* * Interactive mode */ @@ -46,7 +49,6 @@ void interact(void) { static char input[256]; /* big enough? */ - const char * volatile interp_identifier; TSENTER(); @@ -58,6 +60,7 @@ interact(void) * we need to switch interpreters. */ interp_identifier = bootprog_interp; + interp_preinit(); interp_init(); printf("\n"); @@ -80,6 +83,10 @@ interact(void) input[0] = '\0'; interp_emit_prompt(); ngets(input, sizeof(input)); +#ifdef LOADER_VERIEXEC + /* some settings should be restritcted */ + ve_status_set(-1, VE_UNVERIFIED_OK); +#endif interp_run(input); } } @@ -151,6 +158,19 @@ interp_emit_prompt(void) free(pr); } +static struct bootblk_command * +interp_lookup_cmd(const char *cmd) +{ + struct bootblk_command **cmdp; + + /* search the command set for the command */ + SET_FOREACH(cmdp, Xcommand_set) { + if (((*cmdp)->c_name != NULL) && !strcmp(cmd, (*cmdp)->c_name)) + return (*cmdp); + } + return (NULL); +} + /* * Perform a builtin command */ @@ -158,27 +178,32 @@ int interp_builtin_cmd(int argc, char *argv[]) { int result; - struct bootblk_command **cmdp; - bootblk_cmd_t *cmd; + struct bootblk_command *cmd; if (argc < 1) - return(CMD_OK); + return (CMD_OK); /* set return defaults; a successful command will override these */ command_errmsg = command_errbuf; strcpy(command_errbuf, "no error message"); - cmd = NULL; result = CMD_ERROR; - /* search the command set for the command */ - SET_FOREACH(cmdp, Xcommand_set) { - if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name)) - cmd = (*cmdp)->c_fn; - } - if (cmd != NULL) { - result = (cmd)(argc, argv); + cmd = interp_lookup_cmd(argv[0]); + if (cmd != NULL && cmd->c_fn) { + TSENTER2(argv[0]); + result = cmd->c_fn(argc, argv); + TSEXIT(); } else { command_errmsg = "unknown command"; } - return(result); + return (result); +} + +/* + * Return true if the builtin command exists + */ +bool +interp_has_builtin_cmd(const char *cmd) +{ + return (interp_lookup_cmd(cmd) != NULL); } diff --git a/stand/common/interp_backslash.c b/stand/common/interp_backslash.c index c75081beca56..e1bc84c3a1a7 100644 --- a/stand/common/interp_backslash.c +++ b/stand/common/interp_backslash.c @@ -14,9 +14,6 @@ * Routine for doing backslash elimination. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include "bootstrap.h" diff --git a/stand/common/interp_forth.c b/stand/common/interp_forth.c index 19f1c75dc191..388a20e319b3 100644 --- a/stand/common/interp_forth.c +++ b/stand/common/interp_forth.c @@ -24,16 +24,12 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> /* to pick up __FreeBSD_version */ #include <string.h> #include <stand.h> #include "bootstrap.h" #include "ficl.h" -extern unsigned bootprog_rev; INTERP_DEFINE("4th"); /* #define BFORTH_DEBUG */ @@ -341,12 +337,21 @@ bf_run(const char *line) return (result); } +static bool preinit_run = false; + void -interp_init(void) +interp_preinit(void) { - + if (preinit_run) + return; setenv("script.lang", "forth", 1); bf_init(); + preinit_run = true; +} + +void +interp_init(void) +{ /* Read our default configuration. */ interp_include("/boot/loader.rc"); } diff --git a/stand/common/interp_lua.c b/stand/common/interp_lua.c index 8a420660683e..2a61bb9d04af 100644 --- a/stand/common/interp_lua.c +++ b/stand/common/interp_lua.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" @@ -99,16 +96,21 @@ static const luaL_Reg loadedlibs[] = { {NULL, NULL} }; +static bool preinit_done = false; + void -interp_init(void) +interp_preinit(void) { lua_State *luap; struct interp_lua_softc *softc = &lua_softc; - const char *filename; const luaL_Reg *lib; + lua_init_md_t **fnpp; TSENTER(); + if (preinit_done) + return; + setenv("script.lang", "lua", 1); LDBG("creating context"); @@ -125,7 +127,27 @@ interp_init(void) lua_pop(luap, 1); /* remove lib */ } - filename = LOADER_LUA; + LUA_FOREACH_SET(fnpp) + (*fnpp)(luap); + + preinit_done = true; + + TSEXIT(); +} + +void +interp_init(void) +{ + lua_State *luap; + struct interp_lua_softc *softc = &lua_softc; + const char *filename; + + TSENTER(); + + luap = softc->luap; + filename = getenv("loader_lua"); + if (filename == NULL) + filename = LOADER_LUA; if (interp_include(filename) != 0) { const char *errstr = lua_tostring(luap, -1); errstr = errstr == NULL ? "unknown" : errstr; diff --git a/stand/common/interp_parse.c b/stand/common/interp_parse.c index c46a497e240d..9efcade04b36 100644 --- a/stand/common/interp_parse.c +++ b/stand/common/interp_parse.c @@ -14,9 +14,6 @@ * The meat of the simple parser. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include "bootstrap.h" diff --git a/stand/common/interp_simple.c b/stand/common/interp_simple.c index e25743d4f01c..437739a3bcc4 100644 --- a/stand/common/interp_simple.c +++ b/stand/common/interp_simple.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Simple commandline interpreter, toplevel and misc. */ @@ -38,6 +35,11 @@ __FBSDID("$FreeBSD$"); INTERP_DEFINE("simp"); void +interp_preinit(void) +{ +} + +void interp_init(void) { @@ -200,3 +202,11 @@ interp_include(const char *filename) } return(res); } + +/* + * There's no graphics commands for the simple interpreter. + */ +void +gfx_interp_ref(void) +{ +} diff --git a/stand/common/isapnp.c b/stand/common/isapnp.c index 8a0cdfda2ace..eaf5a08cf82a 100644 --- a/stand/common/isapnp.c +++ b/stand/common/isapnp.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Machine-independent ISA PnP enumerator implementing a subset of the * ISA PnP specification. diff --git a/stand/common/isapnp.h b/stand/common/isapnp.h index a5b8f28304f7..e0bdb97dc048 100644 --- a/stand/common/isapnp.h +++ b/stand/common/isapnp.h @@ -28,8 +28,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _I386_ISA_PNP_H_ diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c index fd9985f51bf9..b9f55a21e403 100644 --- a/stand/common/load_elf.c +++ b/stand/common/load_elf.c @@ -25,22 +25,16 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/endian.h> #include <sys/exec.h> #include <sys/linker.h> #include <sys/module.h> -#include <sys/stdint.h> -#include <string.h> #include <machine/elf.h> #include <stand.h> -#define FREEBSD_ELF -#include <sys/link_elf.h> #include "bootstrap.h" +#include "modinfo.h" #define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) @@ -93,11 +87,9 @@ static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef, static symaddr_fn __elfN(symaddr); static char *fake_modname(const char *name); -const char *__elfN(kerneltype) = "elf kernel"; -const char *__elfN(moduletype) = "elf module"; - uint64_t __elfN(relocation_offset) = 0; +#ifdef __powerpc__ extern void elf_wrong_field_size(void); #define CONVERT_FIELD(b, f, e) \ switch (sizeof((b)->f)) { \ @@ -203,9 +195,24 @@ static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr) } #undef CONVERT_SWITCH #undef CONVERT_FIELD +#else +static int elf_header_convert(Elf_Ehdr *ehdr) +{ + return (0); +} + +static int elf_program_header_convert(const Elf_Ehdr *ehdr, Elf_Phdr *phdr) +{ + return (0); +} +static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr) +{ + return (0); +} +#endif -#ifdef __amd64__ +#if defined(__amd64__) || (defined(__i386__) && defined(EFI)) static bool is_kernphys_relocatable(elf_file_t ef) { @@ -372,7 +379,7 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest, /* * Check to see what sort of module we are. */ - kfp = file_findfile(NULL, __elfN(kerneltype)); + kfp = file_findfile(NULL, md_kerntype); #ifdef __powerpc__ /* * Kernels can be ET_DYN, so just assume the first loaded object is the @@ -396,6 +403,7 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest, * in the elf header (an ARM kernel can be loaded at any 2MB * boundary), so we leave dest set to the value calculated by * archsw.arch_loadaddr() and passed in to this function. + * XXX This comment is obsolete, but it still seems to work */ #ifndef __arm__ if (ehdr->e_type == ET_EXEC) @@ -423,7 +431,7 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest, err = EPERM; goto oerr; } - if (strcmp(__elfN(kerneltype), kfp->f_type)) { + if (strcmp(md_kerntype, kfp->f_type)) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); @@ -438,10 +446,7 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest, goto oerr; } - if (archsw.arch_loadaddr != NULL) - dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); - else - dest = roundup(dest, PAGE_SIZE); + dest = md_align(dest); /* * Ok, we think we should handle this. @@ -458,9 +463,9 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest, fp->f_name = strdup(filename); if (multiboot == 0) fp->f_type = strdup(ef.kernel ? - __elfN(kerneltype) : __elfN(moduletype)); + md_kerntype : md_modtype); else - fp->f_type = strdup("elf multiboot kernel"); + fp->f_type = strdup(md_kerntype_mb); if (module_verbose >= MODULE_VERBOSE_FULL) { if (ef.kernel) @@ -479,10 +484,10 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest, /* Load OK, return module pointer */ *result = (struct preloaded_file *)fp; err = 0; -#ifdef __amd64__ +#if defined(__amd64__) || (defined(__i386__) && defined(EFI)) fp->f_kernphys_relocatable = multiboot || is_kernphys_relocatable(&ef); #endif -#ifdef __i386__ +#if defined(__i386__) && !defined(EFI) fp->f_tg_kernel_support = is_tg_kernel_support(fp, &ef); #endif goto out; @@ -1246,9 +1251,8 @@ __elfN(lookup_symbol)(elf_file_t ef, const char* name, Elf_Sym *symp, strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); if (strcmp(name, strp) == 0) { free(strp); - if (sym.st_shndx != SHN_UNDEF || - (sym.st_value != 0 && - ELF_ST_TYPE(sym.st_info) == type)) { + if (sym.st_shndx != SHN_UNDEF && sym.st_value != 0 && + ELF_ST_TYPE(sym.st_info) == type) { *symp = sym; return 0; } diff --git a/stand/common/load_elf32.c b/stand/common/load_elf32.c index 0c9f460d4863..4ecdeb773228 100644 --- a/stand/common/load_elf32.c +++ b/stand/common/load_elf32.c @@ -1,7 +1,5 @@ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +/* This file is in the public domain */ #define __ELF_WORD_SIZE 32 #define _MACHINE_ELF_WANT_32BIT - #include "load_elf.c" diff --git a/stand/common/load_elf32_obj.c b/stand/common/load_elf32_obj.c index 94b089618836..d0278930f5e4 100644 --- a/stand/common/load_elf32_obj.c +++ b/stand/common/load_elf32_obj.c @@ -1,7 +1,5 @@ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +/* This file is in the public domain */ #define __ELF_WORD_SIZE 32 #define _MACHINE_ELF_WANT_32BIT - #include "load_elf_obj.c" diff --git a/stand/common/load_elf64.c b/stand/common/load_elf64.c index c29e8e3596a7..d55f139d1e6a 100644 --- a/stand/common/load_elf64.c +++ b/stand/common/load_elf64.c @@ -1,6 +1,4 @@ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +/* This file is in the public domain */ #define __ELF_WORD_SIZE 64 - #include "load_elf.c" diff --git a/stand/common/load_elf64_obj.c b/stand/common/load_elf64_obj.c index 3c9371ba0130..0f01258fa372 100644 --- a/stand/common/load_elf64_obj.c +++ b/stand/common/load_elf64_obj.c @@ -1,6 +1,4 @@ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +/* This file is in the public domain */ #define __ELF_WORD_SIZE 64 - #include "load_elf_obj.c" diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c index ed202e08b780..9e32daa53696 100644 --- a/stand/common/load_elf_obj.c +++ b/stand/common/load_elf_obj.c @@ -26,21 +26,15 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/exec.h> #include <sys/linker.h> #include <sys/module.h> -#include <stdint.h> -#include <string.h> #include <machine/elf.h> #include <stand.h> -#define FREEBSD_ELF -#include <sys/link_elf.h> #include "bootstrap.h" +#include "modinfo.h" #define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) @@ -81,9 +75,6 @@ static int __elfN(obj_parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef); static Elf_Addr __elfN(obj_symaddr)(struct elf_file *ef, Elf_Size symidx); -const char *__elfN(obj_kerneltype) = "elf kernel"; -const char *__elfN(obj_moduletype) = "elf obj module"; - /* * Attempt to load the file (file) as an ELF module. It will be stored at * (dest), and a pointer to a module structure describing the loaded object @@ -158,7 +149,7 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest, } #endif - kfp = file_findfile(NULL, __elfN(obj_kerneltype)); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadfile: can't load module before kernel\n"); @@ -166,10 +157,7 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest, goto oerr; } - if (archsw.arch_loadaddr != NULL) - dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest); - else - dest = roundup(dest, PAGE_SIZE); + dest = md_align(dest); /* * Ok, we think we should handle this. @@ -182,7 +170,7 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest, goto out; } fp->f_name = strdup(filename); - fp->f_type = strdup(__elfN(obj_moduletype)); + fp->f_type = strdup(md_modtype_obj); if (module_verbose > MODULE_VERBOSE_SILENT) printf("%s ", filename); diff --git a/stand/common/ls.c b/stand/common/ls.c index cd6b7c49ea5f..0cf57f7e281c 100644 --- a/stand/common/ls.c +++ b/stand/common/ls.c @@ -37,9 +37,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> diff --git a/stand/common/md.c b/stand/common/md.c index 5585218b3276..2c3eb5ded19b 100644 --- a/stand/common/md.c +++ b/stand/common/md.c @@ -24,14 +24,11 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/endian.h> #include <sys/queue.h> -#include <machine/stdarg.h> +#include <sys/stdarg.h> #include "bootstrap.h" @@ -66,15 +63,15 @@ static int md_close(struct open_file *); static int md_print(int); struct devsw md_dev = { - "md", - DEVT_DISK, - md_init, - md_strategy, - md_open, - md_close, - noioctl, - md_print, - NULL + .dv_name = "md", + .dv_type = DEVT_DISK, + .dv_init = md_init, + .dv_strategy = md_strategy, + .dv_open = md_open, + .dv_close = md_close, + .dv_ioctl = noioctl, + .dv_print = md_print, + .dv_cleanup = nullsys, }; static int diff --git a/stand/common/merge_help.awk b/stand/common/merge_help.awk index 1070f73f1fe9..aab8383c4c71 100644 --- a/stand/common/merge_help.awk +++ b/stand/common/merge_help.awk @@ -1,6 +1,5 @@ #!/usr/bin/awk -f # -# $FreeBSD$ # # Merge two boot loader help files for FreeBSD 3.0 # Joe Abley <jabley@patho.gen.nz> diff --git a/stand/common/metadata.c b/stand/common/metadata.c index a9c81added02..3b2ba3e4d790 100644 --- a/stand/common/metadata.c +++ b/stand/common/metadata.c @@ -26,9 +26,6 @@ * from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/linker.h> @@ -44,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <machine/metadata.h> #include "bootstrap.h" +#include "modinfo.h" #ifdef LOADER_GELI_SUPPORT #include "geliboot.h" @@ -65,136 +63,6 @@ md_getboothowto(char *kargs) } /* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -static vm_offset_t -md_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - archsw.arch_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - archsw.arch_copyin("", addr, 1); - addr++; - } - archsw.arch_copyin("", addr, 1); - addr++; - return(addr); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ - -static int align; - -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c) \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += roundup(strlen(s) + 1, align); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), align); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c);\ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += roundup(mm->md_size, align); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -md_copymodules(vm_offset_t addr, int kern64) -{ - struct preloaded_file *fp; - struct file_metadata *md; - uint64_t scratch64; - uint32_t scratch32; - int c; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - if (kern64) { - scratch64 = fp->f_addr; - MOD_ADDR(addr, scratch64, c); - scratch64 = fp->f_size; - MOD_SIZE(addr, scratch64, c); - } else { - scratch32 = fp->f_addr; -#ifdef __arm__ - scratch32 -= __elfN(relocation_offset); -#endif - MOD_ADDR(addr, scratch32, c); - MOD_SIZE(addr, fp->f_size, c); - } - for (md = fp->f_metadata; md != NULL; md = md->md_next) { - if (!(md->md_type & MODINFOMD_NOCOPY)) { - MOD_METADATA(addr, md, c); - } - } - } - MOD_END(addr, c); - return(addr); -} - -/* * Load the information expected by a kernel. * * - The 'boothowto' argument is constructed @@ -235,7 +103,6 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) }; #endif - align = kern64 ? 8 : 4; howto = md_getboothowto(args); /* @@ -244,7 +111,7 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); - if (rootdevname == NULL) + if (rootdevname == NULL || *rootdevname == '\0') rootdevname = getenv("currdev"); /* Try reading the /etc/fstab file to select the root device */ getrootmount(rootdevname); @@ -256,14 +123,14 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) addr = xp->f_addr + xp->f_size; } /* Pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); /* Copy our environment */ envp = addr; addr = md_copyenv(addr); /* Pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); #if defined(LOADER_FDT_SUPPORT) /* Copy out FDT */ @@ -274,14 +141,12 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) { size = fdt_copy(addr); fdtp = addr; - addr = roundup(addr + size, PAGE_SIZE); + addr = md_align(addr + size); } #endif kernend = 0; - kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) panic("can't find kernel file"); file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); @@ -311,7 +176,7 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) *modulep = addr; size = md_copymodules(0, kern64); - kernend = roundup(addr + size, PAGE_SIZE); + kernend = md_align(addr + size); md = file_findmetadata(kfp, MODINFOMD_KERNEND); if (kern64) { diff --git a/stand/common/misc.c b/stand/common/misc.c index 9cb5550344ca..a7c46ad2e74c 100644 --- a/stand/common/misc.c +++ b/stand/common/misc.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <string.h> #include <stand.h> #include <bootstrap.h> @@ -169,17 +166,6 @@ alloc_pread(readin_handle_t fd, off_t off, size_t len) return (buf); } -void -dev_cleanup(void) -{ - int i; - - /* Call cleanup routines */ - for (i = 0; devsw[i] != NULL; ++i) - if (devsw[i]->dv_cleanup != NULL) - (devsw[i]->dv_cleanup)(); -} - /* * mount new rootfs and unmount old, set "currdev" environment variable. */ @@ -201,3 +187,49 @@ int mount_currdev(struct env_var *ev, int flags, const void *value) } return (rv); } + +/* + * Set currdev to suit the value being supplied in (value) + */ +int +gen_setcurrdev(struct env_var *ev, int flags, const void *value) +{ + struct devdesc *ncurr; + int rv; + + if ((rv = devparse(&ncurr, value, NULL)) != 0) + return (rv); + free(ncurr); + + return (mount_currdev(ev, flags, value)); +} + +/* + * Wrapper to set currdev and loaddev at the same time. + */ +void +set_currdev(const char *devname) +{ + + env_setenv("currdev", EV_VOLATILE, devname, gen_setcurrdev, + env_nounset); + /* + * Don't execute hook here; the loaddev hook makes it immutable + * once we've determined what the proper currdev is. + */ + env_setenv("loaddev", EV_VOLATILE | EV_NOHOOK, devname, env_noset, + env_nounset); +} + +#ifndef LOADER_NET_SUPPORT +/* + * This api is normally provided by dev_net.c + * This stub keeps libsa happy when LOADER_NET_SUPPORT + * is not enabled. + */ +bool +is_tftp(void) +{ + return false; +} +#endif diff --git a/stand/common/modinfo.c b/stand/common/modinfo.c new file mode 100644 index 000000000000..1e39bd858cc2 --- /dev/null +++ b/stand/common/modinfo.c @@ -0,0 +1,220 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6 + */ +#include <stand.h> +#include <sys/param.h> +#include <sys/linker.h> +#include <sys/boot.h> +#include <sys/reboot.h> +#if defined(LOADER_FDT_SUPPORT) +#include <fdt_platform.h> +#endif + +#ifdef __arm__ +#include <machine/elf.h> +#endif +#include <machine/metadata.h> + +#include "bootstrap.h" +#include "modinfo.h" + +/* + * Copy module-related data into the load area, where it can be + * used as a directory for loaded modules. + * + * Module data is presented in a self-describing format. Each datum + * is preceded by a 32-bit identifier and a 32-bit size field. + * + * Currently, the following data are saved: + * + * MOD_NAME (variable) module name (string) + * MOD_TYPE (variable) module type (string) + * MOD_ARGS (variable) module parameters (string) + * MOD_ADDR sizeof(vm_offset_t) module load address + * MOD_SIZE sizeof(size_t) module size + * MOD_METADATA (variable) type-specific metadata + * + * Clients are required to define a MOD_ALIGN(l) macro which rounds the passed + * in length to the required alignment for the kernel being booted. + */ + +#define COPY32(v, a, c) { \ + uint32_t x = (v); \ + if (c) \ + archsw.arch_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(strlen(s) + 1, a, c) \ + if (c) \ + archsw.arch_copyin(s, a, strlen(s) + 1);\ + a += MOD_ALIGN(strlen(s) + 1); \ +} + +#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) +#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) +#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) + +#define MOD_VAR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(sizeof(s), a, c); \ + if (c) \ + archsw.arch_copyin(&s, a, sizeof(s)); \ + a += MOD_ALIGN(sizeof(s)); \ +} + +#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) +#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) + +#define MOD_METADATA(a, mm, c) { \ + COPY32(MODINFO_METADATA | mm->md_type, a, c);\ + COPY32(mm->md_size, a, c); \ + if (c) { \ + archsw.arch_copyin(mm->md_data, a, mm->md_size);\ + mm->md_addr = a; \ + } \ + a += MOD_ALIGN(mm->md_size); \ +} + +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ +} + +#define MOD_ALIGN(l) roundup(l, align) + +const char md_modtype[] = MODTYPE; +const char md_kerntype[] = KERNTYPE; +const char md_modtype_obj[] = MODTYPE_OBJ; +const char md_kerntype_mb[] = KERNTYPE_MB; + +vm_offset_t +md_copymodules(vm_offset_t addr, bool kern64) +{ + struct preloaded_file *fp; + struct file_metadata *md; + uint64_t scratch64; + uint32_t scratch32; + int c; + int align; + + align = kern64 ? sizeof(uint64_t) : sizeof(uint32_t); + c = addr != 0; + /* start with the first module on the list, should be the kernel */ + for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { + + MOD_NAME(addr, fp->f_name, c); /* this field must come first */ + MOD_TYPE(addr, fp->f_type, c); + if (fp->f_args) + MOD_ARGS(addr, fp->f_args, c); + if (kern64) { + scratch64 = fp->f_addr; + MOD_ADDR(addr, scratch64, c); + scratch64 = fp->f_size; + MOD_SIZE(addr, scratch64, c); + } else { + scratch32 = fp->f_addr; +#ifdef __arm__ + scratch32 -= __elfN(relocation_offset); +#endif + MOD_ADDR(addr, scratch32, c); + MOD_SIZE(addr, fp->f_size, c); + } + for (md = fp->f_metadata; md != NULL; md = md->md_next) { + if (!(md->md_type & MODINFOMD_NOCOPY)) { + MOD_METADATA(addr, md, c); + } + } + } + MOD_END(addr, c); + return(addr); +} + +/* + * Copy the environment into the load area starting at (addr). + * Each variable is formatted as <name>=<value>, with a single nul + * separating each variable, and a double nul terminating the environment. + */ +vm_offset_t +md_copyenv(vm_offset_t start) +{ + struct env_var *ep; + vm_offset_t addr, last; + size_t len; + + addr = last = start; + + /* Traverse the environment. */ + for (ep = environ; ep != NULL; ep = ep->ev_next) { + if ((ep->ev_flags & EV_NOKENV) != 0) + continue; + len = strlen(ep->ev_name); + if ((size_t)archsw.arch_copyin(ep->ev_name, addr, len) != len) + break; + addr += len; + if (archsw.arch_copyin("=", addr, 1) != 1) + break; + addr++; + if (ep->ev_value != NULL) { + len = strlen(ep->ev_value); + if ((size_t)archsw.arch_copyin(ep->ev_value, addr, len) != len) + break; + addr += len; + } + if (archsw.arch_copyin("", addr, 1) != 1) + break; + last = ++addr; + } + + if (archsw.arch_copyin("", last++, 1) != 1) + last = start; + return(last); +} + +/* + * Take the ending address and round it up to the currently required + * alignment. This typically is the page size, but is the larger of the compiled + * kernel page size, the loader page size, and the typical page size on the + * platform. + * + * XXX For the moment, it's just PAGE_SIZE to make the refactoring go faster, + * but needs to hook-in the replacement of arch_loadaddr. + * + * Also, we may need other logical things when dealing with different types of + * page sizes and/or masking or sizes. This works well for addr and sizes, but + * not for masks. + * + * Also, this is different than the MOD_ALIGN macro above, which is used for + * aligning elements in the metadata lists, not for whare modules can begin. + */ +vm_offset_t +md_align(vm_offset_t addr) +{ + return (roundup(addr, PAGE_SIZE)); +} diff --git a/stand/common/modinfo.h b/stand/common/modinfo.h new file mode 100644 index 000000000000..d613d8e27f1f --- /dev/null +++ b/stand/common/modinfo.h @@ -0,0 +1,21 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef COMMON_MODINFO_H +#define COMMON_MODINFO_H + +extern const char md_modtype[]; +extern const char md_kerntype[]; +extern const char md_modtype_obj[]; +extern const char md_kerntype_mb[]; + +int md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb); +int md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); + +vm_offset_t md_copymodules(vm_offset_t addr, bool kern64); +vm_offset_t md_copyenv(vm_offset_t addr); +vm_offset_t md_align(vm_offset_t addr); + +#endif /* COMMON_MODINFO_H */ diff --git a/stand/common/module.c b/stand/common/module.c index 43c04728b4fa..bc06ba01fa06 100644 --- a/stand/common/module.c +++ b/stand/common/module.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * file/module function dispatcher, support, etc. */ @@ -46,6 +43,7 @@ __FBSDID("$FreeBSD$"); #endif #include "bootstrap.h" +#include "modinfo.h" #define MDIR_REMOVED 0x0001 #define MDIR_NOHINTS 0x0002 @@ -67,7 +65,8 @@ static char *mod_searchmodule(char *name, struct mod_depend *verinfo); static char * mod_searchmodule_pnpinfo(const char *bus, const char *pnpinfo); static void file_insert_tail(struct preloaded_file *mp); static void file_remove(struct preloaded_file *fp); -struct file_metadata* metadata_next(struct file_metadata *base_mp, int type); +static void file_remove_tail(struct preloaded_file *fp); +static struct file_metadata * metadata_next(struct file_metadata *base_mp, int type); static void moduledir_readhints(struct moduledir *mdp); static void moduledir_rebuild(void); @@ -114,10 +113,14 @@ command_load(int argc, char *argv[]) char *typestr; #ifdef LOADER_VERIEXEC char *prefix, *skip; + int dflag = 0; + char *args = "dkp:s:t:"; +#else + char *args = "kt:"; #endif - int dflag, dofile, dokld, ch, error; + int dofile, dokld, ch, error; - dflag = dokld = dofile = 0; + dokld = dofile = 0; optind = 1; optreset = 1; typestr = NULL; @@ -129,11 +132,13 @@ command_load(int argc, char *argv[]) prefix = NULL; skip = NULL; #endif - while ((ch = getopt(argc, argv, "dkp:s:t:")) != -1) { + while ((ch = getopt(argc, argv, args)) != -1) { switch(ch) { +#ifdef LOADER_VERIEXEC case 'd': dflag++; break; +#endif case 'k': dokld = 1; break; @@ -450,7 +455,8 @@ command_pnpload(int argc, char *argv[]) #if defined(LOADER_FDT_SUPPORT) static void -pnpautoload_fdt_bus(const char *busname) { +pnpautoload_fdt_bus(const char *busname) +{ const char *pnpstring; const char *compatstr; char *pnpinfo = NULL; @@ -548,7 +554,7 @@ command_pnpautoload(int argc, char *argv[]) /* * File level interface, functions file_* */ -int +static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result) { static int last_file_format = 0; @@ -557,8 +563,7 @@ file_load(char *filename, vm_offset_t dest, struct preloaded_file **result) int i; TSENTER2(filename); - if (archsw.arch_loadaddr != NULL) - dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest); + dest = md_align(dest); error = EFTYPE; for (i = last_file_format, fp = NULL; @@ -636,93 +641,6 @@ file_load_dependencies(struct preloaded_file *base_file) return (error); } -vm_offset_t -build_font_module(vm_offset_t addr) -{ - vt_font_bitmap_data_t *bd; - struct vt_font *fd; - struct preloaded_file *fp; - size_t size; - uint32_t checksum; - int i; - struct font_info fi; - struct fontlist *fl; - uint64_t fontp; - - if (STAILQ_EMPTY(&fonts)) - return (addr); - - /* We can't load first */ - if ((file_findfile(NULL, NULL)) == NULL) { - printf("Can not load font module: %s\n", - "the kernel is not loaded"); - return (addr); - } - - /* helper pointers */ - bd = NULL; - STAILQ_FOREACH(fl, &fonts, font_next) { - if (gfx_state.tg_font.vf_width == fl->font_data->vfbd_width && - gfx_state.tg_font.vf_height == fl->font_data->vfbd_height) { - /* - * Kernel does have better built in font. - */ - if (fl->font_flags == FONT_BUILTIN) - return (addr); - - bd = fl->font_data; - break; - } - } - if (bd == NULL) - return (addr); - fd = bd->vfbd_font; - - fi.fi_width = fd->vf_width; - checksum = fi.fi_width; - fi.fi_height = fd->vf_height; - checksum += fi.fi_height; - fi.fi_bitmap_size = bd->vfbd_uncompressed_size; - checksum += fi.fi_bitmap_size; - - size = roundup2(sizeof (struct font_info), 8); - for (i = 0; i < VFNT_MAPS; i++) { - fi.fi_map_count[i] = fd->vf_map_count[i]; - checksum += fi.fi_map_count[i]; - size += fd->vf_map_count[i] * sizeof (struct vfnt_map); - size += roundup2(size, 8); - } - size += bd->vfbd_uncompressed_size; - - fi.fi_checksum = -checksum; - - fp = file_findfile(NULL, "elf kernel"); - if (fp == NULL) - fp = file_findfile(NULL, "elf64 kernel"); - if (fp == NULL) - panic("can't find kernel file"); - - fontp = addr; - addr += archsw.arch_copyin(&fi, addr, sizeof (struct font_info)); - addr = roundup2(addr, 8); - - /* Copy maps. */ - for (i = 0; i < VFNT_MAPS; i++) { - if (fd->vf_map_count[i] != 0) { - addr += archsw.arch_copyin(fd->vf_map[i], addr, - fd->vf_map_count[i] * sizeof (struct vfnt_map)); - addr = roundup2(addr, 8); - } - } - - /* Copy the bitmap. */ - addr += archsw.arch_copyin(fd->vf_bytes, addr, fi.fi_bitmap_size); - - /* Looks OK so far; populate control structure */ - file_addmetadata(fp, MODINFOMD_FONT, sizeof(fontp), &fontp); - return (addr); -} - #ifdef LOADER_VERIEXEC_VECTX #define VECTX_HANDLE(fd) vctx #else @@ -735,7 +653,7 @@ build_font_module(vm_offset_t addr) * no arguments or anything. */ struct preloaded_file * -file_loadraw(const char *fname, char *type, int insert) +file_loadraw(const char *fname, const char *type, int insert) { struct preloaded_file *fp; char *name; @@ -795,8 +713,7 @@ file_loadraw(const char *fname, char *type, int insert) #endif #endif - if (archsw.arch_loadaddr != NULL) - loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr); + loadaddr = md_align(loadaddr); if (module_verbose > MODULE_VERBOSE_SILENT) printf("%s ", name); @@ -960,7 +877,7 @@ mod_loadkld(const char *kldname, int argc, char *argv[]) file_insert_tail(fp); /* Add to the list of loaded files */ if (file_load_dependencies(fp) != 0) { err = ENOENT; - file_remove(fp); + file_remove_tail(fp); loadaddr = loadaddr_saved; fp = NULL; break; @@ -998,7 +915,7 @@ file_findfile(const char *name, const char *type) * Find a module matching (name) inside of given file. * NULL may be passed as a wildcard. */ -struct kernel_module * +static struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo) { @@ -1097,9 +1014,7 @@ file_addbuf(const char *name, const char *type, size_t len, void *buf) } /* Figure out where to load the data. */ - dest = loadaddr; - if (archsw.arch_loadaddr != NULL) - dest = archsw.arch_loadaddr(LOAD_RAW, (void *)name, dest); + dest = md_align(loadaddr); /* Create & populate control structure */ fp = file_alloc(); @@ -1132,7 +1047,7 @@ file_addbuf(const char *name, const char *type, size_t len, void *buf) return(0); } -struct file_metadata * +static struct file_metadata * metadata_next(struct file_metadata *md, int type) { @@ -1721,25 +1636,45 @@ file_insert_tail(struct preloaded_file *fp) * Remove module from the chain */ static void -file_remove(struct preloaded_file *fp) +file_remove_impl(struct preloaded_file *fp, bool keep_tail) { - struct preloaded_file *cm; + struct preloaded_file *cm, *next; if (preloaded_files == NULL) return; + if (keep_tail) + next = fp->f_next; + else + next = NULL; + if (preloaded_files == fp) { - preloaded_files = fp->f_next; + preloaded_files = next; return; } + for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) { if (cm->f_next == fp) { - cm->f_next = fp->f_next; + cm->f_next = next; return; } } } +static void +file_remove(struct preloaded_file *fp) +{ + + file_remove_impl(fp, true); +} + +static void +file_remove_tail(struct preloaded_file *fp) +{ + + file_remove_impl(fp, false); +} + static char * moduledir_fullpath(struct moduledir *mdp, const char *fname) { diff --git a/stand/common/newvers.sh b/stand/common/newvers.sh index 714adba6c9cb..8541d61ed76c 100755 --- a/stand/common/newvers.sh +++ b/stand/common/newvers.sh @@ -1,6 +1,5 @@ #!/bin/sh - # -# $FreeBSD$ # $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $ # # Copyright (c) 1984, 1986, 1990, 1993 @@ -29,8 +28,6 @@ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -# -# @(#)newvers.sh 8.1 (Berkeley) 4/20/94 tempfile=$(mktemp tmp.XXXXXX) || exit trap "rm -f $tempfile" EXIT INT TERM @@ -46,17 +43,28 @@ done shift $((OPTIND - 1)) LC_ALL=C; export LC_ALL -u=${USER-root} h=${HOSTNAME-`hostname`} t=`date` -#r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '` +u=${USER-root} h=${HOSTNAME-`hostname`} +if [ -n "$SOURCE_DATE_EPOCH" ]; then + if ! t=$(date -ur $SOURCE_DATE_EPOCH 2>/dev/null); then + echo "Invalid SOURCE_DATE_EPOCH" >&2 + exit 1 + fi +else + t="${NEWVERS_DATE:-`date`}" +fi r=`awk -F: ' /^[0-9]\.[0-9]+:/ { print $1; exit }' $1` bootprog_info="FreeBSD/${3} ${2}, Revision ${r}\\n" if [ -n "${include_metadata}" ]; then bootprog_info="$bootprog_info(${t} ${u}@${h})\\n" + if [ -n "$BUILD_UTC" ]; then + # We can use what(1) to extract BUILD_UTC + bootprog_info="$bootprog_info\\0@(#)BUILD_UTC=$BUILD_UTC" + fi fi cat > $tempfile <<EOF char bootprog_info[] = "$bootprog_info"; -unsigned bootprog_rev = ${r%%.*}${r##*.}; +unsigned bootprog_rev = ${r%%.*} * 1000 + ${r##*.}; EOF mv $tempfile vers.c diff --git a/stand/common/nvstore.c b/stand/common/nvstore.c index c6d230584f9d..3cdb094c858f 100644 --- a/stand/common/nvstore.c +++ b/stand/common/nvstore.c @@ -29,138 +29,12 @@ * nvstore is abstraction layer to implement data read/write to different * types of non-volatile storage. * - * User interfaces: - * Provide mapping via environment: setenv/unsetenv/putenv. Access via - * environment functions/commands is available once nvstore has - * attached the backend and stored textual data is mapped to environment. - * - * Provide command "nvstore" to create new data instances. - * - * API: TBD. - * nvstore_init(): attach new backend and create the environment mapping. - * nvstore_fini: detach backend and unmap the related environment. - * - * The disk based storage, such as UFS file or ZFS bootenv label area, is - * only accessible after root file system is set. Root file system change - * will switch the back end storage. + * Provides cli command 'nvostre' */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdbool.h> -#include <sys/queue.h> -#include <bootstrap.h> #include "stand.h" - -typedef struct nvstore { - char *nvs_name; - void *nvs_data; - nvs_callbacks_t *nvs_cb; - STAILQ_ENTRY(nvstore) nvs_next; -} nvstore_t; - -typedef STAILQ_HEAD(store_list, nvstore) nvstore_list_t; - -nvstore_list_t stores = STAILQ_HEAD_INITIALIZER(stores); - -void * -nvstore_get_store(const char *name) -{ - nvstore_t *st; - - st = NULL; - - STAILQ_FOREACH(st, &stores, nvs_next) { - if (strcmp(name, st->nvs_name) == 0) - break; - } - - return (st); -} - -int -nvstore_init(const char *name, nvs_callbacks_t *cb, void *data) -{ - nvstore_t *st; - - st = nvstore_get_store(name); - if (st != NULL) - return (EEXIST); - - if ((st = malloc(sizeof (*st))) == NULL) - return (ENOMEM); - - if ((st->nvs_name = strdup(name)) == NULL) { - free(st); - return (ENOMEM); - } - - st->nvs_data = data; - st->nvs_cb = cb; - - STAILQ_INSERT_TAIL(&stores, st, nvs_next); - return (0); -} - -int -nvstore_fini(const char *name) -{ - nvstore_t *st; - - st = nvstore_get_store(name); - if (st == NULL) - return (ENOENT); - - STAILQ_REMOVE(&stores, st, nvstore, nvs_next); - - free(st->nvs_name); - free(st->nvs_data); - free(st); - return (0); -} - -int -nvstore_print(void *ptr) -{ - nvstore_t *st = ptr; - - return (st->nvs_cb->nvs_iterate(st->nvs_data, st->nvs_cb->nvs_print)); -} - -int -nvstore_get_var(void *ptr, const char *name, void **data) -{ - nvstore_t *st = ptr; - - return (st->nvs_cb->nvs_getter(st->nvs_data, name, data)); -} - -int -nvstore_set_var(void *ptr, int type, const char *name, - void *data, size_t size) -{ - nvstore_t *st = ptr; - - return (st->nvs_cb->nvs_setter(st->nvs_data, type, name, data, size)); -} - -int -nvstore_set_var_from_string(void *ptr, const char *type, const char *name, - const char *data) -{ - nvstore_t *st = ptr; - - return (st->nvs_cb->nvs_setter_str(st->nvs_data, type, name, data)); -} - -int -nvstore_unset_var(void *ptr, const char *name) -{ - nvstore_t *st = ptr; - - return (st->nvs_cb->nvs_unset(st->nvs_data, name)); -} +#include "nvstore.h" +#include "bootstrap.h" COMMAND_SET(nvstore, "nvstore", "manage non-volatile data", command_nvstore); diff --git a/stand/common/part.c b/stand/common/part.c index 4ae38bfb7682..5f7bc2103c01 100644 --- a/stand/common/part.c +++ b/stand/common/part.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/diskmbr.h> @@ -35,7 +32,6 @@ __FBSDID("$FreeBSD$"); #include <sys/gpt.h> #include <sys/stddef.h> #include <sys/queue.h> -#include <sys/vtoc.h> #include <fs/cd9660/iso.h> @@ -70,7 +66,6 @@ struct pentry { uint8_t bsd; uint8_t mbr; uuid_t gpt; - uint16_t vtoc8; } type; STAILQ_ENTRY(pentry) entry; }; @@ -519,88 +514,6 @@ out: return (table); } -#ifdef LOADER_VTOC8_SUPPORT -static enum partition_type -vtoc8_parttype(uint16_t type) -{ - - switch (type) { - case VTOC_TAG_FREEBSD_SWAP: - return (PART_FREEBSD_SWAP); - case VTOC_TAG_FREEBSD_UFS: - return (PART_FREEBSD_UFS); - case VTOC_TAG_FREEBSD_VINUM: - return (PART_FREEBSD_VINUM); - case VTOC_TAG_FREEBSD_ZFS: - return (PART_FREEBSD_ZFS); - } - return (PART_UNKNOWN); -} - -static struct ptable * -ptable_vtoc8read(struct ptable *table, void *dev, diskread_t dread) -{ - struct pentry *entry; - struct vtoc8 *dl; - uint8_t *buf; - uint16_t sum, heads, sectors; - int i; - - if (table->sectorsize != sizeof(struct vtoc8)) - return (table); - buf = malloc(table->sectorsize); - if (buf == NULL) - return (table); - if (dread(dev, buf, 1, 0) != 0) { - DPRINTF("read failed"); - ptable_close(table); - table = NULL; - goto out; - } - dl = (struct vtoc8 *)buf; - /* Check the sum */ - for (i = sum = 0; i < sizeof(struct vtoc8); i += sizeof(sum)) - sum ^= be16dec(buf + i); - if (sum != 0) { - DPRINTF("incorrect checksum"); - goto out; - } - if (be16toh(dl->nparts) != VTOC8_NPARTS) { - DPRINTF("invalid number of entries"); - goto out; - } - sectors = be16toh(dl->nsecs); - heads = be16toh(dl->nheads); - if (sectors * heads == 0) { - DPRINTF("invalid geometry"); - goto out; - } - DPRINTF("VTOC8 detected"); - for (i = 0; i < VTOC8_NPARTS; i++) { - dl->part[i].tag = be16toh(dl->part[i].tag); - if (i == VTOC_RAW_PART || - dl->part[i].tag == VTOC_TAG_UNASSIGNED) - continue; - entry = malloc(sizeof(*entry)); - if (entry == NULL) - break; - entry->part.start = be32toh(dl->map[i].cyl) * heads * sectors; - entry->part.end = be32toh(dl->map[i].nblks) + - entry->part.start - 1; - entry->part.type = vtoc8_parttype(dl->part[i].tag); - entry->part.index = i; /* starts from zero */ - entry->type.vtoc8 = dl->part[i].tag; - STAILQ_INSERT_TAIL(&table->entries, entry, entry); - DPRINTF("new VTOC8 partition added"); - } - table->type = PTABLE_VTOC8; -out: - free(buf); - return (table); - -} -#endif /* LOADER_VTOC8_SUPPORT */ - #define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / table->sectorsize) static struct ptable * @@ -678,16 +591,6 @@ ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, } else if (table->type == PTABLE_ISO9660) goto out; -#ifdef LOADER_VTOC8_SUPPORT - if (be16dec(buf + offsetof(struct vtoc8, magic)) == VTOC_MAGIC) { - if (ptable_vtoc8read(table, dev, dread) == NULL) { - /* Read error. */ - table = NULL; - goto out; - } else if (table->type == PTABLE_VTOC8) - goto out; - } -#endif /* Check the BSD label. */ if (ptable_bsdread(table, dev, dread) == NULL) { /* Read error. */ table = NULL; @@ -929,12 +832,6 @@ ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter) sprintf(name, "p%d", entry->part.index); else #endif -#ifdef LOADER_VTOC8_SUPPORT - if (table->type == PTABLE_VTOC8) - sprintf(name, "%c", (uint8_t) 'a' + - entry->part.index); - else -#endif if (table->type == PTABLE_BSD) sprintf(name, "%c", (uint8_t) 'a' + entry->part.index); diff --git a/stand/common/part.h b/stand/common/part.h index b991ae3c381c..a38680e9573f 100644 --- a/stand/common/part.h +++ b/stand/common/part.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _PART_H_ @@ -36,7 +34,6 @@ enum ptable_type { PTABLE_BSD, PTABLE_MBR, PTABLE_GPT, - PTABLE_VTOC8, PTABLE_ISO9660 }; diff --git a/stand/common/paths.h b/stand/common/paths.h index ed30abda4903..81540b3f8c11 100644 --- a/stand/common/paths.h +++ b/stand/common/paths.h @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _PATHS_H_ diff --git a/stand/common/pnp.c b/stand/common/pnp.c index 4759c4417d19..aab84e07935d 100644 --- a/stand/common/pnp.c +++ b/stand/common/pnp.c @@ -3,9 +3,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * "Plug and Play" functionality. * diff --git a/stand/common/rbx.h b/stand/common/rbx.h index 21371a563805..98d453967a47 100644 --- a/stand/common/rbx.h +++ b/stand/common/rbx.h @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ #ifndef _RBX_H_ diff --git a/stand/common/readin.h b/stand/common/readin.h index 72e2de8f6087..919514fb2995 100644 --- a/stand/common/readin.h +++ b/stand/common/readin.h @@ -21,8 +21,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _READIN_H_ #define _READIN_H_ diff --git a/stand/common/reloc_elf.c b/stand/common/reloc_elf.c index 262091b9f6c6..e68e59a303a1 100644 --- a/stand/common/reloc_elf.c +++ b/stand/common/reloc_elf.c @@ -27,15 +27,11 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <machine/elf.h> #include <stand.h> -#define FREEBSD_ELF #include <sys/link_elf.h> #include "bootstrap.h" @@ -56,7 +52,10 @@ __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, __ELF_WORD_SIZE == 64 Elf64_Addr *where, val; Elf_Addr addend, addr; - Elf_Size rtype, symidx; + Elf_Size rtype; +#if defined(__amd64__) || defined(__i386__) + Elf_Size symidx; +#endif const Elf_Rel *rel; const Elf_Rela *rela; @@ -67,7 +66,9 @@ __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, dataaddr); addend = 0; rtype = ELF_R_TYPE(rel->r_info); +#if defined(__amd64__) || defined(__i386__) symidx = ELF_R_SYM(rel->r_info); +#endif addend = 0; break; case ELF_RELOC_RELA: @@ -76,7 +77,9 @@ __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, dataaddr); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); +#if defined(__amd64__) || defined(__i386__) symidx = ELF_R_SYM(rela->r_info); +#endif break; default: return (EINVAL); diff --git a/stand/common/reloc_elf32.c b/stand/common/reloc_elf32.c index 03d9d73bab7f..04b4969a51b3 100644 --- a/stand/common/reloc_elf32.c +++ b/stand/common/reloc_elf32.c @@ -1,6 +1,2 @@ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 32 - #include "reloc_elf.c" diff --git a/stand/common/reloc_elf64.c b/stand/common/reloc_elf64.c index c8dcf2a36b0d..1230f27741cd 100644 --- a/stand/common/reloc_elf64.c +++ b/stand/common/reloc_elf64.c @@ -1,6 +1,2 @@ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 - #include "reloc_elf.c" diff --git a/stand/common/self_reloc.c b/stand/common/self_reloc.c index aee19cd8c574..a4faeeace63f 100644 --- a/stand/common/self_reloc.c +++ b/stand/common/self_reloc.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <elf.h> #include <bootstrap.h> diff --git a/stand/common/tslog.c b/stand/common/tslog.c index 3851e760daf1..8a17b0ca110c 100644 --- a/stand/common/tslog.c +++ b/stand/common/tslog.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <stand.h> diff --git a/stand/common/vdisk.c b/stand/common/vdisk.c index 521ad498b194..067e3ca3a481 100644 --- a/stand/common/vdisk.c +++ b/stand/common/vdisk.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <stdarg.h> #include <machine/_inttypes.h> @@ -52,7 +49,9 @@ struct devsw vdisk_dev = { .dv_close = vdisk_close, .dv_ioctl = vdisk_ioctl, .dv_print = vdisk_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; typedef STAILQ_HEAD(vdisk_info_list, vdisk_info) vdisk_info_list_t; diff --git a/stand/common/zfs_cmd.c b/stand/common/zfs_cmd.c index cee5b8993210..0180d31f374b 100644 --- a/stand/common/zfs_cmd.c +++ b/stand/common/zfs_cmd.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * MD bootstrap main() and assorted miscellaneous * commands. diff --git a/stand/defaults/Makefile b/stand/defaults/Makefile index 131034dd8322..f3ee630a9c13 100644 --- a/stand/defaults/Makefile +++ b/stand/defaults/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> FILES+= loader.conf diff --git a/stand/defaults/loader.conf b/stand/defaults/loader.conf index 24a47e75c39a..036479d22285 100644 --- a/stand/defaults/loader.conf +++ b/stand/defaults/loader.conf @@ -6,7 +6,6 @@ # # All arguments must be in double quotes. # -# $FreeBSD$ ### Basic configuration options ############################ exec="echo Loading /boot/defaults/loader.conf" @@ -14,8 +13,9 @@ exec="echo Loading /boot/defaults/loader.conf" kernel="kernel" # /boot sub-directory containing kernel and modules bootfile="kernel" # Kernel name (possibly absolute path) kernel_options="" # Flags to be passed to the kernel -loader_conf_files="/boot/device.hints /boot/loader.conf /boot/loader.conf.local" +loader_conf_files="/boot/device.hints /boot/loader.conf" loader_conf_dirs="/boot/loader.conf.d" +local_loader_conf_files="/boot/loader.conf.local" nextboot_conf="/boot/nextboot.conf" verbose_loading="NO" # Set to YES for verbose loader output @@ -27,6 +27,7 @@ vesa_load="NO" # Set this to YES to load the vesa module bitmap_load="NO" # Set this to YES if you want splash screen! bitmap_name="splash.bmp" # Set this to the name of the file bitmap_type="splash_image_data" # and place it on the module_path +splash="/boot/images/freebsd-logo-rev.png" # Set boot_mute=YES to load it ### Screen saver modules ################################### # This is best done in rc.conf @@ -48,8 +49,12 @@ entropy_cache_type="boot_entropy_cache" # Required for the kernel to find # the boot-time entropy cache. This # must not change value even if the # _name above does change! -entropy_efi_seed="YES" # Set this to NO to disable loading - # entropy from the UEFI hardware random number generator API +entropy_efi_seed="YES" # Set this to NO to disable loading + # entropy from the UEFI hardware + # random number generator API +entropy_efi_seed_size="2048" # Set this to a different value to + # change the amount of entropy + # requested from EFI ### RAM Blacklist configuration ############################ ram_blacklist_load="NO" # Set this to YES to load a file @@ -90,22 +95,26 @@ audit_event_type="etc_security_audit_event" # Default is unset and disabled (no delay). #autoboot_delay="10" # Delay in seconds before autobooting, # -1 for no user interrupts, NO to disable +#print_delay="1000000" # Slow printing of loader messages, useful for + # debugging. Given in microseconds. #password="" # Prevent changes to boot options #bootlock_password="" # Prevent booting (see check-password.4th(8)) #geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments #beastie_disable="NO" # Turn the beastie boot menu on and off efi_max_resolution="1x1" # Set the max resolution for EFI loader to use: - # 480p, 720p, 1080p, 2160p/4k, 5k, or specify + # 480p, 720p, 1080p, 1440p, 2160p/4k, 5k, or # WidthxHeight (e.g. 1920x1080) #kernels="kernel kernel.old" # Kernels to display in the boot menu kernels_autodetect="YES" # Auto-detect kernel directories in /boot +#loader_gfx="YES" # Use graphical images when available #loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none -#comconsole_speed="9600" # Set the current serial console speed +#comconsole_speed="115200" # Set the current serial console speed #console="vidconsole" # A comma separated list of console(s) #currdev="disk1s1a" # Set the current device -module_path="/boot/modules;/boot/dtb;/boot/dtb/overlays" # Set the module search path -module_blacklist="drm drm2 radeonkms i915kms amdgpu" # Loader module blacklist +module_path="/boot/modules;/boot/firmware;/boot/dtb;/boot/dtb/overlays" # Set the module search path +module_blacklist="drm drm2 radeonkms i915kms amdgpu if_iwlwifi if_rtw88 if_rtw89" # Loader module blacklist +module_blacklist="${module_blacklist} nvidia nvidia-drm nvidia-modeset" #prompt="\\${interpret}" # Set the command prompt #root_disk_unit="0" # Force the root disk unit number #rootdev="disk1s1a" # Set the root filesystem @@ -177,3 +186,14 @@ module_blacklist="drm drm2 radeonkms i915kms amdgpu" # Loader module blacklist #module_before="cmd" # executes "cmd" before loading the module #module_after="cmd" # executes "cmd" after loading the module #module_error="cmd" # executes "cmd" if load fails + +### Firmware names mapping list +iwm3160fw_type="firmware" +iwm7260fw_type="firmware" +iwm7265fw_type="firmware" +iwm8265fw_type="firmware" +iwm9260fw_type="firmware" +iwm3168fw_type="firmware" +iwm7265Dfw_type="firmware" +iwm8000C_type="firmware" +iwm9000fw_type="firmware" diff --git a/stand/defaults/loader.conf.5 b/stand/defaults/loader.conf.5 index 23a65935c95a..dc1c8f7f44e0 100644 --- a/stand/defaults/loader.conf.5 +++ b/stand/defaults/loader.conf.5 @@ -21,9 +21,7 @@ .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.Dd July 31, 2021 +.Dd June 12, 2025 .Dt LOADER.CONF 5 .Os .Sh NAME @@ -118,6 +116,17 @@ option in this manner, .Va beastie_disable must be set to .Dq Li YES . +.It Ar print_delay +Add a delay in microseconds after printing each line. +Default +.Dq Li 0 . +.It Ar boot_* +See list in +.Xr loader.efi 8 +since those flags apply to all boot loaders. +.It Ar boot_verbose +Set to "yes" to get the same effect as boot -v or booting verbose from the +loader menu. .It Ar exec Immediately executes a .Xr loader 8 @@ -133,6 +142,10 @@ Space separated list of directories to process for configuration files. The lua-based loader will process files with a .Dq .conf suffix that are placed in these directories. +Files found here are processed after the ones listed in +.Va loader_conf_files +but before the ones found in +.Va local_loader_conf_files . .It Ar loader_conf_files Defines additional configuration files to be processed right after the present file. @@ -140,6 +153,45 @@ present file. should be treated as write-only. One cannot depend on any value remaining in the loader environment or carried over into the kernel environment. +.It Ar local_loader_conf_files +Space separated list of additional configuration files to be processed at last, +i.e., after +.Va loader_conf_files +and +.Va loader_conf_dirs +are processed. +.It Ar product_vars +When set, must be a space separated list of environment variable names to walk +through to guess product information. +The order matters as reading a config file override the previously defined +values. +Undefined variables are silently ignored. +.Pp +When product information can be guessed, for each product information found, +append +.Pa /boot/loader.conf.d/PRODUCT +to +.Ar loader_conf_dirs . +It can be typically used as follow: +.Bd -literal +smbios.system.planar.maker="PLANAR_MAKER" +smbios.system.planar.product="PLANAR_PRODUCT" +smbios.system.product="PRODUCT" +uboot.m_product="M_PRODUCT" +product_vars="smbios.system.planar.maker smbios.system.planar.product smbios.system.product uboot.m_product" +.Ed +.Pp +to read files found in the following directories, in that order: +.Bl -bullet -compact +.It +.Pa /boot/loader.conf.d/PLANAR_MAKER +.It +.Pa /boot/loader.conf.d/PLANAR_PRODUCT +.It +.Pa /boot/loader.conf.d/PRODUCT +.It +.Pa /boot/loader.conf.d/M_PRODUCT +.El .It Ar kernel Name of the kernel to be loaded. If no kernel name is set, no additional @@ -244,6 +296,14 @@ default settings can be ignored. The few of them which are important or useful are: .Bl -tag -width bootfile -offset indent +.It Va local_loader_conf_files +.Pq Dq /boot/loader.conf.local +Ensure +.Va loader.conf.local +can always be used to override settings from files found in +.Va loader_conf_files +and +.Va loader_conf_dirs . .It Va bitmap_load .Pq Dq NO If set to @@ -254,7 +314,7 @@ a bitmap will be loaded to be displayed on screen while booting. Name of the bitmap to be loaded. Any other name can be used. .It Va comconsole_speed -.Dq ( 9600 +.Dq ( 115200 or the value of the .Va BOOT_COMCONSOLE_SPEED variable when @@ -282,8 +342,8 @@ replacing it with character (useful for embedded products and such). .It Va screen.font Set font size for framebuffer mode. -Default font size is selected based on screen resolution, to achieve -terminal dimensions 80x24. +The default font size is selected based on screen resolution. +Note that the terminal's size may vary. .It Va screen.textmode Value .Dq 0 @@ -317,6 +377,7 @@ The following values are accepted: .It 480p Ta 640x480 .It 720p Ta 1280x720 .It 1080p Ta 1920x1080 +.It 1440p Ta 2560x1440 .It 2160p Ta 3840x2160 .It 4k Ta 3840x2160 .It 5k Ta 5120x2880 @@ -353,6 +414,16 @@ be displayed. If set to .Dq YES , the beastie boot menu will be skipped. +.It Va loader_autoboot_show Pq Dq Li YES +If set to +.Dq NO , +the autoboot menu will not be displayed +.It Va loader_gfx +If set to +.Dq NO , +the ASCII art version of the brand and logo will be used even if graphical +versions are available. +Additionally, the menu frame will be drawn with ASCII art as well. .It Va loader_logo Pq Dq Li orbbw Selects a desired logo in the beastie boot menu. Possible values are: @@ -363,6 +434,10 @@ Possible values are: .Dq Li beastie , and .Dq Li none . +.It Va loader_menu +If set to +.Dq NONE , +the menu will not be displayed .It Va loader_color If set to .Dq NO , @@ -424,13 +499,22 @@ It is not available in the default Forth-based loader. .Sh FILES .Bl -tag -width /boot/defaults/loader.conf -compact .It Pa /boot/defaults/loader.conf -default settings \(em do not change this file. +Default settings \(em do not change this file. .It Pa /boot/loader.conf -user defined settings. +User defined settings. +.It Pa /boot/loader.conf.lua +User defined settings written in lua. +.It Pa /boot/loader.conf.d/*.conf +User defined settings split in separate files. +.It Pa /boot/loader.conf.d/*.lua +User defined settings written in lua and split in separate files. .It Pa /boot/loader.conf.local -machine-specific settings for sites with a common loader.conf. +Machine-specific settings for sites with a common loader.conf. Allow to override +settings defined in other files. .El .Sh SEE ALSO +.Xr kenv 1 , +.Xr loader.conf.lua 5 , .Xr rc.conf 5 , .Xr boot 8 , .Xr cpucontrol 8 , diff --git a/stand/defs.mk b/stand/defs.mk index e9c97f7720ab..eb4133b604eb 100644 --- a/stand/defs.mk +++ b/stand/defs.mk @@ -1,16 +1,17 @@ -# $FreeBSD$ .if !defined(__BOOT_DEFS_MK__) __BOOT_DEFS_MK__=${MFILE} +FORTIFY_SOURCE= 0 + # We need to define all the MK_ options before including src.opts.mk # because it includes bsd.own.mk which needs the right MK_ values, # espeically MK_CTF. MK_CTF= no MK_SSP= no -MK_PROFILE= no MK_PIE= no +MK_ZEROREGS= no MAN= .if !defined(PIC) NO_PIC= @@ -39,7 +40,14 @@ WARNS?= 1 BOOTSRC= ${SRCTOP}/stand EFISRC= ${BOOTSRC}/efi EFIINC= ${EFISRC}/include +# For amd64, there's a bit of mixed bag. Some of the tree (i386, lib*32) is +# built 32-bit and some 64-bit (lib*, efi). Centralize all the 32-bit magic here +# and activate it when DO32 is explicitly defined to be 1. +.if ${MACHINE_ARCH} == "amd64" && ${DO32:U0} == 1 +EFIINCMD= ${EFIINC}/i386 +.else EFIINCMD= ${EFIINC}/${MACHINE} +.endif FDTSRC= ${BOOTSRC}/fdt FICLSRC= ${BOOTSRC}/ficl LDRSRC= ${BOOTSRC}/common @@ -63,6 +71,7 @@ BINDIR?= /boot # LUAPATH is where we search for and install lua scripts. LUAPATH?= /boot/lua FLUASRC?= ${SRCTOP}/libexec/flua +FLUALIB?= ${SRCTOP}/libexec/flua LIBSA= ${BOOTOBJ}/libsa/libsa.a .if ${MACHINE} == "i386" @@ -128,9 +137,6 @@ CFLAGS+= -m32 -mcpu=powerpc -mbig-endian CFLAGS+= -m32 -mcpu=powerpc -mlittle-endian .endif -# For amd64, there's a bit of mixed bag. Some of the tree (i386, lib*32) is -# build 32-bit and some 64-bit (lib*, efi). Centralize all the 32-bit magic here -# and activate it when DO32 is explicitly defined to be 1. .if ${MACHINE_ARCH} == "amd64" && ${DO32:U0} == 1 CFLAGS+= -m32 # LD_FLAGS is passed directly to ${LD}, not via ${CC}: @@ -201,6 +207,8 @@ LOADER_INTERP?=${LOADER_DEFAULT_INTERP} # Make sure we use the machine link we're about to create CFLAGS+=-I. +.include "${BOOTSRC}/veriexec.mk" + all: ${PROG} CLEANFILES+= teken_state.h @@ -252,4 +260,6 @@ ${_ILINKS}: .NOMETA ${ECHO} ${.TARGET} "->" $$path ; \ ln -fns $$path ${.TARGET} .endif # !NO_OBJ + +.-include "local.defs.mk" .endif # __BOOT_DEFS_MK__ diff --git a/stand/efi/Makefile b/stand/efi/Makefile index 94cb5bba5638..1887b9536a5b 100644 --- a/stand/efi/Makefile +++ b/stand/efi/Makefile @@ -1,10 +1,9 @@ -# $FreeBSD$ - NO_OBJ=t .include <bsd.init.mk> SUBDIR.yes+= libefi +SUBDIR.${MK_LOADER_IA32}+= libefi32 SUBDIR.${MK_FDT}+= fdt SUBDIR.yes+= .WAIT @@ -12,6 +11,7 @@ SUBDIR.yes+= boot1 gptboot SUBDIR.${MK_FORTH}+= loader_4th SUBDIR.${MK_LOADER_LUA}+= loader_lua +SUBDIR.${MK_LOADER_IA32}+= loader_ia32 SUBDIR.yes+= loader_simp .include <bsd.subdir.mk> diff --git a/stand/efi/Makefile.inc b/stand/efi/Makefile.inc index c2d803ddc1ab..6bb0af1d84f3 100644 --- a/stand/efi/Makefile.inc +++ b/stand/efi/Makefile.inc @@ -1,4 +1,4 @@ -# $FreeBSD$ +.include <src.opts.mk> # Options used when building app-specific efi components # See conf/kern.mk for the correct set of these @@ -20,15 +20,31 @@ CFLAGS+= -fPIC .endif .if ${MACHINE_CPUARCH} == "amd64" -EFI_TARGET= efi-app-x86_64 -.elif ${MACHINE_CPUARCH} == "i386" +.if ${DO32:U0} == 1 EFI_TARGET= efi-app-ia32 .else +EFI_TARGET= efi-app-x86_64 +.endif +.else EFI_TARGET= binary .endif -# Arbitrarily set the PE/COFF header timestamps to 1 Jan 2016 00:00:00 +# GNU or ELF Tool Chain objcopy is usable for building EFI objects. +# LLVM objcopy is not. Use elfcopy if we've bootstrapped it (and thus +# known to be available) or objcopy is LLVM's. +.if ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no" +EFI_OBJCOPY?= elfcopy +.else +_v!= ${OBJCOPY} --version +.if ${_v:Mllvm-objcopy*} == "" +EFI_OBJCOPY?= ${OBJCOPY} +.else +EFI_OBJCOPY?= elfcopy +.endif +.endif + +# Arbitrarily set the PE/COFF header timestamps to 1 Jan 2024 00:00:00 # for build reproducibility. -SOURCE_DATE_EPOCH?=1451606400 +SOURCE_DATE_EPOCH?=1704067200 .include "../Makefile.inc" diff --git a/stand/efi/boot1/Makefile b/stand/efi/boot1/Makefile index daedc627e5dc..e2966e813504 100644 --- a/stand/efi/boot1/Makefile +++ b/stand/efi/boot1/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> BOOT1?= boot1 @@ -13,11 +11,12 @@ CFLAGS+= -DEFI_BOOT1 # seems to matter on arm64 where wchar_t defaults to an int instead # of a short. There's no good cast to use here so just ignore the # warnings for now. -CWARNFLAGS.proto.c+= -Wno-format -CWARNFLAGS.boot1.c+= -Wno-format +CWARNFLAGS.proto.c += -Wno-format +CWARNFLAGS.boot1.c += -Wno-format +CWARNFLAGS.ufs_module.c += -Wno-format +CWARNFLAGS.zfs_module.c += -Wno-format # Disable bogus alignment issues -CWARNFLAGS.ufs_module.c += -Wno-format CWARNFLAGS.ufs_module.c += -Wno-cast-align # Disable warnings that are currently incompatible with the zfs boot code @@ -30,7 +29,7 @@ CWARNFLAGS.zfs_module.c += -Wno-unused-parameter CWARNFLAGS.zfs_module.c += -Wno-unused-function # architecture-specific loader code -SRCS+= boot1.c proto.c self_reloc.c start.S ufs_module.c devpath.c +SRCS+= boot1.c proto.c self_reloc.c start.S ufs_module.c .if ${MK_LOADER_ZFS} != "no" SRCS+= zfs_module.c CFLAGS.zfs_module.c+= -I${ZFSSRC} @@ -59,13 +58,12 @@ CFLAGS+= -DEFI_DEBUG .PATH: ${EFISRC}/loader/arch/${MACHINE} .PATH: ${EFISRC}/loader .PATH: ${LDRSRC} -.PATH: ${EFISRC}/libefi CFLAGS+= -I${LDRSRC} FILES= ${BOOT1}.efi FILESMODE_${BOOT1}.efi= ${BINMODE} -LDSCRIPT= ${EFISRC}/loader/arch/${MACHINE}/ldscript.${MACHINE} +LDSCRIPT= ${EFISRC}/loader/arch/${MACHINE}/${MACHINE}.ldscript LDFLAGS+= -Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -pie .if ${LINKER_TYPE} == "bfd" && ${LINKER_VERSION} >= 23400 LDFLAGS+= -Wl,--no-dynamic-linker @@ -74,7 +72,7 @@ LDFLAGS+= -Wl,--no-dynamic-linker .if ${MACHINE_CPUARCH} == "aarch64" CFLAGS+= -mgeneral-regs-only .endif -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +.if ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -fPIC LDFLAGS+= -Wl,-znocombreloc .endif @@ -82,22 +80,23 @@ LDFLAGS+= -Wl,-znocombreloc LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a # -# Add libsa for the runtime functions used by the compiler - for example -# __aeabi_* (arm) or __divdi3 (i386). -# as well as required string and memory functions for all platforms. +# Add libsa for the runtime functions used by the compiler as well as required +# string and memory functions for all platforms. # DPADD+= ${LIBEFI} ${LIBSA} LDADD+= ${LIBEFI} ${LIBSA} DPADD+= ${LDSCRIPT} +CLEANFILES+= ${BOOT1}.efi + ${BOOT1}.efi: ${PROG} - if ${NM} ${.ALLSRC} | grep ' U '; then \ + @if ${NM} ${.ALLSRC} | grep ' U '; then \ echo "Undefined symbols in ${.ALLSRC}"; \ exit 1; \ fi SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \ - ${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \ + ${EFI_OBJCOPY} -j .peheader -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ -j .rela.dyn -j .reloc -j .eh_frame \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} diff --git a/stand/efi/boot1/Makefile.depend b/stand/efi/boot1/Makefile.depend index ffc5430cceec..9f7ade2e75eb 100644 --- a/stand/efi/boot1/Makefile.depend +++ b/stand/efi/boot1/Makefile.depend @@ -1,13 +1,8 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - include \ - include/xlocale \ - lib/libmd \ stand/efi/libefi \ stand/libsa \ - stand/zfs \ .include <dirdeps.mk> diff --git a/stand/efi/boot1/boot1.c b/stand/efi/boot1/boot1.c index 088821ecd1f8..b93c6b425160 100644 --- a/stand/efi/boot1/boot1.c +++ b/stand/efi/boot1/boot1.c @@ -19,12 +19,11 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> +#include <sys/stdarg.h> + #include <machine/elf.h> -#include <machine/stdarg.h> + #include <stand.h> #include <efi.h> @@ -96,6 +95,26 @@ try_boot(const boot_module_t *mod, dev_info_t *dev, void *loaderbuf, size_t load buf = NULL; } + /* + * See if there's any env variables the module wants to set. If so, + * append it to any config present. + */ + if (mod->extra_env != NULL) { + const char *env = mod->extra_env(); + if (env != NULL) { + size_t newlen = cmdsize + strlen(env) + 1; + + cmd = realloc(cmd, newlen); + if (cmd == NULL) + goto errout; + if (cmdsize > 0) + strlcat(cmd, " ", newlen); + strlcat(cmd, env, newlen); + cmdsize = strlen(cmd); + free(__DECONST(char *, env)); + } + } + if ((status = BS->LoadImage(TRUE, IH, efi_devpath_last_node(dev->devpath), loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) { printf("Failed to load image provided by %s, size: %zu, (%lu)\n", diff --git a/stand/efi/boot1/boot_module.h b/stand/efi/boot1/boot_module.h index 99046fb53577..dd86249fbe3e 100644 --- a/stand/efi/boot1/boot_module.h +++ b/stand/efi/boot1/boot_module.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _BOOT_MODULE_H_ @@ -94,6 +92,9 @@ typedef struct boot_module_t /* valid devices as found by probe. */ dev_info_t *(*devices)(void); + + /* return any environment variables to pass to next stage */ + const char *(*extra_env)(void); } boot_module_t; extern const boot_module_t *boot_modules[]; diff --git a/stand/efi/boot1/proto.c b/stand/efi/boot1/proto.c index eeb3cd9568a4..f81debd168b9 100644 --- a/stand/efi/boot1/proto.c +++ b/stand/efi/boot1/proto.c @@ -19,12 +19,11 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> +#include <sys/stdarg.h> + #include <machine/elf.h> -#include <machine/stdarg.h> + #include <stand.h> #include <efi.h> diff --git a/stand/efi/boot1/proto.h b/stand/efi/boot1/proto.h index 5d80f907a5a5..435da4714f12 100644 --- a/stand/efi/boot1/proto.h +++ b/stand/efi/boot1/proto.h @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ void choice_protocol(EFI_HANDLE *handles, UINTN nhandles, EFI_DEVICE_PATH *imgpath); diff --git a/stand/efi/boot1/ufs_module.c b/stand/efi/boot1/ufs_module.c index edd7918e00b6..0bdd5c018b06 100644 --- a/stand/efi/boot1/ufs_module.c +++ b/stand/efi/boot1/ufs_module.c @@ -28,13 +28,11 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stdarg.h> #include <stdbool.h> -#include <sys/cdefs.h> + #include <sys/param.h> #include <sys/disk/bsd.h> #include <efi.h> diff --git a/stand/efi/boot1/zfs_module.c b/stand/efi/boot1/zfs_module.c index 7aaca72e30f1..16722b33f0b9 100644 --- a/stand/efi/boot1/zfs_module.c +++ b/stand/efi/boot1/zfs_module.c @@ -22,13 +22,11 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stddef.h> #include <stdarg.h> #include <stdbool.h> -#include <sys/cdefs.h> + #include <sys/param.h> #include <sys/queue.h> #include <efi.h> @@ -40,6 +38,8 @@ static dev_info_t *devices; +static char zfs_bootonce[VDEV_PAD_SIZE]; + uint64_t ldi_get_size(void *priv) { @@ -142,6 +142,7 @@ load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize) struct zfsmount zmount; dnode_phys_t dn; struct stat st; + uint64_t rootobj; int err; void *buf; @@ -160,8 +161,47 @@ load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize) return (EFI_NOT_FOUND); } - if ((err = zfs_mount_impl(spa, 0, &zmount)) != 0) { - DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err); + if (zfs_get_bootonce_spa(spa, OS_BOOTONCE, zfs_bootonce, + sizeof(zfs_bootonce)) == 0) { + /* + * If bootonce attribute is present, use it as root dataset. + * Any attempt to use it should clear the 'once' flag. Prior + * to now, we'd not be able to clear it anyway. We don't care + * if we can't find the files to boot, or if there's a problem + * with it: we've tried to use it once we're able to mount the + * ZFS dataset. + * + * Note: the attribute is prefixed with "zfs:" and suffixed + * with ":". + */ + char *dname, *end; + + if (zfs_bootonce[0] != 'z' || zfs_bootonce[1] != 'f' || + zfs_bootonce[2] != 's' || zfs_bootonce[3] != ':' || + (dname = strchr(&zfs_bootonce[4], '/')) == NULL || + (end = strrchr(&zfs_bootonce[4], ':')) == NULL) { + printf("INVALID zfs bootonce: %s\n", zfs_bootonce); + *zfs_bootonce = '\0'; + rootobj = 0; + } else { + dname += 1; + *end = '\0'; + if (zfs_lookup_dataset(spa, dname, &rootobj) != 0) { + printf("zfs bootonce dataset %s NOT FOUND\n", + dname); + *zfs_bootonce = '\0'; + rootobj = 0; + } else + printf("zfs bootonce: %s\n", zfs_bootonce); + *end = ':'; + } + } else { + *zfs_bootonce = '\0'; + rootobj = 0; + } + + if ((err = zfs_mount_impl(spa, rootobj, &zmount)) != 0) { + printf("Failed to mount pool '%s' (%d)\n", spa->spa_name, err); return (EFI_NOT_FOUND); } @@ -220,6 +260,18 @@ status(void) printf("\n"); } +static const char * +extra_env(void) +{ + char *rv = NULL; /* So we return NULL if asprintf fails */ + + if (*zfs_bootonce == '\0') + return NULL; + asprintf(&rv, "zfs-bootonce=%s", zfs_bootonce); + return (rv); +} + + static void init(void) { @@ -241,5 +293,6 @@ const boot_module_t zfs_module = .probe = probe, .load = load, .status = status, - .devices = _devices + .devices = _devices, + .extra_env = extra_env, }; diff --git a/stand/efi/fdt/Makefile b/stand/efi/fdt/Makefile index 7f69ce1b3f11..bbb380f52184 100644 --- a/stand/efi/fdt/Makefile +++ b/stand/efi/fdt/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> .PATH: ${LDRSRC} diff --git a/stand/efi/fdt/Makefile.depend b/stand/efi/fdt/Makefile.depend index 18be76b0cb6f..18537add9fe3 100644 --- a/stand/efi/fdt/Makefile.depend +++ b/stand/efi/fdt/Makefile.depend @@ -1,9 +1,7 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - include \ - include/xlocale \ + stand/libsa \ .include <dirdeps.mk> diff --git a/stand/efi/fdt/efi_fdt.c b/stand/efi/fdt/efi_fdt.c index cf3cbabee722..adf830e44182 100644 --- a/stand/efi/fdt/efi_fdt.c +++ b/stand/efi/fdt/efi_fdt.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2014 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. @@ -27,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <stand.h> #include <efi.h> diff --git a/stand/efi/gptboot/Makefile b/stand/efi/gptboot/Makefile index 2dcf8dda8f59..7d4c225bc5d4 100644 --- a/stand/efi/gptboot/Makefile +++ b/stand/efi/gptboot/Makefile @@ -1,4 +1,4 @@ -# $FreeBSD$ +.include <bsd.init.mk> # ZFS is not supported, we want debugging until this is vetted and # we don't want the gptboot.efifat thing created. diff --git a/stand/efi/gptboot/drv.h b/stand/efi/gptboot/drv.h index d7df6a10f1e4..aa58237180f0 100644 --- a/stand/efi/gptboot/drv.h +++ b/stand/efi/gptboot/drv.h @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _DRV_H_ diff --git a/stand/efi/gptboot/gptboot.efi.8 b/stand/efi/gptboot/gptboot.efi.8 index 134c5353e9f1..e520509e35e6 100644 --- a/stand/efi/gptboot/gptboot.efi.8 +++ b/stand/efi/gptboot/gptboot.efi.8 @@ -22,9 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd April 6, 2021 +.Dd April 13, 2023 .Dt GPTBOOT.EFI 8 .Os .Sh NAME @@ -274,7 +272,7 @@ gpart set -a bootonce -i 2 ada0 appeared in .Fx 13.0 .Sh AUTHORS -This manual page written by +This manual page was written by .An Warner Losh Aq imp@FreeBSD.org . It is based heavily on the .Xr gptboot 8 diff --git a/stand/efi/gptboot/proto.c b/stand/efi/gptboot/proto.c index 38ccb5023c16..a1825d9c1c15 100644 --- a/stand/efi/gptboot/proto.c +++ b/stand/efi/gptboot/proto.c @@ -23,12 +23,11 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> +#include <sys/stdarg.h> + #include <machine/elf.h> -#include <machine/stdarg.h> + #include <stand.h> #include <efi.h> diff --git a/stand/efi/include/Guid/MemoryTypeInformation.h b/stand/efi/include/Guid/MemoryTypeInformation.h index 50386b747d35..be9c4b5177a9 100644 --- a/stand/efi/include/Guid/MemoryTypeInformation.h +++ b/stand/efi/include/Guid/MemoryTypeInformation.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file This file defines: * Memory Type Information GUID for HOB and Variable. diff --git a/stand/efi/include/Guid/MtcVendor.h b/stand/efi/include/Guid/MtcVendor.h index 471e7df4d673..3aa774f55477 100644 --- a/stand/efi/include/Guid/MtcVendor.h +++ b/stand/efi/include/Guid/MtcVendor.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file GUID is for MTC variable. diff --git a/stand/efi/include/Guid/ZeroGuid.h b/stand/efi/include/Guid/ZeroGuid.h index a7502cb83534..6de8c3821f5f 100644 --- a/stand/efi/include/Guid/ZeroGuid.h +++ b/stand/efi/include/Guid/ZeroGuid.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file GUID has all zero values. diff --git a/stand/efi/include/Protocol/EdidActive.h b/stand/efi/include/Protocol/EdidActive.h index 88fc0c68ec37..1f6ff052a91c 100644 --- a/stand/efi/include/Protocol/EdidActive.h +++ b/stand/efi/include/Protocol/EdidActive.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file EDID Active Protocol from the UEFI 2.0 specification. diff --git a/stand/efi/include/Protocol/EdidDiscovered.h b/stand/efi/include/Protocol/EdidDiscovered.h index a521e90d0056..c10b6ee89a82 100644 --- a/stand/efi/include/Protocol/EdidDiscovered.h +++ b/stand/efi/include/Protocol/EdidDiscovered.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file EDID Discovered Protocol from the UEFI 2.0 specification. diff --git a/stand/efi/include/Protocol/EdidOverride.h b/stand/efi/include/Protocol/EdidOverride.h index d64d400e8c06..450c95641fce 100644 --- a/stand/efi/include/Protocol/EdidOverride.h +++ b/stand/efi/include/Protocol/EdidOverride.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file EDID Override Protocol from the UEFI 2.0 specification. diff --git a/stand/efi/include/Protocol/Http.h b/stand/efi/include/Protocol/Http.h index 54f49ab5e35c..c88cc9f78847 100644 --- a/stand/efi/include/Protocol/Http.h +++ b/stand/efi/include/Protocol/Http.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file This file defines the EFI HTTP Protocol interface. It is split into the following two main sections: diff --git a/stand/efi/include/Protocol/Ip4Config2.h b/stand/efi/include/Protocol/Ip4Config2.h index 47241d7ad7d4..41b5abaafa02 100644 --- a/stand/efi/include/Protocol/Ip4Config2.h +++ b/stand/efi/include/Protocol/Ip4Config2.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file This file provides a definition of the EFI IPv4 Configuration II Protocol. diff --git a/stand/efi/include/Protocol/ServiceBinding.h b/stand/efi/include/Protocol/ServiceBinding.h index 39602b086e5b..ac501515ac67 100644 --- a/stand/efi/include/Protocol/ServiceBinding.h +++ b/stand/efi/include/Protocol/ServiceBinding.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file UEFI Service Binding Protocol is defined in UEFI specification. diff --git a/stand/efi/include/README b/stand/efi/include/README index bf821fae7e60..126cfa752f69 100644 --- a/stand/efi/include/README +++ b/stand/efi/include/README @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- Files in this directory and subdirectories are subject to the following diff --git a/stand/efi/include/amd64/efibind.h b/stand/efi/include/amd64/efibind.h index 8cfce5bbc5f1..1c974ee39f84 100644 --- a/stand/efi/include/amd64/efibind.h +++ b/stand/efi/include/amd64/efibind.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved @@ -27,102 +26,19 @@ Revision History #pragma pack() - -#ifdef __FreeBSD__ -#include <sys/stdint.h> -#else -// -// Basic int types of various widths -// - -#if (__STDC_VERSION__ < 199901L ) - - // No ANSI C 1999/2000 stdint.h integer width declarations - - #ifdef _MSC_EXTENSIONS - - // Use Microsoft C compiler integer width declarations - - typedef unsigned __int64 uint64_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - typedef __int32 int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #else - #ifdef UNIX_LP64 - - // Use LP64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long uint64_t; - typedef long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #else - - // Assume P64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long long uint64_t; - typedef long long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #endif - #endif -#endif -#endif /* __FreeBSD__ */ - -// -// Basic EFI types of various widths -// - -#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ -#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */ - -typedef uint64_t UINT64; -typedef int64_t INT64; - -#ifndef _BASETSD_H_ - typedef uint32_t UINT32; - typedef int32_t INT32; -#endif - -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint8_t UINT8; -typedef int8_t INT8; - -#endif - -#undef VOID -#define VOID void - - -typedef int64_t INTN; -typedef uint64_t UINTN; - #ifdef EFI_NT_EMULATOR #define POST_CODE(_Data) -#else +#else #ifdef EFI_DEBUG #define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al #else #define POST_CODE(_Data) - #endif + #endif #endif #define EFIERR(a) (0x8000000000000000 | a) #define EFI_ERROR_MASK 0x8000000000000000 -#define EFIERR_OEM(a) (0xc000000000000000 | a) +#define EFIERR_OEM(a) (0xc000000000000000 | a) #define BAD_POINTER 0xFBFBFBFBFBFBFBFB @@ -156,18 +72,18 @@ typedef uint64_t UINTN; // BOOTSERVICE - prototype for implementation of a boot service interface // RUNTIMESERVICE - prototype for implementation of a runtime service interface // RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service -// RUNTIME_CODE - pragma macro for declaring runtime code +// RUNTIME_CODE - pragma macro for declaring runtime code // #ifdef __amd64__ #define EFIAPI __attribute__((ms_abi)) #endif -#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options #ifdef _MSC_EXTENSIONS - #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler #else - #define EFIAPI // Substitute expresion to force C calling convention + #define EFIAPI // Substitute expresion to force C calling convention #endif #endif @@ -184,7 +100,7 @@ typedef uint64_t UINTN; #define VOLATILE volatile -#define MEMORY_FENCE() +#define MEMORY_FENCE() #ifdef EFI_NO_INTERFACE_DECL #define EFI_FORWARD_DECLARATION(x) @@ -233,9 +149,9 @@ typedef uint64_t UINTN; #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ - (_if)->LoadInternal(type, name, NULL) + (_if)->LoadInternal(type, name, NULL) -#else // EFI_NT_EMULATOR +#else // EFI_NT_EMULATOR // // When building similar to FW, link everything together as @@ -247,7 +163,7 @@ typedef uint64_t UINTN; #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ (_if)->LoadInternal(type, name, entry) -#endif // EFI_FW_NT +#endif // EFI_FW_NT #ifdef __FreeBSD__ #define INTERFACE_DECL(x) struct x diff --git a/stand/efi/include/amd64/pe.h b/stand/efi/include/amd64/pe.h index f8033c55ac55..faf8eafde1e9 100644 --- a/stand/efi/include/amd64/pe.h +++ b/stand/efi/include/amd64/pe.h @@ -1,5 +1,4 @@ -/* $FreeBSD$ */ -/* +/* PE32+ header file */ #ifndef _PE_H @@ -8,7 +7,7 @@ #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ #define IMAGE_OS2_SIGNATURE 0x454E // NE #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE -#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 #define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED @@ -84,7 +83,7 @@ typedef struct _IMAGE_FILE_HEADER { #define IMAGE_SIZEOF_FILE_HEADER 20 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. -#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved external references). #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. @@ -130,7 +129,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER { UINT32 AddressOfEntryPoint; UINT32 BaseOfCode; UINT32 BaseOfData; - + // // NT additional fields. // diff --git a/stand/efi/include/arm/efibind.h b/stand/efi/include/arm/efibind.h index 177032adc01a..a08d26ac84c4 100644 --- a/stand/efi/include/arm/efibind.h +++ b/stand/efi/include/arm/efibind.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved. @@ -41,41 +40,6 @@ Abstract: #endif -#ifdef __FreeBSD__ -#include <sys/stdint.h> -#else -// -// Assume standard IA-32 alignment. -// BugBug: Need to check portability of long long -// -typedef unsigned long long uint64_t; -typedef long long int64_t; -typedef unsigned int uint32_t; -typedef int int32_t; -typedef unsigned short uint16_t; -typedef short int16_t; -typedef unsigned char uint8_t; -typedef signed char int8_t; -#endif - -typedef uint64_t UINT64; -typedef int64_t INT64; -typedef uint32_t UINT32; -typedef int32_t INT32; -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint8_t UINT8; -typedef int8_t INT8; - -#undef VOID -#define VOID void - -// -// Native integer size in stdint.h -// -typedef uint32_t UINTN; -typedef int32_t INTN; - #define EFIERR(a) (0x80000000 | a) #define EFI_ERROR_MASK 0x80000000 #define EFIERR_OEM(a) (0xc0000000 | a) diff --git a/stand/efi/include/arm64/efibind.h b/stand/efi/include/arm64/efibind.h index 4751e2e944a8..c81506f79334 100644 --- a/stand/efi/include/arm64/efibind.h +++ b/stand/efi/include/arm64/efibind.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved @@ -27,91 +26,15 @@ Revision History #pragma pack() - -#ifdef __FreeBSD__ -#include <sys/stdint.h> -#else -// -// Basic int types of various widths -// - -#if (__STDC_VERSION__ < 199901L ) - - // No ANSI C 1999/2000 stdint.h integer width declarations - - #ifdef _MSC_EXTENSIONS - - // Use Microsoft C compiler integer width declarations - - typedef unsigned __int64 uint64_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - typedef __int32 int32_t; - typedef unsigned __int16 uint16_t; - typedef __int16 int16_t; - typedef unsigned __int8 uint8_t; - typedef __int8 int8_t; - #else - #ifdef UNIX_LP64 - - // Use LP64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long uint64_t; - typedef long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #else - - // Assume P64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long long uint64_t; - typedef long long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #endif - #endif -#endif -#endif /* __FreeBSD__ */ - -// -// Basic EFI types of various widths -// - - -typedef uint64_t UINT64; -typedef int64_t INT64; -typedef uint32_t UINT32; -typedef int32_t INT32; -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint8_t UINT8; -typedef int8_t INT8; - - -#undef VOID -#define VOID void - - -typedef int64_t INTN; -typedef uint64_t UINTN; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BugBug: Code to debug // #define BIT63 0x8000000000000000 -#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) +#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) #define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) ) - -// + +// // Macro's with casts make this much easier to use and read. // #define PORT_TO_MEM8D(_Port) (*(UINT8 *)(PORT_TO_MEMD(_Port))) @@ -122,7 +45,7 @@ typedef uint64_t UINTN; #define EFIERR(a) (0x8000000000000000 | a) #define EFI_ERROR_MASK 0x8000000000000000 -#define EFIERR_OEM(a) (0xc000000000000000 | a) +#define EFIERR_OEM(a) (0xc000000000000000 | a) #define BAD_POINTER 0xFBFBFBFBFBFBFBFB #define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF @@ -154,14 +77,14 @@ typedef uint64_t UINTN; // BOOTSERVICE - prototype for implementation of a boot service interface // RUNTIMESERVICE - prototype for implementation of a runtime service interface // RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service -// RUNTIME_CODE - pragma macro for declaring runtime code +// RUNTIME_CODE - pragma macro for declaring runtime code // -#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options #ifdef _MSC_EXTENSIONS - #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler #else - #define EFIAPI // Substitute expresion to force C calling convention + #define EFIAPI // Substitute expresion to force C calling convention #endif #endif @@ -178,7 +101,7 @@ typedef uint64_t UINTN; // // BugBug: Need to find out if this is portable across compilers. // -void __mfa (void); +void __mfa (void); #define MEMORY_FENCE() __mfa() #ifdef EFI_NO_INTERFACE_DECL diff --git a/stand/efi/include/efi.h b/stand/efi/include/efi.h index 7e44a5b819fc..b603c3a78205 100644 --- a/stand/efi/include/efi.h +++ b/stand/efi/include/efi.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved @@ -40,6 +39,37 @@ Revision History #define EFI_FIRMWARE_MINOR_REVISION 62 #define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) +// +// Basic EFI types of various widths. +// + +#include <stdint.h> +#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ +#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */ + +typedef uint64_t UINT64; +typedef int64_t INT64; +typedef uint32_t UINT32; +typedef int32_t INT32; +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + +#ifdef __LP64__ +typedef int64_t INTN; +typedef uint64_t UINTN; +#else +typedef int32_t INTN; +typedef uint32_t UINTN; +#endif + +#endif + +#undef VOID +#define VOID void + + #include "efibind.h" #include "efidef.h" #include "efidevp.h" diff --git a/stand/efi/include/efi_driver_utils.h b/stand/efi/include/efi_driver_utils.h index 520cff128a27..9f0b6dfd638d 100644 --- a/stand/efi/include/efi_driver_utils.h +++ b/stand/efi/include/efi_driver_utils.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _EFI_DRIVER_UTILS_H_ diff --git a/stand/efi/include/efi_drivers.h b/stand/efi/include/efi_drivers.h index 8df9133f73d4..938e17b6863d 100644 --- a/stand/efi/include/efi_drivers.h +++ b/stand/efi/include/efi_drivers.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _EFI_DRIVERS_H_ diff --git a/stand/efi/include/efi_nii.h b/stand/efi/include/efi_nii.h index 561cbd46a3ea..173108c55004 100644 --- a/stand/efi/include/efi_nii.h +++ b/stand/efi/include/efi_nii.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_NII_H #define _EFI_NII_H @@ -21,7 +20,7 @@ Revision history: 2000-Feb-18 M(f)J GUID updated. Structure order changed for machine word alignment. Added StringId[4] to structure. - + 2000-Feb-14 M(f)J Genesis. --*/ diff --git a/stand/efi/include/efiapi.h b/stand/efi/include/efiapi.h index 2347a4d9cf73..6c96c6f707ad 100644 --- a/stand/efi/include/efiapi.h +++ b/stand/efi/include/efiapi.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_API_H #define _EFI_API_H diff --git a/stand/efi/include/efichar.h b/stand/efi/include/efichar.h index 49ff43b3cb20..0a40906aeedf 100644 --- a/stand/efi/include/efichar.h +++ b/stand/efi/include/efichar.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _BOOT_EFI_EFICHAR_H_ @@ -39,4 +37,12 @@ int ucs2_to_utf8(const efi_char *, char **); int utf8_to_ucs2(const char *, efi_char **, size_t *); int ucs2len(const efi_char *); +#ifdef _KERNEL +#define EFICHAR_MALLOC(sz) malloc((sz), M_TEMP, M_WAITOK | M_ZERO) +#define EFICHAR_FREE(sz) free((sz), M_TEMP) +#else +#define EFICHAR_MALLOC(sz) malloc(sz) +#define EFICHAR_FREE(sz) free(sz) +#endif + #endif /* _BOOT_EFI_EFICHAR_H_ */ diff --git a/stand/efi/include/eficon.h b/stand/efi/include/eficon.h index ba80114eb9be..3196ef4b4bf5 100644 --- a/stand/efi/include/eficon.h +++ b/stand/efi/include/eficon.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_CON_H #define _EFI_CON_H @@ -486,7 +485,7 @@ EFI_STATUS Returns: EFI_SUCCESS - The notification function was registered successfully. - EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures. + EFI_OUT_OF_RESOURCES - Unable to allocate resources for necessary data structures. EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. --*/ diff --git a/stand/efi/include/eficonsctl.h b/stand/efi/include/eficonsctl.h index 68be3d69f4fd..c7f5a137045e 100644 --- a/stand/efi/include/eficonsctl.h +++ b/stand/efi/include/eficonsctl.h @@ -29,7 +29,6 @@ * Abstract: Abstraction of a Text mode or GOP/UGA screen */ -/* $FreeBSD$ */ #ifndef _EFI_CONS_CTL_H #define _EFI_CONS_CTL_H diff --git a/stand/efi/include/efidebug.h b/stand/efi/include/efidebug.h index 5576d5f4e48c..40a3cd0d5bb2 100644 --- a/stand/efi/include/efidebug.h +++ b/stand/efi/include/efidebug.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_DEBUG_H #define _EFI_DEBUG_H @@ -33,12 +32,12 @@ extern UINTN EFIDebug; #define DBGASSERT(a) DbgAssert(__FILE__, __LINE__, #a) #define DEBUG(a) DbgPrint a - + #else #define DBGASSERT(a) #define DEBUG(a) - + #endif #if EFI_DEBUG_CLEAR_MEMORY @@ -60,7 +59,7 @@ extern UINTN EFIDebug; #define D_INFO 0x00000040 // Verbose #define D_VARIABLE 0x00000100 // Variable #define D_VAR 0x00000100 // Variable -#define D_BM 0x00000400 // Boot Manager +#define D_BM 0x00000400 // Boot Manager #define D_BLKIO 0x00001000 // BlkIo Driver #define D_BLKIO_ULTRA 0x00002000 // BlkIo Driver #define D_NET 0x00004000 // SNI Driver @@ -91,9 +90,9 @@ extern UINTN EFIDebug; #else - #define ASSERT(a) - #define ASSERT_LOCKED(l) - #define ASSERT_STRUCT(p,t) + #define ASSERT(a) + #define ASSERT_LOCKED(l) + #define ASSERT_STRUCT(p,t) #endif diff --git a/stand/efi/include/efidef.h b/stand/efi/include/efidef.h index a8f88d41df24..7a63fd185874 100644 --- a/stand/efi/include/efidef.h +++ b/stand/efi/include/efidef.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_DEF_H #define _EFI_DEF_H @@ -71,11 +70,11 @@ typedef VOID *EFI_EVENT; // A GUID // -typedef struct { +typedef struct { UINT32 Data1; UINT16 Data2; UINT16 Data3; - UINT8 Data4[8]; + UINT8 Data4[8]; } EFI_GUID; @@ -83,7 +82,7 @@ typedef struct { // Time // -typedef struct { +typedef struct { UINT16 Year; // 1998 - 20XX UINT8 Month; // 1 - 12 UINT8 Day; // 1 - 31 @@ -180,9 +179,9 @@ typedef enum { #define EFI_MEMORY_WC 0x0000000000000002 #define EFI_MEMORY_WT 0x0000000000000004 #define EFI_MEMORY_WB 0x0000000000000008 -#define EFI_MEMORY_UCE 0x0000000000000010 +#define EFI_MEMORY_UCE 0x0000000000000010 -// physical memory protection on range +// physical memory protection on range #define EFI_MEMORY_WP 0x0000000000001000 #define EFI_MEMORY_RP 0x0000000000002000 #define EFI_MEMORY_XP 0x0000000000004000 diff --git a/stand/efi/include/efidevp.h b/stand/efi/include/efidevp.h index b00b78f02c6a..5fe42a3e7e8f 100644 --- a/stand/efi/include/efidevp.h +++ b/stand/efi/include/efidevp.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _DEVPATH_H #define _DEVPATH_H @@ -151,8 +150,8 @@ typedef struct _ACPI_EXTENDED_HID_DEVICE_PATH { // bits[31:16] - binary number // Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' // -#define PNP_EISA_ID_CONST 0x41d0 -#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) #define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) #define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) @@ -161,7 +160,7 @@ typedef struct _ACPI_EXTENDED_HID_DEVICE_PATH { /* * */ -#define MESSAGING_DEVICE_PATH 0x03 +#define MESSAGING_DEVICE_PATH 0x03 #define MSG_ATAPI_DP 0x01 typedef struct _ATAPI_DEVICE_PATH { @@ -175,7 +174,7 @@ typedef struct _ATAPI_DEVICE_PATH { typedef struct _SCSI_DEVICE_PATH { EFI_DEVICE_PATH Header; UINT16 Pun; - UINT16 Lun; + UINT16 Lun; } SCSI_DEVICE_PATH; #define MSG_FIBRECHANNEL_DP 0x03 @@ -284,7 +283,7 @@ typedef struct _UART_DEVICE_PATH { #define DEVICE_PATH_MESSAGING_VT_100_PLUS \ { 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43} } - + #define DEVICE_PATH_MESSAGING_VT_UTF8 \ { 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} } @@ -394,7 +393,7 @@ typedef union { PCCARD_DEVICE_PATH PcCard; MEMMAP_DEVICE_PATH MemMap; VENDOR_DEVICE_PATH Vendor; - UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; CONTROLLER_DEVICE_PATH Controller; ACPI_HID_DEVICE_PATH Acpi; @@ -428,7 +427,7 @@ typedef union { PCCARD_DEVICE_PATH *PcCard; MEMMAP_DEVICE_PATH *MemMap; VENDOR_DEVICE_PATH *Vendor; - UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; CONTROLLER_DEVICE_PATH *Controller; ACPI_HID_DEVICE_PATH *Acpi; ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; diff --git a/stand/efi/include/efierr.h b/stand/efi/include/efierr.h index a8b655718599..2aa2622a3877 100644 --- a/stand/efi/include/efierr.h +++ b/stand/efi/include/efierr.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_ERR_H #define _EFI_ERR_H diff --git a/stand/efi/include/efifpswa.h b/stand/efi/include/efifpswa.h index 21823c5ff6f1..ed831d02e51b 100644 --- a/stand/efi/include/efifpswa.h +++ b/stand/efi/include/efifpswa.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_FPSWA_H #define _EFI_FPSWA_H diff --git a/stand/efi/include/efifs.h b/stand/efi/include/efifs.h index 76aa93d6d07f..0197449a9399 100644 --- a/stand/efi/include/efifs.h +++ b/stand/efi/include/efifs.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_FS_H #define _EFI_FS_H @@ -101,7 +100,7 @@ typedef struct _EFI_LBAL { UINT32 ArrayCount; } EFI_LBAL; -// Array size +// Array size #define EFI_LBAL_ARRAY_SIZE(lbal,offs,blks) \ (((blks) - (offs) - (lbal)->Hdr.HeaderSize) / sizeof(EFI_RL)) diff --git a/stand/efi/include/efigop.h b/stand/efi/include/efigop.h index 104fa6e44b5a..e1d4b8163401 100644 --- a/stand/efi/include/efigop.h +++ b/stand/efi/include/efigop.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved diff --git a/stand/efi/include/efigpt.h b/stand/efi/include/efigpt.h index 045d49520b40..ac90a304f762 100644 --- a/stand/efi/include/efigpt.h +++ b/stand/efi/include/efigpt.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_GPT_H #define _EFI_GPT_H /*++ diff --git a/stand/efi/include/efiip.h b/stand/efi/include/efiip.h index ce0910a1b998..839507964f75 100644 --- a/stand/efi/include/efiip.h +++ b/stand/efi/include/efiip.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_IP_H #define _EFI_IP_H diff --git a/stand/efi/include/efilib.h b/stand/efi/include/efilib.h index 903e1f0d00e5..e1920430a7d1 100644 --- a/stand/efi/include/efilib.h +++ b/stand/efi/include/efilib.h @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _LOADER_EFILIB_H @@ -85,9 +83,6 @@ efi_exit_boot_services(UINTN key) } int efi_getdev(void **vdev, const char *devspec, const char **path); -char *efi_fmtdev(void *vdev); -int efi_setcurrdev(struct env_var *ev, int flags, const void *value); - int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int); EFI_HANDLE efi_find_handle(struct devsw *, int); @@ -100,6 +95,7 @@ void efi_close_devpath(EFI_HANDLE); EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_next_instance(EFI_DEVICE_PATH *); bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); bool efi_devpath_match_node(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); bool efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); diff --git a/stand/efi/include/efinet.h b/stand/efi/include/efinet.h index 3ac58b2431ca..d8bcf9a36bcb 100644 --- a/stand/efi/include/efinet.h +++ b/stand/efi/include/efinet.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFINET_H #define _EFINET_H @@ -173,8 +172,8 @@ typedef struct { /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_START) ( IN struct _EFI_SIMPLE_NETWORK *This ); @@ -182,8 +181,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_STOP) ( IN struct _EFI_SIMPLE_NETWORK *This ); @@ -191,8 +190,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE) ( IN struct _EFI_SIMPLE_NETWORK *This, IN UINTN ExtraRxBufferSize OPTIONAL, @@ -202,8 +201,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_RESET) ( IN struct _EFI_SIMPLE_NETWORK *This, IN BOOLEAN ExtendedVerification @@ -212,8 +211,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN) ( IN struct _EFI_SIMPLE_NETWORK *This ); @@ -221,8 +220,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS) ( IN struct _EFI_SIMPLE_NETWORK *This, IN UINT32 Enable, @@ -235,8 +234,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS) ( IN struct _EFI_SIMPLE_NETWORK *This, IN BOOLEAN Reset, @@ -246,8 +245,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS) ( IN struct _EFI_SIMPLE_NETWORK *This, IN BOOLEAN Reset, @@ -258,8 +257,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC) ( IN struct _EFI_SIMPLE_NETWORK *This, IN BOOLEAN IPv6, @@ -270,8 +269,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_NVDATA) ( IN struct _EFI_SIMPLE_NETWORK *This, IN BOOLEAN ReadWrite, @@ -283,8 +282,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS) ( IN struct _EFI_SIMPLE_NETWORK *This, OUT UINT32 *InterruptStatus OPTIONAL, @@ -294,8 +293,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT) ( IN struct _EFI_SIMPLE_NETWORK *This, IN UINTN HeaderSize, @@ -309,8 +308,8 @@ EFI_STATUS /////////////////////////////////////////////////////////////////////////////// // -typedef -EFI_STATUS +typedef +EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE) ( IN struct _EFI_SIMPLE_NETWORK *This, OUT UINTN *HeaderSize OPTIONAL, diff --git a/stand/efi/include/efipart.h b/stand/efi/include/efipart.h index ef1a8709d91b..abad72440657 100644 --- a/stand/efi/include/efipart.h +++ b/stand/efi/include/efipart.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_PART_H #define _EFI_PART_H @@ -16,8 +15,8 @@ Intel Corporation. Module Name: efipart.h - -Abstract: + +Abstract: Info about disk partitions and Master Boot Records @@ -55,7 +54,7 @@ typedef struct { #define MIN_MBR_DEVICE_SIZE 0x80000 #define MBR_ERRATA_PAD 0x40000 // 128 MB -#define MAX_MBR_PARTITIONS 4 +#define MAX_MBR_PARTITIONS 4 typedef struct { UINT8 BootStrapCode[440]; UINT8 UniqueMbrSignature[4]; diff --git a/stand/efi/include/efipciio.h b/stand/efi/include/efipciio.h index b42fa59395a0..8499ad9e9d7a 100644 --- a/stand/efi/include/efipciio.h +++ b/stand/efi/include/efipciio.h @@ -1,16 +1,15 @@ -/* $FreeBSD$ */ /** @file - EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration, + EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration, and DMA interfaces that a driver uses to access its PCI controller. Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ @@ -128,27 +127,27 @@ typedef enum { EfiPciIoAttributeOperationMaximum } EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; -/** +/** Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is - satisfied or after a defined duration. - + satisfied or after a defined duration. + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory or I/O operations. @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory operation to perform. + base address for the memory operation to perform. @param Offset The offset within the selected BAR to start the memory operation. @param Mask Mask used for the polling criteria. @param Value The comparison value used for the polling exit criteria. @param Delay The number of 100 ns units to poll. @param Result Pointer to the last value read from the memory location. - + @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. @retval EFI_TIMEOUT Delay expired before a match occurred. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - + **/ typedef EFI_STATUS @@ -163,25 +162,25 @@ EFI_STATUS OUT UINT64 *Result ); -/** +/** Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory or I/O operations. @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. + base address for the memory or I/O operation to perform. + @param Offset The offset within the selected BAR to start the memory or I/O operation. @param Count The number of memory or I/O operations to perform. @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - + operations, the source buffer to write data from. + @retval EFI_SUCCESS The data was read from or written to the PCI controller. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. + valid for the PCI BAR specified by BarIndex. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - + **/ typedef EFI_STATUS @@ -205,23 +204,22 @@ typedef struct { EFI_PCI_IO_PROTOCOL_IO_MEM Write; } EFI_PCI_IO_PROTOCOL_ACCESS; -/** +/** Enable a PCI driver to access PCI controller registers in PCI configuration space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory operations. @param Offset The offset within the PCI configuration space for the PCI controller. @param Count The number of PCI configuration operations to perform. @param Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer to write data from. - - + @retval EFI_SUCCESS The data was read from or written to the PCI controller. @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not valid for the PCI configuration header of the PCI controller. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. - + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. + **/ typedef EFI_STATUS @@ -244,33 +242,33 @@ typedef struct { EFI_PCI_IO_PROTOCOL_CONFIG Write; } EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS; -/** +/** Enables a PCI driver to copy one region of PCI memory space to another region of PCI memory space. - + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory operations. @param DestBarIndex The BAR index in the standard PCI Configuration header to use as the - base address for the memory operation to perform. + base address for the memory operation to perform. @param DestOffset The destination offset within the BAR specified by DestBarIndex to - start the memory writes for the copy operation. + start the memory writes for the copy operation. @param SrcBarIndex The BAR index in the standard PCI Configuration header to use as the - base address for the memory operation to perform. + base address for the memory operation to perform. @param SrcOffset The source offset within the BAR specified by SrcBarIndex to start - the memory reads for the copy operation. + the memory reads for the copy operation. @param Count The number of memory operations to perform. Bytes moved is Width - size * Count, starting at DestOffset and SrcOffset. - + size * Count, starting at DestOffset and SrcOffset. + @retval EFI_SUCCESS The data was copied from one memory region to another memory region. @retval EFI_UNSUPPORTED DestBarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED SrcBarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED The address range specified by DestOffset, Width, and Count - is not valid for the PCI BAR specified by DestBarIndex. + is not valid for the PCI BAR specified by DestBarIndex. @retval EFI_UNSUPPORTED The address range specified by SrcOffset, Width, and Count is - not valid for the PCI BAR specified by SrcBarIndex. + not valid for the PCI BAR specified by SrcBarIndex. @retval EFI_INVALID_PARAMETER Width is invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - + **/ typedef EFI_STATUS @@ -284,24 +282,24 @@ EFI_STATUS IN UINTN Count ); -/** +/** Provides the PCI controller-specific addresses needed to access system memory. - + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Operation Indicates if the bus master is going to read or write to system memory. @param HostAddress The system memory address to map to the PCI controller. @param NumberOfBytes On input the number of bytes to map. On output the number of bytes - that were mapped. + that were mapped. @param DeviceAddress The resulting map address for the bus master PCI controller to use to - access the hosts HostAddress. + access the hosts HostAddress. @param Mapping A resulting value to pass to Unmap(). - + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. - + **/ typedef EFI_STATUS @@ -314,15 +312,15 @@ EFI_STATUS OUT VOID **Mapping ); -/** +/** Completes the Map() operation and releases any corresponding resources. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Mapping The mapping value returned from Map(). - + @retval EFI_SUCCESS The range was unmapped. @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. - + **/ typedef EFI_STATUS @@ -331,25 +329,25 @@ EFI_STATUS IN VOID *Mapping ); -/** +/** Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer - mapping. - + mapping. + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Type This parameter is not used and must be ignored. @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. @param HostAddress A pointer to store the base system memory address of the - allocated range. + allocated range. @param Attributes The requested bit mask of attributes for the allocated range. - + @retval EFI_SUCCESS The requested memory pages were allocated. @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are - MEMORY_WRITE_COMBINE and MEMORY_CACHED. + MEMORY_WRITE_COMBINE and MEMORY_CACHED. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + **/ typedef EFI_STATUS @@ -362,17 +360,17 @@ EFI_STATUS IN UINT64 Attributes ); -/** +/** Frees memory that was allocated with AllocateBuffer(). - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allocated range. - + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated range. + @retval EFI_SUCCESS The requested memory pages were freed. @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages was not allocated with AllocateBuffer(). - + **/ typedef EFI_STATUS @@ -382,16 +380,16 @@ EFI_STATUS IN VOID *HostAddress ); -/** +/** Flushes all PCI posted write transactions from a PCI host bridge to system memory. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host - bridge to system memory. + bridge to system memory. @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI - host bridge due to a hardware error. - + host bridge due to a hardware error. + **/ typedef EFI_STATUS @@ -399,18 +397,18 @@ EFI_STATUS IN EFI_PCI_IO_PROTOCOL *This ); -/** +/** Retrieves this PCI controller's current PCI bus number, device number, and function number. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param SegmentNumber The PCI controller's current PCI segment number. @param BusNumber The PCI controller's current PCI bus number. @param DeviceNumber The PCI controller's current PCI device number. @param FunctionNumber The PCI controller's current PCI function number. - - @retval EFI_SUCCESS The PCI controller location was returned. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - + + @retval EFI_SUCCESS The PCI controller location was returned. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + **/ typedef EFI_STATUS @@ -422,24 +420,24 @@ EFI_STATUS OUT UINTN *FunctionNumber ); -/** +/** Performs an operation on the attributes that this PCI controller supports. The operations include - getting the set of supported attributes, retrieving the current attributes, setting the current - attributes, enabling attributes, and disabling attributes. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + getting the set of supported attributes, retrieving the current attributes, setting the current + attributes, enabling attributes, and disabling attributes. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Operation The operation to perform on the attributes for this PCI controller. @param Attributes The mask of attributes that are used for Set, Enable, and Disable - operations. + operations. @param Result A pointer to the result mask of attributes that are returned for the Get - and Supported operations. - + and Supported operations. + @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED one or more of the bits set in + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED one or more of the bits set in Attributes are not supported by this PCI controller or one of its parent bridges when Operation is Set, Enable or Disable. - + **/ typedef EFI_STATUS @@ -450,27 +448,27 @@ EFI_STATUS OUT UINT64 *Result OPTIONAL ); -/** +/** Gets the attributes that this PCI controller supports setting on a BAR using SetBarAttributes(), and retrieves the list of resource descriptors for a BAR. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param BarIndex The BAR index of the standard PCI Configuration header to use as the base address for resource range. The legal range for this field is 0..5. @param Supports A pointer to the mask of attributes that this PCI controller supports - setting for this BAR with SetBarAttributes(). + setting for this BAR with SetBarAttributes(). @param Resources A pointer to the ACPI 2.0 resource descriptors that describe the current - configuration of this BAR of the PCI controller. - - @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI - controller supports are returned in Supports. If Resources + configuration of this BAR of the PCI controller. + + @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI + controller supports are returned in Supports. If Resources is not NULL, then the ACPI 2.0 resource descriptors that the PCI - controller is currently using are returned in Resources. + controller is currently using are returned in Resources. @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate - Resources. - + Resources. + **/ typedef EFI_STATUS @@ -481,29 +479,29 @@ EFI_STATUS OUT VOID **Resources OPTIONAL ); -/** +/** Sets the attributes for a range of a BAR on a PCI controller. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Attributes The mask of attributes to set for the resource range specified by - BarIndex, Offset, and Length. + BarIndex, Offset, and Length. @param BarIndex The BAR index of the standard PCI Configuration header to use as the base address for resource range. The legal range for this field is 0..5. @param Offset A pointer to the BAR relative base address of the resource range to be - modified by the attributes specified by Attributes. + modified by the attributes specified by Attributes. @param Length A pointer to the length of the resource range to be modified by the - attributes specified by Attributes. - - @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource - range specified by BarIndex, Offset, and Length were + attributes specified by Attributes. + + @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource + range specified by BarIndex, Offset, and Length were set on the PCI controller, and the actual resource range is returned - in Offset and Length. + in Offset and Length. @retval EFI_INVALID_PARAMETER Offset or Length is NULL. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the - resource range specified by BarIndex, Offset, and - Length. - + resource range specified by BarIndex, Offset, and + Length. + **/ typedef EFI_STATUS @@ -516,11 +514,11 @@ EFI_STATUS ); /// -/// The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration, -/// and DMA interfaces used to abstract accesses to PCI controllers. -/// There is one EFI_PCI_IO_PROTOCOL instance for each PCI controller on a PCI bus. -/// A device driver that wishes to manage a PCI controller in a system will have to -/// retrieve the EFI_PCI_IO_PROTOCOL instance that is associated with the PCI controller. +/// The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration, +/// and DMA interfaces used to abstract accesses to PCI controllers. +/// There is one EFI_PCI_IO_PROTOCOL instance for each PCI controller on a PCI bus. +/// A device driver that wishes to manage a PCI controller in a system will have to +/// retrieve the EFI_PCI_IO_PROTOCOL instance that is associated with the PCI controller. /// struct _EFI_PCI_IO_PROTOCOL { EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem; @@ -538,20 +536,20 @@ struct _EFI_PCI_IO_PROTOCOL { EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes; EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes; EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes; - + /// /// The size, in bytes, of the ROM image. /// UINT64 RomSize; /// - /// A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible - /// for allocating memory for the ROM image, and copying the contents of the ROM to memory. - /// The contents of this buffer are either from the PCI option ROM that can be accessed - /// through the ROM BAR of the PCI controller, or it is from a platform-specific location. - /// The Attributes() function can be used to determine from which of these two sources + /// A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible + /// for allocating memory for the ROM image, and copying the contents of the ROM to memory. + /// The contents of this buffer are either from the PCI option ROM that can be accessed + /// through the ROM BAR of the PCI controller, or it is from a platform-specific location. + /// The Attributes() function can be used to determine from which of these two sources /// the RomImage buffer was initialized. - /// + /// VOID *RomImage; }; diff --git a/stand/efi/include/efipoint.h b/stand/efi/include/efipoint.h index 99944f720378..46e92ffd3b48 100644 --- a/stand/efi/include/efipoint.h +++ b/stand/efi/include/efipoint.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* Copyright (C) 2014 by John Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/stand/efi/include/efiprot.h b/stand/efi/include/efiprot.h index 351b2d347ad4..bcedf8b1f653 100644 --- a/stand/efi/include/efiprot.h +++ b/stand/efi/include/efiprot.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_PROT_H #define _EFI_PROT_H @@ -309,9 +308,9 @@ typedef struct { // // The FileName field of the EFI_FILE_INFO data structure is variable length. // Whenever code needs to know the size of the EFI_FILE_INFO data structure, it needs to -// be the size of the data structure without the FileName field. The following macro +// be the size of the data structure without the FileName field. The following macro // computes this size correctly no matter how big the FileName array is declared. -// This is required to make the EFI_FILE_INFO data structure ANSI compilant. +// This is required to make the EFI_FILE_INFO data structure ANSI compilant. // #define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName) @@ -331,9 +330,9 @@ typedef struct { // // The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length. // Whenever code needs to know the size of the EFI_FILE_SYSTEM_INFO data structure, it needs -// to be the size of the data structure without the VolumeLable field. The following macro +// to be the size of the data structure without the VolumeLable field. The following macro // computes this size correctly no matter how big the VolumeLable array is declared. -// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant. +// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant. // #define SIZE_OF_EFI_FILE_SYSTEM_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO,VolumeLabel) @@ -413,7 +412,7 @@ typedef struct { EFI_DEVICE_IO Write; } EFI_IO_ACCESS; -typedef +typedef EFI_STATUS (EFIAPI *EFI_PCI_DEVICE_PATH) ( IN struct _EFI_DEVICE_IO_INTERFACE *This, @@ -633,4 +632,31 @@ typedef struct _EFI_COMPONENT_NAME2 { CHAR8 **SupportedLanguages; } EFI_COMPONENT_NAME2; +// +// RISC-V EFI Boot Protocol +// +// https://github.com/riscv-non-isa/riscv-uefi +// + +#define RISCV_EFI_BOOT_PROTOCOL_GUID \ + { 0xccd15fec, 0x6f73, 0x4eec, {0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf} } + +INTERFACE_DECL(_RISCV_EFI_BOOT_PROTOCOL); + +#define RISCV_EFI_BOOT_PROTOCOL_REVISION 0x00010000 +#define RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION \ + RISCV_EFI_BOOT_PROTOCOL_REVISION + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_BOOT_HARTID) ( + IN struct _RISCV_EFI_BOOT_PROTOCOL *This, + OUT UINTN *BootHartId + ); + +typedef struct _RISCV_EFI_BOOT_PROTOCOL { + UINT64 Revision; + EFI_GET_BOOT_HARTID GetBootHartId; +} RISCV_EFI_BOOT_PROTOCOL; + #endif diff --git a/stand/efi/include/efipxebc.h b/stand/efi/include/efipxebc.h index ba0b2e9b6c5d..80a190d9c150 100644 --- a/stand/efi/include/efipxebc.h +++ b/stand/efi/include/efipxebc.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFIPXEBC_H #define _EFIPXEBC_H @@ -151,7 +150,7 @@ typedef struct { // Discover() definitions // -#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 #define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1 #define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2 #define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3 @@ -356,7 +355,7 @@ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_ARP) ( IN struct _EFI_PXE_BASE_CODE *This, - IN EFI_IP_ADDRESS *IpAddr, + IN EFI_IP_ADDRESS *IpAddr, IN EFI_MAC_ADDRESS *MacAddr OPTIONAL ); @@ -455,7 +454,7 @@ typedef enum { } EFI_PXE_BASE_CODE_CALLBACK_STATUS; typedef -EFI_PXE_BASE_CODE_CALLBACK_STATUS +EFI_PXE_BASE_CODE_CALLBACK_STATUS (EFIAPI *EFI_PXE_CALLBACK) ( IN struct _EFI_PXE_BASE_CODE_CALLBACK *This, IN EFI_PXE_BASE_CODE_FUNCTION Function, diff --git a/stand/efi/include/efirng.h b/stand/efi/include/efirng.h index 3d6c77677981..d5a2212ea13f 100644 --- a/stand/efi/include/efirng.h +++ b/stand/efi/include/efirng.h @@ -2,10 +2,10 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2006 - 2016 Unified EFI, Inc.<BR> - * Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR> + * Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR> * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License - * which accompanies this distribution. The full text of the license may be found at + * which accompanies this distribution. The full text of the license may be found at * http://opensource.org/licenses/bsd-license.php * * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, diff --git a/stand/efi/include/efiser.h b/stand/efi/include/efiser.h index e3d66e203a4b..596d2b94db59 100644 --- a/stand/efi/include/efiser.h +++ b/stand/efi/include/efiser.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_SER_H #define _EFI_SER_H @@ -35,8 +34,8 @@ Revision History INTERFACE_DECL(_SERIAL_IO_INTERFACE); typedef enum { - DefaultParity, - NoParity, + DefaultParity, + NoParity, EvenParity, OddParity, MarkParity, @@ -44,7 +43,7 @@ typedef enum { } EFI_PARITY_TYPE; typedef enum { - DefaultStopBits, + DefaultStopBits, OneStopBit, // 1 stop bit OneFiveStopBits, // 1.5 stop bits TwoStopBits // 2 stop bits diff --git a/stand/efi/include/efistdarg.h b/stand/efi/include/efistdarg.h index 25f556984112..f4cf0356563c 100644 --- a/stand/efi/include/efistdarg.h +++ b/stand/efi/include/efistdarg.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFISTDARG_H_ #define _EFISTDARG_H_ diff --git a/stand/efi/include/efitcp.h b/stand/efi/include/efitcp.h index 9f47b5ce8edc..6c5df7fd944d 100644 --- a/stand/efi/include/efitcp.h +++ b/stand/efi/include/efitcp.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_TCP_H #define _EFI_TCP_H diff --git a/stand/efi/include/efiudp.h b/stand/efi/include/efiudp.h index 82c8df79b59a..7c8b467eb9c4 100644 --- a/stand/efi/include/efiudp.h +++ b/stand/efi/include/efiudp.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef _EFI_UDP_H #define _EFI_UDP_H diff --git a/stand/efi/include/efiuga.h b/stand/efi/include/efiuga.h index 00464b7cb4c0..8c4b40dc84cc 100644 --- a/stand/efi/include/efiuga.h +++ b/stand/efi/include/efiuga.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /** @file UGA Draw protocol from the EFI 1.1 specification. @@ -100,33 +99,33 @@ typedef enum { The following table defines actions for BltOperations: - <B>EfiUgaVideoFill</B> - Write data from the BltBuffer pixel (SourceX, SourceY) - directly to every pixel of the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + <B>EfiUgaVideoFill</B> - Write data from the BltBuffer pixel (SourceX, SourceY) + directly to every pixel of the video display rectangle + (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). Only one pixel will be used from the BltBuffer. Delta is NOT used. - <B>EfiUgaVideoToBltBuffer</B> - Read data from the video display rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in - the BltBuffer rectangle (DestinationX, DestinationY ) - (DestinationX + Width, DestinationY + Height). If DestinationX or - DestinationY is not zero then Delta must be set to the length in bytes + <B>EfiUgaVideoToBltBuffer</B> - Read data from the video display rectangle + (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in + the BltBuffer rectangle (DestinationX, DestinationY ) + (DestinationX + Width, DestinationY + Height). If DestinationX or + DestinationY is not zero then Delta must be set to the length in bytes of a row in the BltBuffer. - <B>EfiUgaBltBufferToVideo</B> - Write data from the BltBuffer rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the - video display rectangle (DestinationX, DestinationY) - (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is - not zero then Delta must be set to the length in bytes of a row in the + <B>EfiUgaBltBufferToVideo</B> - Write data from the BltBuffer rectangle + (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the + video display rectangle (DestinationX, DestinationY) + (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is + not zero then Delta must be set to the length in bytes of a row in the BltBuffer. <B>EfiUgaVideoToVideo</B> - Copy from the video display rectangle (SourceX, SourceY) - (SourceX + Width, SourceY + Height) .to the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + (SourceX + Width, SourceY + Height) .to the video display rectangle + (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). The BltBuffer and Delta are not used in this mode. @param[in] This - Protocol instance pointer. - @param[in] BltBuffer - Buffer containing data to blit into video buffer. This + @param[in] BltBuffer - Buffer containing data to blit into video buffer. This buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL) @param[in] BltOperation - Operation to perform on BlitBuffer and video memory @param[in] SourceX - X coordinate of source for the BltBuffer. @@ -136,7 +135,7 @@ typedef enum { @param[in] Width - Width of rectangle in BltBuffer in pixels. @param[in] Height - Hight of rectangle in BltBuffer in pixels. @param[in] Delta - OPTIONAL - + @retval EFI_SUCCESS - The Blt operation completed. @retval EFI_INVALID_PARAMETER - BltOperation is not valid. @retval EFI_DEVICE_ERROR - A hardware error occurred writing to the video buffer. diff --git a/stand/efi/include/efizfs.h b/stand/efi/include/efizfs.h index 97f28097b2a1..b29fb8d1af7e 100644 --- a/stand/efi/include/efizfs.h +++ b/stand/efi/include/efizfs.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stdint.h> diff --git a/stand/efi/include/i386/efibind.h b/stand/efi/include/i386/efibind.h index 0f1d4f115598..dac056571c7c 100644 --- a/stand/efi/include/i386/efibind.h +++ b/stand/efi/include/i386/efibind.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved @@ -27,102 +26,19 @@ Revision History #pragma pack() - -#ifdef __FreeBSD__ -#include <sys/stdint.h> -#else -// -// Basic int types of various widths -// - -#if (__STDC_VERSION__ < 199901L ) - - // No ANSI C 1999/2000 stdint.h integer width declarations - - #ifdef _MSC_EXTENSIONS - - // Use Microsoft C compiler integer width declarations - - typedef unsigned __int64 uint64_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - typedef __int32 int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #else - #ifdef UNIX_LP64 - - // Use LP64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long uint64_t; - typedef long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #else - - // Assume P64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long long uint64_t; - typedef long long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #endif - #endif -#endif -#endif /* __FreeBSD__ */ - -// -// Basic EFI types of various widths -// - -#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine, use those */ -#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */ - -typedef uint64_t UINT64; -typedef int64_t INT64; - -#ifndef _BASETSD_H_ - typedef uint32_t UINT32; - typedef int32_t INT32; -#endif - -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint8_t UINT8; -typedef int8_t INT8; - -#endif - -#undef VOID -#define VOID void - - -typedef int32_t INTN; -typedef uint32_t UINTN; - #ifdef EFI_NT_EMULATOR #define POST_CODE(_Data) -#else +#else #ifdef EFI_DEBUG #define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al #else #define POST_CODE(_Data) - #endif + #endif #endif #define EFIERR(a) (0x80000000 | a) #define EFI_ERROR_MASK 0x80000000 -#define EFIERR_OEM(a) (0xc0000000 | a) +#define EFIERR_OEM(a) (0xc0000000 | a) #define BAD_POINTER 0xFBFBFBFB @@ -156,14 +72,14 @@ typedef uint32_t UINTN; // BOOTSERVICE - prototype for implementation of a boot service interface // RUNTIMESERVICE - prototype for implementation of a runtime service interface // RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service -// RUNTIME_CODE - pragma macro for declaring runtime code +// RUNTIME_CODE - pragma macro for declaring runtime code // -#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options #ifdef _MSC_EXTENSIONS - #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler #else - #define EFIAPI // Substitute expresion to force C calling convention + #define EFIAPI // Substitute expresion to force C calling convention #endif #endif @@ -180,7 +96,7 @@ typedef uint32_t UINTN; #define VOLATILE volatile -#define MEMORY_FENCE() +#define MEMORY_FENCE() #ifdef EFI_NO_INTERFACE_DECL #define EFI_FORWARD_DECLARATION(x) @@ -229,9 +145,9 @@ typedef uint32_t UINTN; #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ - (_if)->LoadInternal(type, name, NULL) + (_if)->LoadInternal(type, name, NULL) -#else // EFI_NT_EMULATOR +#else // EFI_NT_EMULATOR // // When build similar to FW, then link everything together as @@ -243,7 +159,7 @@ typedef uint32_t UINTN; #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ (_if)->LoadInternal(type, name, entry) -#endif // EFI_FW_NT +#endif // EFI_FW_NT #ifdef __FreeBSD__ #define INTERFACE_DECL(x) struct x diff --git a/stand/efi/include/i386/pe.h b/stand/efi/include/i386/pe.h index e2ae25c3ddf6..226c6c7564a7 100644 --- a/stand/efi/include/i386/pe.h +++ b/stand/efi/include/i386/pe.h @@ -1,5 +1,4 @@ -/* $FreeBSD$ */ -/* +/* PE32+ header file */ #ifndef _PE_H @@ -8,7 +7,7 @@ #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ #define IMAGE_OS2_SIGNATURE 0x454E // NE #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE -#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 #define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED @@ -84,7 +83,7 @@ typedef struct _IMAGE_FILE_HEADER { #define IMAGE_SIZEOF_FILE_HEADER 20 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. -#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved external references). #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. @@ -130,7 +129,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER { UINT32 AddressOfEntryPoint; UINT32 BaseOfCode; UINT32 BaseOfData; - + // // NT additional fields. // @@ -607,7 +606,7 @@ typedef struct { UINT32 Signature; // "NB10" UINT32 Unknown; UINT32 Unknown2; - UINT32 Unknown3; + UINT32 Unknown3; // // Filename of .PDB goes here // @@ -619,9 +618,9 @@ typedef struct { UINT32 Signature; // "RSDS" UINT32 Unknown; UINT32 Unknown2; - UINT32 Unknown3; - UINT32 Unknown4; - UINT32 Unknown5; + UINT32 Unknown3; + UINT32 Unknown4; + UINT32 Unknown5; // // Filename of .PDB goes here // diff --git a/stand/efi/include/riscv/efibind.h b/stand/efi/include/riscv/efibind.h index 4751e2e944a8..c81506f79334 100644 --- a/stand/efi/include/riscv/efibind.h +++ b/stand/efi/include/riscv/efibind.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved @@ -27,91 +26,15 @@ Revision History #pragma pack() - -#ifdef __FreeBSD__ -#include <sys/stdint.h> -#else -// -// Basic int types of various widths -// - -#if (__STDC_VERSION__ < 199901L ) - - // No ANSI C 1999/2000 stdint.h integer width declarations - - #ifdef _MSC_EXTENSIONS - - // Use Microsoft C compiler integer width declarations - - typedef unsigned __int64 uint64_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - typedef __int32 int32_t; - typedef unsigned __int16 uint16_t; - typedef __int16 int16_t; - typedef unsigned __int8 uint8_t; - typedef __int8 int8_t; - #else - #ifdef UNIX_LP64 - - // Use LP64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long uint64_t; - typedef long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #else - - // Assume P64 programming model from C_FLAGS for integer width declarations - - typedef unsigned long long uint64_t; - typedef long long int64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned char uint8_t; - typedef char int8_t; - #endif - #endif -#endif -#endif /* __FreeBSD__ */ - -// -// Basic EFI types of various widths -// - - -typedef uint64_t UINT64; -typedef int64_t INT64; -typedef uint32_t UINT32; -typedef int32_t INT32; -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint8_t UINT8; -typedef int8_t INT8; - - -#undef VOID -#define VOID void - - -typedef int64_t INTN; -typedef uint64_t UINTN; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BugBug: Code to debug // #define BIT63 0x8000000000000000 -#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) +#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) #define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) ) - -// + +// // Macro's with casts make this much easier to use and read. // #define PORT_TO_MEM8D(_Port) (*(UINT8 *)(PORT_TO_MEMD(_Port))) @@ -122,7 +45,7 @@ typedef uint64_t UINTN; #define EFIERR(a) (0x8000000000000000 | a) #define EFI_ERROR_MASK 0x8000000000000000 -#define EFIERR_OEM(a) (0xc000000000000000 | a) +#define EFIERR_OEM(a) (0xc000000000000000 | a) #define BAD_POINTER 0xFBFBFBFBFBFBFBFB #define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF @@ -154,14 +77,14 @@ typedef uint64_t UINTN; // BOOTSERVICE - prototype for implementation of a boot service interface // RUNTIMESERVICE - prototype for implementation of a runtime service interface // RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service -// RUNTIME_CODE - pragma macro for declaring runtime code +// RUNTIME_CODE - pragma macro for declaring runtime code // -#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options #ifdef _MSC_EXTENSIONS - #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler #else - #define EFIAPI // Substitute expresion to force C calling convention + #define EFIAPI // Substitute expresion to force C calling convention #endif #endif @@ -178,7 +101,7 @@ typedef uint64_t UINTN; // // BugBug: Need to find out if this is portable across compilers. // -void __mfa (void); +void __mfa (void); #define MEMORY_FENCE() __mfa() #ifdef EFI_NO_INTERFACE_DECL diff --git a/stand/efi/libefi/Makefile b/stand/efi/libefi/Makefile index 8f1a30d86900..8ce57280d615 100644 --- a/stand/efi/libefi/Makefile +++ b/stand/efi/libefi/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> LIB= efi @@ -11,6 +9,7 @@ SRCS= delay.c \ efi_console.c \ efi_driver_utils.c \ efichar.c \ + eficom.c \ efienv.c \ efihttp.c \ efinet.c \ @@ -25,7 +24,7 @@ SRCS= delay.c \ .PATH: ${SYSDIR}/teken SRCS+= teken.c -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +.if ${MACHINE_CPUARCH} == "amd64" SRCS+= time.c .elif ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "riscv" SRCS+= time_event.c diff --git a/stand/efi/libefi/Makefile.depend b/stand/efi/libefi/Makefile.depend index 73bc18c8c0fc..8a29d17bb768 100644 --- a/stand/efi/libefi/Makefile.depend +++ b/stand/efi/libefi/Makefile.depend @@ -1,8 +1,8 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ stand/libsa \ + usr.bin/awk.host \ .include <dirdeps.mk> diff --git a/stand/efi/libefi/delay.c b/stand/efi/libefi/delay.c index 9bf40d28f96b..af03f0075330 100644 --- a/stand/efi/libefi/delay.c +++ b/stand/efi/libefi/delay.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> diff --git a/stand/efi/libefi/devicename.c b/stand/efi/libefi/devicename.c index cdf4830697fd..c18017429665 100644 --- a/stand/efi/libefi/devicename.c +++ b/stand/efi/libefi/devicename.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <sys/disklabel.h> @@ -39,8 +36,6 @@ __FBSDID("$FreeBSD$"); #include <efilib.h> #include <efizfs.h> -static int efi_parsedev(struct devdesc **, const char *, const char **); - /* * Point (dev) at an allocated device specifier for the device matching the * path in (devspec). If it contains an explicit device specification, @@ -57,159 +52,11 @@ efi_getdev(void **vdev, const char *devspec, const char **path) * use the current device instead. */ if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) { - rv = efi_parsedev(dev, getenv("currdev"), NULL); + rv = devparse(dev, getenv("currdev"), NULL); if (rv == 0 && path != NULL) *path = devspec; return (rv); } - /* Parse the device name off the beginning of the devspec. */ - return (efi_parsedev(dev, devspec, path)); -} - -/* - * Point (dev) at an allocated device specifier matching the string version - * at the beginning of (devspec). Return a pointer to the remaining - * text in (path). - * - * In all cases, the beginning of (devspec) is compared to the names - * of known devices in the device switch, and then any following text - * is parsed according to the rules applied to the device type. - * - * For disk-type devices, the syntax is: - * - * fs<unit>: - */ -static int -efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) -{ - struct devdesc *idev; - struct devsw *dv; - int i, unit, err; - char *cp; - const char *np; - - /* minimum length check */ - if (strlen(devspec) < 2) - return (EINVAL); - - /* look for a device that matches */ - for (i = 0; devsw[i] != NULL; i++) { - dv = devsw[i]; - if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name))) - break; - } - if (devsw[i] == NULL) - return (ENOENT); - - np = devspec + strlen(dv->dv_name); - idev = NULL; - err = 0; - - switch (dv->dv_type) { - case DEVT_NONE: - break; - - case DEVT_DISK: - idev = malloc(sizeof(struct disk_devdesc)); - if (idev == NULL) - return (ENOMEM); - - err = disk_parsedev((struct disk_devdesc *)idev, np, path); - if (err != 0) - goto fail; - break; - -#ifdef EFI_ZFS_BOOT - case DEVT_ZFS: - idev = malloc(sizeof(struct zfs_devdesc)); - if (idev == NULL) - return (ENOMEM); - - err = zfs_parsedev((struct zfs_devdesc*)idev, np, path); - if (err != 0) - goto fail; - break; -#endif - default: - idev = malloc(sizeof(struct devdesc)); - if (idev == NULL) - return (ENOMEM); - - unit = 0; - cp = (char *)np; - - if (*np != '\0' && *np != ':') { - errno = 0; - unit = strtol(np, &cp, 0); - if (errno != 0 || cp == np) { - err = EUNIT; - goto fail; - } - } - if (*cp != '\0' && *cp != ':') { - err = EINVAL; - goto fail; - } - - idev->d_unit = unit; - if (path != NULL) - *path = (*cp == 0) ? cp : cp + 1; - break; - } - - idev->d_dev = dv; - - if (dev != NULL) - *dev = idev; - else - free(idev); - return (0); - -fail: - free(idev); - return (err); -} - -char * -efi_fmtdev(void *vdev) -{ - struct devdesc *dev = (struct devdesc *)vdev; - static char buf[SPECNAMELEN + 1]; - - switch(dev->d_dev->dv_type) { - case DEVT_NONE: - strcpy(buf, "(no device)"); - break; - - case DEVT_DISK: - return (disk_fmtdev(vdev)); - -#ifdef EFI_ZFS_BOOT - case DEVT_ZFS: - return (zfs_fmtdev(dev)); -#endif - default: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); - break; - } - - return (buf); -} - -/* - * Set currdev to suit the value being supplied in (value) - */ -int -efi_setcurrdev(struct env_var *ev, int flags, const void *value) -{ - struct devdesc *ncurr; - int rv; - - rv = efi_parsedev(&ncurr, value, NULL); - if (rv != 0) - return (rv); - free(ncurr); - - return (mount_currdev(ev, flags, value)); + return (devparse(dev, devspec, path)); } diff --git a/stand/efi/libefi/devpath.c b/stand/efi/libefi/devpath.c index c25ae73e463c..db152f8eb9ad 100644 --- a/stand/efi/libefi/devpath.c +++ b/stand/efi/libefi/devpath.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> #include <efichar.h> @@ -494,7 +491,7 @@ efi_devpath_to_name(EFI_DEVICE_PATH *devpath) free(ptr); ptr = out; } - + return (ptr); } @@ -575,6 +572,23 @@ efi_devpath_last_node(EFI_DEVICE_PATH *devpath) return (devpath); } +/* + * Walk device path nodes, return next instance or end node. + */ +EFI_DEVICE_PATH * +efi_devpath_next_instance(EFI_DEVICE_PATH *devpath) +{ + while (!IsDevicePathEnd(devpath)) { + devpath = NextDevicePathNode(devpath); + if (IsDevicePathEndType(devpath) && + devpath->SubType == END_INSTANCE_DEVICE_PATH_SUBTYPE) { + devpath = NextDevicePathNode(devpath); + break; + } + } + return (devpath); +} + EFI_DEVICE_PATH * efi_devpath_trim(EFI_DEVICE_PATH *devpath) { diff --git a/stand/efi/libefi/efi_console.c b/stand/efi/libefi/efi_console.c index 1aeb94344c58..46a3c957f151 100644 --- a/stand/efi/libefi/efi_console.c +++ b/stand/efi/libefi/efi_console.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <efi.h> #include <efilib.h> @@ -66,7 +63,7 @@ void HO(void); void end_term(void); #endif -#define TEXT_ROWS 24 +#define TEXT_ROWS 25 #define TEXT_COLS 80 static tf_bell_t efi_cons_bell; @@ -129,14 +126,14 @@ int efi_cons_poll(void); static void cons_draw_frame(teken_attr_t *); struct console efi_console = { - "efi", - "EFI console", - C_WIDEOUT, - efi_cons_probe, - efi_cons_init, - efi_cons_putchar, - efi_cons_getchar, - efi_cons_poll + .c_name = "efi", + .c_desc = "EFI console", + .c_flags = C_WIDEOUT, + .c_probe = efi_cons_probe, + .c_init = efi_cons_init, + .c_out = efi_cons_putchar, + .c_in = efi_cons_getchar, + .c_ready = efi_cons_poll }; /* @@ -555,7 +552,7 @@ curs_move(int *_x, int *_y, int x, int y) if (_y != NULL) *_y = conout->Mode->CursorRow; } - + /* Clear internal state of the terminal emulation code. */ void end_term(void) @@ -690,7 +687,7 @@ HO(void) args[0] = args[1] = 1; CM(); } - + /* Clear line from current position to end of line */ static void CL(int direction) @@ -713,7 +710,7 @@ CL(int direction) default: /* NOTREACHED */ __unreachable(); } - + if (cury == y - 1) len--; @@ -728,7 +725,7 @@ CL(int direction) if (direction != 0) curs_move(NULL, NULL, 0, cury); - + conout->OutputString(conout, line); /* restore cursor position */ curs_move(NULL, NULL, curx, cury); @@ -745,7 +742,7 @@ get_arg(int c) args[argc] += c - '0'; } #endif - + /* Emulate basic capabilities of cons25 terminal */ static void efi_term_emu(int c) @@ -758,7 +755,7 @@ efi_term_emu(int c) }; int t, i; EFI_STATUS status; - + switch (esc) { case 0: switch (c) { @@ -1044,28 +1041,7 @@ cons_update_mode(bool use_gfx_mode) a = teken_get_defattr(&gfx_state.tg_teken); attr = *a; - /* - * On first run, we set up the efi_set_colors() - * callback. If the env is already set, we - * pick up fg and bg color values from the environment. - */ - ptr = getenv("teken.fg_color"); - if (ptr != NULL) { - attr.ta_fgcolor = strtol(ptr, NULL, 10); - ptr = getenv("teken.bg_color"); - attr.ta_bgcolor = strtol(ptr, NULL, 10); - - teken_set_defattr(&gfx_state.tg_teken, &attr); - } else { - snprintf(env, sizeof(env), "%d", - attr.ta_fgcolor); - env_setenv("teken.fg_color", EV_VOLATILE, env, - efi_set_colors, env_nounset); - snprintf(env, sizeof(env), "%d", - attr.ta_bgcolor); - env_setenv("teken.bg_color", EV_VOLATILE, env, - efi_set_colors, env_nounset); - } + gfx_fb_setcolors(&attr, efi_set_colors, env_nounset); } } diff --git a/stand/efi/libefi/efi_driver_utils.c b/stand/efi/libefi/efi_driver_utils.c index e5034c2e34d6..adb57f39fdce 100644 --- a/stand/efi/libefi/efi_driver_utils.c +++ b/stand/efi/libefi/efi_driver_utils.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stdbool.h> diff --git a/stand/efi/libefi/efichar.c b/stand/efi/libefi/efichar.c index 233027f4e6ea..659212799b6a 100644 --- a/stand/efi/libefi/efichar.c +++ b/stand/efi/libefi/efichar.c @@ -24,18 +24,22 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> +#ifndef _KERNEL #include <errno.h> +#endif #ifdef _STANDALONE #include <stand.h> #else +#ifdef _KERNEL +#include <sys/malloc.h> +#include <sys/systm.h> +#else #include <stddef.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#endif #include <sys/efi.h> #include <machine/efi.h> #endif @@ -90,7 +94,7 @@ ucs2_to_utf8(const efi_char *nm, char **name) if (*name != NULL) cp = *name; else - cp = *name = malloc(sz); + cp = *name = EFICHAR_MALLOC(sz); if (*name == NULL) return (ENOMEM); @@ -117,7 +121,7 @@ ucs2_to_utf8(const efi_char *nm, char **name) if (len >= sz) { /* Absent bugs, we'll never return EOVERFLOW */ if (freeit) { - free(*name); + EFICHAR_FREE(*name); *name = NULL; } return (EOVERFLOW); @@ -138,7 +142,7 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) sz = strlen(name) * 2 + 2; if (*nmp == NULL) - *nmp = malloc(sz); + *nmp = EFICHAR_MALLOC(sz); if (*nmp == NULL) return (ENOMEM); nm = *nmp; @@ -186,7 +190,7 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) } if (sz < 2) { if (freeit) { - free(nm); + EFICHAR_FREE(nm); *nmp = NULL; } return (EDOOFUS); @@ -197,7 +201,7 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) return (0); ilseq: if (freeit) { - free(nm); + EFICHAR_FREE(nm); *nmp = NULL; } return (EILSEQ); diff --git a/stand/efi/loader/efiserialio.c b/stand/efi/libefi/eficom.c index 8b3f8e83e0b3..2aa592da47f4 100644 --- a/stand/efi/loader/efiserialio.c +++ b/stand/efi/libefi/eficom.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/errno.h> #include <bootstrap.h> @@ -34,25 +31,20 @@ __FBSDID("$FreeBSD$"); #include <efi.h> #include <efilib.h> -#include "loader_efi.h" - static EFI_GUID serial = SERIAL_IO_PROTOCOL; #define COMC_TXWAIT 0x40000 /* transmit timeout */ -#ifndef COMSPEED -#define COMSPEED 9600 -#endif - #define PNP0501 0x501 /* 16550A-compatible COM port */ struct serial { + uint64_t newbaudrate; uint64_t baudrate; - uint8_t databits; + uint32_t timeout; + uint32_t receivefifodepth; + uint32_t databits; EFI_PARITY_TYPE parity; EFI_STOP_BITS_TYPE stopbits; - uint8_t ignore_cd; /* boolean */ - uint8_t rtsdtr_off; /* boolean */ int ioaddr; /* index in handles array */ EFI_HANDLE currdev; /* current serial device */ EFI_HANDLE condev; /* EFI Console device */ @@ -72,16 +64,30 @@ static int comc_speed_set(struct env_var *, int, const void *); static struct serial *comc_port; extern struct console efi_console; +struct console eficom = { + .c_name = "eficom", + .c_desc = "serial port", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, +}; + +#if defined(__aarch64__) && __FreeBSD_version < 1500000 +static void comc_probe_compat(struct console *); struct console comconsole = { .c_name = "comconsole", .c_desc = "serial port", .c_flags = 0, - .c_probe = comc_probe, + .c_probe = comc_probe_compat, .c_init = comc_init, .c_out = comc_putchar, .c_in = comc_getchar, .c_ready = comc_ischar, }; +#endif static EFI_STATUS efi_serial_init(EFI_HANDLE **handlep, int *nhandles) @@ -245,6 +251,11 @@ comc_get_con_serial_handle(const char *name) return (NULL); } +/* + * Called from cons_probe() to see if this device is available. + * Return immediately on x86, except for hyperv, since it interferes with + * common configurations otherwise (yes, this is just firewalling the bug). + */ static void comc_probe(struct console *sc) { @@ -256,19 +267,28 @@ comc_probe(struct console *sc) char *env, *buf, *ep; size_t sz; +#ifdef __amd64__ + /* + * This driver tickles issues on a number of different firmware loads. + * It is only required for HyperV, and is only known to work on HyperV, + * so only allow it on HyperV. + */ + env = getenv("smbios.bios.version"); + if (env == NULL || strncmp(env, "Hyper-V", 7) != 0) { + return; + } +#endif + if (comc_port == NULL) { - comc_port = malloc(sizeof (struct serial)); + comc_port = calloc(1, sizeof (struct serial)); if (comc_port == NULL) return; } - comc_port->baudrate = COMSPEED; - comc_port->ioaddr = 0; /* default port */ - comc_port->databits = 8; /* 8,n,1 */ - comc_port->parity = NoParity; /* 8,n,1 */ - comc_port->stopbits = OneStopBit; /* 8,n,1 */ - comc_port->ignore_cd = 1; /* ignore cd */ - comc_port->rtsdtr_off = 0; /* rts-dtr is on */ - comc_port->sio = NULL; + + /* Use defaults from firmware */ + comc_port->databits = 8; + comc_port->parity = DefaultParity; + comc_port->stopbits = DefaultStopBits; handle = NULL; env = getenv("efi_com_port"); @@ -292,19 +312,43 @@ comc_probe(struct console *sc) (void**)&comc_port->sio, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (EFI_ERROR(status)) + if (EFI_ERROR(status)) { comc_port->sio = NULL; + } else { + comc_port->newbaudrate = + comc_port->baudrate = comc_port->sio->Mode->BaudRate; + comc_port->timeout = comc_port->sio->Mode->Timeout; + comc_port->receivefifodepth = + comc_port->sio->Mode->ReceiveFifoDepth; + comc_port->databits = comc_port->sio->Mode->DataBits; + comc_port->parity = comc_port->sio->Mode->Parity; + comc_port->stopbits = comc_port->sio->Mode->StopBits; + } + } + + /* + * If there's no sio, then the device isn't there, so just return since + * the present flags aren't yet set. + */ + if (comc_port->sio == NULL) { + free(comc_port); + comc_port = NULL; + return; } - if (env != NULL) + if (env != NULL) unsetenv("efi_com_port"); snprintf(value, sizeof (value), "%u", comc_port->ioaddr); env_setenv("efi_com_port", EV_VOLATILE, value, comc_port_set, env_nounset); env = getenv("efi_com_speed"); + if (env == NULL) + /* fallback to comconsole setting */ + env = getenv("comconsole_speed"); + if (comc_parse_intval(env, &val) == CMD_OK) - comc_port->baudrate = val; + comc_port->newbaudrate = val; if (env != NULL) unsetenv("efi_com_speed"); @@ -312,20 +356,44 @@ comc_probe(struct console *sc) env_setenv("efi_com_speed", EV_VOLATILE, value, comc_speed_set, env_nounset); - comconsole.c_flags = 0; - if (comc_setup()) + if (comc_setup()) { sc->c_flags = C_PRESENTIN | C_PRESENTOUT; + } else { + sc->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + free(comc_port); + comc_port = NULL; + } } +#if defined(__aarch64__) && __FreeBSD_version < 1500000 +static void +comc_probe_compat(struct console *sc) +{ + comc_probe(&eficom); + if (eficom.c_flags & (C_PRESENTIN | C_PRESENTOUT)) { + printf("comconsole: comconsole device name is deprecated, switch to eficom\n"); + } + /* + * Note: We leave the present bits unset in sc to avoid ghosting. + */ +} +#endif + +/* + * Called when the console is selected in cons_change. If we didn't detect the + * device, comc_port will be NULL, and comc_setup will fail. It may be called + * even when the device isn't present as a 'fallback' console or when listed + * specifically in console env, so we have to reset the c_flags in those case to + * say it's not present. + */ static int comc_init(int arg __unused) { - if (comc_setup()) - return (CMD_OK); + return (0); - comconsole.c_flags = 0; - return (CMD_ERROR); + eficom.c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT); + return (1); } static void @@ -426,10 +494,10 @@ comc_port_set(struct env_var *ev, int flags, const void *value) EFI_HANDLE handle; EFI_STATUS status; - if (value == NULL) + if (value == NULL || comc_port == NULL) return (CMD_ERROR); - if (comc_parse_intval(value, &port) != CMD_OK) + if (comc_parse_intval(value, &port) != CMD_OK) return (CMD_ERROR); handle = efi_serial_get_handle(port, NULL); @@ -461,16 +529,15 @@ comc_speed_set(struct env_var *ev, int flags, const void *value) { unsigned speed; - if (value == NULL) + if (value == NULL || comc_port == NULL) return (CMD_ERROR); - if (comc_parse_intval(value, &speed) != CMD_OK) + if (comc_parse_intval(value, &speed) != CMD_OK) return (CMD_ERROR); - comc_port->baudrate = speed; - (void) comc_setup(); - - env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + comc_port->newbaudrate = speed; + if (comc_setup()) + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } @@ -483,33 +550,52 @@ static bool comc_setup(void) { EFI_STATUS status; - UINT32 control; + char *ev; - /* port is not usable */ - if (comc_port->sio == NULL) + /* + * If the device isn't active, or there's no port present. + */ + if ((eficom.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == 0 || comc_port == NULL) return (false); - status = comc_port->sio->Reset(comc_port->sio); - if (EFI_ERROR(status)) - return (false); + if (comc_port->sio->Reset != NULL) { + status = comc_port->sio->Reset(comc_port->sio); + if (EFI_ERROR(status)) + return (false); + } - status = comc_port->sio->SetAttributes(comc_port->sio, - comc_port->baudrate, 0, 0, comc_port->parity, - comc_port->databits, comc_port->stopbits); - if (EFI_ERROR(status)) - return (false); + /* + * Avoid setting the baud rate on Hyper-V. Also, only set the baud rate + * if the baud rate has changed from the default. And pass in '0' or + * DefaultFoo when we're not changing those values. Some EFI + * implementations get cranky when you set things to the values reported + * back even when they are unchanged. + */ + if (comc_port->sio->SetAttributes != NULL && + comc_port->newbaudrate != comc_port->baudrate) { + ev = getenv("smbios.bios.version"); + if (ev != NULL && strncmp(ev, "Hyper-V", 7) != 0) { + status = comc_port->sio->SetAttributes(comc_port->sio, + comc_port->newbaudrate, 0, 0, DefaultParity, 0, + DefaultStopBits); + if (EFI_ERROR(status)) + return (false); + comc_port->baudrate = comc_port->newbaudrate; + } + } - status = comc_port->sio->GetControl(comc_port->sio, &control); - if (EFI_ERROR(status)) - return (false); - if (comc_port->rtsdtr_off) { - control &= ~(EFI_SERIAL_REQUEST_TO_SEND | - EFI_SERIAL_DATA_TERMINAL_READY); - } else { +#ifdef EFI_FORCE_RTS + if (comc_port->sio->GetControl != NULL && comc_port->sio->SetControl != NULL) { + UINT32 control; + + status = comc_port->sio->GetControl(comc_port->sio, &control); + if (EFI_ERROR(status)) + return (false); control |= EFI_SERIAL_REQUEST_TO_SEND; + (void) comc_port->sio->SetControl(comc_port->sio, control); } - (void) comc_port->sio->SetControl(comc_port->sio, control); +#endif /* Mark this port usable. */ - comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT); + eficom.c_flags |= (C_PRESENTIN | C_PRESENTOUT); return (true); } diff --git a/stand/efi/libefi/efienv.c b/stand/efi/libefi/efienv.c index 04df6bc00fc3..83da2acc816b 100644 --- a/stand/efi/libefi/efienv.c +++ b/stand/efi/libefi/efienv.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <efi.h> #include <efichar.h> diff --git a/stand/efi/libefi/efihttp.c b/stand/efi/libefi/efihttp.c index 05d338fbaf04..fd0ed744047c 100644 --- a/stand/efi/libefi/efihttp.c +++ b/stand/efi/libefi/efihttp.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Intel Corporation * @@ -23,13 +23,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <netinet/in.h> @@ -94,7 +89,7 @@ struct devsw efihttp_dev = { .dv_close = efihttp_dev_close, .dv_ioctl = noioctl, .dv_print = NULL, - .dv_cleanup = NULL, + .dv_cleanup = nullsys, }; struct fs_ops efihttp_fsops = { @@ -570,6 +565,8 @@ efihttp_fs_open(const char *path, struct open_file *f) if (!efihttp_init_done) return (ENXIO); + if (f->f_dev != &efihttp_dev) + return (EINVAL); /* * If any path fails to open, try with a trailing slash in * case it's a directory. diff --git a/stand/efi/libefi/efinet.c b/stand/efi/libefi/efinet.c index c52b11d32ec8..e872110ef08f 100644 --- a/stand/efi/libefi/efinet.c +++ b/stand/efi/libefi/efinet.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <net/ethernet.h> #include <netinet/in.h> @@ -51,7 +48,7 @@ static int efinet_match(struct netif *, void *); static int efinet_probe(struct netif *, void *); static ssize_t efinet_put(struct iodesc *, void *, size_t); -struct netif_driver efinetif = { +struct netif_driver efinetif = { .netif_bname = "efinet", .netif_match = efinet_match, .netif_probe = efinet_probe, @@ -153,7 +150,7 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len) buf = NULL; /* XXX Is this needed? */ status = net->GetStatus(net, NULL, &buf); /* - * XXX EFI1.1 and the E1000 card returns a different + * XXX EFI1.1 and the E1000 card returns a different * address than we gave. Sigh. */ } while (status == EFI_SUCCESS && buf == NULL); @@ -259,6 +256,7 @@ efi_env_net_params(struct iodesc *desc) rootip.s_addr = rootaddr; #ifdef EFINET_DEBUG + printf("%s: proto=%d\n", __func__, netproto); printf("%s: ip=%s\n", __func__, inet_ntoa(myip)); printf("%s: mask=%s\n", __func__, intoa(netmask)); printf("%s: gateway=%s\n", __func__, inet_ntoa(gateip)); @@ -331,7 +329,7 @@ efinet_init(struct iodesc *desc, void *machdep_hint) static void efinet_end(struct netif *nif) { - EFI_SIMPLE_NETWORK *net = nif->nif_devdata; + EFI_SIMPLE_NETWORK *net = nif->nif_devdata; if (net == NULL) return; @@ -351,11 +349,11 @@ struct devsw efinet_dev = { .dv_close = NULL, /* Will be set in efinet_dev_init */ .dv_ioctl = noioctl, .dv_print = efinet_dev_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, }; static int -efinet_dev_init() +efinet_dev_init(void) { struct netif_dif *dif; struct netif_stats *stats; @@ -430,6 +428,7 @@ efinet_dev_init() dif->dif_private = handles2[i]; } + efinet_dev.dv_cleanup = netdev.dv_cleanup; efinet_dev.dv_open = netdev.dv_open; efinet_dev.dv_close = netdev.dv_close; efinet_dev.dv_strategy = netdev.dv_strategy; diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c index 7807c17077a6..3df6034571f5 100644 --- a/stand/efi/libefi/efipart.c +++ b/stand/efi/libefi/efipart.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/disk.h> #include <sys/param.h> #include <sys/time.h> @@ -78,7 +75,7 @@ struct devsw efipart_fddev = { .dv_close = efipart_close, .dv_ioctl = efipart_ioctl, .dv_print = efipart_printfd, - .dv_cleanup = NULL + .dv_cleanup = nullsys, }; struct devsw efipart_cddev = { @@ -90,7 +87,7 @@ struct devsw efipart_cddev = { .dv_close = efipart_close, .dv_ioctl = efipart_ioctl, .dv_print = efipart_printcd, - .dv_cleanup = NULL + .dv_cleanup = nullsys, }; struct devsw efipart_hddev = { @@ -102,7 +99,9 @@ struct devsw efipart_hddev = { .dv_close = efipart_close, .dv_ioctl = efipart_ioctl, .dv_print = efipart_printhd, - .dv_cleanup = NULL + .dv_cleanup = nullsys, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; static pdinfo_list_t fdinfo = STAILQ_HEAD_INITIALIZER(fdinfo); diff --git a/stand/efi/libefi/efizfs.c b/stand/efi/libefi/efizfs.c index 7f3986d47140..1c80f1ae26b9 100644 --- a/stand/efi/libefi/efizfs.c +++ b/stand/efi/libefi/efizfs.c @@ -25,9 +25,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <stand.h> @@ -115,7 +112,7 @@ efi_zfs_probe(void) snprintf(devname, sizeof(devname), "%s%dp%d:", efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit); guid = 0; - if (zfs_probe_dev(devname, &guid) == 0) { + if (zfs_probe_dev(devname, &guid, false) == 0) { insert_zfs(pd->pd_handle, guid); if (pd->pd_handle == boot_img->DeviceHandle) pool_guid = guid; diff --git a/stand/efi/libefi/env.c b/stand/efi/libefi/env.c index 77e232343040..328476a9f68b 100644 --- a/stand/efi/libefi/env.c +++ b/stand/efi/libefi/env.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <efi.h> @@ -537,7 +534,7 @@ efi_print_global(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) goto done; } if (strncmp("Boot", var, 4) == 0 || - strncmp("Driver", var, 5) == 0 || + strncmp("Driver", var, 6) == 0 || strncmp("SysPrep", var, 7) == 0 || strncmp("OsRecovery", var, 10) == 0) { UINT16 filepathlistlen; diff --git a/stand/efi/libefi/errno.c b/stand/efi/libefi/errno.c index 0f354c3f3c8f..92050af7f4e1 100644 --- a/stand/efi/libefi/errno.c +++ b/stand/efi/libefi/errno.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> diff --git a/stand/efi/libefi/handles.c b/stand/efi/libefi/handles.c index a55239dbec8c..d3ec428b8d4a 100644 --- a/stand/efi/libefi/handles.c +++ b/stand/efi/libefi/handles.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> diff --git a/stand/efi/libefi/libefi.c b/stand/efi/libefi/libefi.c index e7b1406839fe..f615bd214bfc 100644 --- a/stand/efi/libefi/libefi.c +++ b/stand/efi/libefi/libefi.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <eficonsctl.h> #include <efilib.h> diff --git a/stand/efi/libefi/time.c b/stand/efi/libefi/time.c index fe0d2ef2702b..aa8508879b20 100644 --- a/stand/efi/libefi/time.c +++ b/stand/efi/libefi/time.c @@ -38,9 +38,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> @@ -178,7 +175,7 @@ from_efi_time(EFI_TIME *ETime) /* * UTime should now be set to 00:00:00 on Jan 1 of the file's year. * - * Months + * Months */ UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); diff --git a/stand/efi/libefi/time_arm64.c b/stand/efi/libefi/time_arm64.c index baa0f8bfa1ed..d3c7a4e236d0 100644 --- a/stand/efi/libefi/time_arm64.c +++ b/stand/efi/libefi/time_arm64.c @@ -28,9 +28,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> diff --git a/stand/efi/libefi/time_event.c b/stand/efi/libefi/time_event.c index f171bf997078..c4334412a4fe 100644 --- a/stand/efi/libefi/time_event.c +++ b/stand/efi/libefi/time_event.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> diff --git a/stand/efi/libefi/wchar.c b/stand/efi/libefi/wchar.c index d0c653514366..953f29418c21 100644 --- a/stand/efi/libefi/wchar.c +++ b/stand/efi/libefi/wchar.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <efi.h> #include <efilib.h> diff --git a/stand/efi/libefi32/Makefile b/stand/efi/libefi32/Makefile new file mode 100644 index 000000000000..779c7e604686 --- /dev/null +++ b/stand/efi/libefi32/Makefile @@ -0,0 +1,4 @@ +DO32=1 + +.PATH: ${.CURDIR}/../libefi +.include "${.CURDIR}/../libefi/Makefile" diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile index 1edb5674712e..ae2ffc475730 100644 --- a/stand/efi/loader/Makefile +++ b/stand/efi/loader/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_NET_SUPPORT?= yes LOADER_MSDOS_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes @@ -8,7 +6,13 @@ LOADER_EXT2FS_SUPPORT?= no .include <bsd.init.mk> +.if ${MACHINE} == "amd64" && ${DO32:U0} == 1 +__arch= i386 +LOADER?= loader_ia32 +.else +__arch= ${MACHINE} LOADER?= loader_${LOADER_INTERP} +.endif PROG= ${LOADER}.sym INTERNALPROG= WARNS?= 3 @@ -39,6 +43,8 @@ CFLAGS.bootinfo.c += -I$(SRCTOP)/sys/teken CFLAGS.bootinfo.c += -I${SRCTOP}/contrib/pnglite CFLAGS.framebuffer.c += -I$(SRCTOP)/sys/teken CFLAGS.framebuffer.c += -I${SRCTOP}/contrib/pnglite +CFLAGS.main.c += -I$(SRCTOP)/sys/teken +CFLAGS.main.c += -I${SRCTOP}/contrib/pnglite CFLAGS.gfx_fb.c += -I$(SRCTOP)/sys/teken CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite @@ -52,13 +58,13 @@ CFLAGS.gfx_fb.c += -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib CWARNFLAGS.main.c+= -Wno-format .PATH: ${.CURDIR}/../loader -.PATH: ${.CURDIR}/../loader/arch/${MACHINE} -.include "${.CURDIR}/../loader/arch/${MACHINE}/Makefile.inc" +.PATH: ${.CURDIR}/../loader/arch/${__arch} +.include "${.CURDIR}/../loader/arch/${__arch}/Makefile.inc" CFLAGS+= -I${.CURDIR} -CFLAGS+= -I${.CURDIR}/arch/${MACHINE} +CFLAGS+= -I${.CURDIR}/arch/${__arch} CFLAGS+= -I${EFISRC}/include -CFLAGS+= -I${EFISRC}/include/${MACHINE} +CFLAGS+= -I${EFISRC}/include/${__arch} CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include CFLAGS+= -I${BOOTSRC}/i386/libi386 CFLAGS+= -DEFI @@ -66,6 +72,7 @@ CFLAGS+= -DEFI .if defined(HAVE_FDT) && ${MK_FDT} != "no" .include "${BOOTSRC}/fdt.mk" LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a +HELP_FILES+= ${FDTSRC}/help.fdt .endif # Include bcache code. @@ -79,8 +86,9 @@ CFLAGS+= -DEFI_STAGING_SIZE=${EFI_STAGING_SIZE} CFLAGS+= -DEFI_SECUREBOOT .endif -NEWVERSWHAT= "EFI loader" ${MACHINE} -VERSION_FILE= ${.CURDIR}/../loader/version +NEWVERSWHAT?= "EFI loader" ${MACHINE} +VERSION_FILE?= ${.CURDIR}/../loader/version +HELP_FILENAME= loader.help.efi # Always add MI sources .include "${BOOTSRC}/loader.mk" @@ -93,33 +101,48 @@ CLEANFILES+= 8x16.c FILES+= ${LOADER}.efi FILESMODE_${LOADER}.efi= ${BINMODE} -.if ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP} +.if ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP} && ${__arch} != "i386" LINKS+= ${BINDIR}/${LOADER}.efi ${BINDIR}/loader.efi .endif -LDSCRIPT= ${.CURDIR}/../loader/arch/${MACHINE}/ldscript.${MACHINE} +LDSCRIPT= ${.CURDIR}/../loader/arch/${__arch}/${__arch}.ldscript LDFLAGS+= -Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -pie .if ${LINKER_TYPE} == "bfd" && ${LINKER_VERSION} >= 23400 LDFLAGS+= -Wl,--no-dynamic-linker .endif -CLEANFILES+= loader.efi +.include <bsd.linker.mk> + +.if ${LINKER_TYPE} == "lld" && ${LINKER_FREEBSD_VERSION} < 1500001 +# When lld is using multiple threads, which it does by default, it can +# result in non-reproducible output with the custom linker script. Work +# around this by disabling threading. +LDFLAGS+= -Wl,--threads=1 +.endif + +CLEANFILES+= ${LOADER}.efi ${LOADER}.efi: ${PROG} - if ${NM} ${.ALLSRC} | grep ' U '; then \ + @if ${NM} ${.ALLSRC} | grep ' U '; then \ echo "Undefined symbols in ${.ALLSRC}"; \ exit 1; \ fi SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \ - ${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \ + ${EFI_OBJCOPY} -j .peheader -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ - -j set_Xficl_compile_set \ + -j set_X${LOADER_INTERP}_compile_set \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a - -DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} ${LDSCRIPT} -LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} +LIBEFI32= ${BOOTOBJ}/efi/libefi32/libefi.a + +.if ${__arch} == "i386" +DPADD= ${LDR_INTERP32} ${LIBEFI32} ${LIBSA32} ${LDSCRIPT} +LDADD= ${LDR_INTERP32} ${LIBEFI32} ${LIBSA32} +.else +DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBSAFDT} ${LIBEFI_FDT} ${LIBSA} ${LDSCRIPT} +LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBSAFDT} ${LIBEFI_FDT} ${LIBSA} +.endif .include <bsd.prog.mk> diff --git a/stand/efi/loader/Makefile.depend b/stand/efi/loader/Makefile.depend index 06e5b772c214..ae9e6b6efaa4 100644 --- a/stand/efi/loader/Makefile.depend +++ b/stand/efi/loader/Makefile.depend @@ -1,10 +1,10 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ + bin/sh.host \ stand/efi/libefi \ - stand/ficl \ stand/libsa \ + usr.bin/awk.host \ .include <dirdeps.mk> diff --git a/stand/efi/loader/Makefile.depend.arm b/stand/efi/loader/Makefile.depend.arm new file mode 100644 index 000000000000..4ba1445d8a5f --- /dev/null +++ b/stand/efi/loader/Makefile.depend.arm @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + bin/sh.host \ + stand/efi/fdt \ + stand/efi/libefi \ + stand/fdt \ + stand/libsa \ + usr.bin/awk.host \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/efi/loader/Makefile.depend.arm64 b/stand/efi/loader/Makefile.depend.arm64 new file mode 100644 index 000000000000..4ba1445d8a5f --- /dev/null +++ b/stand/efi/loader/Makefile.depend.arm64 @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + bin/sh.host \ + stand/efi/fdt \ + stand/efi/libefi \ + stand/fdt \ + stand/libsa \ + usr.bin/awk.host \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/efi/loader/Makefile.depend.options b/stand/efi/loader/Makefile.depend.options new file mode 100644 index 000000000000..33c99a773af5 --- /dev/null +++ b/stand/efi/loader/Makefile.depend.options @@ -0,0 +1,15 @@ +# options that impact our dependencies +DIRDEPS_OPTIONS = FDT FORTH LOADER_LUA + +DIRDEPS.FDT.yes += \ + stand/fdt \ + stand/efi/fdt \ + +DIRDEPS.FORTH.yes += \ + stand/ficl \ + +DIRDEPS.LOADER_LUA.yes += \ + stand/liblua \ + stand/lua \ + +.include <dirdeps-options.mk> diff --git a/stand/efi/loader/Makefile.depend.riscv b/stand/efi/loader/Makefile.depend.riscv new file mode 100644 index 000000000000..4ba1445d8a5f --- /dev/null +++ b/stand/efi/loader/Makefile.depend.riscv @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + bin/sh.host \ + stand/efi/fdt \ + stand/efi/libefi \ + stand/fdt \ + stand/libsa \ + usr.bin/awk.host \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/efi/loader/arch/amd64/Makefile.inc b/stand/efi/loader/arch/amd64/Makefile.inc index 0d9e2648cb59..25ff8fa9ce59 100644 --- a/stand/efi/loader/arch/amd64/Makefile.inc +++ b/stand/efi/loader/arch/amd64/Makefile.inc @@ -1,5 +1,3 @@ -# $FreeBSD$ - SRCS+= amd64_tramp.S \ start.S \ elf64_freebsd.c \ diff --git a/stand/efi/loader/arch/amd64/ldscript.amd64 b/stand/efi/loader/arch/amd64/amd64.ldscript index 874df9b08f9e..0e620654ea81 100644 --- a/stand/efi/loader/arch/amd64/ldscript.amd64 +++ b/stand/efi/loader/arch/amd64/amd64.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf64-x86-64-freebsd", "elf64-x86-64-freebsd", "elf64-x86-64-freebsd") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) @@ -35,17 +34,6 @@ SECTIONS *(COMMON) } . = ALIGN(4096); - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } - . = ALIGN(4096); __gp = .; .sdata : { *(.got.plt .got) diff --git a/stand/efi/loader/arch/amd64/amd64_tramp.S b/stand/efi/loader/arch/amd64/amd64_tramp.S index 877705407f92..515ffc5d784d 100644 --- a/stand/efi/loader/arch/amd64/amd64_tramp.S +++ b/stand/efi/loader/arch/amd64/amd64_tramp.S @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asmacros.h> diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c index 4bdf675cd5a3..35bd4d6c1419 100644 --- a/stand/efi/loader/arch/amd64/elf64_freebsd.c +++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> #include <sys/exec.h> @@ -43,20 +40,8 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" -#include "platform/acfreebsd.h" -#include "acconfig.h" -#define ACPI_SYSTEM_XFACE -#include "actypes.h" -#include "actbl.h" - #include "loader_efi.h" -static EFI_GUID acpi_guid = ACPI_TABLE_GUID; -static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; - -extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); - static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); @@ -86,8 +71,6 @@ static pdp_entry_t *PT3_l, *PT3_u; static pd_entry_t *PT2; static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; -extern EFI_PHYSICAL_ADDRESS staging; - static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry); @@ -106,9 +89,6 @@ elf64_exec(struct preloaded_file *fp) Elf_Ehdr *ehdr; vm_offset_t modulep, kernend, trampcode, trampstack; int err, i; - ACPI_TABLE_RSDP *rsdp; - char buf[24]; - int revision; bool copy_auto; copy_auto = copy_staging == COPY_STAGING_AUTO; @@ -116,57 +96,12 @@ elf64_exec(struct preloaded_file *fp) copy_staging = fp->f_kernphys_relocatable ? COPY_STAGING_DISABLE : COPY_STAGING_ENABLE; - /* - * Report the RSDP to the kernel. While this can be found with - * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. - * The old code used the 'hints' method to communite this to - * the kernel. However, while convenient, the 'hints' method - * is fragile and does not work when static hints are compiled - * into the kernel. Instead, move to setting different tunables - * that start with acpi. The old 'hints' can be removed before - * we branch for FreeBSD 12. - */ - - rsdp = efi_get_table(&acpi20_guid); - if (rsdp == NULL) { - rsdp = efi_get_table(&acpi_guid); - } - if (rsdp != NULL) { - sprintf(buf, "0x%016llx", (unsigned long long)rsdp); - setenv("hint.acpi.0.rsdp", buf, 1); - setenv("acpi.rsdp", buf, 1); - revision = rsdp->Revision; - if (revision == 0) - revision = 1; - sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); - setenv("acpi.revision", buf, 1); - strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); - buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); - setenv("acpi.oem", buf, 1); - sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); - setenv("acpi.rsdt", buf, 1); - if (revision >= 2) { - /* XXX extended checksum? */ - sprintf(buf, "0x%016llx", - (unsigned long long)rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); - setenv("acpi.xsdt", buf, 1); - sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); - setenv("acpi.xsdt_length", buf, 1); - } - } - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); trampcode = copy_staging == COPY_STAGING_ENABLE ? - (vm_offset_t)0x0000000040000000 /* 1G */ : - (vm_offset_t)0x0000000100000000; /* 4G */; + (vm_offset_t)G(1) : (vm_offset_t)G(4); err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, (EFI_PHYSICAL_ADDRESS *)&trampcode); if (EFI_ERROR(err)) { @@ -181,7 +116,7 @@ elf64_exec(struct preloaded_file *fp) trampoline = (void *)trampcode; if (copy_staging == COPY_STAGING_ENABLE) { - PT4 = (pml4_entry_t *)0x0000000040000000; + PT4 = (pml4_entry_t *)G(1); err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, (EFI_PHYSICAL_ADDRESS *)&PT4); if (EFI_ERROR(err)) { @@ -218,11 +153,11 @@ elf64_exec(struct preloaded_file *fp) /* * The L2 page slots are mapped with 2MB pages for 1GB. */ - PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024); + PT2[i] = (pd_entry_t)i * M(2); PT2[i] |= PG_V | PG_RW | PG_PS; } } else { - PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */ + PT4 = (pml4_entry_t *)G(4); err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9, (EFI_PHYSICAL_ADDRESS *)&PT4); if (EFI_ERROR(err)) { @@ -274,6 +209,12 @@ elf64_exec(struct preloaded_file *fp) trampoline, PT4); printf("Start @ 0x%lx ...\n", ehdr->e_entry); + /* + * we have to cleanup here because net_cleanup() doesn't work after + * we call ExitBootServices + */ + dev_cleanup(); + efi_time_fini(); err = bi_load(fp->f_args, &modulep, &kernend, true); if (err != 0) { @@ -283,8 +224,6 @@ elf64_exec(struct preloaded_file *fp) return (err); } - dev_cleanup(); - trampoline(trampstack, copy_staging == COPY_STAGING_ENABLE ? efi_copy_finish : efi_copy_finish_nop, kernend, modulep, PT4, ehdr->e_entry); diff --git a/stand/efi/loader/arch/amd64/exc.S b/stand/efi/loader/arch/amd64/exc.S index 0035d4a37e20..940bfa160161 100644 --- a/stand/efi/loader/arch/amd64/exc.S +++ b/stand/efi/loader/arch/amd64/exc.S @@ -1,6 +1,5 @@ /*- * Copyright (c) 2016 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov under sponsorship * from the FreeBSD Foundation. @@ -25,8 +24,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ .macro EH N, err=1 diff --git a/stand/efi/loader/arch/amd64/multiboot2.c b/stand/efi/loader/arch/amd64/multiboot2.c index 4d7b2713685d..eb7362293406 100644 --- a/stand/efi/loader/arch/amd64/multiboot2.c +++ b/stand/efi/loader/arch/amd64/multiboot2.c @@ -34,8 +34,6 @@ * https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */ -#include <sys/cdefs.h> - #include <sys/param.h> #include <sys/exec.h> #include <sys/linker.h> @@ -53,14 +51,13 @@ #include "bootstrap.h" #include "multiboot2.h" #include "loader_efi.h" +#include "modinfo.h" extern int elf32_loadfile_raw(char *filename, uint64_t dest, struct preloaded_file **result, int multiboot); extern int elf64_load_modmetadata(struct preloaded_file *fp, uint64_t dest); extern int elf64_obj_loadfile(char *filename, uint64_t dest, struct preloaded_file **result); -extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); extern void multiboot2_exec(void *entry, uint64_t multiboot_info, uint64_t stack); @@ -334,7 +331,7 @@ exec(struct preloaded_file *fp) struct mb2hdr *hdr; - CTASSERT(sizeof(header) <= PAGE_SIZE); + _Static_assert(sizeof(header) <= PAGE_SIZE, "header too big"); if ((md = file_findmetadata(fp, MODINFOMD_NOCOPY | MODINFOMD_MB2HDR)) == NULL) { @@ -440,7 +437,7 @@ exec(struct preloaded_file *fp) * module 0 module 1 */ - fp = file_findfile(NULL, "elf kernel"); + fp = file_findfile(NULL, md_kerntype); if (fp == NULL) { printf("No FreeBSD kernel provided, aborting\n"); error = EINVAL; @@ -502,7 +499,7 @@ obj_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) int error; /* See if there's a multiboot kernel loaded */ - mfp = file_findfile(NULL, "elf multiboot kernel"); + mfp = file_findfile(NULL, md_kerntype_mb); if (mfp == NULL) return (EFTYPE); @@ -510,14 +507,14 @@ obj_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) * We have a multiboot kernel loaded, see if there's a FreeBSD * kernel loaded also. */ - kfp = file_findfile(NULL, "elf kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) { /* * No kernel loaded, this must be it. The kernel has to * be loaded as a raw file, it will be processed by * Xen and correctly loaded as an ELF file. */ - rfp = file_loadraw(filename, "elf kernel", 0); + rfp = file_loadraw(filename, md_kerntype, 0); if (rfp == NULL) { printf( "Unable to load %s as a multiboot payload kernel\n", diff --git a/stand/efi/loader/arch/amd64/multiboot2.h b/stand/efi/loader/arch/amd64/multiboot2.h index 5693923c014f..a039aa0439aa 100644 --- a/stand/efi/loader/arch/amd64/multiboot2.h +++ b/stand/efi/loader/arch/amd64/multiboot2.h @@ -244,7 +244,7 @@ struct multiboot_tag_mmap multiboot_uint32_t size; multiboot_uint32_t entry_size; multiboot_uint32_t entry_version; - struct multiboot_mmap_entry entries[0]; + struct multiboot_mmap_entry entries[0]; }; struct multiboot_vbe_info_block @@ -388,7 +388,7 @@ struct multiboot_tag_efi_mmap multiboot_uint32_t descr_size; multiboot_uint32_t descr_vers; multiboot_uint8_t efi_mmap[0]; -}; +}; struct multiboot_tag_efi32_ih { diff --git a/stand/efi/loader/arch/amd64/start.S b/stand/efi/loader/arch/amd64/start.S index 774ef4fa7901..34bf166c6501 100644 --- a/stand/efi/loader/arch/amd64/start.S +++ b/stand/efi/loader/arch/amd64/start.S @@ -33,7 +33,6 @@ /* * crt0-efi-x86_64.S - x86_64 EFI startup code. - * $FreeBSD$ */ .text diff --git a/stand/efi/loader/arch/amd64/trap.c b/stand/efi/loader/arch/amd64/trap.c index e8cf188cf22f..61feb76e2dca 100644 --- a/stand/efi/loader/arch/amd64/trap.c +++ b/stand/efi/loader/arch/amd64/trap.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2016 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov under sponsorship * from the FreeBSD Foundation. @@ -27,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <sys/param.h> @@ -79,11 +75,21 @@ static uint32_t loader_tss; /* Loader TSS segment */ static struct region_descriptor fw_gdt; /* Descriptor of pristine GDT */ static EFI_PHYSICAL_ADDRESS loader_gdt_pa; /* Address of loader shadow GDT */ +struct frame { + struct frame *fr_savfp; + uintptr_t fr_savpc; +}; + void report_exc(struct trapframe *tf); void report_exc(struct trapframe *tf) { + struct frame *fp; + uintptr_t pc, base; + char buf[80]; + int ret; + base = (uintptr_t)boot_img->ImageBase; /* * printf() depends on loader runtime and UEFI firmware health * to produce the console output, in case of exception, the @@ -109,6 +115,33 @@ report_exc(struct trapframe *tf) tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_rcx, tf->tf_r8, tf->tf_r9, tf->tf_rax, tf->tf_rbx, tf->tf_rbp, tf->tf_r10, tf->tf_r11, tf->tf_r12, tf->tf_r13, tf->tf_r14, tf->tf_r15); + + fp = (struct frame *)tf->tf_rbp; + pc = tf->tf_rip; + + printf("Stack trace:\n"); + pager_open(); + while (fp != NULL || pc != 0) { + char *source = "PC"; + + if (pc >= base && pc < base + boot_img->ImageSize) { + pc -= base; + source = "loader PC"; + } + (void) snprintf(buf, sizeof (buf), "FP %016lx: %s 0x%016lx\n", + (uintptr_t)fp, source, pc); + if (pager_output(buf)) + break; + + if (fp != NULL) + fp = fp->fr_savfp; + + if (fp != NULL) + pc = fp->fr_savpc; + else + pc = 0; + } + pager_close(); printf("Machine stopped.\n"); } @@ -323,7 +356,7 @@ efi_redirect_exceptions(void) PREPARE_EXCEPTION(19); PREPARE_EXCEPTION(20); - exc_rsp = exc_stack_pa + PAGE_SIZE - + exc_rsp = exc_stack_pa + EFI_PAGE_SIZE - (6 /* hw exception frame */ + 3 /* scratch regs */) * 8; /* Find free IST and use it */ @@ -343,7 +376,7 @@ efi_redirect_exceptions(void) if (intercepted[i]) loader_idt_e->gd_ist = ist; } - (&(tss->tss_ist1))[ist - 1] = exc_stack_pa + PAGE_SIZE; + (&(tss->tss_ist1))[ist - 1] = exc_stack_pa + EFI_PAGE_SIZE; /* Switch to new IDT */ rfl = intr_disable(); diff --git a/stand/efi/loader/arch/arm/Makefile.inc b/stand/efi/loader/arch/arm/Makefile.inc index 284e517bfbb8..3d07122530e7 100644 --- a/stand/efi/loader/arch/arm/Makefile.inc +++ b/stand/efi/loader/arch/arm/Makefile.inc @@ -1,7 +1,4 @@ -# $FreeBSD$ - SRCS+= exec.c \ - efiserialio.c \ start.S HAVE_FDT=yes diff --git a/stand/efi/loader/arch/arm/ldscript.arm b/stand/efi/loader/arch/arm/arm.ldscript index 68775a88a9cd..7b5c2af399c9 100644 --- a/stand/efi/loader/arch/arm/ldscript.arm +++ b/stand/efi/loader/arch/arm/arm.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS @@ -43,16 +42,6 @@ SECTIONS *(.got.plt .got) *(.sdata*.sdata.* .gnu.linkonce.s.*) } - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } __gp = .; .plt : { *(.plt) } .reloc : { *(.reloc) } diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c index a110f3d07cbc..3963b6c0104b 100644 --- a/stand/efi/loader/arch/arm/exec.c +++ b/stand/efi/loader/arch/arm/exec.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/linker.h> @@ -43,9 +40,6 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "loader_efi.h" -extern vm_offset_t md_load(char *, vm_offset_t *); -extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool); - static int __elfN(arm_load)(char *filename, uint64_t dest, struct preloaded_file **result) @@ -80,16 +74,17 @@ __elfN(arm_exec)(struct preloaded_file *fp) printf("Kernel entry at %p...\n", entry); printf("Kernel args: %s\n", fp->f_args); + /* + * we have to cleanup here because net_cleanup() doesn't work after + * we call ExitBootServices + */ + dev_cleanup(); + if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) { efi_time_init(); return (error); } - /* At this point we've called ExitBootServices, so we can't call - * printf or any other function that uses Boot Services */ - - dev_cleanup(); - (*entry)((void *)modulep); panic("exec returned"); } diff --git a/stand/efi/loader/arch/arm/start.S b/stand/efi/loader/arch/arm/start.S index 5b6182d67d0a..5e4301ec7141 100644 --- a/stand/efi/loader/arch/arm/start.S +++ b/stand/efi/loader/arch/arm/start.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asm.h> @@ -140,6 +138,7 @@ section_table: _end_header: .text + .globl _start _start: /* Save the boot params to the stack */ push {r0, r1} diff --git a/stand/efi/loader/arch/arm64/Makefile.inc b/stand/efi/loader/arch/arm64/Makefile.inc index 9978d9c4ea9c..9474767cf2f2 100644 --- a/stand/efi/loader/arch/arm64/Makefile.inc +++ b/stand/efi/loader/arch/arm64/Makefile.inc @@ -1,9 +1,6 @@ -# $FreeBSD$ - HAVE_FDT=yes SRCS+= exec.c \ - efiserialio.c \ start.S .PATH: ${BOOTSRC}/arm64/libarm64 diff --git a/stand/efi/loader/arch/arm64/ldscript.arm64 b/stand/efi/loader/arch/arm64/arm64.ldscript index d0ed320a319c..889a1bafb9f7 100644 --- a/stand/efi/loader/arch/arm64/ldscript.arm64 +++ b/stand/efi/loader/arch/arm64/arm64.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* OUTPUT_FORMAT("elf64-aarch64-freebsd", "elf64-aarch64-freebsd", "elf64-aarch64-freebsd") */ @@ -16,7 +15,9 @@ SECTIONS *(.gnu.warning) *(.plt) } =0xD4200000 - . = ALIGN(16); + . = ALIGN(4096); + _etext = .; + __data_start = .; .data : { *(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata1) @@ -38,17 +39,6 @@ SECTIONS __bss_end = .; } . = ALIGN(16); - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } - . = ALIGN(16); __gp = .; .sdata : { *(.got.plt .got) @@ -78,6 +68,7 @@ SECTIONS . = ALIGN(16); .dynsym : { *(.dynsym) } _edata = .; + __data_size = ABSOLUTE(. - __data_start); /* Unused sections */ .interp : { *(.interp) } diff --git a/stand/efi/loader/arch/arm64/exec.c b/stand/efi/loader/arch/arm64/exec.c index 6cf4a4fd8e4d..89e2ad7521a8 100644 --- a/stand/efi/loader/arch/arm64/exec.c +++ b/stand/efi/loader/arch/arm64/exec.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> @@ -42,22 +39,9 @@ __FBSDID("$FreeBSD$"); #include "loader_efi.h" #include "cache.h" -#include "platform/acfreebsd.h" -#include "acconfig.h" -#define ACPI_SYSTEM_XFACE -#define ACPI_USE_SYSTEM_INTTYPES -#include "actypes.h" -#include "actbl.h" - -static EFI_GUID acpi_guid = ACPI_TABLE_GUID; -static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; - static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); -int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); - static struct file_format arm64_elf = { elf64_loadfile, elf64_exec @@ -75,45 +59,22 @@ elf64_exec(struct preloaded_file *fp) vm_offset_t clean_addr; size_t clean_size; struct file_metadata *md; - ACPI_TABLE_RSDP *rsdp; Elf_Ehdr *ehdr; - char buf[24]; - int err, revision; + int err; void (*entry)(vm_offset_t); - rsdp = efi_get_table(&acpi20_guid); - if (rsdp == NULL) { - rsdp = efi_get_table(&acpi_guid); - } - if (rsdp != NULL) { - sprintf(buf, "0x%016llx", (unsigned long long)rsdp); - setenv("hint.acpi.0.rsdp", buf, 1); - revision = rsdp->Revision; - if (revision == 0) - revision = 1; - sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); - strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); - buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); - sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); - if (revision >= 2) { - /* XXX extended checksum? */ - sprintf(buf, "0x%016llx", - (unsigned long long)rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); - sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); - } - } - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); entry = efi_translate(ehdr->e_entry); + /* + * we have to cleanup here because net_cleanup() doesn't work after + * we call ExitBootServices + */ + dev_cleanup(); + efi_time_fini(); err = bi_load(fp->f_args, &modulep, &kernendp, true); if (err != 0) { @@ -121,8 +82,6 @@ elf64_exec(struct preloaded_file *fp) return (err); } - dev_cleanup(); - /* Clean D-cache under kernel area and invalidate whole I-cache */ clean_addr = (vm_offset_t)efi_translate(fp->f_addr); clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr; diff --git a/stand/efi/loader/arch/arm64/start.S b/stand/efi/loader/arch/arm64/start.S index 675d4e153f36..6e30287453c5 100644 --- a/stand/efi/loader/arch/arm64/start.S +++ b/stand/efi/loader/arch/arm64/start.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -34,11 +32,14 @@ #define IMAGE_FILE_MACHINE_ARM64 0xaa64 +#define IMAGE_FILE_EXECUTABLE 0x0002 + #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 .section .peheader,"a" efi_start: @@ -60,22 +61,22 @@ coff_head: .long 0 /* No symbol table */ .long 0 /* No symbols */ .short section_table - optional_header /* Optional header size */ - .short 0 /* Characteristics TODO: Fill in */ + .short IMAGE_FILE_EXECUTABLE /* Characteristics */ optional_header: .short 0x020b /* PE32+ (64-bit addressing) */ .byte 0 /* Major linker version */ .byte 0 /* Minor linker version */ - .long _edata - _end_header /* Code size */ - .long 0 /* No initialized data */ + .long _etext - _end_header /* Code size */ + .long __data_size /* Initialized data size */ .long 0 /* No uninitialized data */ .long _start - efi_start /* Entry point */ .long _end_header - efi_start /* Start of code */ optional_windows_header: .quad 0 /* Image base */ - .long 32 /* Section Alignment */ - .long 8 /* File alignment */ + .long 4096 /* Section Alignment */ + .long 512 /* File alignment */ .short 0 /* Major OS version */ .short 0 /* Minor OS version */ .short 0 /* Major image version */ @@ -104,36 +105,37 @@ optional_windows_header: .quad 0 section_table: - /* We need a .reloc section for EFI */ - .ascii ".reloc" + .ascii ".text" + .byte 0 .byte 0 .byte 0 /* Pad to 8 bytes */ - .long 0 /* Virtual size */ - .long 0 /* Virtual address */ - .long 0 /* Size of raw data */ - .long 0 /* Pointer to raw data */ + .long _etext - _end_header /* Virtual size */ + .long _end_header - efi_start /* Virtual address */ + .long _etext - _end_header /* Size of raw data */ + .long _end_header - efi_start /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ - .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \ - IMAGE_SCN_MEM_DISCARDABLE) /* Characteristics */ + .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \ + IMAGE_SCN_MEM_READ) /* Characteristics */ - /* The contents of the loader */ - .ascii ".text" + .ascii ".data" .byte 0 .byte 0 .byte 0 /* Pad to 8 bytes */ - .long _edata - _end_header /* Virtual size */ - .long _end_header - efi_start /* Virtual address */ - .long _edata - _end_header /* Size of raw data */ - .long _end_header - efi_start /* Pointer to raw data */ + .long __data_size /* Virtual size */ + .long __data_start - efi_start /* Virtual address */ + .long __data_size /* Size of raw data */ + .long __data_start - efi_start /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ - .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \ - IMAGE_SCN_MEM_READ) /* Characteristics */ + .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE) /* Characteristics */ + + .align 12 _end_header: .text diff --git a/stand/efi/loader/arch/i386/Makefile.inc b/stand/efi/loader/arch/i386/Makefile.inc index fcdb6324b2f0..e27b553c6bab 100644 --- a/stand/efi/loader/arch/i386/Makefile.inc +++ b/stand/efi/loader/arch/i386/Makefile.inc @@ -1,13 +1,9 @@ -# $FreeBSD$ +SRCS+= amd64_tramp.S \ + start.S \ + setup.c \ + elf64_freebsd.c -SRCS+= start.S \ - elf32_freebsd.c \ - exec.c - -.PATH: ${BOOTSRC}/i386/libi386 +.PATH: ${BOOTSRC}/i386/libi386 SRCS+= nullconsole.c \ comconsole.c \ spinconsole.c - -CFLAGS+= -fPIC -LDFLAGS+= -Wl,-znocombreloc diff --git a/stand/kboot/arch/amd64/amd64_tramp.S b/stand/efi/loader/arch/i386/amd64_tramp.S index 877705407f92..06f9262014b3 100644 --- a/stand/kboot/arch/amd64/amd64_tramp.S +++ b/stand/efi/loader/arch/i386/amd64_tramp.S @@ -1,6 +1,6 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. + * Copyright (c) 2023 Ahmad Khalifa <ahmadkhalifa570@gmail.com> * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,52 +24,76 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asmacros.h> -#define ASM_FILE -#include "multiboot2.h" - .text .globl amd64_tramp /* - * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend, - * uint64_t modulep, uint64_t pagetable, uint64_t entry) + * void amd64_tramp(uint32_t stack, void *copy_finish, uint32_t kernend, + * uint32_t modulep, uint32_t pagetable, uint32_t gdtr, uint64_t entry) */ amd64_tramp: - cli /* Make sure we don't get interrupted. */ - movq %rdi,%rsp /* Switch to our temporary stack. */ + cli /* Make sure we don't get interrupted. */ + + calll *8(%esp) /* Call copy_finish so we're all ready to go. */ + + movl %cr0, %eax /* Paging may be enabled, disable it. */ + andl $0x7FFFFFFF, %eax + movl %eax, %cr0 + + movl %cr4, %eax /* PAE may be disabled, enable it. */ + orl $0x20, %eax + movl %eax, %cr4 + + movl 20(%esp), %eax /* Swap page tables. */ + movl %eax, %cr3 + + movl $0xC0000080, %ecx /* Enable long mode. */ + rdmsr + orl $0x100, %eax + wrmsr + + movl 12(%esp), %edi /* Stash the kernel and GDT values for later. */ + movl 16(%esp), %esi + movl 24(%esp), %ebx + movl 28(%esp), %edx + movl 32(%esp), %ebp - movq %rdx,%r12 /* Stash the kernel values for later. */ - movq %rcx,%r13 - movq %r8,%r14 - movq %r9,%r15 + movl 4(%esp), %esp /* Switch to our temporary stack. */ - callq *%rsi /* Call copy_finish so we're all ready to go. */ + movl %cr0, %eax /* Enable paging and enter compatibility mode. */ + orl $0x80000000, %eax + movl %eax, %cr0 - pushq %r12 /* Push kernend. */ - salq $32,%r13 /* Shift modulep and push it. */ - pushq %r13 - pushq %r15 /* Push the entry address. */ - movq %r14,%cr3 /* Switch page tables. */ - ret /* "Return" to kernel entry. */ + lgdtl (%ebx) /* Load GDT. */ + + pushl %edi /* Push kernend. */ + pushl %esi /* Push modulep. */ + pushl $0x0 + pushl %ebp /* Push 64-bit entry address. */ + pushl %edx + + calll 0f /* Find the address of ".longmode". */ +0: popl %eax + addl $(.longmode-0b), %eax + + pushl $0x8 /* Push CS. */ + pushl %eax /* Push the address. */ + lretl /* "Return" to 64-bit code. */ + + .code64 + +.longmode: + retq /* "Return" to kernel entry. */ + + .code32 ALIGN_TEXT amd64_tramp_end: -/* void multiboot2_exec(uint64_t entry, uint64_t multiboot_info, uint64_t stack) */ - .globl multiboot2_exec -multiboot2_exec: - movq %rdx,%rsp - pushq %rdi - movq %rsi,%rbx - movq $MULTIBOOT2_BOOTLOADER_MAGIC,%rax - ret - .data .globl amd64_tramp_size amd64_tramp_size: diff --git a/stand/efi/loader/arch/i386/elf32_freebsd.c b/stand/efi/loader/arch/i386/elf32_freebsd.c deleted file mode 100644 index 97d114f09610..000000000000 --- a/stand/efi/loader/arch/i386/elf32_freebsd.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/exec.h> -#include <sys/linker.h> -#include <string.h> -#include <machine/bootinfo.h> -#include <machine/elf.h> -#include <stand.h> - -#include <efi.h> -#include <efilib.h> - -#include "bootstrap.h" -#include "../libi386/libi386.h" -#include "../btx/lib/btxv86.h" - -extern void __exec(caddr_t addr, ...); -extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); - -static int elf32_exec(struct preloaded_file *amp); -static int elf32_obj_exec(struct preloaded_file *amp); - -struct file_format i386_elf = { elf32_loadfile, elf32_exec }; -struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec }; - -struct file_format *file_formats[] = { - &i386_elf, - &i386_elf_obj, - NULL -}; - -/* - * There is an ELF kernel and one or more ELF modules loaded. - * We wish to start executing the kernel image, so make such - * preparations as are required, and do so. - */ -static int -elf32_exec(struct preloaded_file *fp) -{ - struct file_metadata *md; - Elf_Ehdr *ehdr; - vm_offset_t entry, bootinfop, modulep, kernend; - int boothowto, err, bootdev; - - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) - return(EFTYPE); - ehdr = (Elf_Ehdr *)&(md->md_data); - - efi_time_fini(); - - entry = ehdr->e_entry & 0xffffff; - - printf("Start @ 0x%x ...\n", entry); - - err = bi_load(fp->f_args, &modulep, &kernend, true); - if (err != 0) { - efi_time_init(); - return(err); - } - - /* At this point we've called ExitBootServices, so we can't call - * printf or any other function that uses Boot Services */ - - dev_cleanup(); - __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend); - - panic("exec returned"); -} - -static int -elf32_obj_exec(struct preloaded_file *fp) -{ - return (EFTYPE); -} diff --git a/stand/efi/loader/arch/i386/elf64_freebsd.c b/stand/efi/loader/arch/i386/elf64_freebsd.c new file mode 100644 index 000000000000..22cdd685ea9b --- /dev/null +++ b/stand/efi/loader/arch/i386/elf64_freebsd.c @@ -0,0 +1,279 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define __ELF_WORD_SIZE 64 +#include <sys/param.h> +#include <sys/linker.h> +#include <vm/vm.h> +#include <vm/pmap.h> +#include <machine/elf.h> +#include <machine/pmap_pae.h> +#include <machine/segments.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" + +#include "loader_efi.h" + +static int elf64_exec(struct preloaded_file *amp); +static int elf64_obj_exec(struct preloaded_file *amp); + +static struct file_format amd64_elf = { + .l_load = elf64_loadfile, + .l_exec = elf64_exec +}; + +static struct file_format amd64_elf_obj = { + .l_load = elf64_obj_loadfile, + .l_exec = elf64_obj_exec +}; + +struct file_format *file_formats[] = { + &amd64_elf, + &amd64_elf_obj, + NULL +}; + +/* + * i386's pmap_pae.h doesn't provide this, so + * just typedef our own. + */ +typedef pdpt_entry_t pml4_entry_t; + +static void (*trampoline)(uint32_t stack, void *copy_finish, uint32_t kernend, + uint32_t modulep, uint64_t *pagetable, void *gdtr, uint64_t entry); + +extern void *amd64_tramp; +extern uint32_t amd64_tramp_size; + +/* + * There is an ELF kernel and one or more ELF modules loaded. + * We wish to start executing the kernel image, so make such + * preparations as are required, and do so. + */ +static int +elf64_exec(struct preloaded_file *fp) +{ + /* + * segments.h gives us a 32-bit gdtr, but + * we want a 64-bit one, so define our own. + */ + struct { + uint16_t rd_limit; + uint64_t rd_base; + } __packed *gdtr; + EFI_PHYSICAL_ADDRESS ptr; + EFI_ALLOCATE_TYPE type; + EFI_STATUS err; + struct file_metadata *md; + Elf_Ehdr *ehdr; + pml4_entry_t *PT4; + pdpt_entry_t *PT3; + pd_entry_t *PT2; + struct user_segment_descriptor *gdt; + vm_offset_t modulep, kernend, trampstack; + int i; + + switch (copy_staging) { + case COPY_STAGING_ENABLE: + type = AllocateMaxAddress; + break; + case COPY_STAGING_DISABLE: + type = AllocateAnyPages; + break; + case COPY_STAGING_AUTO: + type = fp->f_kernphys_relocatable ? + AllocateAnyPages : AllocateMaxAddress; + break; + } + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return (EFTYPE); + ehdr = (Elf_Ehdr *)&(md->md_data); + + ptr = G(1); + err = BS->AllocatePages(type, EfiLoaderCode, + EFI_SIZE_TO_PAGES(amd64_tramp_size), &ptr); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline\n"); + return (ENOMEM); + } + + trampoline = (void *)(uintptr_t)ptr; + bcopy(&amd64_tramp, trampoline, amd64_tramp_size); + + /* + * Allocate enough space for the GDTR + two GDT segments + + * our temporary stack (28 bytes). + */ +#define DATASZ (sizeof(*gdtr) + \ + sizeof(struct user_segment_descriptor) * 2 + 28) + + ptr = G(1); + err = BS->AllocatePages(type, EfiLoaderData, + EFI_SIZE_TO_PAGES(DATASZ), &ptr); + if (EFI_ERROR(err)) { + printf("Unable to allocate GDT and stack\n"); + BS->FreePages((uintptr_t)trampoline, 1); + return (ENOMEM); + } + + trampstack = ptr + DATASZ; + +#undef DATASZ + + gdt = (void *)(uintptr_t)ptr; + gdt[0] = (struct user_segment_descriptor) { 0 }; + gdt[1] = (struct user_segment_descriptor) { + .sd_p = 1, .sd_long = 1, .sd_type = SDT_MEMERC + }; + + gdtr = (void *)(uintptr_t)(ptr + + sizeof(struct user_segment_descriptor) * 2); + gdtr->rd_limit = sizeof(struct user_segment_descriptor) * 2 - 1; + gdtr->rd_base = (uintptr_t)gdt; + + if (type == AllocateMaxAddress) { + /* Copy staging enabled */ + + ptr = G(1); + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, + EFI_SIZE_TO_PAGES(512 * 3 * sizeof(uint64_t)), &ptr); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline page table\n"); + BS->FreePages((uintptr_t)trampoline, 1); + BS->FreePages((uintptr_t)gdt, 1); + return (ENOMEM); + } + PT4 = (pml4_entry_t *)(uintptr_t)ptr; + + PT3 = &PT4[512]; + PT2 = &PT3[512]; + + /* + * This is kinda brutal, but every single 1GB VM + * memory segment points to the same first 1GB of + * physical memory. But it is more than adequate. + */ + for (i = 0; i < 512; i++) { + /* + * Each slot of the L4 pages points to the + * same L3 page. + */ + PT4[i] = (uintptr_t)PT3 | PG_V | PG_RW; + + /* + * Each slot of the L3 pages points to the + * same L2 page. + */ + PT3[i] = (uintptr_t)PT2 | PG_V | PG_RW; + + /* + * The L2 page slots are mapped with 2MB pages for 1GB. + */ + PT2[i] = (i * M(2)) | PG_V | PG_RW | PG_PS; + } + } else { + pdpt_entry_t *PT3_l, *PT3_u; + pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; + + err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, + EFI_SIZE_TO_PAGES(512 * 9 * sizeof(uint64_t)), &ptr); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline page table\n"); + BS->FreePages((uintptr_t)trampoline, 1); + BS->FreePages((uintptr_t)gdt, 1); + return (ENOMEM); + } + PT4 = (pml4_entry_t *)(uintptr_t)ptr; + + PT3_l = &PT4[512]; + PT3_u = &PT3_l[512]; + PT2_l0 = &PT3_u[512]; + PT2_l1 = &PT2_l0[512]; + PT2_l2 = &PT2_l1[512]; + PT2_l3 = &PT2_l2[512]; + PT2_u0 = &PT2_l3[512]; + PT2_u1 = &PT2_u0[512]; + + /* 1:1 mapping of lower 4G */ + PT4[0] = (uintptr_t)PT3_l | PG_V | PG_RW; + PT3_l[0] = (uintptr_t)PT2_l0 | PG_V | PG_RW; + PT3_l[1] = (uintptr_t)PT2_l1 | PG_V | PG_RW; + PT3_l[2] = (uintptr_t)PT2_l2 | PG_V | PG_RW; + PT3_l[3] = (uintptr_t)PT2_l3 | PG_V | PG_RW; + for (i = 0; i < 2048; i++) { + PT2_l0[i] = ((pd_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS; + } + + /* mapping of kernel 2G below top */ + PT4[511] = (uintptr_t)PT3_u | PG_V | PG_RW; + PT3_u[511] = (uintptr_t)PT2_u1 | PG_V | PG_RW; + PT3_u[510] = (uintptr_t)PT2_u0 | PG_V | PG_RW; + /* compat mapping of phys @0 */ + PT2_u0[0] = PG_PS | PG_V | PG_RW; + /* this maps past staging area */ + for (i = 1; i < 1024; i++) { + PT2_u0[i] = (staging + (i - 1) * M(2)) + | PG_V | PG_RW | PG_PS; + } + } + + printf( + "staging %#llx (%scopying) tramp %p PT4 %p GDT %p\n" + "Start @ %#llx ...\n", staging, + type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, gdt, + ehdr->e_entry + ); + + + /* + * we have to cleanup here because net_cleanup() doesn't work after + * we call ExitBootServices + */ + dev_cleanup(); + + efi_time_fini(); + err = bi_load(fp->f_args, &modulep, &kernend, true); + if (err != 0) { + efi_time_init(); + return (err); + } + + trampoline(trampstack, type == AllocateMaxAddress ? efi_copy_finish : + efi_copy_finish_nop, kernend, modulep, PT4, gdtr, ehdr->e_entry); + + panic("exec returned"); +} + +static int +elf64_obj_exec(struct preloaded_file *fp) +{ + return (EFTYPE); +} diff --git a/stand/efi/loader/arch/i386/exec.c b/stand/efi/loader/arch/i386/exec.c deleted file mode 100644 index 579f5593b24b..000000000000 --- a/stand/efi/loader/arch/i386/exec.c +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <machine/elf.h> -#include "../btx/lib/btxv86.h" - -#include "../../common/bootstrap.h" - -uint32_t __base; -struct __v86 __v86; - -void -__v86int() -{ - printf("%s\n", __func__); - exit(1); -} - -void -__exec(caddr_t addr, ...) -{ -} diff --git a/stand/efi/loader/arch/i386/ldscript.i386 b/stand/efi/loader/arch/i386/i386.ldscript index e17212a1bddd..dcbbf1b6d609 100644 --- a/stand/efi/loader/arch/i386/ldscript.i386 +++ b/stand/efi/loader/arch/i386/i386.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd") OUTPUT_ARCH(i386) ENTRY(_start) @@ -30,17 +29,6 @@ SECTIONS *(COMMON) } . = ALIGN(4096); - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } - . = ALIGN(4096); __gp = .; .sdata : { *(.got.plt .got) @@ -53,18 +41,8 @@ SECTIONS .dynamic : { *(.dynamic) } . = ALIGN(4096); .rel.dyn : { - *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) - *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) - *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) - *(.rel.got) - *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) - *(.rel.plt) + *(.rel.*) *(.relset_*) - *(.rel.dyn .rel.dyn.*) } . = ALIGN(4096); .reloc : { *(.reloc) } diff --git a/stand/efi/loader/arch/i386/i386_copy.c b/stand/efi/loader/arch/i386/setup.c index 2c4b0deb49cf..5d15e499ddb3 100644 --- a/stand/efi/loader/arch/i386/i386_copy.c +++ b/stand/efi/loader/arch/i386/setup.c @@ -1,6 +1,7 @@ /*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * All rights reserved. + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Ahmad Khalifa <ahmadkhalifa570@gmail.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -11,10 +12,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -24,35 +25,27 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +#include <sys/types.h> -/* - * MD primitives supporting placement of module data - * - * XXX should check load address/size against memory top. - */ -#include <stand.h> +#include <efi.h> +#include <efilib.h> -#include "libi386.h" -#include "btxv86.h" +#include <machine/specialreg.h> -ssize_t -i386_copyin(const void *src, vm_offset_t dest, const size_t len) -{ - bcopy(src, PTOV(dest), len); - return(len); -} +/* + * Check for long mode then call efi_main + */ +EFI_STATUS +setup(EFI_HANDLE IH, EFI_SYSTEM_TABLE *ST) { + u_int edx; -ssize_t -i386_copyout(const vm_offset_t src, void *dest, const size_t len) -{ - bcopy(PTOV(src), dest, len); - return(len); -} + asm("cpuid" : "=d"(edx) : "a"(0x80000001) : "ebx", "ecx"); + if ((edx & AMDID_LM) == 0) { + ST->ConOut->OutputString(ST->ConOut, (CHAR16 *) + L"This CPU doesn't support long mode.\r\n" + L"Unable to proceed.\r\n"); + ST->BootServices->Exit(IH, EFI_UNSUPPORTED, 0, NULL); + } -ssize_t -i386_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) -{ - return (VECTX_READ(fd, PTOV(dest), len)); + return (efi_main(IH, ST)); } diff --git a/stand/efi/loader/arch/i386/start.S b/stand/efi/loader/arch/i386/start.S index b597f419d4a1..2754c81e509c 100644 --- a/stand/efi/loader/arch/i386/start.S +++ b/stand/efi/loader/arch/i386/start.S @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org> + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger <davidm@hpl.hp.com>. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,59 +11,65 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hewlett-Packard Co. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ + */ + +/* + * crt0-efi-ia32.S - x86 EFI startup code. */ .text + .align 4 -#include <machine/asm.h> + .globl _start +_start: + pushl %ebp + movl %esp, %ebp -#define EFI_SUCCESS 0 + pushl 12(%ebp) + pushl 8(%ebp) -/* - * EFI entry point. - * _start(EFI_IMAGE image_handle, EFI_SYSTEM_TABLE *system_table); - * - * We calculate the base address along with _DYNAMIC, relocate us and finally - * pass control to efi_main. - */ + call 0f +0: popl %eax + movl %eax, %ebx + + addl $ImageBase-0b, %eax + addl $_DYNAMIC-0b, %ebx -ENTRY(_start) - pushl %ebp - movl %esp, %ebp + pushl %ebx + pushl %eax + call self_reloc + popl %ebx + popl %ebx - pushl 12(%ebp) /* image_handle */ - pushl 8(%ebp) /* system_table */ - call 0f -0: popl %eax - movl %eax, %ebx - addl $ImageBase-0b, %eax - addl $_DYNAMIC-0b, %ebx - pushl %ebx /* dynamic */ - pushl %eax /* ImageBase */ - call self_reloc - popl %ebx /* remove ImageBase from the stack */ - popl %ebx /* remove dynamic from the stack */ - call efi_main -1: leave + call setup + +.exit: + leave ret -END(_start) + + /* + * hand-craft a dummy .reloc section so EFI knows it's a relocatable + * executable: + */ .data .section .reloc, "a" - .long 0 - .long 10 - .word 0 + .long 0 + .long 10 + .word 0 diff --git a/stand/efi/loader/arch/riscv/Makefile.inc b/stand/efi/loader/arch/riscv/Makefile.inc index 333b789e935d..e7f7fd8b7f4f 100644 --- a/stand/efi/loader/arch/riscv/Makefile.inc +++ b/stand/efi/loader/arch/riscv/Makefile.inc @@ -1,7 +1,4 @@ -# $FreeBSD$ - HAVE_FDT=yes SRCS+= exec.c \ - efiserialio.c \ start.S diff --git a/stand/efi/loader/arch/riscv/exec.c b/stand/efi/loader/arch/riscv/exec.c index c7d90a4f31d0..a53fbd9442b0 100644 --- a/stand/efi/loader/arch/riscv/exec.c +++ b/stand/efi/loader/arch/riscv/exec.c @@ -2,6 +2,7 @@ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org> * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com> * All rights reserved. + * Copyright (c) 2024 The FreeBSD Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/linker.h> @@ -43,7 +41,27 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "loader_efi.h" -extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool); +static void +riscv_set_boot_hart(struct preloaded_file *fp) +{ + EFI_GUID riscvboot = RISCV_EFI_BOOT_PROTOCOL_GUID; + RISCV_EFI_BOOT_PROTOCOL *proto; + EFI_STATUS status = 0; + uint64_t boot_hartid = ULONG_MAX; + + status = BS->LocateProtocol(&riscvboot, NULL, (void **)&proto); + if (EFI_ERROR(status)) { + return; + } + + status = proto->GetBootHartId(proto, &boot_hartid); + if (EFI_ERROR(status)) { + return; + } + + file_addmetadata(fp, MODINFOMD_BOOT_HARTID, sizeof(boot_hartid), + &boot_hartid); +} static int __elfN(exec)(struct preloaded_file *fp) @@ -57,6 +75,8 @@ __elfN(exec)(struct preloaded_file *fp) if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); + riscv_set_boot_hart(fp); + e = (Elf_Ehdr *)&fmp->md_data; efi_time_fini(); @@ -66,17 +86,17 @@ __elfN(exec)(struct preloaded_file *fp) printf("Kernel entry at %p...\n", entry); printf("Kernel args: %s\n", fp->f_args); + /* + * we have to cleanup here because net_cleanup() doesn't work after + * we call ExitBootServices + */ + dev_cleanup(); + if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) { efi_time_init(); return (error); } - /* - * At this point we've called ExitBootServices, so we can't call - * printf or any other function that uses Boot Services - */ - dev_cleanup(); - (*entry)((void *)modulep); panic("exec returned"); } diff --git a/stand/efi/loader/arch/riscv/ldscript.riscv b/stand/efi/loader/arch/riscv/riscv.ldscript index aa736f0d9b2a..63b71c3bd702 100644 --- a/stand/efi/loader/arch/riscv/ldscript.riscv +++ b/stand/efi/loader/arch/riscv/riscv.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") OUTPUT_ARCH(riscv64) ENTRY(_start) @@ -36,17 +35,6 @@ SECTIONS __bss_end = .; } . = ALIGN(16); - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } - . = ALIGN(16); .sdata : { /* * u-boot expects the gp register to be untouched by the EFI payload, so we diff --git a/stand/efi/loader/arch/riscv/start.S b/stand/efi/loader/arch/riscv/start.S index e63ce68d86ba..fb7d65f17c99 100644 --- a/stand/efi/loader/arch/riscv/start.S +++ b/stand/efi/loader/arch/riscv/start.S @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 Mitchell Horne <mhorne@FreeBSD.org> * @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asm.h> diff --git a/stand/efi/loader/autoload.c b/stand/efi/loader/autoload.c index d409285834c3..ba7997487ffc 100644 --- a/stand/efi/loader/autoload.c +++ b/stand/efi/loader/autoload.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #if defined(LOADER_FDT_SUPPORT) #include <sys/param.h> #include <fdt_platform.h> diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c index c7b682819a98..b8f1a2ffd56c 100644 --- a/stand/efi/loader/bootinfo.c +++ b/stand/efi/loader/bootinfo.c @@ -26,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <sys/param.h> @@ -40,17 +37,24 @@ __FBSDID("$FreeBSD$"); #include <machine/metadata.h> #include <machine/psl.h> +#ifdef EFI #include <efi.h> #include <efilib.h> +#else +#include "kboot.h" +#endif #include "bootstrap.h" -#include "loader_efi.h" +#include "modinfo.h" #if defined(__amd64__) #include <machine/specialreg.h> #endif +#ifdef EFI +#include "loader_efi.h" #include "gfx_fb.h" +#endif #if defined(LOADER_FDT_SUPPORT) #include <fdt_platform.h> @@ -60,17 +64,17 @@ __FBSDID("$FreeBSD$"); #include "geliboot.h" #endif -int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); - static int bi_getboothowto(char *kargs) { +#ifdef EFI const char *sw, *tmp; char *opts; - char *console; - int howto, speed, port; + int speed, port; char buf[50]; +#endif + char *console; + int howto; howto = boot_parse_cmdline(kargs); howto |= boot_env_to_howto(); @@ -81,6 +85,7 @@ bi_getboothowto(char *kargs) howto |= RB_SERIAL; if (strcmp(console, "nullconsole") == 0) howto |= RB_MUTE; +#ifdef EFI #if defined(__i386__) || defined(__amd64__) if (strcmp(console, "efi") == 0 && getenv("efi_8250_uid") != NULL && @@ -108,10 +113,17 @@ bi_getboothowto(char *kargs) if (tmp != NULL) speed = strtol(tmp, NULL, 0); tmp = getenv("efi_com_port"); - if (tmp == NULL) - tmp = getenv("comconsole_port"); if (tmp != NULL) port = strtol(tmp, NULL, 0); + if (port <= 0) { + tmp = getenv("comconsole_port"); + if (tmp != NULL) + port = strtol(tmp, NULL, 0); + else { + if (port == 0) + port = 0x3f8; + } + } if (speed != -1 && port != -1) { snprintf(buf, sizeof(buf), "io:%d,br:%d", port, speed); @@ -120,139 +132,13 @@ bi_getboothowto(char *kargs) } } #endif +#endif } return (howto); } -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -static vm_offset_t -bi_copyenv(vm_offset_t start) -{ - struct env_var *ep; - vm_offset_t addr, last; - size_t len; - - addr = last = start; - - /* Traverse the environment. */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - len = strlen(ep->ev_name); - if ((size_t)archsw.arch_copyin(ep->ev_name, addr, len) != len) - break; - addr += len; - if (archsw.arch_copyin("=", addr, 1) != 1) - break; - addr++; - if (ep->ev_value != NULL) { - len = strlen(ep->ev_value); - if ((size_t)archsw.arch_copyin(ep->ev_value, addr, len) != len) - break; - addr += len; - } - if (archsw.arch_copyin("", addr, 1) != 1) - break; - last = ++addr; - } - - if (archsw.arch_copyin("", last++, 1) != 1) - last = start; - return(last); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long)); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long)); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -bi_copymodules(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - uint64_t v; - - c = addr != 0; - /* Start with the first module on the list, should be the kernel. */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - MOD_NAME(addr, fp->f_name, c); /* This must come first. */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - v = fp->f_addr; -#if defined(__arm__) - v -= __elfN(relocation_offset); -#endif - MOD_ADDR(addr, v, c); - v = fp->f_size; - MOD_SIZE(addr, v, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - MOD_END(addr, c); - return(addr); -} - +#ifdef EFI static EFI_STATUS efi_do_vmap(EFI_MEMORY_DESCRIPTOR *mm, UINTN sz, UINTN mmsz, UINT32 mmver) { @@ -296,7 +182,7 @@ bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs) struct efi_map_header *efihdr; bool do_vmap; -#if defined(__amd64__) || defined(__aarch64__) +#ifdef MODINFOMD_EFI_FB struct efi_fb efifb; efifb.fb_addr = gfx_state.tg_fb.fb_addr; @@ -309,16 +195,19 @@ bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs) efifb.fb_mask_blue = gfx_state.tg_fb.fb_mask_blue; efifb.fb_mask_reserved = gfx_state.tg_fb.fb_mask_reserved; - printf("EFI framebuffer information:\n"); - printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, efifb.fb_size); - printf("dimensions %d x %d\n", efifb.fb_width, efifb.fb_height); - printf("stride %d\n", efifb.fb_stride); - printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, - efifb.fb_mask_reserved); + if (efifb.fb_addr != 0) { + printf("EFI framebuffer information:\n"); + printf("addr, size 0x%jx, 0x%jx\n", + efifb.fb_addr, efifb.fb_size); + printf("dimensions %d x %d\n", + efifb.fb_width, efifb.fb_height); + printf("stride %d\n", efifb.fb_stride); + printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, + efifb.fb_mask_reserved); - if (efifb.fb_addr != 0) file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb); + } #endif do_vmap = true; @@ -421,6 +310,7 @@ bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs) return (0); } +#endif /* * Load the information expected by an amd64 kernel. @@ -438,11 +328,24 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) struct devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; - uint64_t kernend, module; + uint64_t kernend; +#ifdef MODINFOMD_MODULEP + uint64_t module; +#endif uint64_t envp; vm_offset_t size; char *rootdevname; int howto; +#ifdef __i386__ + /* + * The 32-bit UEFI loader is used to + * boot the 64-bit kernel on machines + * that support it. + */ + bool is64 = true; +#else + bool is64 = sizeof(long) == 8; +#endif #if defined(LOADER_FDT_SUPPORT) vm_offset_t dtbp; int dtb_size; @@ -462,7 +365,6 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif }; #endif - howto = bi_getboothowto(args); /* @@ -478,48 +380,53 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(efi_fmtdev((void *)rootdev)); + getrootmount(devformat(rootdev)); addr = 0; for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) + if (addr < xp->f_addr + xp->f_size) addr = xp->f_addr + xp->f_size; } /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); +#ifdef EFI addr = build_font_module(addr); /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); + + addr = build_splash_module(addr); + + /* Pad to a page boundary. */ + addr = md_align(addr); +#endif /* Copy our environment. */ envp = addr; - addr = bi_copyenv(addr); + addr = md_copyenv(addr); /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); #if defined(LOADER_FDT_SUPPORT) /* Handle device tree blob */ dtbp = addr; dtb_size = fdt_copy(addr); - + /* Pad to a page boundary */ if (dtb_size) - addr += roundup(dtb_size, PAGE_SIZE); + addr += md_align(dtb_size); #endif - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf64 kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ /* Figure out the size and location of the metadata. */ - module = *modulep = addr; + *modulep = addr; file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof(howto), &howto); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof(envp), &envp); @@ -532,16 +439,29 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof(kernend), &kernend); #ifdef MODINFOMD_MODULEP + module = *modulep; file_addmetadata(kfp, MODINFOMD_MODULEP, sizeof(module), &module); #endif +#ifdef EFI +#ifndef __i386__ file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof(ST), &ST); +#endif +#if defined(__amd64__) || defined(__i386__) + file_addmetadata(kfp, MODINFOMD_EFI_ARCH, sizeof(MACHINE_ARCH), + MACHINE_ARCH); +#endif +#endif #ifdef LOADER_GELI_SUPPORT geli_export_key_metadata(kfp); #endif +#ifdef EFI bi_load_efi_data(kfp, exit_bs); +#else + bi_loadsmap(kfp); +#endif - size = bi_copymodules(0); - kernend = roundup(addr + size, PAGE_SIZE); + size = md_copymodules(0, is64); /* Find the size of the modules */ + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ @@ -565,7 +485,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif /* Copy module list and metadata. */ - (void)bi_copymodules(addr); + (void)md_copymodules(addr, is64); return (0); } diff --git a/stand/efi/loader/conf.c b/stand/efi/loader/conf.c index 863c9188c72c..0a0476873fe1 100644 --- a/stand/efi/loader/conf.c +++ b/stand/efi/loader/conf.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <bootstrap.h> #include <efi.h> @@ -80,16 +77,25 @@ struct netif_driver *netif_drivers[] = { }; extern struct console efi_console; +extern struct console eficom; +#if defined(__aarch64__) && __FreeBSD_version < 1500000 +/* Hack for backward compatibility -- but only for a while */ extern struct console comconsole; +#endif #if defined(__amd64__) || defined(__i386__) +extern struct console comconsole; extern struct console nullconsole; extern struct console spinconsole; #endif struct console *consoles[] = { &efi_console, + &eficom, +#if defined(__aarch64__) && __FreeBSD_version < 1500000 &comconsole, +#endif #if defined(__amd64__) || defined(__i386__) + &comconsole, &nullconsole, &spinconsole, #endif diff --git a/stand/efi/loader/copy.c b/stand/efi/loader/copy.c index 47e613ccc2f3..e4ad865a4acd 100644 --- a/stand/efi/loader/copy.c +++ b/stand/efi/loader/copy.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -26,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <stand.h> @@ -39,10 +35,7 @@ __FBSDID("$FreeBSD$"); #include "loader_efi.h" -#define M(x) ((x) * 1024 * 1024) -#define G(x) (1UL * (x) * 1024 * 1024 * 1024) - -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) #include <machine/cpufunc.h> #include <machine/specialreg.h> #include <machine/vmparam.h> @@ -174,7 +167,7 @@ efi_verify_staging_size(unsigned long *nr_pages) out: free(map); } -#endif /* __i386__ || __amd64__ */ +#endif /* __amd64__ */ #if defined(__arm__) #define DEFAULT_EFI_STAGING_SIZE 32 @@ -185,14 +178,9 @@ out: #define EFI_STAGING_SIZE DEFAULT_EFI_STAGING_SIZE #endif -#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \ - defined(__riscv) #define EFI_STAGING_2M_ALIGN 1 -#else -#define EFI_STAGING_2M_ALIGN 0 -#endif -#if defined(__amd64__) +#if defined(__amd64__) || defined(__i386__) #define EFI_STAGING_SLOP M(8) #else #define EFI_STAGING_SLOP 0 @@ -201,7 +189,7 @@ out: static u_long staging_slop = EFI_STAGING_SLOP; EFI_PHYSICAL_ADDRESS staging, staging_end, staging_base; -int stage_offset_set = 0; +bool stage_offset_set = false; ssize_t stage_offset; static void @@ -209,11 +197,11 @@ efi_copy_free(void) { BS->FreePages(staging_base, (staging_end - staging_base) / EFI_PAGE_SIZE); - stage_offset_set = 0; + stage_offset_set = false; stage_offset = 0; } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__i386__) int copy_staging = COPY_STAGING_AUTO; static int @@ -224,11 +212,10 @@ command_copy_staging(int argc, char *argv[]) [COPY_STAGING_DISABLE] = "disable", [COPY_STAGING_AUTO] = "auto", }; - int prev, res; + int prev; - res = CMD_OK; if (argc > 2) { - res = CMD_ERROR; + goto usage; } else if (argc == 2) { prev = copy_staging; if (strcmp(argv[1], "enable") == 0) @@ -237,11 +224,9 @@ command_copy_staging(int argc, char *argv[]) copy_staging = COPY_STAGING_DISABLE; else if (strcmp(argv[1], "auto") == 0) copy_staging = COPY_STAGING_AUTO; - else { - printf("usage: copy_staging enable|disable|auto\n"); - res = CMD_ERROR; - } - if (res == CMD_OK && prev != copy_staging) { + else + goto usage; + if (prev != copy_staging) { printf("changed copy_staging, unloading kernel\n"); unload(); efi_copy_free(); @@ -250,7 +235,11 @@ command_copy_staging(int argc, char *argv[]) } else { printf("copy staging: %s\n", mode[copy_staging]); } - return (res); + return (CMD_OK); + +usage: + command_errmsg = "usage: copy_staging enable|disable|auto"; + return (CMD_ERROR); } COMMAND_SET(copy_staging, "copy_staging", "copy staging", command_copy_staging); #endif @@ -260,19 +249,17 @@ command_staging_slop(int argc, char *argv[]) { char *endp; u_long new, prev; - int res; - res = CMD_OK; if (argc > 2) { - res = CMD_ERROR; + goto err; } else if (argc == 2) { new = strtoul(argv[1], &endp, 0); - if (*endp != '\0') { - printf("invalid slop value\n"); - res = CMD_ERROR; - } - if (res == CMD_OK && staging_slop != new) { + if (*endp != '\0') + goto err; + if (staging_slop != new) { + staging_slop = new; printf("changed slop, unloading kernel\n"); + unload(); efi_copy_free(); efi_copy_init(); @@ -280,14 +267,18 @@ command_staging_slop(int argc, char *argv[]) } else { printf("staging slop %#lx\n", staging_slop); } - return (res); + return (CMD_OK); + +err: + command_errmsg = "invalid slop value"; + return (CMD_ERROR); } COMMAND_SET(staging_slop, "staging_slop", "set staging slop", command_staging_slop); -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) || defined(__i386__) /* - * The staging area must reside in the the first 1GB or 4GB physical + * The staging area must reside in the first 1GB or 4GB physical * memory: see elf64_exec() in * boot/efi/loader/arch/amd64/elf64_freebsd.c. */ @@ -296,13 +287,20 @@ get_staging_max(void) { EFI_PHYSICAL_ADDRESS res; -#if defined(__i386__) - res = G(1); -#elif defined(__amd64__) res = copy_staging == COPY_STAGING_ENABLE ? G(1) : G(4); -#endif return (res); } +#define EFI_ALLOC_MAX_ADDR +#elif defined(__aarch64__) +/* + * Older kernels only support a 48-bit physical address space, and locore.S + * only supports a 50-bit space. Limit to 48 bits so older kernels can boot + * even if FEAT_LPA2 is supported by the hardware. + */ +#define get_staging_max() (1ul << 48) +#define EFI_ALLOC_MAX_ADDR +#endif +#ifdef EFI_ALLOC_MAX_ADDR #define EFI_ALLOC_METHOD AllocateMaxAddress #else #define EFI_ALLOC_METHOD AllocateAnyPages @@ -320,7 +318,7 @@ efi_copy_init(void) ess = DEFAULT_EFI_STAGING_SIZE; nr_pages = EFI_SIZE_TO_PAGES(M(1) * ess); -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) /* * We'll decrease nr_pages, if it's too big. Currently we only * apply this to FreeBSD VM running on Hyper-V. Why? Please see @@ -328,10 +326,11 @@ efi_copy_init(void) */ if (running_on_hyperv()) efi_verify_staging_size(&nr_pages); - +#endif +#ifdef EFI_ALLOC_MAX_ADDR staging = get_staging_max(); #endif - status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderData, + status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderCode, nr_pages, &staging); if (EFI_ERROR(status)) { printf("failed to allocate staging area: %lu\n", @@ -388,10 +387,10 @@ efi_check_space(vm_offset_t end) end += staging_slop; nr_pages = EFI_SIZE_TO_PAGES(end - staging_end); -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) || defined(__i386__) /* - * i386 needs all memory to be allocated under the 1G boundary. - * amd64 needs all memory to be allocated under the 1G or 4G boundary. + * The amd64 kernel needs all memory to be allocated under the 1G or + * 4G boundary. */ if (end > get_staging_max()) goto before_staging; @@ -399,7 +398,7 @@ efi_check_space(vm_offset_t end) /* Try to allocate more space after the previous allocation */ addr = staging_end; - status = BS->AllocatePages(AllocateAddress, EfiLoaderData, nr_pages, + status = BS->AllocatePages(AllocateAddress, EfiLoaderCode, nr_pages, &addr); if (!EFI_ERROR(status)) { staging_end = staging_end + nr_pages * EFI_PAGE_SIZE; @@ -416,7 +415,7 @@ before_staging: addr = rounddown2(addr, M(2)); #endif nr_pages = EFI_SIZE_TO_PAGES(staging_base - addr); - status = BS->AllocatePages(AllocateAddress, EfiLoaderData, nr_pages, + status = BS->AllocatePages(AllocateAddress, EfiLoaderCode, nr_pages, &addr); if (!EFI_ERROR(status)) { /* @@ -436,10 +435,10 @@ expand: #if EFI_STAGING_2M_ALIGN nr_pages += M(2) / EFI_PAGE_SIZE; #endif -#if defined(__i386__) || defined(__amd64__) +#ifdef EFI_ALLOC_MAX_ADDR new_base = get_staging_max(); #endif - status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderData, + status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderCode, nr_pages, &new_base); if (!EFI_ERROR(status)) { #if EFI_STAGING_2M_ALIGN @@ -479,7 +478,7 @@ efi_copyin(const void *src, vm_offset_t dest, const size_t len) if (!stage_offset_set) { stage_offset = (vm_offset_t)staging - dest; - stage_offset_set = 1; + stage_offset_set = true; } /* XXX: Callers do not check for failure. */ @@ -510,7 +509,7 @@ efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) if (!stage_offset_set) { stage_offset = (vm_offset_t)staging - dest; - stage_offset_set = 1; + stage_offset_set = true; } if (!efi_check_space(dest + stage_offset + len)) { diff --git a/stand/efi/loader/efi_main.c b/stand/efi/loader/efi_main.c index 3e1fa06638e9..2a5120dc89d7 100644 --- a/stand/efi/loader/efi_main.c +++ b/stand/efi/loader/efi_main.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <bootstrap.h> #include <efi.h> #include <eficonsctl.h> diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c index d5504c9cff35..141a29305f7c 100644 --- a/stand/efi/loader/framebuffer.c +++ b/stand/efi/loader/framebuffer.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -26,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <bootstrap.h> #include <sys/endian.h> #include <sys/param.h> @@ -81,6 +77,11 @@ static struct named_resolution { .height = 1080, }, { + .name = "1440p", + .width = 2560, + .height = 1440, + }, + { .name = "2160p", .alias = "4k", .width = 3840, @@ -148,7 +149,16 @@ efifb_from_gop(struct efi_fb *efifb, EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode, { int result; - efifb->fb_addr = mode->FrameBufferBase; + /* + * The Asus EEEPC 1025C, and possibly others, + * require the address to be masked. + */ + efifb->fb_addr = +#ifdef __i386__ + mode->FrameBufferBase & 0xffffffff; +#else + mode->FrameBufferBase; +#endif efifb->fb_size = mode->FrameBufferSize; efifb->fb_height = info->VerticalResolution; efifb->fb_width = info->HorizontalResolution; @@ -536,9 +546,25 @@ efifb_get_edid(edid_res_list_t *res) return (rv); } +bool +efi_has_gop(void) +{ + EFI_STATUS status; + EFI_HANDLE *hlist; + UINTN hsize; + + hsize = 0; + hlist = NULL; + status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize, hlist); + + return (status == EFI_BUFFER_TOO_SMALL); +} + + int efi_find_framebuffer(teken_gfx_t *gfx_state) { + EFI_PHYSICAL_ADDRESS ptr; EFI_HANDLE *hlist; UINTN nhandles, i, hsize; struct efi_fb efifb; @@ -635,16 +661,15 @@ efi_find_framebuffer(teken_gfx_t *gfx_state) efifb.fb_mask_blue | efifb.fb_mask_reserved); if (gfx_state->tg_shadow_fb != NULL) - BS->FreePages((EFI_PHYSICAL_ADDRESS)gfx_state->tg_shadow_fb, + BS->FreePages((uintptr_t)gfx_state->tg_shadow_fb, gfx_state->tg_shadow_sz); gfx_state->tg_shadow_sz = EFI_SIZE_TO_PAGES(efifb.fb_height * efifb.fb_width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, - gfx_state->tg_shadow_sz, - (EFI_PHYSICAL_ADDRESS *)&gfx_state->tg_shadow_fb); - if (status != EFI_SUCCESS) - gfx_state->tg_shadow_fb = NULL; + status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, + gfx_state->tg_shadow_sz, &ptr); + gfx_state->tg_shadow_fb = status == EFI_SUCCESS ? + (uint32_t *)(uintptr_t)ptr : NULL; return (0); } @@ -831,6 +856,7 @@ command_gop(int argc, char *argv[]) struct efi_fb efifb; EFI_STATUS status; u_int mode; + extern bool ignore_gop_blt; if (gop == NULL) { snprintf(command_errbuf, sizeof(command_errbuf), @@ -841,7 +867,7 @@ command_gop(int argc, char *argv[]) if (argc < 2) goto usage; - if (!strcmp(argv[1], "set")) { + if (strcmp(argv[1], "set") == 0) { char *cp; if (argc != 3) @@ -859,7 +885,26 @@ command_gop(int argc, char *argv[]) return (CMD_ERROR); } (void) cons_update_mode(true); + } else if (strcmp(argv[1], "blt") == 0) { + /* + * "blt on" does allow gop->Blt() to be used (default). + * "blt off" does block gop->Blt() to be used and use + * software rendering instead. + */ + if (argc != 3) + goto usage; + if (strcmp(argv[2], "on") == 0) + ignore_gop_blt = false; + else if (strcmp(argv[2], "off") == 0) + ignore_gop_blt = true; + else + goto usage; } else if (strcmp(argv[1], "off") == 0) { + /* + * Tell console to use SimpleTextOutput protocol. + * This means that we do not render the glyphs, but rely on + * UEFI firmware to draw on ConsOut device(s). + */ (void) cons_update_mode(false); } else if (strcmp(argv[1], "get") == 0) { edid_res_list_t res; @@ -883,7 +928,7 @@ command_gop(int argc, char *argv[]) } print_efifb(gop->Mode->Mode, &efifb, 1); printf("\n"); - } else if (!strcmp(argv[1], "list")) { + } else if (strcmp(argv[1], "list") == 0) { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; UINTN infosz; @@ -906,7 +951,7 @@ command_gop(int argc, char *argv[]) usage: snprintf(command_errbuf, sizeof(command_errbuf), - "usage: %s [list | get | set <mode> | off]", argv[0]); + "usage: %s [list | get | set <mode> | off | blt <on|off>]", argv[0]); return (CMD_ERROR); } diff --git a/stand/efi/loader/framebuffer.h b/stand/efi/loader/framebuffer.h index 008df7f6c167..c6015f4ccbd3 100644 --- a/stand/efi/loader/framebuffer.h +++ b/stand/efi/loader/framebuffer.h @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,15 +23,15 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ +#include <teken.h> #include <gfx_fb.h> #ifndef _EFIFB_H_ #define _EFIFB_H_ +bool efi_has_gop(void); int efi_find_framebuffer(teken_gfx_t *gfx_state); #endif /* _EFIFB_H_ */ diff --git a/stand/efi/loader/loader_efi.h b/stand/efi/loader/loader_efi.h index 8254d16b1592..be991eeb9573 100644 --- a/stand/efi/loader/loader_efi.h +++ b/stand/efi/loader/loader_efi.h @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _LOADER_EFI_COPY_H_ @@ -33,8 +30,9 @@ #include <stand.h> #include <readin.h> +#include <efi.h> -#ifdef __amd64__ +#if defined(__amd64__) || defined(__i386__) enum { COPY_STAGING_ENABLE, COPY_STAGING_DISABLE, @@ -43,6 +41,12 @@ enum { extern int copy_staging; #endif +/* Useful for various calculations */ +#define M(x) ((x) * 1024 * 1024) +#define G(x) (1ULL * (x) * 1024 * 1024 * 1024) + +extern EFI_LOADED_IMAGE *boot_img; + int efi_autoload(void); int efi_copy_init(void); @@ -55,4 +59,12 @@ void * efi_translate(vm_offset_t ptr); void efi_copy_finish(void); void efi_copy_finish_nop(void); +#if defined(__amd64__) || defined(__i386__) +/* Need this to setup page tables */ +extern EFI_PHYSICAL_ADDRESS staging; +#endif + +int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, + bool exit_bs); + #endif /* _LOADER_EFI_COPY_H_ */ diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index eb143989190d..436676368447 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -4,7 +4,7 @@ * All rights reserved. * * Copyright (c) 2016-2019 Netflix, Inc. written by M. Warner Losh - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -27,9 +27,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/disk.h> @@ -48,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <disk.h> #include <dev_net.h> #include <net.h> +#include <machine/_inttypes.h> #include <efi.h> #include <efilib.h> @@ -59,11 +57,31 @@ __FBSDID("$FreeBSD$"); #include <bootstrap.h> #include <smbios.h> +#include <dev/random/fortuna.h> +#include <geom/eli/pkcs5v2.h> + #include "efizfs.h" +#include "framebuffer.h" + +#include "platform/acfreebsd.h" +#include "acconfig.h" +#define ACPI_SYSTEM_XFACE +#include "actypes.h" +#include "actbl.h" #include "loader_efi.h" -struct arch_switch archsw; /* MI/MD interface boundary */ +struct arch_switch archsw = { /* MI/MD interface boundary */ + .arch_autoload = efi_autoload, + .arch_getdev = efi_getdev, + .arch_copyin = efi_copyin, + .arch_copyout = efi_copyout, +#if defined(__amd64__) || defined(__i386__) + .arch_hypervisor = x86_hypervisor, +#endif + .arch_readin = efi_readin, + .arch_zfs_probe = efi_zfs_probe, +}; EFI_GUID acpi = ACPI_TABLE_GUID; EFI_GUID acpi20 = ACPI_20_TABLE_GUID; @@ -102,6 +120,11 @@ UINT16 boot_current; */ EFI_LOADED_IMAGE *boot_img; +/* + * RSDP base table. + */ +ACPI_TABLE_RSDP *rsdp; + static bool has_keyboard(void) { @@ -185,25 +208,11 @@ out: } static void -set_currdev(const char *devname) -{ - - env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, - env_nounset); - /* - * Don't execute hook here; the loaddev hook makes it immutable - * once we've determined what the proper currdev is. - */ - env_setenv("loaddev", EV_VOLATILE | EV_NOHOOK, devname, env_noset, - env_nounset); -} - -static void set_currdev_devdesc(struct devdesc *currdev) { const char *devname; - devname = efi_fmtdev(currdev); + devname = devformat(currdev); printf("Setting currdev to %s\n", devname); set_currdev(devname); } @@ -263,42 +272,36 @@ sanity_check_currdev(void) static bool probe_zfs_currdev(uint64_t guid) { + char buf[VDEV_PAD_SIZE]; char *devname; struct zfs_devdesc currdev; - char *buf = NULL; - bool rv; currdev.dd.d_dev = &zfs_dev; currdev.dd.d_unit = 0; currdev.pool_guid = guid; currdev.root_guid = 0; - set_currdev_devdesc((struct devdesc *)&currdev); - devname = efi_fmtdev(&currdev); + devname = devformat(&currdev.dd); + set_currdev(devname); + printf("Setting currdev to %s\n", devname); init_zfs_boot_options(devname); - rv = sanity_check_currdev(); - if (rv) { - buf = malloc(VDEV_PAD_SIZE); - if (buf != NULL) { - if (zfs_get_bootonce(&currdev, OS_BOOTONCE, buf, - VDEV_PAD_SIZE) == 0) { - printf("zfs bootonce: %s\n", buf); - set_currdev(buf); - setenv("zfs-bootonce", buf, 1); - } - free(buf); - (void) zfs_attach_nvstore(&currdev); - } + if (zfs_get_bootonce(&currdev, OS_BOOTONCE, buf, sizeof(buf)) == 0) { + printf("zfs bootonce: %s\n", buf); + set_currdev(buf); + setenv("zfs-bootonce", buf, 1); } - return (rv); + (void)zfs_attach_nvstore(&currdev); + + return (sanity_check_currdev()); } #endif #ifdef MD_IMAGE_SIZE +extern struct devsw md_dev; + static bool probe_md_currdev(void) { - extern struct devsw md_dev; bool rv; set_currdev_devsw(&md_dev, 0); @@ -520,7 +523,7 @@ find_currdev(bool do_bootmgr, bool is_last, * it's wrong. */ rootdev = getenv("rootdev"); - if (rootdev != NULL) { + if (rootdev != NULL && *rootdev != '\0') { printf(" Setting currdev to configured rootdev %s\n", rootdev); set_currdev(rootdev); @@ -701,8 +704,7 @@ interactive_interrupt(const char *msg) static int parse_args(int argc, CHAR16 *argv[]) { - int i, j, howto; - bool vargood; + int i, howto; char var[128]; /* @@ -719,7 +721,7 @@ parse_args(int argc, CHAR16 *argv[]) * method is flawed for non-ASCII characters). */ howto = 0; - for (i = 1; i < argc; i++) { + for (i = 0; i < argc; i++) { cpy16to8(argv[i], var, sizeof(var)); howto |= boot_parse_arg(var); } @@ -736,11 +738,211 @@ setenv_int(const char *key, int val) setenv(key, buf, 1); } +static void * +acpi_map_sdt(vm_offset_t addr) +{ + /* PA == VA */ + return ((void *)addr); +} + +static int +acpi_checksum(void *p, size_t length) +{ + uint8_t *bp; + uint8_t sum; + + bp = p; + sum = 0; + while (length--) + sum += *bp++; + + return (sum); +} + +static void * +acpi_find_table(uint8_t *sig) +{ + int entries, i, addr_size; + ACPI_TABLE_HEADER *sdp; + ACPI_TABLE_RSDT *rsdt; + ACPI_TABLE_XSDT *xsdt; + vm_offset_t addr; + + if (rsdp == NULL) + return (NULL); + + rsdt = (ACPI_TABLE_RSDT *)(uintptr_t)rsdp->RsdtPhysicalAddress; + xsdt = (ACPI_TABLE_XSDT *)(uintptr_t)rsdp->XsdtPhysicalAddress; + if (rsdp->Revision < 2) { + sdp = (ACPI_TABLE_HEADER *)rsdt; + addr_size = sizeof(uint32_t); + } else { + sdp = (ACPI_TABLE_HEADER *)xsdt; + addr_size = sizeof(uint64_t); + } + entries = (sdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; + for (i = 0; i < entries; i++) { + if (addr_size == 4) + addr = le32toh(rsdt->TableOffsetEntry[i]); + else + addr = le64toh(xsdt->TableOffsetEntry[i]); + if (addr == 0) + continue; + sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); + if (acpi_checksum(sdp, sdp->Length)) { + printf("RSDT entry %d (sig %.4s) is corrupt", i, + sdp->Signature); + continue; + } + if (memcmp(sig, sdp->Signature, 4) == 0) + return (sdp); + } + return (NULL); +} + +/* + * Convert the InterfaceType in the SPCR. These are encoded the same for DBG2 + * tables as well (though we don't parse those here). + */ +static const char * +acpi_uart_type(UINT8 t) +{ + static const char *types[] = { + [0x00] = "ns8250", /* Full 16550 */ + [0x01] = "ns8250", /* DBGP Rev 1 16550 subset */ + [0x03] = "pl011", /* Arm PL011 */ + [0x05] = "ns8250", /* Nvidia 16550 */ + [0x0d] = "pl011", /* Arm SBSA 32-bit width */ + [0x0e] = "pl011", /* Arm SBSA generic */ + [0x12] = "ns8250", /* 16550 defined in SerialPort */ + }; + + if (t >= nitems(types)) + return (NULL); + return (types[t]); +} + +static int +acpi_uart_baud(UINT8 b) +{ + static int baud[] = { 0, -1, -1, 9600, 19200, -1, 57600, 115200 }; + + if (b > 7) + return (-1); + return (baud[b]); +} + +static int +acpi_uart_regionwidth(UINT8 rw) +{ + if (rw == 0) + return (1); + if (rw > 4) + return (-1); + return (1 << (rw - 1)); +} + +static const char * +acpi_uart_parity(UINT8 p) +{ + /* Some of these SPCR entires get this wrong, hard wire none */ + return ("none"); +} + /* - * Parse ConOut (the list of consoles active) and see if we can find a - * serial port and/or a video port. It would be nice to also walk the - * ACPI name space to map the UID for the serial port to a port. The - * latter is especially hard. + * See if we can find a SPCR ACPI table in the static tables. If so, then it + * describes the serial console that's been redirected to, so we know that at + * least there's a serial console. this is most important for embedded systems + * that don't have traidtional PC serial ports. + * + * All the two letter variables in this function correspond to their usage in + * the uart(4) console string. We use io == -1 to select between I/O ports and + * memory mapped addresses. Set both hw.uart.console and hw.uart.consol.extra + * to communicate settings from SPCR to the kernel. + */ +static int +check_acpi_spcr(void) +{ + ACPI_TABLE_SPCR *spcr; + int br, db, io, rs, rw, sb, xo, pv, pd; + uintmax_t mm; + const char *dt, *pa; + char *val = NULL; + + spcr = acpi_find_table(ACPI_SIG_SPCR); + if (spcr == NULL) + return (0); + dt = acpi_uart_type(spcr->InterfaceType); + if (dt == NULL) { /* Kernel can't use unknown types */ + printf("UART Type %d not known\n", spcr->InterfaceType); + return (0); + } + + /* I/O vs Memory mapped vs PCI device */ + io = -1; + pv = spcr->PciVendorId; + pd = spcr->PciDeviceId; + if (pv == 0xffff && pd == 0xffff) { + if (spcr->SerialPort.SpaceId == 1) + io = spcr->SerialPort.Address; + else { + mm = spcr->SerialPort.Address; + rs = ffs(spcr->SerialPort.BitWidth) - 4; + rw = acpi_uart_regionwidth(spcr->SerialPort.AccessWidth); + } + } else { + /* XXX todo: bus:device:function + flags and segment */ + } + + /* Uart settings */ + pa = acpi_uart_parity(spcr->Parity); + sb = spcr->StopBits; + db = 8; + + /* + * UartClkFreq is 3 and newer. We always use it then (it's only valid if + * it isn't 0, but if it is 0, we want to use 0 to have the kernel + * guess). + */ + if (spcr->Header.Revision <= 2) + xo = 0; + else + xo = spcr->UartClkFreq; + + /* + * PreciseBaudrate, when non-zero, is to be preferred. It's only valid, + * though, for rev 4 and newer. So when it's 0 or the version is too + * old, we do the old-style table lookup. Otherwise we believe it. + */ + if (spcr->Header.Revision <= 3 || spcr->PreciseBaudrate == 0) + br = acpi_uart_baud(spcr->BaudRate); + else + br = spcr->PreciseBaudrate; + + if (io != -1) { + asprintf(&val, "db:%d,dt:%s,io:%#x,pa:%s,br:%d,xo=%d", + db, dt, io, pa, br, xo); + } else if (pv != 0xffff && pd != 0xffff) { + asprintf(&val, "db:%d,dt:%s,pv:%#x,pd:%#x,pa:%s,br:%d,xo=%d", + db, dt, pv, pd, pa, br, xo); + } else { + asprintf(&val, "db:%d,dt:%s,mm:%#jx,rs:%d,rw:%d,pa:%s,br:%d,xo=%d", + db, dt, mm, rs, rw, pa, br, xo); + } + env_setenv("hw.uart.console", EV_VOLATILE, val, NULL, NULL); + free(val); + + return (RB_SERIAL); +} + + +/* + * Parse ConOut (the list of consoles active) and see if we can find a serial + * port and/or a video port. It would be nice to also walk the ACPI DSDT to map + * the UID for the serial port to a port since there's no standard mapping. Also + * check for ConIn as well. This will be enough to determine if we have serial, + * and if we don't, we default to video. If there's a dual-console situation + * with only ConIn defined, this will currently fail. */ int parse_uefi_con_out(void) @@ -754,14 +956,33 @@ parse_uefi_con_out(void) UART_DEVICE_PATH *uart; bool pci_pending; - how = 0; + /* + * A SPCR in the ACPI fixed tables documents a serial port used for the + * console. It may mirror a video console, or may be stand alone. If it + * is present, we return RB_SERIAL and will use it for the kernel. + */ + how = check_acpi_spcr(); sz = sizeof(buf); rv = efi_global_getenv("ConOut", buf, &sz); if (rv != EFI_SUCCESS) rv = efi_global_getenv("ConOutDev", buf, &sz); + if (rv != EFI_SUCCESS) + rv = efi_global_getenv("ConIn", buf, &sz); if (rv != EFI_SUCCESS) { - /* If we don't have any ConOut default to serial */ - how = RB_SERIAL; + /* + * If we don't have any Con* variable use both. If we have GOP + * make video primary, otherwise set serial primary. In either + * case, try to use both the 'efi' console which will use the + * GOP, if present and serial. If there's an EFI BIOS that omits + * this, but has a serial port redirect, we'll unavioidably get + * doubled characters, but we'll be right in all the other more + * common cases. + */ + if (efi_has_gop()) + how |= RB_MULTIPLE; + else + how |= RB_MULTIPLE | RB_SERIAL; + setenv("console", "efi,comconsole", 1); goto out; } ep = buf + sz; @@ -908,12 +1129,78 @@ ptov(uintptr_t x) return ((caddr_t)x); } +static void +acpi_detect(void) +{ + char buf[24]; + int revision; + + feature_enable(FEATURE_EARLY_ACPI); + if ((rsdp = efi_get_table(&acpi20)) == NULL) + if ((rsdp = efi_get_table(&acpi)) == NULL) + return; + + sprintf(buf, "0x%016"PRIxPTR, (uintptr_t)rsdp); + setenv("acpi.rsdp", buf, 1); + revision = rsdp->Revision; + if (revision == 0) + revision = 1; + sprintf(buf, "%d", revision); + setenv("acpi.revision", buf, 1); + strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); + buf[sizeof(rsdp->OemId)] = '\0'; + setenv("acpi.oem", buf, 1); + sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); + setenv("acpi.rsdt", buf, 1); + if (revision >= 2) { + /* XXX extended checksum? */ + sprintf(buf, "0x%016llx", + (unsigned long long)rsdp->XsdtPhysicalAddress); + setenv("acpi.xsdt", buf, 1); + sprintf(buf, "%d", rsdp->Length); + setenv("acpi.xsdt_length", buf, 1); + } +} + +static void +efi_smbios_detect(void) +{ + VOID *smbios_v2_ptr = NULL; + UINTN k; + + for (k = 0; k < ST->NumberOfTableEntries; k++) { + EFI_GUID *guid; + VOID *const VT = ST->ConfigurationTable[k].VendorTable; + char buf[40]; + bool is_smbios_v2, is_smbios_v3; + + guid = &ST->ConfigurationTable[k].VendorGuid; + is_smbios_v2 = memcmp(guid, &smbios, sizeof(*guid)) == 0; + is_smbios_v3 = memcmp(guid, &smbios3, sizeof(*guid)) == 0; + + if (!is_smbios_v2 && !is_smbios_v3) + continue; + + snprintf(buf, sizeof(buf), "%p", VT); + setenv("hint.smbios.0.mem", buf, 1); + if (is_smbios_v2) + /* + * We will parse a v2 table only if we don't find a v3 + * table. In the meantime, store the address. + */ + smbios_v2_ptr = VT; + else if (smbios_detect(VT) != NULL) + /* v3 parsing succeeded, we are done. */ + return; + } + if (smbios_v2_ptr != NULL) + (void)smbios_detect(smbios_v2_ptr); +} + EFI_STATUS main(int argc, CHAR16 *argv[]) { - EFI_GUID *guid; int howto, i, uhowto; - UINTN k; bool has_kbd, is_last; char *s; EFI_DEVICE_PATH *imgpath; @@ -925,19 +1212,16 @@ main(int argc, CHAR16 *argv[]) char buf[32]; bool uefi_boot_mgr; - archsw.arch_autoload = efi_autoload; - archsw.arch_getdev = efi_getdev; - archsw.arch_copyin = efi_copyin; - archsw.arch_copyout = efi_copyout; -#ifdef __amd64__ - archsw.arch_hypervisor = x86_hypervisor; +#if !defined(__arm__) + efi_smbios_detect(); #endif - archsw.arch_readin = efi_readin; - archsw.arch_zfs_probe = efi_zfs_probe; /* Get our loaded image protocol interface structure. */ (void) OpenProtocolByHandle(IH, &imgid, (void **)&boot_img); + /* Report the RSDP early. */ + acpi_detect(); + /* * Chicken-and-egg problem; we want to have console output early, but * some console attributes may depend on reading from eg. the boot @@ -949,13 +1233,19 @@ main(int argc, CHAR16 *argv[]) setenv("console", "efi", 1); uhowto = parse_uefi_con_out(); #if defined(__riscv) + /* + * This workaround likely is papering over a real issue + */ if ((uhowto & RB_SERIAL) != 0) setenv("console", "comconsole", 1); #endif cons_probe(); + /* Set print_delay variable to have hooks in place. */ + env_setenv("print_delay", EV_VOLATILE, "", setprint_delay, env_nounset); + /* Set up currdev variable to have hooks in place. */ - env_setenv("currdev", EV_VOLATILE, "", efi_setcurrdev, env_nounset); + env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, env_nounset); /* Init the time source */ efi_time_init(); @@ -975,9 +1265,7 @@ main(int argc, CHAR16 *argv[]) "failures\n", i); } - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); + devinit(); /* * Detect console settings two different ways: one via the command @@ -1055,10 +1343,8 @@ main(int argc, CHAR16 *argv[]) */ boot_howto_to_env(howto); - if (efi_copy_init()) { - printf("failed to allocate staging area\n"); + if (efi_copy_init()) return (EFI_BUFFER_TOO_SMALL); - } if ((s = getenv("fail_timeout")) != NULL) fail_timeout = strtol(s, NULL, 10); @@ -1185,21 +1471,6 @@ main(int argc, CHAR16 *argv[]) autoload_font(false); /* Set up the font list for console. */ efi_init_environment(); -#if !defined(__arm__) - for (k = 0; k < ST->NumberOfTableEntries; k++) { - guid = &ST->ConfigurationTable[k].VendorGuid; - if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) { - char buf[40]; - - snprintf(buf, sizeof(buf), "%p", - ST->ConfigurationTable[k].VendorTable); - setenv("hint.smbios.0.mem", buf, 1); - smbios_detect(ST->ConfigurationTable[k].VendorTable); - break; - } - } -#endif - interact(); /* doesn't return */ return (EFI_SUCCESS); /* keep compiler happy */ @@ -1212,11 +1483,27 @@ command_seed_entropy(int argc, char *argv[]) { EFI_STATUS status; EFI_RNG_PROTOCOL *rng; - unsigned int size = 2048; + unsigned int size_efi = RANDOM_FORTUNA_DEFPOOLSIZE * RANDOM_FORTUNA_NPOOLS; + unsigned int size = RANDOM_FORTUNA_DEFPOOLSIZE * RANDOM_FORTUNA_NPOOLS; + void *buf_efi; void *buf; if (argc > 1) { - size = strtol(argv[1], NULL, 0); + size_efi = strtol(argv[1], NULL, 0); + + /* Don't *compress* the entropy we get from EFI. */ + if (size_efi > size) + size = size_efi; + + /* + * If the amount of entropy we get from EFI is less than the + * size of a single Fortuna pool -- i.e. not enough to ensure + * that Fortuna is safely seeded -- don't expand it since we + * don't want to trick Fortuna into thinking that it has been + * safely seeded when it has not. + */ + if (size_efi < RANDOM_FORTUNA_DEFPOOLSIZE) + size = size_efi; } status = BS->LocateProtocol(&rng_guid, NULL, (VOID **)&rng); @@ -1230,23 +1517,40 @@ command_seed_entropy(int argc, char *argv[]) return (CMD_ERROR); } - status = rng->GetRNG(rng, NULL, size, (UINT8 *)buf); + if ((buf_efi = malloc(size_efi)) == NULL) { + free(buf); + command_errmsg = "out of memory"; + return (CMD_ERROR); + } + + TSENTER2("rng->GetRNG"); + status = rng->GetRNG(rng, NULL, size_efi, (UINT8 *)buf_efi); + TSEXIT(); if (status != EFI_SUCCESS) { + free(buf_efi); free(buf); command_errmsg = "GetRNG failed"; return (CMD_ERROR); } + if (size_efi < size) + pkcs5v2_genkey_raw(buf, size, "", 0, buf_efi, size_efi, 1); + else + memcpy(buf, buf_efi, size); if (file_addbuf("efi_rng_seed", "boot_entropy_platform", size, buf) != 0) { + free(buf_efi); free(buf); return (CMD_ERROR); } + explicit_bzero(buf_efi, size_efi); + free(buf_efi); free(buf); return (CMD_OK); } COMMAND_SET(poweroff, "poweroff", "power off the system", command_poweroff); +COMMAND_SET(halt, "halt", "power off the system", command_poweroff); static int command_poweroff(int argc __unused, char *argv[] __unused) @@ -1280,15 +1584,6 @@ command_reboot(int argc, char *argv[]) return (CMD_ERROR); } -COMMAND_SET(quit, "quit", "exit the loader", command_quit); - -static int -command_quit(int argc, char *argv[]) -{ - exit(0); - return (CMD_OK); -} - COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); static int @@ -1692,6 +1987,7 @@ command_chain(int argc, char *argv[]) COMMAND_SET(chain, "chain", "chain load file", command_chain); +#if defined(LOADER_NET_SUPPORT) extern struct in_addr servip; static int command_netserver(int argc, char *argv[]) @@ -1722,3 +2018,4 @@ command_netserver(int argc, char *argv[]) COMMAND_SET(netserver, "netserver", "change or display netserver URI", command_netserver); +#endif diff --git a/stand/efi/loader/version b/stand/efi/loader/version index 3a4c47c5efb1..570796b66956 100644 --- a/stand/efi/loader/version +++ b/stand/efi/loader/version @@ -1,7 +1,3 @@ -$FreeBSD$ - -NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this -file is important. Make sure the current version number is on line 6. - +3.0: Lua scripts API stability 1.1: Keep in sync with i386 version. 0.1: Initial i386 version. Derived from ia64. diff --git a/stand/efi/loader/version.veriexec b/stand/efi/loader/version.veriexec new file mode 100644 index 000000000000..529f3ef5544b --- /dev/null +++ b/stand/efi/loader/version.veriexec @@ -0,0 +1,5 @@ +3.0: Lua scripts API stability +2.1: SMBIOS 3 support +2.0: Secure boot support +1.1: Keep in sync with i386 version. +0.1: Initial i386 version. Derived from ia64. diff --git a/stand/efi/loader_4th/Makefile b/stand/efi/loader_4th/Makefile index 3659f7efe673..2361952ccc5d 100644 --- a/stand/efi/loader_4th/Makefile +++ b/stand/efi/loader_4th/Makefile @@ -1,6 +1,5 @@ -# $FreeBSD$ - LOADER_INTERP=4th +INSTALL_LOADER_HELP_FILE=no .include "../loader/Makefile" diff --git a/stand/efi/loader_4th/Makefile.depend b/stand/efi/loader_4th/Makefile.depend new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/stand/efi/loader_4th/Makefile.depend diff --git a/stand/efi/loader_ia32/Makefile b/stand/efi/loader_ia32/Makefile new file mode 100644 index 000000000000..003c75f43948 --- /dev/null +++ b/stand/efi/loader_ia32/Makefile @@ -0,0 +1,6 @@ +DO32=1 +INSTALL_LOADER_HELP_FILE=no + +NEWVERSWHAT?= "EFI loader" amd64-ia32 + +.include "../loader/Makefile" diff --git a/stand/efi/loader_lua/Makefile b/stand/efi/loader_lua/Makefile index 3a4268440cf6..628aab34c0b8 100644 --- a/stand/efi/loader_lua/Makefile +++ b/stand/efi/loader_lua/Makefile @@ -1,6 +1,5 @@ -# $FreeBSD$ - LOADER_INTERP=lua +INSTALL_LOADER_HELP_FILE=no .include "../loader/Makefile" diff --git a/stand/efi/loader_simp/Makefile b/stand/efi/loader_simp/Makefile index 0c27d5673941..2e10a6595ed2 100644 --- a/stand/efi/loader_simp/Makefile +++ b/stand/efi/loader_simp/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_INTERP=simp .include "../loader/Makefile" diff --git a/stand/fdt.mk b/stand/fdt.mk index 4d4794d980f2..1b3df587d0db 100644 --- a/stand/fdt.mk +++ b/stand/fdt.mk @@ -1,9 +1,8 @@ -# $FreeBSD$ .if ${MK_FDT} == "yes" CFLAGS+= -I${FDTSRC} CFLAGS+= -I${BOOTOBJ}/fdt CFLAGS+= -I${SYSDIR}/contrib/libfdt CFLAGS+= -DLOADER_FDT_SUPPORT -LIBFDT= ${BOOTOBJ}/fdt/libfdt.a +LIBSAFDT= ${BOOTOBJ}/fdt/libfdt.a .endif diff --git a/stand/fdt/Makefile b/stand/fdt/Makefile index e0fd2dbb4e8d..f585d8a2098a 100644 --- a/stand/fdt/Makefile +++ b/stand/fdt/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> .PATH: ${SYSDIR}/contrib/libfdt/ diff --git a/stand/fdt/Makefile.depend b/stand/fdt/Makefile.depend index 18be76b0cb6f..18537add9fe3 100644 --- a/stand/fdt/Makefile.depend +++ b/stand/fdt/Makefile.depend @@ -1,9 +1,7 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - include \ - include/xlocale \ + stand/libsa \ .include <dirdeps.mk> diff --git a/stand/fdt/fdt_loader_cmd.c b/stand/fdt/fdt_loader_cmd.c index c14b99768d70..161c2435c410 100644 --- a/stand/fdt/fdt_loader_cmd.c +++ b/stand/fdt/fdt_loader_cmd.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2009-2010 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Semihalf under sponsorship from * the FreeBSD Foundation. @@ -27,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <libfdt.h> #include <fdt.h> @@ -114,7 +110,7 @@ static const struct cmdtab commands[] = { static char cwd[FDT_CWD_LEN] = "/"; static vm_offset_t -fdt_find_static_dtb() +fdt_find_static_dtb(void) { Elf_Ehdr *ehdr; Elf_Shdr *shdr; @@ -431,7 +427,7 @@ fdt_check_overlay_compatible(void *base_fdt, void *overlay_fdt) * Returns the number of overlays successfully applied */ int -fdt_apply_overlays() +fdt_apply_overlays(void) { struct preloaded_file *fp; size_t max_overlay_size, next_fdtp_size; @@ -554,7 +550,7 @@ fdt_is_setup(void) } int -fdt_setup_fdtp() +fdt_setup_fdtp(void) { struct preloaded_file *bfp; vm_offset_t va; @@ -994,7 +990,7 @@ int fdt_copy(vm_offset_t va) { int err; - debugf("fdt_copy va 0x%08x\n", va); + debugf("fdt_copy va 0x%08jx\n", (uintmax_t)va); if (fdtp == NULL) { err = fdt_setup_fdtp(); if (err) { @@ -1244,13 +1240,6 @@ fdt_cmd_ls(int argc, char *argv[]) return (CMD_OK); } -static __inline int -isprint(int c) -{ - - return (c >= ' ' && c <= 0x7e); -} - static int fdt_isprint(const void *data, int len, int *count) { diff --git a/stand/fdt/fdt_platform.h b/stand/fdt/fdt_platform.h index 7bd1c977b4d6..41f03ff17f98 100644 --- a/stand/fdt/fdt_platform.h +++ b/stand/fdt/fdt_platform.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef FDT_PLATFORM_H diff --git a/stand/fdt/help.fdt b/stand/fdt/help.fdt index 665f63c260c6..32681d93be33 100644 --- a/stand/fdt/help.fdt +++ b/stand/fdt/help.fdt @@ -1,4 +1,3 @@ -$FreeBSD$ ############################################################################### # Tfdt Dfdt manipulation commands diff --git a/stand/ficl.mk b/stand/ficl.mk index e9fa1eb84f4b..a2cfca9fc3bb 100644 --- a/stand/ficl.mk +++ b/stand/ficl.mk @@ -1,4 +1,3 @@ -# $FreeBSD$ # Common flags to build FICL related files diff --git a/stand/ficl/Makefile b/stand/ficl/Makefile index 0f70286ff7df..fe4ee03974b1 100644 --- a/stand/ficl/Makefile +++ b/stand/ficl/Makefile @@ -1,4 +1,3 @@ -# $FreeBSD$ # .include <bsd.init.mk> @@ -12,8 +11,8 @@ BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ SRCS= ${BASE_SRCS} sysdep.c softcore.c CLEANFILES+= softcore.c testmain testmain.o -CFLAGS.loader.c += -I${SRCTOP}/sys/teken -CFLAGS.loader.c += -I${SRCTOP}/contrib/pnglite +CFLAGS.gfx_loader.c += -I${SRCTOP}/sys/teken +CFLAGS.gfx_loader.c += -I${SRCTOP}/contrib/pnglite .ifmake testmain CFLAGS= -DTESTMAIN -D_TESTMAIN CFLAGS+= -I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC} @@ -22,6 +21,7 @@ PROG= testmain .include <bsd.prog.mk> .else LIB= ficl +BASE_SRCS+= gfx_loader.c # Not TESTMAINable .include <bsd.lib.mk> .endif diff --git a/stand/ficl/Makefile.depend b/stand/ficl/Makefile.depend index 73bc18c8c0fc..8a29d17bb768 100644 --- a/stand/ficl/Makefile.depend +++ b/stand/ficl/Makefile.depend @@ -1,8 +1,8 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ stand/libsa \ + usr.bin/awk.host \ .include <dirdeps.mk> diff --git a/stand/ficl/aarch64/sysdep.c b/stand/ficl/aarch64/sysdep.c index 43e7c3c91f1d..87bed142d684 100644 --- a/stand/ficl/aarch64/sysdep.c +++ b/stand/ficl/aarch64/sysdep.c @@ -7,7 +7,6 @@ ** *******************************************************************/ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/aarch64/sysdep.h b/stand/ficl/aarch64/sysdep.h index 3726b9ef838f..1bb45efcae26 100644 --- a/stand/ficl/aarch64/sysdep.h +++ b/stand/ficl/aarch64/sysdep.h @@ -46,7 +46,6 @@ ** contact me by email at the address above. ** ** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -** $FreeBSD$ */ #if !defined (__SYSDEP_H__) diff --git a/stand/ficl/amd64/sysdep.c b/stand/ficl/amd64/sysdep.c index 147c4683b6c2..41a5c679e9b3 100644 --- a/stand/ficl/amd64/sysdep.c +++ b/stand/ficl/amd64/sysdep.c @@ -7,7 +7,6 @@ ** *******************************************************************/ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/amd64/sysdep.h b/stand/ficl/amd64/sysdep.h index 08bc0e1f4d0b..0e9a8bb0c788 100644 --- a/stand/ficl/amd64/sysdep.h +++ b/stand/ficl/amd64/sysdep.h @@ -48,7 +48,6 @@ ** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ */ -/* $FreeBSD$ */ #if !defined (__SYSDEP_H__) #define __SYSDEP_H__ diff --git a/stand/ficl/arm/sysdep.c b/stand/ficl/arm/sysdep.c index 43e7c3c91f1d..87bed142d684 100644 --- a/stand/ficl/arm/sysdep.c +++ b/stand/ficl/arm/sysdep.c @@ -7,7 +7,6 @@ ** *******************************************************************/ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/arm/sysdep.h b/stand/ficl/arm/sysdep.h index 00718eedd35c..e376aa9d334b 100644 --- a/stand/ficl/arm/sysdep.h +++ b/stand/ficl/arm/sysdep.h @@ -46,7 +46,6 @@ ** contact me by email at the address above. ** ** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -** $FreeBSD$ */ #if !defined (__SYSDEP_H__) diff --git a/stand/ficl/dict.c b/stand/ficl/dict.c index b76d92559f8f..7a6fc7568236 100644 --- a/stand/ficl/dict.c +++ b/stand/ficl/dict.c @@ -51,7 +51,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/ficl.c b/stand/ficl/ficl.c index 219cf84b2225..3731b42b2a32 100644 --- a/stand/ficl/ficl.c +++ b/stand/ficl/ficl.c @@ -55,7 +55,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdlib.h> diff --git a/stand/ficl/ficl.h b/stand/ficl/ficl.h index 97cf00b0dff3..7be78f1a36b8 100644 --- a/stand/ficl/ficl.h +++ b/stand/ficl/ficl.h @@ -41,7 +41,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #if !defined (__FICL_H__) #define __FICL_H__ @@ -1154,8 +1153,8 @@ typedef struct ficlFILE typedef void ficlCompileFcn(FICL_SYSTEM *); #define FICL_COMPILE_SET(func) \ - DATA_SET(Xficl_compile_set, func) -SET_DECLARE(Xficl_compile_set, ficlCompileFcn); + DATA_SET(X4th_compile_set, func) +SET_DECLARE(X4th_compile_set, ficlCompileFcn); #ifdef LOADER_VERIEXEC #include <verify_file.h> diff --git a/stand/ficl/fileaccess.c b/stand/ficl/fileaccess.c index 9dd23f9d34b8..a66262fb2bf3 100644 --- a/stand/ficl/fileaccess.c +++ b/stand/ficl/fileaccess.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #include <errno.h> #include <stdlib.h> diff --git a/stand/ficl/float.c b/stand/ficl/float.c index dfd1456c8dac..895252b60f20 100644 --- a/stand/ficl/float.c +++ b/stand/ficl/float.c @@ -41,7 +41,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #include "ficl.h" diff --git a/stand/ficl/gfx_loader.c b/stand/ficl/gfx_loader.c new file mode 100644 index 000000000000..4ac69e3c9895 --- /dev/null +++ b/stand/ficl/gfx_loader.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* Copied from a file that likely shoulve have had this at the top */ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2020 Toomas Soome + * Copyright 2020 RackTop Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/******************************************************************* +** g f x _ l o a d e r . c +** Additional FICL words designed for FreeBSD's loader +** for graphics +*******************************************************************/ + +#include <stand.h> +#include "bootstrap.h" +#include <gfx_fb.h> +#include <pnglite.h> +#include "ficl.h" + +/* FreeBSD's loader interaction words and extras + * for graphics + * fb-bezier ( x0 y0 x1 y1 x2 y2 wd -- ) + * fb-drawrect ( x1 y1 x2 y2 fill -- ) + * fb-line ( x0 y0 x1 y1 wd -- ) + * fb-putimage ( flags x1 y1 x2 y2 -- flag ) + * fb-setpixel ( x y -- ) + * term-drawrect ( x1 y1 x2 y2 fill -- ) + * term-putimage ( flags x1 y1 x2 y2 -- flag ) + */ + +/* ( flags x1 y1 x2 y2 -- flag ) */ +void +ficl_term_putimage(FICL_VM *pVM) +{ + char *namep, *name; + int names; + unsigned long ret = FICL_FALSE; + uint32_t x1, y1, x2, y2, f; + png_t png; + int error; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 7, 1); +#endif + names = stackPopINT(pVM->pStack); + namep = (char *) stackPopPtr(pVM->pStack); + y2 = stackPopINT(pVM->pStack); + x2 = stackPopINT(pVM->pStack); + y1 = stackPopINT(pVM->pStack); + x1 = stackPopINT(pVM->pStack); + f = stackPopINT(pVM->pStack); + + x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; + y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; + if (x2 != 0) { + x2 = gfx_state.tg_origin.tp_col + + x2 * gfx_state.tg_font.vf_width; + } + if (y2 != 0) { + y2 = gfx_state.tg_origin.tp_row + + y2 * gfx_state.tg_font.vf_height; + } + + name = ficlMalloc(names + 1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + (void) strncpy(name, namep, names); + name[names] = '\0'; + + if ((error = png_open(&png, name)) != PNG_NO_ERROR) { + if (f & FL_PUTIMAGE_DEBUG) + printf("%s\n", png_error_string(error)); + } else { + if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) + ret = FICL_TRUE; /* success */ + (void) png_close(&png); + } + ficlFree(name); + stackPushUNS(pVM->pStack, ret); +} + +/* ( flags x1 y1 x2 y2 -- flag ) */ +void +ficl_fb_putimage(FICL_VM *pVM) +{ + char *namep, *name; + int names; + unsigned long ret = FICL_FALSE; + uint32_t x1, y1, x2, y2, f; + png_t png; + int error; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 7, 1); +#endif + names = stackPopINT(pVM->pStack); + namep = (char *) stackPopPtr(pVM->pStack); + y2 = stackPopINT(pVM->pStack); + x2 = stackPopINT(pVM->pStack); + y1 = stackPopINT(pVM->pStack); + x1 = stackPopINT(pVM->pStack); + f = stackPopINT(pVM->pStack); + + name = ficlMalloc(names + 1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + (void) strncpy(name, namep, names); + name[names] = '\0'; + + if ((error = png_open(&png, name)) != PNG_NO_ERROR) { + if (f & FL_PUTIMAGE_DEBUG) + printf("%s\n", png_error_string(error)); + } else { + if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) + ret = FICL_TRUE; /* success */ + (void) png_close(&png); + } + ficlFree(name); + stackPushUNS(pVM->pStack, ret); +} + +void +ficl_fb_setpixel(FICL_VM *pVM) +{ + FICL_UNS x, y; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 2, 0); +#endif + + y = stackPopUNS(pVM->pStack); + x = stackPopUNS(pVM->pStack); + gfx_fb_setpixel(x, y); +} + +void +ficl_fb_line(FICL_VM *pVM) +{ + FICL_UNS x0, y0, x1, y1, wd; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 5, 0); +#endif + + wd = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + y0 = stackPopUNS(pVM->pStack); + x0 = stackPopUNS(pVM->pStack); + gfx_fb_line(x0, y0, x1, y1, wd); +} + +void +ficl_fb_bezier(FICL_VM *pVM) +{ + FICL_UNS x0, y0, x1, y1, x2, y2, width; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 7, 0); +#endif + + width = stackPopUNS(pVM->pStack); + y2 = stackPopUNS(pVM->pStack); + x2 = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + y0 = stackPopUNS(pVM->pStack); + x0 = stackPopUNS(pVM->pStack); + gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); +} + +void +ficl_fb_drawrect(FICL_VM *pVM) +{ + FICL_UNS x1, x2, y1, y2, fill; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 5, 0); +#endif + + fill = stackPopUNS(pVM->pStack); + y2 = stackPopUNS(pVM->pStack); + x2 = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + gfx_fb_drawrect(x1, y1, x2, y2, fill); +} + +void +ficl_term_drawrect(FICL_VM *pVM) +{ + FICL_UNS x1, x2, y1, y2; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 4, 0); +#endif + + y2 = stackPopUNS(pVM->pStack); + x2 = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + gfx_term_drawrect(x1, y1, x2, y2); +} + +/************************************************************************** + f i c l C o m p i l e G f x +** Build FreeBSD platform extensions into the system dictionary +** for gfx +**************************************************************************/ +static void ficlCompileGfx(FICL_SYSTEM *pSys) +{ + ficlCompileFcn **fnpp; + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT); + dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT); + dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT); + dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT); + dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT); + dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT); + dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT); + + return; +} +FICL_COMPILE_SET(ficlCompileGfx); + +void +gfx_interp_ref(void) +{ +} diff --git a/stand/ficl/i386/sysdep.c b/stand/ficl/i386/sysdep.c index 147c4683b6c2..41a5c679e9b3 100644 --- a/stand/ficl/i386/sysdep.c +++ b/stand/ficl/i386/sysdep.c @@ -7,7 +7,6 @@ ** *******************************************************************/ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/i386/sysdep.h b/stand/ficl/i386/sysdep.h index 94fda2047ede..8eebbe9e7177 100644 --- a/stand/ficl/i386/sysdep.h +++ b/stand/ficl/i386/sysdep.h @@ -46,7 +46,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #if !defined (__SYSDEP_H__) #define __SYSDEP_H__ diff --git a/stand/ficl/loader.c b/stand/ficl/loader.c index fca2b7421ffb..32ec2d6fc172 100644 --- a/stand/ficl/loader.c +++ b/stand/ficl/loader.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /******************************************************************* @@ -46,8 +44,6 @@ #include "bootstrap.h" #include <string.h> #include <uuid.h> -#include <gfx_fb.h> -#include <pnglite.h> #include "ficl.h" /* FreeBSD's loader interaction words and extras @@ -67,182 +63,6 @@ * .# ( value -- ) */ -#ifndef TESTMAIN -/* ( flags x1 y1 x2 y2 -- flag ) */ -void -ficl_term_putimage(FICL_VM *pVM) -{ - char *namep, *name; - int names; - unsigned long ret = FICL_FALSE; - uint32_t x1, y1, x2, y2, f; - png_t png; - int error; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 7, 1); -#endif - names = stackPopINT(pVM->pStack); - namep = (char *) stackPopPtr(pVM->pStack); - y2 = stackPopINT(pVM->pStack); - x2 = stackPopINT(pVM->pStack); - y1 = stackPopINT(pVM->pStack); - x1 = stackPopINT(pVM->pStack); - f = stackPopINT(pVM->pStack); - - x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; - y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; - if (x2 != 0) { - x2 = gfx_state.tg_origin.tp_col + - x2 * gfx_state.tg_font.vf_width; - } - if (y2 != 0) { - y2 = gfx_state.tg_origin.tp_row + - y2 * gfx_state.tg_font.vf_height; - } - - name = ficlMalloc(names + 1); - if (!name) - vmThrowErr(pVM, "Error: out of memory"); - (void) strncpy(name, namep, names); - name[names] = '\0'; - - if ((error = png_open(&png, name)) != PNG_NO_ERROR) { - if (f & FL_PUTIMAGE_DEBUG) - printf("%s\n", png_error_string(error)); - } else { - if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) - ret = FICL_TRUE; /* success */ - (void) png_close(&png); - } - ficlFree(name); - stackPushUNS(pVM->pStack, ret); -} - -/* ( flags x1 y1 x2 y2 -- flag ) */ -void -ficl_fb_putimage(FICL_VM *pVM) -{ - char *namep, *name; - int names; - unsigned long ret = FICL_FALSE; - uint32_t x1, y1, x2, y2, f; - png_t png; - int error; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 7, 1); -#endif - names = stackPopINT(pVM->pStack); - namep = (char *) stackPopPtr(pVM->pStack); - y2 = stackPopINT(pVM->pStack); - x2 = stackPopINT(pVM->pStack); - y1 = stackPopINT(pVM->pStack); - x1 = stackPopINT(pVM->pStack); - f = stackPopINT(pVM->pStack); - - name = ficlMalloc(names + 1); - if (!name) - vmThrowErr(pVM, "Error: out of memory"); - (void) strncpy(name, namep, names); - name[names] = '\0'; - - if ((error = png_open(&png, name)) != PNG_NO_ERROR) { - if (f & FL_PUTIMAGE_DEBUG) - printf("%s\n", png_error_string(error)); - } else { - if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) - ret = FICL_TRUE; /* success */ - (void) png_close(&png); - } - ficlFree(name); - stackPushUNS(pVM->pStack, ret); -} - -void -ficl_fb_setpixel(FICL_VM *pVM) -{ - FICL_UNS x, y; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 2, 0); -#endif - - y = stackPopUNS(pVM->pStack); - x = stackPopUNS(pVM->pStack); - gfx_fb_setpixel(x, y); -} - -void -ficl_fb_line(FICL_VM *pVM) -{ - FICL_UNS x0, y0, x1, y1, wd; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 5, 0); -#endif - - wd = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - y0 = stackPopUNS(pVM->pStack); - x0 = stackPopUNS(pVM->pStack); - gfx_fb_line(x0, y0, x1, y1, wd); -} - -void -ficl_fb_bezier(FICL_VM *pVM) -{ - FICL_UNS x0, y0, x1, y1, x2, y2, width; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 7, 0); -#endif - - width = stackPopUNS(pVM->pStack); - y2 = stackPopUNS(pVM->pStack); - x2 = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - y0 = stackPopUNS(pVM->pStack); - x0 = stackPopUNS(pVM->pStack); - gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); -} - -void -ficl_fb_drawrect(FICL_VM *pVM) -{ - FICL_UNS x1, x2, y1, y2, fill; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 5, 0); -#endif - - fill = stackPopUNS(pVM->pStack); - y2 = stackPopUNS(pVM->pStack); - x2 = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - gfx_fb_drawrect(x1, y1, x2, y2, fill); -} - -void -ficl_term_drawrect(FICL_VM *pVM) -{ - FICL_UNS x1, x2, y1, y2; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 4, 0); -#endif - - y2 = stackPopUNS(pVM->pStack); - x2 = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - gfx_term_drawrect(x1, y1, x2, y2); -} -#endif /* TESTMAIN */ - void ficlSetenv(FICL_VM *pVM) { @@ -1045,17 +865,10 @@ void ficlCompilePlatform(FICL_SYSTEM *pSys) dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT); dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT); #ifndef TESTMAIN - dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT); - dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT); - dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT); - dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT); - dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT); - dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT); - dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT); - dictAppendWord(dp, "isvirtualized?",ficlIsvirtualizedQ, FW_DEFAULT); + dictAppendWord(dp, "isvirtualized?", ficlIsvirtualizedQ, FW_DEFAULT); #endif - SET_FOREACH(fnpp, Xficl_compile_set) + SET_FOREACH(fnpp, X4th_compile_set) (*fnpp)(pSys); #if defined(__i386__) diff --git a/stand/ficl/math64.c b/stand/ficl/math64.c index 6e50458151bc..2122a02629f0 100644 --- a/stand/ficl/math64.c +++ b/stand/ficl/math64.c @@ -42,7 +42,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #include "ficl.h" #include "math64.h" diff --git a/stand/ficl/math64.h b/stand/ficl/math64.h index a4e56369564f..3acbbffec75f 100644 --- a/stand/ficl/math64.h +++ b/stand/ficl/math64.h @@ -40,7 +40,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #if !defined (__MATH64_H__) #define __MATH64_H__ diff --git a/stand/ficl/mips/sysdep.c b/stand/ficl/mips/sysdep.c deleted file mode 100644 index 43e7c3c91f1d..000000000000 --- a/stand/ficl/mips/sysdep.c +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************* -** s y s d e p . c -** Forth Inspired Command Language -** Author: John Sadler (john_sadler@alum.mit.edu) -** Created: 16 Oct 1997 -** Implementations of FICL external interface functions... -** -*******************************************************************/ - -/* $FreeBSD$ */ - -#ifdef TESTMAIN -#include <stdio.h> -#include <stdlib.h> -#else -#include <stand.h> -#endif -#include "ficl.h" - -/* -******************* FreeBSD P O R T B E G I N S H E R E ******************** Michael Smith -*/ - -#if PORTABLE_LONGMULDIV == 0 -DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) -{ - DPUNS q; - uint64_t qx; - - qx = (uint64_t)x * (uint64_t) y; - - q.hi = (uint32_t)( qx >> 32 ); - q.lo = (uint32_t)( qx & 0xFFFFFFFFL); - - return q; -} - -UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) -{ - UNSQR result; - uint64_t qx, qh; - - qh = q.hi; - qx = (qh << 32) | q.lo; - - result.quot = qx / y; - result.rem = qx % y; - - return result; -} -#endif - -void ficlTextOut(FICL_VM *pVM, char *msg, int fNewline) -{ - IGNORE(pVM); - - while(*msg != 0) - putchar(*(msg++)); - if (fNewline) - putchar('\n'); - - return; -} - -void *ficlMalloc (size_t size) -{ - return malloc(size); -} - -void *ficlRealloc (void *p, size_t size) -{ - return realloc(p, size); -} - -void ficlFree (void *p) -{ - free(p); -} - - -/* -** Stub function for dictionary access control - does nothing -** by default, user can redefine to guarantee exclusive dict -** access to a single thread for updates. All dict update code -** is guaranteed to be bracketed as follows: -** ficlLockDictionary(TRUE); -** <code that updates dictionary> -** ficlLockDictionary(FALSE); -** -** Returns zero if successful, nonzero if unable to acquire lock -** befor timeout (optional - could also block forever) -*/ -#if FICL_MULTITHREAD -int ficlLockDictionary(short fLock) -{ - IGNORE(fLock); - return 0; -} -#endif /* FICL_MULTITHREAD */ diff --git a/stand/ficl/mips/sysdep.h b/stand/ficl/mips/sysdep.h deleted file mode 100644 index 3ae748e259c7..000000000000 --- a/stand/ficl/mips/sysdep.h +++ /dev/null @@ -1,432 +0,0 @@ -/******************************************************************* - s y s d e p . h -** Forth Inspired Command Language -** Author: John Sadler (john_sadler@alum.mit.edu) -** Created: 16 Oct 1997 -** Ficl system dependent types and prototypes... -** -** Note: Ficl also depends on the use of "assert" when -** FICL_ROBUST is enabled. This may require some consideration -** in firmware systems since assert often -** assumes stderr/stdout. -** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -*******************************************************************/ -/* -** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) -** All rights reserved. -** -** Get the latest Ficl release at http://ficl.sourceforge.net -** -** L I C E N S E and D I S C L A I M E R -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** I am interested in hearing from anyone who uses ficl. If you have -** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release, please send -** contact me by email at the address above. -** -** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -** $FreeBSD$ -*/ - -#if !defined (__SYSDEP_H__) -#define __SYSDEP_H__ - -#include <sys/types.h> - -#include <stddef.h> /* size_t, NULL */ -#include <setjmp.h> -#include <assert.h> - -#if !defined IGNORE /* Macro to silence unused param warnings */ -#define IGNORE(x) &x -#endif - -/* -** TRUE and FALSE for C boolean operations, and -** portable 32 bit types for CELLs -** -*/ -#if !defined TRUE -#define TRUE 1 -#endif -#if !defined FALSE -#define FALSE 0 -#endif - - -/* -** System dependent data type declarations... -*/ -#if !defined INT32 -#define INT32 int -#endif - -#if !defined UNS32 -#define UNS32 unsigned int -#endif - -#if !defined UNS16 -#define UNS16 unsigned short -#endif - -#if !defined UNS8 -#define UNS8 unsigned char -#endif - -#if !defined NULL -#define NULL ((void *)0) -#endif - -/* -** FICL_UNS and FICL_INT must have the same size as a void* on -** the target system. A CELL is a union of void*, FICL_UNS, and -** FICL_INT. -** (11/2000: same for FICL_FLOAT) -*/ -#if !defined FICL_INT -#define FICL_INT INT32 -#endif - -#if !defined FICL_UNS -#define FICL_UNS UNS32 -#endif - -#if !defined FICL_FLOAT -#define FICL_FLOAT float -#endif - -/* -** Ficl presently supports values of 32 and 64 for BITS_PER_CELL -*/ -#if !defined BITS_PER_CELL -#define BITS_PER_CELL 32 -#endif - -#if ((BITS_PER_CELL != 32) && (BITS_PER_CELL != 64)) - Error! -#endif - -typedef struct -{ - FICL_UNS hi; - FICL_UNS lo; -} DPUNS; - -typedef struct -{ - FICL_UNS quot; - FICL_UNS rem; -} UNSQR; - -typedef struct -{ - FICL_INT hi; - FICL_INT lo; -} DPINT; - -typedef struct -{ - FICL_INT quot; - FICL_INT rem; -} INTQR; - - -/* -** B U I L D C O N T R O L S -*/ - -#if !defined (FICL_MINIMAL) -#define FICL_MINIMAL 0 -#endif -#if (FICL_MINIMAL) -#define FICL_WANT_SOFTWORDS 0 -#define FICL_WANT_FILE 0 -#define FICL_WANT_FLOAT 0 -#define FICL_WANT_USER 0 -#define FICL_WANT_LOCALS 0 -#define FICL_WANT_DEBUGGER 0 -#define FICL_WANT_OOP 0 -#define FICL_PLATFORM_EXTEND 0 -#define FICL_MULTITHREAD 0 -#define FICL_ROBUST 1 -#define FICL_EXTENDED_PREFIX 0 -#endif - -/* -** FICL_PLATFORM_EXTEND -** Includes words defined in ficlCompilePlatform -*/ -#if !defined (FICL_PLATFORM_EXTEND) -#define FICL_PLATFORM_EXTEND 1 -#endif - -/* -** FICL_WANT_FILE -** Includes the FILE and FILE-EXT wordset and associated code. Turn this off if you do not -** have a filesystem! -** Contributed by Larry Hastings -*/ -#if !defined (FICL_WANT_FILE) -#define FICL_WANT_FILE 0 -#endif - -/* -** FICL_WANT_FLOAT -** Includes a floating point stack for the VM, and words to do float operations. -** Contributed by Guy Carver -*/ -#if !defined (FICL_WANT_FLOAT) -#define FICL_WANT_FLOAT 0 -#endif - -/* -** FICL_WANT_DEBUGGER -** Inludes a simple source level debugger -*/ -#if !defined (FICL_WANT_DEBUGGER) -#define FICL_WANT_DEBUGGER 1 -#endif - -/* -** User variables: per-instance variables bound to the VM. -** Kinda like thread-local storage. Could be implemented in a -** VM private dictionary, but I've chosen the lower overhead -** approach of an array of CELLs instead. -*/ -#if !defined FICL_WANT_USER -#define FICL_WANT_USER 1 -#endif - -#if !defined FICL_USER_CELLS -#define FICL_USER_CELLS 16 -#endif - -/* -** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and -** a private dictionary for local variable compilation. -*/ -#if !defined FICL_WANT_LOCALS -#define FICL_WANT_LOCALS 1 -#endif - -/* Max number of local variables per definition */ -#if !defined FICL_MAX_LOCALS -#define FICL_MAX_LOCALS 16 -#endif - -/* -** FICL_WANT_OOP -** Inludes object oriented programming support (in softwords) -** OOP support requires locals and user variables! -*/ -#if !(FICL_WANT_LOCALS) || !(FICL_WANT_USER) -#if !defined (FICL_WANT_OOP) -#define FICL_WANT_OOP 0 -#endif -#endif - -#if !defined (FICL_WANT_OOP) -#define FICL_WANT_OOP 1 -#endif - -/* -** FICL_WANT_SOFTWORDS -** Controls inclusion of all softwords in softcore.c -*/ -#if !defined (FICL_WANT_SOFTWORDS) -#define FICL_WANT_SOFTWORDS 1 -#endif - -/* -** FICL_MULTITHREAD enables dictionary mutual exclusion -** wia the ficlLockDictionary system dependent function. -** Note: this implementation is experimental and poorly -** tested. Further, it's unnecessary unless you really -** intend to have multiple SESSIONS (poor choice of name -** on my part) - that is, threads that modify the dictionary -** at the same time. -*/ -#if !defined FICL_MULTITHREAD -#define FICL_MULTITHREAD 0 -#endif - -/* -** PORTABLE_LONGMULDIV causes ficlLongMul and ficlLongDiv to be -** defined in C in sysdep.c. Use this if you cannot easily -** generate an inline asm definition -*/ -#if !defined (PORTABLE_LONGMULDIV) -#define PORTABLE_LONGMULDIV 0 -#endif - -/* -** INLINE_INNER_LOOP causes the inner interpreter to be inline code -** instead of a function call. This is mainly because MS VC++ 5 -** chokes with an internal compiler error on the function version. -** in release mode. Sheesh. -*/ -#if !defined INLINE_INNER_LOOP -#if defined _DEBUG -#define INLINE_INNER_LOOP 0 -#else -#define INLINE_INNER_LOOP 1 -#endif -#endif - -/* -** FICL_ROBUST enables bounds checking of stacks and the dictionary. -** This will detect stack over and underflows and dictionary overflows. -** Any exceptional condition will result in an assertion failure. -** (As generated by the ANSI assert macro) -** FICL_ROBUST == 1 --> stack checking in the outer interpreter -** FICL_ROBUST == 2 also enables checking in many primitives -*/ - -#if !defined FICL_ROBUST -#define FICL_ROBUST 2 -#endif - -/* -** FICL_DEFAULT_STACK Specifies the default size (in CELLs) of -** a new virtual machine's stacks, unless overridden at -** create time. -*/ -#if !defined FICL_DEFAULT_STACK -#define FICL_DEFAULT_STACK 128 -#endif - -/* -** FICL_DEFAULT_DICT specifies the number of CELLs to allocate -** for the system dictionary by default. The value -** can be overridden at startup time as well. -** FICL_DEFAULT_ENV specifies the number of cells to allot -** for the environment-query dictionary. -*/ -#if !defined FICL_DEFAULT_DICT -#define FICL_DEFAULT_DICT 12288 -#endif - -#if !defined FICL_DEFAULT_ENV -#define FICL_DEFAULT_ENV 260 -#endif - -/* -** FICL_DEFAULT_VOCS specifies the maximum number of wordlists in -** the dictionary search order. See Forth DPANS sec 16.3.3 -** (file://dpans16.htm#16.3.3) -*/ -#if !defined FICL_DEFAULT_VOCS -#define FICL_DEFAULT_VOCS 16 -#endif - -/* -** FICL_MAX_PARSE_STEPS controls the size of an array in the FICL_SYSTEM structure -** that stores pointers to parser extension functions. I would never expect to have -** more than 8 of these, so that's the default limit. Too many of these functions -** will probably exact a nasty performance penalty. -*/ -#if !defined FICL_MAX_PARSE_STEPS -#define FICL_MAX_PARSE_STEPS 8 -#endif - -/* -** FICL_EXTENDED_PREFIX enables a bunch of extra prefixes in prefix.c and prefix.fr (if -** included as part of softcore.c) -*/ -#if !defined FICL_EXTENDED_PREFIX -#define FICL_EXTENDED_PREFIX 0 -#endif - -/* -** FICL_ALIGN is the power of two to which the dictionary -** pointer address must be aligned. This value is usually -** either 1 or 2, depending on the memory architecture -** of the target system; 2 is safe on any 16 or 32 bit -** machine. 3 would be appropriate for a 64 bit machine. -*/ -#if !defined FICL_ALIGN -#define FICL_ALIGN 2 -#define FICL_ALIGN_ADD ((1 << FICL_ALIGN) - 1) -#endif - -/* -** System dependent routines -- -** edit the implementations in sysdep.c to be compatible -** with your runtime environment... -** ficlTextOut sends a NULL terminated string to the -** default output device - used for system error messages -** ficlMalloc and ficlFree have the same semantics as malloc and free -** in standard C -** ficlLongMul multiplies two UNS32s and returns a 64 bit unsigned -** product -** ficlLongDiv divides an UNS64 by an UNS32 and returns UNS32 quotient -** and remainder -*/ -struct vm; -void ficlTextOut(struct vm *pVM, char *msg, int fNewline); -void *ficlMalloc (size_t size); -void ficlFree (void *p); -void *ficlRealloc(void *p, size_t size); -/* -** Stub function for dictionary access control - does nothing -** by default, user can redefine to guarantee exclusive dict -** access to a single thread for updates. All dict update code -** must be bracketed as follows: -** ficlLockDictionary(TRUE); -** <code that updates dictionary> -** ficlLockDictionary(FALSE); -** -** Returns zero if successful, nonzero if unable to acquire lock -** before timeout (optional - could also block forever) -** -** NOTE: this function must be implemented with lock counting -** semantics: nested calls must behave properly. -*/ -#if FICL_MULTITHREAD -int ficlLockDictionary(short fLock); -#else -#define ficlLockDictionary(x) 0 /* ignore */ -#endif - -/* -** 64 bit integer math support routines: multiply two UNS32s -** to get a 64 bit product, & divide the product by an UNS32 -** to get an UNS32 quotient and remainder. Much easier in asm -** on a 32 bit CPU than in C, which usually doesn't support -** the double length result (but it should). -*/ -DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y); -UNSQR ficlLongDiv(DPUNS q, FICL_UNS y); - -/* -** FICL_HAVE_FTRUNCATE indicates whether the current OS supports -** the ftruncate() function (available on most UNIXes). This -** function is necessary to provide the complete File-Access wordset. -*/ -#if !defined (FICL_HAVE_FTRUNCATE) -#define FICL_HAVE_FTRUNCATE 0 -#endif - - -#endif /*__SYSDEP_H__*/ diff --git a/stand/ficl/mips64/sysdep.c b/stand/ficl/mips64/sysdep.c deleted file mode 100644 index 43e7c3c91f1d..000000000000 --- a/stand/ficl/mips64/sysdep.c +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************* -** s y s d e p . c -** Forth Inspired Command Language -** Author: John Sadler (john_sadler@alum.mit.edu) -** Created: 16 Oct 1997 -** Implementations of FICL external interface functions... -** -*******************************************************************/ - -/* $FreeBSD$ */ - -#ifdef TESTMAIN -#include <stdio.h> -#include <stdlib.h> -#else -#include <stand.h> -#endif -#include "ficl.h" - -/* -******************* FreeBSD P O R T B E G I N S H E R E ******************** Michael Smith -*/ - -#if PORTABLE_LONGMULDIV == 0 -DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) -{ - DPUNS q; - uint64_t qx; - - qx = (uint64_t)x * (uint64_t) y; - - q.hi = (uint32_t)( qx >> 32 ); - q.lo = (uint32_t)( qx & 0xFFFFFFFFL); - - return q; -} - -UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) -{ - UNSQR result; - uint64_t qx, qh; - - qh = q.hi; - qx = (qh << 32) | q.lo; - - result.quot = qx / y; - result.rem = qx % y; - - return result; -} -#endif - -void ficlTextOut(FICL_VM *pVM, char *msg, int fNewline) -{ - IGNORE(pVM); - - while(*msg != 0) - putchar(*(msg++)); - if (fNewline) - putchar('\n'); - - return; -} - -void *ficlMalloc (size_t size) -{ - return malloc(size); -} - -void *ficlRealloc (void *p, size_t size) -{ - return realloc(p, size); -} - -void ficlFree (void *p) -{ - free(p); -} - - -/* -** Stub function for dictionary access control - does nothing -** by default, user can redefine to guarantee exclusive dict -** access to a single thread for updates. All dict update code -** is guaranteed to be bracketed as follows: -** ficlLockDictionary(TRUE); -** <code that updates dictionary> -** ficlLockDictionary(FALSE); -** -** Returns zero if successful, nonzero if unable to acquire lock -** befor timeout (optional - could also block forever) -*/ -#if FICL_MULTITHREAD -int ficlLockDictionary(short fLock) -{ - IGNORE(fLock); - return 0; -} -#endif /* FICL_MULTITHREAD */ diff --git a/stand/ficl/mips64/sysdep.h b/stand/ficl/mips64/sysdep.h deleted file mode 100644 index 5c9e163acb70..000000000000 --- a/stand/ficl/mips64/sysdep.h +++ /dev/null @@ -1,432 +0,0 @@ -/******************************************************************* - s y s d e p . h -** Forth Inspired Command Language -** Author: John Sadler (john_sadler@alum.mit.edu) -** Created: 16 Oct 1997 -** Ficl system dependent types and prototypes... -** -** Note: Ficl also depends on the use of "assert" when -** FICL_ROBUST is enabled. This may require some consideration -** in firmware systems since assert often -** assumes stderr/stdout. -** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -*******************************************************************/ -/* -** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) -** All rights reserved. -** -** Get the latest Ficl release at http://ficl.sourceforge.net -** -** L I C E N S E and D I S C L A I M E R -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** I am interested in hearing from anyone who uses ficl. If you have -** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release, please send -** contact me by email at the address above. -** -** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -** $FreeBSD$ -*/ - -#if !defined (__SYSDEP_H__) -#define __SYSDEP_H__ - -#include <sys/types.h> - -#include <stddef.h> /* size_t, NULL */ -#include <setjmp.h> -#include <assert.h> - -#if !defined IGNORE /* Macro to silence unused param warnings */ -#define IGNORE(x) &x -#endif - -/* -** TRUE and FALSE for C boolean operations, and -** portable 32 bit types for CELLs -** -*/ -#if !defined TRUE -#define TRUE 1 -#endif -#if !defined FALSE -#define FALSE 0 -#endif - - -/* -** System dependent data type declarations... -*/ -#if !defined INT32 -#define INT32 int -#endif - -#if !defined UNS32 -#define UNS32 unsigned int -#endif - -#if !defined UNS16 -#define UNS16 unsigned short -#endif - -#if !defined UNS8 -#define UNS8 unsigned char -#endif - -#if !defined NULL -#define NULL ((void *)0) -#endif - -/* -** FICL_UNS and FICL_INT must have the same size as a void* on -** the target system. A CELL is a union of void*, FICL_UNS, and -** FICL_INT. -** (11/2000: same for FICL_FLOAT) -*/ -#if !defined FICL_INT -#define FICL_INT long -#endif - -#if !defined FICL_UNS -#define FICL_UNS unsigned long -#endif - -#if !defined FICL_FLOAT -#define FICL_FLOAT float -#endif - -/* -** Ficl presently supports values of 32 and 64 for BITS_PER_CELL -*/ -#if !defined BITS_PER_CELL -#define BITS_PER_CELL 64 -#endif - -#if ((BITS_PER_CELL != 32) && (BITS_PER_CELL != 64)) - Error! -#endif - -typedef struct -{ - FICL_UNS hi; - FICL_UNS lo; -} DPUNS; - -typedef struct -{ - FICL_UNS quot; - FICL_UNS rem; -} UNSQR; - -typedef struct -{ - FICL_INT hi; - FICL_INT lo; -} DPINT; - -typedef struct -{ - FICL_INT quot; - FICL_INT rem; -} INTQR; - - -/* -** B U I L D C O N T R O L S -*/ - -#if !defined (FICL_MINIMAL) -#define FICL_MINIMAL 0 -#endif -#if (FICL_MINIMAL) -#define FICL_WANT_SOFTWORDS 0 -#define FICL_WANT_FILE 0 -#define FICL_WANT_FLOAT 0 -#define FICL_WANT_USER 0 -#define FICL_WANT_LOCALS 0 -#define FICL_WANT_DEBUGGER 0 -#define FICL_WANT_OOP 0 -#define FICL_PLATFORM_EXTEND 0 -#define FICL_MULTITHREAD 0 -#define FICL_ROBUST 1 -#define FICL_EXTENDED_PREFIX 0 -#endif - -/* -** FICL_PLATFORM_EXTEND -** Includes words defined in ficlCompilePlatform -*/ -#if !defined (FICL_PLATFORM_EXTEND) -#define FICL_PLATFORM_EXTEND 1 -#endif - -/* -** FICL_WANT_FILE -** Includes the FILE and FILE-EXT wordset and associated code. Turn this off if you do not -** have a filesystem! -** Contributed by Larry Hastings -*/ -#if !defined (FICL_WANT_FILE) -#define FICL_WANT_FILE 0 -#endif - -/* -** FICL_WANT_FLOAT -** Includes a floating point stack for the VM, and words to do float operations. -** Contributed by Guy Carver -*/ -#if !defined (FICL_WANT_FLOAT) -#define FICL_WANT_FLOAT 0 -#endif - -/* -** FICL_WANT_DEBUGGER -** Inludes a simple source level debugger -*/ -#if !defined (FICL_WANT_DEBUGGER) -#define FICL_WANT_DEBUGGER 1 -#endif - -/* -** User variables: per-instance variables bound to the VM. -** Kinda like thread-local storage. Could be implemented in a -** VM private dictionary, but I've chosen the lower overhead -** approach of an array of CELLs instead. -*/ -#if !defined FICL_WANT_USER -#define FICL_WANT_USER 1 -#endif - -#if !defined FICL_USER_CELLS -#define FICL_USER_CELLS 16 -#endif - -/* -** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and -** a private dictionary for local variable compilation. -*/ -#if !defined FICL_WANT_LOCALS -#define FICL_WANT_LOCALS 1 -#endif - -/* Max number of local variables per definition */ -#if !defined FICL_MAX_LOCALS -#define FICL_MAX_LOCALS 16 -#endif - -/* -** FICL_WANT_OOP -** Inludes object oriented programming support (in softwords) -** OOP support requires locals and user variables! -*/ -#if !(FICL_WANT_LOCALS) || !(FICL_WANT_USER) -#if !defined (FICL_WANT_OOP) -#define FICL_WANT_OOP 0 -#endif -#endif - -#if !defined (FICL_WANT_OOP) -#define FICL_WANT_OOP 1 -#endif - -/* -** FICL_WANT_SOFTWORDS -** Controls inclusion of all softwords in softcore.c -*/ -#if !defined (FICL_WANT_SOFTWORDS) -#define FICL_WANT_SOFTWORDS 1 -#endif - -/* -** FICL_MULTITHREAD enables dictionary mutual exclusion -** wia the ficlLockDictionary system dependent function. -** Note: this implementation is experimental and poorly -** tested. Further, it's unnecessary unless you really -** intend to have multiple SESSIONS (poor choice of name -** on my part) - that is, threads that modify the dictionary -** at the same time. -*/ -#if !defined FICL_MULTITHREAD -#define FICL_MULTITHREAD 0 -#endif - -/* -** PORTABLE_LONGMULDIV causes ficlLongMul and ficlLongDiv to be -** defined in C in sysdep.c. Use this if you cannot easily -** generate an inline asm definition -*/ -#if !defined (PORTABLE_LONGMULDIV) -#define PORTABLE_LONGMULDIV 0 -#endif - -/* -** INLINE_INNER_LOOP causes the inner interpreter to be inline code -** instead of a function call. This is mainly because MS VC++ 5 -** chokes with an internal compiler error on the function version. -** in release mode. Sheesh. -*/ -#if !defined INLINE_INNER_LOOP -#if defined _DEBUG -#define INLINE_INNER_LOOP 0 -#else -#define INLINE_INNER_LOOP 1 -#endif -#endif - -/* -** FICL_ROBUST enables bounds checking of stacks and the dictionary. -** This will detect stack over and underflows and dictionary overflows. -** Any exceptional condition will result in an assertion failure. -** (As generated by the ANSI assert macro) -** FICL_ROBUST == 1 --> stack checking in the outer interpreter -** FICL_ROBUST == 2 also enables checking in many primitives -*/ - -#if !defined FICL_ROBUST -#define FICL_ROBUST 2 -#endif - -/* -** FICL_DEFAULT_STACK Specifies the default size (in CELLs) of -** a new virtual machine's stacks, unless overridden at -** create time. -*/ -#if !defined FICL_DEFAULT_STACK -#define FICL_DEFAULT_STACK 128 -#endif - -/* -** FICL_DEFAULT_DICT specifies the number of CELLs to allocate -** for the system dictionary by default. The value -** can be overridden at startup time as well. -** FICL_DEFAULT_ENV specifies the number of cells to allot -** for the environment-query dictionary. -*/ -#if !defined FICL_DEFAULT_DICT -#define FICL_DEFAULT_DICT 12288 -#endif - -#if !defined FICL_DEFAULT_ENV -#define FICL_DEFAULT_ENV 260 -#endif - -/* -** FICL_DEFAULT_VOCS specifies the maximum number of wordlists in -** the dictionary search order. See Forth DPANS sec 16.3.3 -** (file://dpans16.htm#16.3.3) -*/ -#if !defined FICL_DEFAULT_VOCS -#define FICL_DEFAULT_VOCS 16 -#endif - -/* -** FICL_MAX_PARSE_STEPS controls the size of an array in the FICL_SYSTEM structure -** that stores pointers to parser extension functions. I would never expect to have -** more than 8 of these, so that's the default limit. Too many of these functions -** will probably exact a nasty performance penalty. -*/ -#if !defined FICL_MAX_PARSE_STEPS -#define FICL_MAX_PARSE_STEPS 8 -#endif - -/* -** FICL_EXTENDED_PREFIX enables a bunch of extra prefixes in prefix.c and prefix.fr (if -** included as part of softcore.c) -*/ -#if !defined FICL_EXTENDED_PREFIX -#define FICL_EXTENDED_PREFIX 0 -#endif - -/* -** FICL_ALIGN is the power of two to which the dictionary -** pointer address must be aligned. This value is usually -** either 1 or 2, depending on the memory architecture -** of the target system; 2 is safe on any 16 or 32 bit -** machine. 3 would be appropriate for a 64 bit machine. -*/ -#if !defined FICL_ALIGN -#define FICL_ALIGN 3 -#define FICL_ALIGN_ADD ((1 << FICL_ALIGN) - 1) -#endif - -/* -** System dependent routines -- -** edit the implementations in sysdep.c to be compatible -** with your runtime environment... -** ficlTextOut sends a NULL terminated string to the -** default output device - used for system error messages -** ficlMalloc and ficlFree have the same semantics as malloc and free -** in standard C -** ficlLongMul multiplies two UNS32s and returns a 64 bit unsigned -** product -** ficlLongDiv divides an UNS64 by an UNS32 and returns UNS32 quotient -** and remainder -*/ -struct vm; -void ficlTextOut(struct vm *pVM, char *msg, int fNewline); -void *ficlMalloc (size_t size); -void ficlFree (void *p); -void *ficlRealloc(void *p, size_t size); -/* -** Stub function for dictionary access control - does nothing -** by default, user can redefine to guarantee exclusive dict -** access to a single thread for updates. All dict update code -** must be bracketed as follows: -** ficlLockDictionary(TRUE); -** <code that updates dictionary> -** ficlLockDictionary(FALSE); -** -** Returns zero if successful, nonzero if unable to acquire lock -** before timeout (optional - could also block forever) -** -** NOTE: this function must be implemented with lock counting -** semantics: nested calls must behave properly. -*/ -#if FICL_MULTITHREAD -int ficlLockDictionary(short fLock); -#else -#define ficlLockDictionary(x) 0 /* ignore */ -#endif - -/* -** 64 bit integer math support routines: multiply two UNS32s -** to get a 64 bit product, & divide the product by an UNS32 -** to get an UNS32 quotient and remainder. Much easier in asm -** on a 32 bit CPU than in C, which usually doesn't support -** the double length result (but it should). -*/ -DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y); -UNSQR ficlLongDiv(DPUNS q, FICL_UNS y); - -/* -** FICL_HAVE_FTRUNCATE indicates whether the current OS supports -** the ftruncate() function (available on most UNIXes). This -** function is necessary to provide the complete File-Access wordset. -*/ -#if !defined (FICL_HAVE_FTRUNCATE) -#define FICL_HAVE_FTRUNCATE 0 -#endif - - -#endif /*__SYSDEP_H__*/ diff --git a/stand/ficl/powerpc/sysdep.c b/stand/ficl/powerpc/sysdep.c index 43e7c3c91f1d..87bed142d684 100644 --- a/stand/ficl/powerpc/sysdep.c +++ b/stand/ficl/powerpc/sysdep.c @@ -7,7 +7,6 @@ ** *******************************************************************/ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/powerpc/sysdep.h b/stand/ficl/powerpc/sysdep.h index b31625e18649..405d4c38176d 100644 --- a/stand/ficl/powerpc/sysdep.h +++ b/stand/ficl/powerpc/sysdep.h @@ -46,7 +46,6 @@ ** contact me by email at the address above. ** ** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -** $FreeBSD$ */ #if !defined (__SYSDEP_H__) diff --git a/stand/ficl/prefix.c b/stand/ficl/prefix.c index a34fc6c78240..f78ee597480f 100644 --- a/stand/ficl/prefix.c +++ b/stand/ficl/prefix.c @@ -41,7 +41,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #include <string.h> #include <ctype.h> diff --git a/stand/ficl/riscv/sysdep.c b/stand/ficl/riscv/sysdep.c index 43e7c3c91f1d..87bed142d684 100644 --- a/stand/ficl/riscv/sysdep.c +++ b/stand/ficl/riscv/sysdep.c @@ -7,7 +7,6 @@ ** *******************************************************************/ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdio.h> diff --git a/stand/ficl/riscv/sysdep.h b/stand/ficl/riscv/sysdep.h index 3726b9ef838f..1bb45efcae26 100644 --- a/stand/ficl/riscv/sysdep.h +++ b/stand/ficl/riscv/sysdep.h @@ -46,7 +46,6 @@ ** contact me by email at the address above. ** ** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ -** $FreeBSD$ */ #if !defined (__SYSDEP_H__) diff --git a/stand/ficl/search.c b/stand/ficl/search.c index d445cb32d93a..2fa0d39ed36e 100644 --- a/stand/ficl/search.c +++ b/stand/ficl/search.c @@ -41,7 +41,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #include <string.h> #include "ficl.h" diff --git a/stand/ficl/softwords/classes.fr b/stand/ficl/softwords/classes.fr index b56da378e970..72524b0b9fa5 100644 --- a/stand/ficl/softwords/classes.fr +++ b/stand/ficl/softwords/classes.fr @@ -4,7 +4,6 @@ \ john sadler 1 sep 98 \ Needs oop.fr \ -\ $FreeBSD$ also oop definitions diff --git a/stand/ficl/softwords/ficlclass.fr b/stand/ficl/softwords/ficlclass.fr index 6d75efb0d3c5..471820c1ac8f 100644 --- a/stand/ficl/softwords/ficlclass.fr +++ b/stand/ficl/softwords/ficlclass.fr @@ -7,7 +7,6 @@ \ ** C - W O R D \ Models a FICL_WORD \ -\ $FreeBSD$ object subclass c-word c-word ref: .link diff --git a/stand/ficl/softwords/ficllocal.fr b/stand/ficl/softwords/ficllocal.fr index c916089696c1..86de6f9b6ea5 100644 --- a/stand/ficl/softwords/ficllocal.fr +++ b/stand/ficl/softwords/ficllocal.fr @@ -7,7 +7,6 @@ \ locstate: 0 = looking for -- or }} \ 1 = found -- \ -\ $FreeBSD$ hide 0 constant zero diff --git a/stand/ficl/softwords/fileaccess.fr b/stand/ficl/softwords/fileaccess.fr index 7297df681cf3..137058572f47 100644 --- a/stand/ficl/softwords/fileaccess.fr +++ b/stand/ficl/softwords/fileaccess.fr @@ -4,7 +4,6 @@ \ ** submitted by Larry Hastings, larry@hastings.org \ ** \ -\ $FreeBSD$ : r/o 1 ; : r/w 3 ; diff --git a/stand/ficl/softwords/forml.fr b/stand/ficl/softwords/forml.fr index 1144ef536792..3e7e56ca2ec1 100644 --- a/stand/ficl/softwords/forml.fr +++ b/stand/ficl/softwords/forml.fr @@ -1,7 +1,6 @@ \ examples from FORML conference paper Nov 98 \ sadler \ -\ $FreeBSD$ .( loading FORML examples ) cr object --> sub c-example diff --git a/stand/ficl/softwords/freebsd.fr b/stand/ficl/softwords/freebsd.fr index 96205c0808dd..948398b4e462 100644 --- a/stand/ficl/softwords/freebsd.fr +++ b/stand/ficl/softwords/freebsd.fr @@ -22,7 +22,6 @@ \ ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ ** SUCH DAMAGE. \ ** -\ ** $FreeBSD$ \ Words for use in scripts: \ % ignore errors here diff --git a/stand/ficl/softwords/ifbrack.fr b/stand/ficl/softwords/ifbrack.fr index a8c60626c4f8..b29b8fa08433 100644 --- a/stand/ficl/softwords/ifbrack.fr +++ b/stand/ficl/softwords/ifbrack.fr @@ -2,7 +2,6 @@ \ ** ANS conditional compile directives [if] [else] [then] \ ** Requires ficl 2.0 or greater... \ -\ $FreeBSD$ hide diff --git a/stand/ficl/softwords/jhlocal.fr b/stand/ficl/softwords/jhlocal.fr index 12ccb9fea753..3cbeb78ff9a1 100644 --- a/stand/ficl/softwords/jhlocal.fr +++ b/stand/ficl/softwords/jhlocal.fr @@ -14,7 +14,6 @@ \ \ revised 2 June 2000 - { | a -- } now works correctly \ -\ $FreeBSD$ hide diff --git a/stand/ficl/softwords/marker.fr b/stand/ficl/softwords/marker.fr index ee3c9bdf2f64..3b9e86acaaf0 100644 --- a/stand/ficl/softwords/marker.fr +++ b/stand/ficl/softwords/marker.fr @@ -3,7 +3,6 @@ \ John Sadler, 4 Oct 98 \ Requires ficl 2.02 FORGET-WID !! \ -\ $FreeBSD$ : marker ( "name" -- ) create diff --git a/stand/ficl/softwords/oo.fr b/stand/ficl/softwords/oo.fr index b1c8e214e5bd..0857cbe4b9fb 100644 --- a/stand/ficl/softwords/oo.fr +++ b/stand/ficl/softwords/oo.fr @@ -3,7 +3,6 @@ \ ** F I C L O - O E X T E N S I O N S \ ** john sadler aug 1998 \ -\ $FreeBSD$ 17 ficl-vocabulary oop also oop definitions diff --git a/stand/ficl/softwords/prefix.fr b/stand/ficl/softwords/prefix.fr index ae1727fc00bc..b1491a384425 100644 --- a/stand/ficl/softwords/prefix.fr +++ b/stand/ficl/softwords/prefix.fr @@ -5,7 +5,6 @@ \ (jws) To make a prefix, simply create a new definition in the <prefixes> \ wordlist. start-prefixes and end-prefixes handle the bookkeeping \ -\ $FreeBSD$ variable save-current diff --git a/stand/ficl/softwords/softcore.awk b/stand/ficl/softwords/softcore.awk index 5a97999a9823..4b736ad46734 100644 --- a/stand/ficl/softwords/softcore.awk +++ b/stand/ficl/softwords/softcore.awk @@ -10,7 +10,6 @@ # Note! This script uses strftime() which is a gawk-ism, and the # POSIX [[:space:]] character class. # -# $FreeBSD$ BEGIN \ { diff --git a/stand/ficl/softwords/softcore.fr b/stand/ficl/softwords/softcore.fr index 3ec74d8cbece..1350f859f3a2 100644 --- a/stand/ficl/softwords/softcore.fr +++ b/stand/ficl/softwords/softcore.fr @@ -3,7 +3,6 @@ \ ** John Sadler (john_sadler@alum.mit.edu) \ ** September, 1998 \ -\ $FreeBSD$ \ ** Ficl USER variables \ ** See words.c for primitive def'n of USER diff --git a/stand/ficl/softwords/string.fr b/stand/ficl/softwords/string.fr index dabb3900892f..bf6c997c70a7 100644 --- a/stand/ficl/softwords/string.fr +++ b/stand/ficl/softwords/string.fr @@ -11,7 +11,6 @@ \ s" woof woof woof " str --> cat \ str --> type cr \ -\ $FreeBSD$ also oop definitions diff --git a/stand/ficl/stack.c b/stand/ficl/stack.c index f98a3b61db7d..366e0adc3cf0 100644 --- a/stand/ficl/stack.c +++ b/stand/ficl/stack.c @@ -40,7 +40,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdlib.h> diff --git a/stand/ficl/testmain.c b/stand/ficl/testmain.c index 7167f30a2561..42c8edf4efa5 100644 --- a/stand/ficl/testmain.c +++ b/stand/ficl/testmain.c @@ -37,7 +37,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #include <stdlib.h> #include <stdio.h> diff --git a/stand/ficl/tools.c b/stand/ficl/tools.c index db1e94850f5e..2e5d3cd3b55b 100644 --- a/stand/ficl/tools.c +++ b/stand/ficl/tools.c @@ -54,7 +54,6 @@ ** Specify breakpoint default action */ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdlib.h> diff --git a/stand/ficl/unix.c b/stand/ficl/unix.c index 5b5644079ba9..77ab3a405d70 100644 --- a/stand/ficl/unix.c +++ b/stand/ficl/unix.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #include <string.h> #include <netinet/in.h> diff --git a/stand/ficl/vm.c b/stand/ficl/vm.c index 97a4f04e3b3b..b435e1b6069c 100644 --- a/stand/ficl/vm.c +++ b/stand/ficl/vm.c @@ -47,7 +47,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdlib.h> diff --git a/stand/ficl/words.c b/stand/ficl/words.c index 3f781c6d2ff4..8d06bedf8375 100644 --- a/stand/ficl/words.c +++ b/stand/ficl/words.c @@ -41,7 +41,6 @@ ** SUCH DAMAGE. */ -/* $FreeBSD$ */ #ifdef TESTMAIN #include <stdlib.h> diff --git a/stand/ficl/x86/sysdep.c b/stand/ficl/x86/sysdep.c index f45c115f7fca..eed3db8ad4c3 100644 --- a/stand/ficl/x86/sysdep.c +++ b/stand/ficl/x86/sysdep.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ #ifndef TESTMAIN #include <machine/cpufunc.h> diff --git a/stand/ficl32/Makefile b/stand/ficl32/Makefile index 09499464ac89..4851e0b8f97f 100644 --- a/stand/ficl32/Makefile +++ b/stand/ficl32/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - DO32=1 .include "${.CURDIR}/../ficl/Makefile" diff --git a/stand/ficl32/Makefile.depend b/stand/ficl32/Makefile.depend index 73bc18c8c0fc..393612bb1e79 100644 --- a/stand/ficl32/Makefile.depend +++ b/stand/ficl32/Makefile.depend @@ -1,8 +1,7 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - stand/libsa \ + stand/libsa32 \ .include <dirdeps.mk> diff --git a/stand/fonts/INDEX.fonts b/stand/fonts/INDEX.fonts index 44aa6a3c81cc..66a6d8a9a3f5 100644 --- a/stand/fonts/INDEX.fonts +++ b/stand/fonts/INDEX.fonts @@ -1,5 +1,4 @@ # -# $FreeBSD$ # # database for vidfont(8) # @@ -61,6 +60,9 @@ FONT:en:8x16v.fnt 16x32.fnt:en:Terminus BSD Console, size 32 16x32.fnt:da:Terminus BSD-konsol, størrelse 32 16x32.fnt:de:Terminus BSD Console, Größe 32 +32x64.fnt:en:Spleen BSD Console, size 64 +32x64.fnt:da:Spleen BSD-konsol, størrelse 64 +32x64.fnt:de:Spleen BSD Console, Größe 64 # (fset 'langnew # "\M-}\C-p\C-k\C-y\C-m\C-y\M-}") diff --git a/stand/fonts/Makefile b/stand/fonts/Makefile index cf45c7ce5e30..4840c07201d6 100644 --- a/stand/fonts/Makefile +++ b/stand/fonts/Makefile @@ -1,7 +1,6 @@ -# $FreeBSD$ - .include <bsd.init.mk> +.PATH: ${SRCTOP}/contrib/spleen .PATH: ${SRCTOP}/contrib/terminus FONTS= \ @@ -17,6 +16,7 @@ FONTS= \ 12x24.fnt.gz \ 14x28.fnt.gz \ 16x32.fnt.gz \ + 32x64.fnt.gz \ FILES= ${FONTS} INDEX.fonts FILESDIR= /boot/fonts @@ -47,6 +47,8 @@ CLEANFILES+= ${FONTS} ${FONTS:T:S/${COMPRESS_EXT}//g} ${COMPRESS_CMD} ${.ALLSRC} > ${.TARGET} 16x32.fnt.gz: 16x32.fnt ${COMPRESS_CMD} ${.ALLSRC} > ${.TARGET} +32x64.fnt.gz: 32x64.fnt + ${COMPRESS_CMD} ${.ALLSRC} > ${.TARGET} 6x12.fnt: ter-u12n.bdf ter-u12b.bdf vtfontcvt -o ${.TARGET} ${.ALLSRC} @@ -84,4 +86,7 @@ CLEANFILES+= ${FONTS} ${FONTS:T:S/${COMPRESS_EXT}//g} 16x32.fnt: ter-u32n.bdf ter-u32b.bdf vtfontcvt -o ${.TARGET} ${.ALLSRC} +32x64.fnt: spleen-32x64.bdf + vtfontcvt -o ${.TARGET} ${.ALLSRC} + .include <bsd.prog.mk> diff --git a/stand/forth/Makefile b/stand/forth/Makefile index a21661d01934..d362863a0970 100644 --- a/stand/forth/Makefile +++ b/stand/forth/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> MAN+= beastie.4th.8 \ diff --git a/stand/forth/Makefile.depend b/stand/forth/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/forth/Makefile.depend +++ b/stand/forth/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/forth/beastie.4th b/stand/forth/beastie.4th index f64cf9f8720b..8aab8214d37e 100644 --- a/stand/forth/beastie.4th +++ b/stand/forth/beastie.4th @@ -24,7 +24,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-beastie.4th diff --git a/stand/forth/beastie.4th.8 b/stand/forth/beastie.4th.8 index 97a5624d5a93..4a5365d981a0 100644 --- a/stand/forth/beastie.4th.8 +++ b/stand/forth/beastie.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd January 6, 2016 .Dt BEASTIE.4TH 8 .Os diff --git a/stand/forth/brand-fbsd.4th b/stand/forth/brand-fbsd.4th index 84245ef232b6..ba84ae0d509a 100644 --- a/stand/forth/brand-fbsd.4th +++ b/stand/forth/brand-fbsd.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ 2 brandX ! 1 brandY ! \ Initialize brand placement defaults diff --git a/stand/forth/brand.4th b/stand/forth/brand.4th index 034e4eb40445..6c7cea584eba 100644 --- a/stand/forth/brand.4th +++ b/stand/forth/brand.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-brand.4th diff --git a/stand/forth/brand.4th.8 b/stand/forth/brand.4th.8 index 7e574d8d96f8..ac02b7feb311 100644 --- a/stand/forth/brand.4th.8 +++ b/stand/forth/brand.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd May 18, 2011 .Dt BRAND.4TH 8 .Os diff --git a/stand/forth/check-password.4th b/stand/forth/check-password.4th index e7996227c5f9..cb938625f4d0 100644 --- a/stand/forth/check-password.4th +++ b/stand/forth/check-password.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-check-password.4th diff --git a/stand/forth/check-password.4th.8 b/stand/forth/check-password.4th.8 index 3c27edd0cf23..83119570d695 100644 --- a/stand/forth/check-password.4th.8 +++ b/stand/forth/check-password.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd June 24, 2018 .Dt CHECK-PASSWORD.4TH 8 .Os diff --git a/stand/forth/color.4th b/stand/forth/color.4th index e73e8b725c31..d3371c17884a 100644 --- a/stand/forth/color.4th +++ b/stand/forth/color.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-color.4th diff --git a/stand/forth/color.4th.8 b/stand/forth/color.4th.8 index 9191da0f0457..8641210613cc 100644 --- a/stand/forth/color.4th.8 +++ b/stand/forth/color.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd August 6, 2013 .Dt COLOR.4TH 8 .Os diff --git a/stand/forth/delay.4th b/stand/forth/delay.4th index 28cfa5c26eb9..45c1c5064827 100644 --- a/stand/forth/delay.4th +++ b/stand/forth/delay.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-delay.4th diff --git a/stand/forth/delay.4th.8 b/stand/forth/delay.4th.8 index af31fd04bad6..74a656ffe11e 100644 --- a/stand/forth/delay.4th.8 +++ b/stand/forth/delay.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd May 18, 2011 .Dt DELAY.4TH 8 .Os diff --git a/stand/forth/efi.4th b/stand/forth/efi.4th index abcf12cffccd..5d4ed912281d 100644 --- a/stand/forth/efi.4th +++ b/stand/forth/efi.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ only forth definitions diff --git a/stand/forth/frames.4th b/stand/forth/frames.4th index 8d2421c758d9..9103f0f0aa3e 100644 --- a/stand/forth/frames.4th +++ b/stand/forth/frames.4th @@ -23,7 +23,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-frames.4th diff --git a/stand/forth/loader.4th b/stand/forth/loader.4th index 89ea9efc4171..db31461f5454 100644 --- a/stand/forth/loader.4th +++ b/stand/forth/loader.4th @@ -23,7 +23,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ only forth definitions @@ -62,8 +61,8 @@ s" arch-i386" environment? [if] [if] [then] [then] [then] -256 dictthreshold ! \ 256 cells minimum free space -2048 dictincrease ! \ 2048 additional cells each time +512 dictthreshold ! \ cells minimum free space +2048 dictincrease ! \ additional cells each time include /boot/support.4th include /boot/color.4th diff --git a/stand/forth/loader.4th.8 b/stand/forth/loader.4th.8 index af8dbfca1b8e..36ba07941a7c 100644 --- a/stand/forth/loader.4th.8 +++ b/stand/forth/loader.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd November 13, 2013 .Dt LOADER.4TH 8 .Os diff --git a/stand/forth/loader.rc b/stand/forth/loader.rc index c15b0f5ce23b..06f2edbd787d 100644 --- a/stand/forth/loader.rc +++ b/stand/forth/loader.rc @@ -1,5 +1,4 @@ \ Loader.rc -\ $FreeBSD$ \ \ You should not edit this file! Put any overrides in loader.rc.local \ instead as this file can be replaced during system updates. diff --git a/stand/forth/logo-beastie.4th b/stand/forth/logo-beastie.4th index 671eb5e496b2..cd049089a44d 100644 --- a/stand/forth/logo-beastie.4th +++ b/stand/forth/logo-beastie.4th @@ -24,7 +24,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ 46 logoX ! 4 logoY ! \ Initialize logo placement defaults diff --git a/stand/forth/logo-beastiebw.4th b/stand/forth/logo-beastiebw.4th index 197099cda0bc..f465dd3d3aa9 100644 --- a/stand/forth/logo-beastiebw.4th +++ b/stand/forth/logo-beastiebw.4th @@ -23,7 +23,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ 46 logoX ! 4 logoY ! \ Initialize logo placement defaults diff --git a/stand/forth/logo-fbsdbw.4th b/stand/forth/logo-fbsdbw.4th index d4a532b78f4f..67c16930c750 100644 --- a/stand/forth/logo-fbsdbw.4th +++ b/stand/forth/logo-fbsdbw.4th @@ -23,7 +23,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ 52 logoX ! 9 logoY ! \ Initialize logo placement defaults diff --git a/stand/forth/logo-orb.4th b/stand/forth/logo-orb.4th index 289353a46926..51efdeaec826 100644 --- a/stand/forth/logo-orb.4th +++ b/stand/forth/logo-orb.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ 46 logoX ! 7 logoY ! \ Initialize logo placement defaults diff --git a/stand/forth/logo-orbbw.4th b/stand/forth/logo-orbbw.4th index 11dc11cabb77..9e49a979f911 100644 --- a/stand/forth/logo-orbbw.4th +++ b/stand/forth/logo-orbbw.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ 46 logoX ! 7 logoY ! \ Initialize logo placement defaults diff --git a/stand/forth/menu-commands.4th b/stand/forth/menu-commands.4th index 9adf30a46b66..13bbcf73201c 100644 --- a/stand/forth/menu-commands.4th +++ b/stand/forth/menu-commands.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-menu-commands.4th @@ -127,20 +126,18 @@ also menu-namespace also menu-command-helpers s" set kern.smp.disabled=1" evaluate s" set hw.ata.ata_dma=0" evaluate s" set hw.ata.atapi_dma=0" evaluate - s" set hw.ata.wc=0" evaluate - s" set hw.eisa_slots=0" evaluate s" set kern.eventtimer.periodic=1" evaluate s" set kern.geom.part.check_integrity=0" evaluate + s" set boot_safe=YES" evaluate ; : safemode_disable ( -- ) s" kern.smp.disabled" unsetenv s" hw.ata.ata_dma" unsetenv s" hw.ata.atapi_dma" unsetenv - s" hw.ata.wc" unsetenv - s" hw.eisa_slots" unsetenv s" kern.eventtimer.periodic" unsetenv s" kern.geom.part.check_integrity" unsetenv + s" boot_safe" unsetenv ; : init_safemode ( N -- N ) diff --git a/stand/forth/menu.4th b/stand/forth/menu.4th index 75e75e3e3654..cc9b0c867e87 100644 --- a/stand/forth/menu.4th +++ b/stand/forth/menu.4th @@ -24,7 +24,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-menu.4th @@ -148,7 +147,7 @@ only forth definitions ; : acpipresent? ( -- flag ) \ Returns TRUE if ACPI is present, FALSE otherwise - s" hint.acpi.0.rsdp" getenv + s" acpi.rsdp" getenv dup -1 = if drop false exit then diff --git a/stand/forth/menu.4th.8 b/stand/forth/menu.4th.8 index 3673eec74aa7..2421fe03be0c 100644 --- a/stand/forth/menu.4th.8 +++ b/stand/forth/menu.4th.8 @@ -22,9 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd August 6, 2013 +.Dd October 4, 2024 .Dt MENU.4TH 8 .Os .Sh NAME @@ -212,8 +210,8 @@ is enabled When set to a number .Dq Li x associated with a given menuitem, that menuitem will only appear when -running on i386-compatible hardware, -.Va hint.acpi.0.rsdp +running on ACPI-compatible hardware, +.Va acpi.rsdp is set (indicating the presence of hardware ACPI support as detected by .Xr loader 8 ) , and @@ -226,10 +224,10 @@ but continue to function as expected. On i386-compatible hardware lacking ACPI support (as detected by .Xr loader 8 ) , subsequent menuitems will retain their associated numbers. -.It Va hint.acpi.0.rsdp +.It Va acpi.rsdp Set automatically by .Xr loader 8 -on i386-compatible hardware when ACPI support is detected at boot time. +on ACPI-compatible hardware when ACPI support is detected at boot time. Effects the display of the .Dq Li menu_acpi menuitem (if configured). diff --git a/stand/forth/menu.rc b/stand/forth/menu.rc index d640e803e61f..da9ef49c84cd 100644 --- a/stand/forth/menu.rc +++ b/stand/forth/menu.rc @@ -1,5 +1,4 @@ \ Menu.rc -\ $FreeBSD$ \ \ You should not edit this file! Put any overrides in menu.rc.local \ instead as this file can be replaced during system updates. diff --git a/stand/forth/menusets.4th b/stand/forth/menusets.4th index 9335b80d511a..c3a4f8e8adb2 100644 --- a/stand/forth/menusets.4th +++ b/stand/forth/menusets.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-menusets.4th diff --git a/stand/forth/menusets.4th.8 b/stand/forth/menusets.4th.8 index f785ae18eabe..ddc0bc02ac41 100644 --- a/stand/forth/menusets.4th.8 +++ b/stand/forth/menusets.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd November 5, 2012 .Dt MENUSETS.4TH 8 .Os diff --git a/stand/forth/screen.4th b/stand/forth/screen.4th index e27482248b57..02eff4dd1b5b 100644 --- a/stand/forth/screen.4th +++ b/stand/forth/screen.4th @@ -23,7 +23,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-screen.4th diff --git a/stand/forth/shortcuts.4th b/stand/forth/shortcuts.4th index 33a1cf678988..6ea885102140 100644 --- a/stand/forth/shortcuts.4th +++ b/stand/forth/shortcuts.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ \ FICL words intended to be used as shortcuts for carrying out common tasks or \ producing common results. Generally, words defined here are simply groupings diff --git a/stand/forth/support.4th b/stand/forth/support.4th index 999ac5005f5d..49318e067678 100644 --- a/stand/forth/support.4th +++ b/stand/forth/support.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ \ Loader.rc support functions: \ diff --git a/stand/forth/version.4th b/stand/forth/version.4th index a5311b4442ac..e92d77b321c8 100644 --- a/stand/forth/version.4th +++ b/stand/forth/version.4th @@ -22,7 +22,6 @@ \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \ SUCH DAMAGE. \ -\ $FreeBSD$ marker task-version.4th diff --git a/stand/forth/version.4th.8 b/stand/forth/version.4th.8 index 256df1ee5f87..6d888df0878e 100644 --- a/stand/forth/version.4th.8 +++ b/stand/forth/version.4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd August 6, 2013 .Dt VERSION.4TH 8 .Os diff --git a/stand/i386/Makefile b/stand/i386/Makefile index 9aa33462f309..299e070d8cd5 100644 --- a/stand/i386/Makefile +++ b/stand/i386/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - NO_OBJ=t .include <bsd.init.mk> @@ -8,7 +6,6 @@ NO_OBJ=t # before everything else proceeds so we don't end up building against a stale # btxldr and ending up with a build-during-install scenario. SUBDIR.yes+= btx libi386 -SUBDIR.${MK_LOADER_FIREWIRE}+= libfirewire SUBDIR.yes+= .WAIT SUBDIR.yes+= mbr pmbr boot0 boot0sio boot2 cdboot gptboot \ @@ -19,10 +16,15 @@ SUBDIR.${MK_LOADER_LUA}+= loader_lua SUBDIR.yes+= loader_simp # special boot programs, 'self-extracting boot2+loader' -SUBDIR.yes+= pxeldr +SUBDIR.${MK_LOADER_PXEBOOT}+= pxeldr -SUBDIR.${MK_LOADER_ZFS}+= zfsboot gptzfsboot +SUBDIR.${MK_LOADER_ZFS}+= gptzfsboot -SUBDIR_DEPEND_pxeldr+= loader_${LOADER_DEFAULT_INTERP} +.if defined(PXEBOOT_DEFAULT_INTERP) +L=${PXEBOOT_DEFAULT_INTERP} +.else +L=${LOADER_DEFAULT_INTERP} +.endif +SUBDIR_DEPEND_pxeldr+= loader_${L} .include <bsd.subdir.mk> diff --git a/stand/i386/Makefile.inc b/stand/i386/Makefile.inc index d12434487877..324c211420ae 100644 --- a/stand/i386/Makefile.inc +++ b/stand/i386/Makefile.inc @@ -1,6 +1,5 @@ # Common defines for all of stand/i386/ # -# $FreeBSD$ .include "bsd.linker.mk" @@ -33,9 +32,4 @@ LD_FLAGS_BIN= -static -N --gc-sections DO32=1 .endif -.if defined(LOADER_FIREWIRE_SUPPORT) -MK_LOADER_FIREWIRE=yes -.warning LOADER_FIREWIRE_SUPPORT deprecated, please move to WITH_LOADER_FIREWIRE -.endif - .include "../Makefile.inc" diff --git a/stand/i386/boot.ldscript b/stand/i386/boot.ldscript index 2f2a2d3e936e..6d2eb71ba465 100644 --- a/stand/i386/boot.ldscript +++ b/stand/i386/boot.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* Simplified linker script for the boot loaders. */ OUTPUT_FORMAT("elf32-i386-freebsd") OUTPUT_ARCH(i386) diff --git a/stand/i386/boot0/Makefile b/stand/i386/boot0/Makefile index 82eb9eefee76..e9c6b2281e37 100644 --- a/stand/i386/boot0/Makefile +++ b/stand/i386/boot0/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - PROG?= boot0 STRIP= BINMODE=${NOBINMODE} @@ -36,19 +34,27 @@ BOOT_BOOT0_FLAGS?= 0x8f # 0xb6 (182d) corresponds to 10 seconds. BOOT_BOOT0_TICKS?= 0xb6 -# The base address that we the boot0 code to to run it. Don't change this -# unless you are glutton for punishment. -BOOT_BOOT0_ORG?= 0x600 -ORG=${BOOT_BOOT0_ORG} +# The BIOS loads boot0 to the hardcoded address 0x7c00. boot0 copies +# itself to this alternate base address before continuing execution so +# that next level boot blocks can be loaded at the 0x7c00 address they +# expect. +ORG= 0x600 # Comm settings for boot0sio. +# +# boot0sio uses BIOS INT $0x14 for serial ports, we can only support these +# baudrates due to INT14's limited interface. In addition, if +# BOOT_BOOT0_COMCONSOLE_SPEED=0, then the baud rate and frame format will remain +# unchanged. Some BIOSes initialize the serial ports to 115200, and this may +# allow boot0sio access at that rate if so. +# # Bit(s) Description # 7-5 data rate (110,150,300,600,1200,2400,4800,9600 bps) # 4-3 parity (00 or 10 = none, 01 = odd, 11 = even) # 2 stop bits (set = 2, clear = 1) # 1-0 data bits (00 = 5, 01 = 6, 10 = 7, 11 = 8) .if !defined(BOOT_BOOT0_COMCONSOLE_SPEED) -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 9600 # BIOS interfaces do not support higher rates. .if ${BOOT_COMCONSOLE_SPEED} == 9600 BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 4800 diff --git a/stand/i386/boot0/Makefile.depend b/stand/i386/boot0/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/boot0/Makefile.depend +++ b/stand/i386/boot0/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/boot0/boot0.S b/stand/i386/boot0/boot0.S index 708f0934c427..6c48e380a32b 100644 --- a/stand/i386/boot0/boot0.S +++ b/stand/i386/boot0/boot0.S @@ -13,23 +13,14 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ /* build options: */ -#ifdef SIO /* use serial console on COM1. */ -#endif #ifdef PXE /* enable PXE/INT18 booting with F6 */ #define SAVE_MORE_MEMORY #endif -#ifdef CHECK_DRIVE /* make sure we boot from a HD. */ -#endif - -#ifdef ONLY_F_KEYS /* Only F1..F6, no digits on console */ -#endif #ifdef VOLUME_SERIAL /* support Volume serial number */ #define B0_BASE 0x1ae /* move the internal data area */ @@ -590,7 +581,7 @@ intx13: # Prepare CHS parameters */ prompt: #ifdef PXE - .ascii "\nF6 PXE\r" + .ascii "F6 PXE\r" #endif .ascii "\nBoot:" item: .ascii " "; .byte ' '|0x80 @@ -674,7 +665,7 @@ ticks: .word TICKS # Delay .org PRT_OFF /* - * Here is the 64 byte partition table that fdisk would fiddle with. + * Here is the 64 byte MBR partition table. */ partbl: .fill 0x40,0x1,0x0 # Partition table .word MAGIC # Magic number diff --git a/stand/i386/boot0sio/Makefile b/stand/i386/boot0sio/Makefile index 1321dd330c4d..3c883a7d93d1 100644 --- a/stand/i386/boot0sio/Makefile +++ b/stand/i386/boot0sio/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .PATH: ${.CURDIR}/../boot0 PROGNAME= boot0sio diff --git a/stand/i386/boot0sio/Makefile.depend b/stand/i386/boot0sio/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/boot0sio/Makefile.depend +++ b/stand/i386/boot0sio/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/boot2/Makefile b/stand/i386/boot2/Makefile index d5ad0f6bd12c..313bb8030f3e 100644 --- a/stand/i386/boot2/Makefile +++ b/stand/i386/boot2/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> FILES= boot boot1 boot2 @@ -8,7 +6,7 @@ FILES= boot boot1 boot2 BOOT_BOOT1_FLAGS?= 0x80 BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 115200 B2SIOFMT?= 0x3 REL1= 0x700 diff --git a/stand/i386/boot2/Makefile.depend b/stand/i386/boot2/Makefile.depend index bc9b1b7bddc9..177fb5979700 100644 --- a/stand/i386/boot2/Makefile.depend +++ b/stand/i386/boot2/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/boot2/boot1.S b/stand/i386/boot2/boot1.S index 984ab52a816f..559c11e86c7f 100644 --- a/stand/i386/boot2/boot1.S +++ b/stand/i386/boot2/boot1.S @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ /* Memory Locations */ diff --git a/stand/i386/boot2/boot2.c b/stand/i386/boot2/boot2.c index 898a8c27df19..b886c70f3808 100644 --- a/stand/i386/boot2/boot2.c +++ b/stand/i386/boot2/boot2.c @@ -13,9 +13,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/disklabel.h> #include <sys/diskmbr.h> @@ -355,7 +352,7 @@ load(void) } static int -parse() +parse(void) { char *arg, *ep, *p, *q; const char *cp; diff --git a/stand/i386/boot2/lib.h b/stand/i386/boot2/lib.h index d8d3317e5aa0..d25dd0f7d28f 100644 --- a/stand/i386/boot2/lib.h +++ b/stand/i386/boot2/lib.h @@ -14,7 +14,6 @@ */ /* - * $FreeBSD$ */ int sio_init(int) __attribute__((regparm (3))); diff --git a/stand/i386/boot2/sio.S b/stand/i386/boot2/sio.S index ca9d0a2406aa..de554efb5b3e 100644 --- a/stand/i386/boot2/sio.S +++ b/stand/i386/boot2/sio.S @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ .set SIO_PRT,SIOPRT # Base port diff --git a/stand/i386/btx/Makefile b/stand/i386/btx/Makefile index 39f78ed639b9..c055927ae59f 100644 --- a/stand/i386/btx/Makefile +++ b/stand/i386/btx/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - SUBDIR= btx btxldr lib .include <bsd.subdir.mk> diff --git a/stand/i386/btx/Makefile.inc b/stand/i386/btx/Makefile.inc index 265f86d1ed55..01b5f23410c8 100644 --- a/stand/i386/btx/Makefile.inc +++ b/stand/i386/btx/Makefile.inc @@ -1,3 +1 @@ -# $FreeBSD$ - .include "../Makefile.inc" diff --git a/stand/i386/btx/btx/Makefile b/stand/i386/btx/btx/Makefile index ce74e4067c9a..6812115213d9 100644 --- a/stand/i386/btx/btx/Makefile +++ b/stand/i386/btx/btx/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= btx @@ -17,7 +15,7 @@ CFLAGS+=-I${BOOTSRC}/i386/common .if defined(BTX_SERIAL) BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 115200 B2SIOFMT?= 0x3 CFLAGS+=-DBTX_SERIAL -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ diff --git a/stand/i386/btx/btx/Makefile.depend b/stand/i386/btx/btx/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/btx/btx/Makefile.depend +++ b/stand/i386/btx/btx/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/btx/btx/btx.S b/stand/i386/btx/btx/btx.S index 87d09a5a1e17..d85ddd04ba4d 100644 --- a/stand/i386/btx/btx/btx.S +++ b/stand/i386/btx/btx/btx.S @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ #include <bootargs.h> diff --git a/stand/i386/btx/btxldr/Makefile b/stand/i386/btx/btxldr/Makefile index d494a5a83201..ef3a04bf12f1 100644 --- a/stand/i386/btx/btxldr/Makefile +++ b/stand/i386/btx/btxldr/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= btxldr diff --git a/stand/i386/btx/btxldr/Makefile.depend b/stand/i386/btx/btxldr/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/btx/btxldr/Makefile.depend +++ b/stand/i386/btx/btxldr/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/btx/btxldr/btxldr.S b/stand/i386/btx/btxldr/btxldr.S index 1a0f5f40ff07..f3174c3a27e0 100644 --- a/stand/i386/btx/btxldr/btxldr.S +++ b/stand/i386/btx/btxldr/btxldr.S @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ #include <bootargs.h> diff --git a/stand/i386/btx/lib/Makefile b/stand/i386/btx/lib/Makefile index a9e2e4350a55..ae7ebc331189 100644 --- a/stand/i386/btx/lib/Makefile +++ b/stand/i386/btx/lib/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= crt0.o diff --git a/stand/i386/btx/lib/Makefile.depend b/stand/i386/btx/lib/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/btx/lib/Makefile.depend +++ b/stand/i386/btx/lib/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/btx/lib/btxcsu.S b/stand/i386/btx/lib/btxcsu.S index c46f8097dbe3..8de4ffb43300 100644 --- a/stand/i386/btx/lib/btxcsu.S +++ b/stand/i386/btx/lib/btxcsu.S @@ -13,8 +13,6 @@ # purpose. # -# $FreeBSD$ - #include <bootargs.h> # diff --git a/stand/i386/btx/lib/btxsys.S b/stand/i386/btx/lib/btxsys.S index 9c77b4295e7c..fa1434d25aea 100644 --- a/stand/i386/btx/lib/btxsys.S +++ b/stand/i386/btx/lib/btxsys.S @@ -13,8 +13,6 @@ # purpose. # -# $FreeBSD$ - # # BTX system calls. # diff --git a/stand/i386/btx/lib/btxv86.S b/stand/i386/btx/lib/btxv86.S index 0d7d1116322d..718406aa96f2 100644 --- a/stand/i386/btx/lib/btxv86.S +++ b/stand/i386/btx/lib/btxv86.S @@ -13,8 +13,6 @@ # purpose. # -# $FreeBSD$ - # # BTX V86 interface. # diff --git a/stand/i386/btx/lib/btxv86.h b/stand/i386/btx/lib/btxv86.h index 0dca768cc2ac..567fdf4690f3 100644 --- a/stand/i386/btx/lib/btxv86.h +++ b/stand/i386/btx/lib/btxv86.h @@ -14,7 +14,6 @@ */ /* - * $FreeBSD$ */ #ifndef _BTXV86_H_ diff --git a/stand/i386/cdboot/Makefile b/stand/i386/cdboot/Makefile index 0598d5d80dce..15b73856c086 100644 --- a/stand/i386/cdboot/Makefile +++ b/stand/i386/cdboot/Makefile @@ -1,10 +1,9 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= cdboot STRIP= BINMODE=${NOBINMODE} +MAN= cdboot.8 SRCS= ${PROG}.S CFLAGS+=-I${BOOTSRC}/i386/common diff --git a/stand/i386/cdboot/Makefile.depend b/stand/i386/cdboot/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/cdboot/Makefile.depend +++ b/stand/i386/cdboot/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/cdboot/cdboot.8 b/stand/i386/cdboot/cdboot.8 new file mode 100644 index 000000000000..6163bd7b4a7a --- /dev/null +++ b/stand/i386/cdboot/cdboot.8 @@ -0,0 +1,21 @@ +.\" +.\" Copyright (c) 2025 Alexander Ziaee +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.Dd May 9 2025 +.Dt CDBOOT 8 i386 +.Os +.Sh NAME +.Nm cdboot +.Nd find a bootloader on ISO-9660 +.Sh DESCRIPTION +.Nm +is a small boot block which finds +.Xr loader 8 +on a +.Xr cd9660 4 +file system. +.Sh SEE ALSO +.Xr cd9660 4 , +.Xr loader 8 diff --git a/stand/i386/cdboot/cdboot.S b/stand/i386/cdboot/cdboot.S index 951b07f209d3..dcac93a9805b 100644 --- a/stand/i386/cdboot/cdboot.S +++ b/stand/i386/cdboot/cdboot.S @@ -23,8 +23,6 @@ # SUCH DAMAGE. # -# $FreeBSD$ - # # This program is a freestanding boot program to load an a.out binary # from a CD-ROM booted with no emulation mode as described by the El diff --git a/stand/i386/common/bootargs.h b/stand/i386/common/bootargs.h index 5a6fef85a8c8..072f7ee505fd 100644 --- a/stand/i386/common/bootargs.h +++ b/stand/i386/common/bootargs.h @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ #ifndef _BOOT_I386_ARGS_H_ @@ -90,7 +88,7 @@ struct bootargs /* * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader) - * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader). + * and in zfs_boot_args (passed from gptzfsboot to loader). */ struct geli_boot_data { diff --git a/stand/i386/common/cons.c b/stand/i386/common/cons.c index 25dda1ce7405..1007d6965d95 100644 --- a/stand/i386/common/cons.c +++ b/stand/i386/common/cons.c @@ -13,9 +13,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <machine/psl.h> diff --git a/stand/i386/common/cons.h b/stand/i386/common/cons.h index 73474fbe9c76..de1b11291771 100644 --- a/stand/i386/common/cons.h +++ b/stand/i386/common/cons.h @@ -11,8 +11,6 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ #ifndef _CONS_H_ diff --git a/stand/i386/common/drv.c b/stand/i386/common/drv.c index e2e4d55e533c..394e1b1e8493 100644 --- a/stand/i386/common/drv.c +++ b/stand/i386/common/drv.c @@ -14,9 +14,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <btxv86.h> diff --git a/stand/i386/common/drv.h b/stand/i386/common/drv.h index c0995df45ea9..d67fd34a04e6 100644 --- a/stand/i386/common/drv.h +++ b/stand/i386/common/drv.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _DRV_H_ diff --git a/stand/i386/common/edd.h b/stand/i386/common/edd.h index 57607be0ebf2..2a8017dd2118 100644 --- a/stand/i386/common/edd.h +++ b/stand/i386/common/edd.h @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _EDD_H_ diff --git a/stand/i386/gptboot/Makefile b/stand/i386/gptboot/Makefile index ee8f4797f3d6..a829be6c745d 100644 --- a/stand/i386/gptboot/Makefile +++ b/stand/i386/gptboot/Makefile @@ -1,14 +1,12 @@ -# $FreeBSD$ - .include <bsd.init.mk> -.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${SASRC} +.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common FILES= gptboot MAN= gptboot.8 BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 115200 B2SIOFMT?= 0x3 REL1= 0x700 @@ -55,12 +53,12 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o CLEANFILES+= gptboot.bin gptboot.out gptboot.o sio.o drv.o \ - cons.o ${OPENCRYPTO_XTS} + cons.o gptboot.bin: gptboot.out ${OBJCOPY} -S -O binary gptboot.out ${.TARGET} -gptboot.out: ${BTXCRT} gptboot.o sio.o drv.o cons.o ${OPENCRYPTO_XTS} +gptboot.out: ${BTXCRT} gptboot.o sio.o drv.o cons.o ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBSA32} .include <bsd.prog.mk> diff --git a/stand/i386/gptboot/Makefile.depend b/stand/i386/gptboot/Makefile.depend index 89aa3261d133..e7f0ac936f3a 100644 --- a/stand/i386/gptboot/Makefile.depend +++ b/stand/i386/gptboot/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/gptboot/gptboot.8 b/stand/i386/gptboot/gptboot.8 index 78e55fb1cb2c..c12d160f06de 100644 --- a/stand/i386/gptboot/gptboot.8 +++ b/stand/i386/gptboot/gptboot.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd March 18, 2022 .Dt GPTBOOT 8 .Os diff --git a/stand/i386/gptboot/gptboot.c b/stand/i386/gptboot/gptboot.c index 78d876554c86..949c00cdf544 100644 --- a/stand/i386/gptboot/gptboot.c +++ b/stand/i386/gptboot/gptboot.c @@ -13,9 +13,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/gpt.h> #include <sys/dirent.h> diff --git a/stand/i386/gptboot/gptldr.S b/stand/i386/gptboot/gptldr.S index ca01082391f2..0c8291586281 100644 --- a/stand/i386/gptboot/gptldr.S +++ b/stand/i386/gptboot/gptldr.S @@ -27,8 +27,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD$ - * * Partly from: src/sys/boot/i386/boot2/boot1.S 1.31 */ diff --git a/stand/i386/gptzfsboot/Makefile b/stand/i386/gptzfsboot/Makefile index 09615c5f97c1..0b67ff8cdaf4 100644 --- a/stand/i386/gptzfsboot/Makefile +++ b/stand/i386/gptzfsboot/Makefile @@ -1,16 +1,14 @@ -# $FreeBSD$ - .include <bsd.init.mk> .PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \ - ${BOOTSRC}/i386/zfsboot ${BOOTSRC}/i386/common \ + ${BOOTSRC}/i386/common \ ${BOOTSRC}/common FILES= gptzfsboot MAN= gptzfsboot.8 BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 115200 B2SIOFMT?= 0x3 REL1= 0x700 @@ -67,7 +65,7 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o misc.o -CLEANFILES+= gptzfsboot.bin gptzfsboot.out ${OBJS} ${OPENCRYPTO_XTS} +CLEANFILES+= gptzfsboot.bin gptzfsboot.out ${OBJS} # i386 standalone support library LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a @@ -75,8 +73,7 @@ LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a gptzfsboot.bin: gptzfsboot.out ${OBJCOPY} -S -O binary gptzfsboot.out ${.TARGET} -gptzfsboot.out: ${BTXCRT} ${OBJS} \ - ${OPENCRYPTO_XTS} +gptzfsboot.out: ${BTXCRT} ${OBJS} ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBI386} ${LIBSA32} zfsboot.o: ${ZFSSRC}/zfsimpl.c diff --git a/stand/i386/gptzfsboot/Makefile.depend b/stand/i386/gptzfsboot/Makefile.depend index ce86c7a5535c..ba3ad3a00d92 100644 --- a/stand/i386/gptzfsboot/Makefile.depend +++ b/stand/i386/gptzfsboot/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/gptzfsboot/gptzfsboot.8 b/stand/i386/gptzfsboot/gptzfsboot.8 index 460178efc577..2a3b6f483c80 100644 --- a/stand/i386/gptzfsboot/gptzfsboot.8 +++ b/stand/i386/gptzfsboot/gptzfsboot.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd September 15, 2014 .Dt GPTZFSBOOT 8 .Os diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/gptzfsboot/zfsboot.c index 8dd3066f15e5..4c8eae9b65e5 100644 --- a/stand/i386/zfsboot/zfsboot.c +++ b/stand/i386/gptzfsboot/zfsboot.c @@ -13,9 +13,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> @@ -134,7 +131,16 @@ static int parse_cmd(void); static char gelipw[GELI_PW_MAXLEN]; #endif -struct arch_switch archsw; /* MI/MD interface boundary */ +/* + * Only because the zfs code requires access through archsw, otherwise the + * 'boot' programs don't need archsw. This is less than ideal, but this + * workaround is easier than many of the alternatives. + */ +struct arch_switch archsw = { /* MI/MD interface boundary */ + .arch_getdev = i386_getdev, + .arch_zfs_probe = i386_zfs_probe, +}; + static char boot_devname[2 * ZFS_MAXNAMELEN + 8]; /* disk or pool:dataset */ struct devsw *devsw[] = { @@ -168,7 +174,7 @@ main(void) { unsigned i; int auto_boot, fd, nextboot = 0; - struct disk_devdesc devdesc; + struct disk_devdesc *devdesc; bios_getmem(); @@ -187,15 +193,6 @@ main(void) */ bcache_init(32768, 512); - archsw.arch_autoload = NULL; - archsw.arch_getdev = i386_getdev; - archsw.arch_copyin = NULL; - archsw.arch_copyout = NULL; - archsw.arch_readin = NULL; - archsw.arch_isainb = NULL; - archsw.arch_isaoutb = NULL; - archsw.arch_zfs_probe = i386_zfs_probe; - bootinfo.bi_version = BOOTINFO_VERSION; bootinfo.bi_size = sizeof(bootinfo); bootinfo.bi_basemem = bios_basemem / 1024; @@ -208,25 +205,25 @@ main(void) bd_bios2unit(bootinfo.bi_bios_dev)); /* Set up currdev variable to have hooks in place. */ - env_setenv("currdev", EV_VOLATILE, "", i386_setcurrdev, + env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, env_nounset); - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); + devinit(); - disk_parsedev(&devdesc, boot_devname + 4, NULL); + /* XXX assumes this will be a disk, but it looks likely give above */ + disk_parsedev((struct devdesc **)&devdesc, boot_devname, NULL); - bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc.d_slice + 1, - devdesc.dd.d_unit, - devdesc.d_partition >= 0 ? devdesc.d_partition : 0xff); + bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc->d_slice + 1, + devdesc->dd.d_unit, + devdesc->d_partition >= 0 ? devdesc->d_partition : 0xff); + free(devdesc); /* - * zfs_fmtdev() can be called only after dv_init + * devformat() can be called only after dv_init */ if (bdev != NULL && bdev->dd.d_dev->dv_type == DEVT_ZFS) { /* set up proper device name string for ZFS */ - strncpy(boot_devname, zfs_fmtdev(bdev), sizeof (boot_devname)); + strncpy(boot_devname, devformat(&bdev->dd), sizeof (boot_devname)); if (zfs_get_bootonce(bdev, OS_BOOTONCE, cmd, sizeof(cmd)) == 0) { nvlist_t *benv; @@ -256,7 +253,7 @@ main(void) free(bdev); i386_getdev((void **)&bdev, boot_devname, NULL); - env_setenv("currdev", EV_VOLATILE, boot_devname, i386_setcurrdev, + env_setenv("currdev", EV_VOLATILE, boot_devname, gen_setcurrdev, env_nounset); /* Process configuration file */ @@ -467,8 +464,8 @@ load(void) if (bdev->dd.d_dev->dv_type == DEVT_ZFS) { zfsargs.size = sizeof(zfsargs); - zfsargs.pool = bdev->d_kind.zfs.pool_guid; - zfsargs.root = bdev->d_kind.zfs.root_guid; + zfsargs.pool = bdev->zfs.pool_guid; + zfsargs.root = bdev->zfs.root_guid; #ifdef LOADER_GELI_SUPPORT export_geli_boot_data(&zfsargs.gelidata); #endif @@ -481,8 +478,8 @@ load(void) __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), bootdev, KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, - (uint32_t)bdev->d_kind.zfs.pool_guid, - (uint32_t)(bdev->d_kind.zfs.pool_guid >> 32), + (uint32_t)bdev->zfs.pool_guid, + (uint32_t)(bdev->zfs.pool_guid >> 32), VTOP(&bootinfo), zfsargs); } else { @@ -528,13 +525,12 @@ mount_root(char *arg) free(bdev); bdev = ddesc; if (bdev->dd.d_dev->dv_type == DEVT_DISK) { - if (bdev->d_kind.biosdisk.partition == -1) + if (bdev->disk.d_partition == -1) part = 0xff; else - part = bdev->d_kind.biosdisk.partition; + part = bdev->disk.d_partition; bootdev = MAKEBOOTDEV(dev_maj[bdev->dd.d_dev->dv_type], - bdev->d_kind.biosdisk.slice + 1, - bdev->dd.d_unit, part); + bdev->disk.d_slice + 1, bdev->dd.d_unit, part); bootinfo.bi_bios_dev = bd_unit2bios(bdev); } strncpy(boot_devname, root, sizeof (boot_devname)); @@ -707,15 +703,15 @@ i386_zfs_probe(void) dev.dd.d_unit); /* If this is not boot disk, use generic probe. */ if (dev.dd.d_unit != boot_unit) - zfs_probe_dev(devname, NULL); + zfs_probe_dev(devname, NULL, true); else - zfs_probe_dev(devname, &pool_guid); + zfs_probe_dev(devname, &pool_guid, true); if (pool_guid != 0 && bdev == NULL) { bdev = malloc(sizeof (struct i386_devdesc)); bzero(bdev, sizeof (struct i386_devdesc)); - bdev->dd.d_dev = &zfs_dev; - bdev->d_kind.zfs.pool_guid = pool_guid; + bdev->zfs.dd.d_dev = &zfs_dev; + bdev->zfs.pool_guid = pool_guid; } } } diff --git a/stand/i386/isoboot/Makefile b/stand/i386/isoboot/Makefile index 7732882b1e5c..0049e7fd3e0a 100644 --- a/stand/i386/isoboot/Makefile +++ b/stand/i386/isoboot/Makefile @@ -1,15 +1,13 @@ -# $FreeBSD$ - .include <bsd.init.mk> .PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \ - ${BOOTSRC}/i386/common ${SASRC} + ${BOOTSRC}/i386/common FILES= isoboot MAN= isoboot.8 BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 115200 B2SIOFMT?= 0x3 REL1= 0x700 @@ -53,12 +51,12 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o CLEANFILES+= isoboot.bin isoboot.out isoboot.o sio.o drv.o \ - cons.o ${OPENCRYPTO_XTS} + cons.o isoboot.bin: isoboot.out ${OBJCOPY} -S -O binary isoboot.out ${.TARGET} -isoboot.out: ${BTXCRT} isoboot.o sio.o drv.o cons.o ${OPENCRYPTO_XTS} +isoboot.out: ${BTXCRT} isoboot.o sio.o drv.o cons.o ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBSA32} .include <bsd.prog.mk> diff --git a/stand/i386/isoboot/isoboot.8 b/stand/i386/isoboot/isoboot.8 index e6971313f9f3..f7e281f5479f 100644 --- a/stand/i386/isoboot/isoboot.8 +++ b/stand/i386/isoboot/isoboot.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd March 30, 2018 .Dt ISOBOOT 8 .Os diff --git a/stand/i386/isoboot/isoboot.c b/stand/i386/isoboot/isoboot.c index f7da4c7d3101..4ffe83cdc9fe 100644 --- a/stand/i386/isoboot/isoboot.c +++ b/stand/i386/isoboot/isoboot.c @@ -13,9 +13,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/gpt.h> #include <sys/dirent.h> diff --git a/stand/i386/libfirewire/Makefile b/stand/i386/libfirewire/Makefile deleted file mode 100644 index bf42c26a918f..000000000000 --- a/stand/i386/libfirewire/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# $FreeBSD$ - -.include <bsd.init.mk> - -LIB= firewire - -.PATH: ${SYSDIR}/dev/dcons ${SYSDIR}/dev/firewire -SRCS+= firewire.c fwohci.c dconsole.c -SRCS+= dcons.c fwcrom.c - -.include "${BOOTSRC}/veriexec.mk" - -CFLAGS+= -D_BOOT - -CFLAGS+= -I${LDRSRC} -CFLAGS+= -I${BOOTSRC}/i386/libi386 - -CFLAGS+= -Wformat -Wall - -.include <bsd.lib.mk> diff --git a/stand/i386/libfirewire/dconsole.c b/stand/i386/libfirewire/dconsole.c deleted file mode 100644 index 338ed26aa417..000000000000 --- a/stand/i386/libfirewire/dconsole.c +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * Copyright (c) 2004 Hidetoshi Shimokawa - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <bootstrap.h> -#include <sys/param.h> -#include <btxv86.h> -#include <dev/dcons/dcons.h> - -void fw_enable(void); -void fw_poll(void); - -static void dconsole_probe(struct console *cp); -static int dconsole_init(int arg); -static void dconsole_putchar(int c); -static int dconsole_getchar(void); -static int dconsole_ischar(void); - -static int dcons_started = 0; - -#define DCONS_BUF_SIZE (64*1024) -static struct dcons_softc sc[DCONS_NPORT]; -uint32_t dcons_paddr; - -/* The buffer must be allocated in BSS because: - * - The dcons driver in the kernel is initialized before VM/pmap is - * initialized, so that the buffer must be allocate in the region - * that is mapped at the very early boot state. - * - We expect identiy map only for regions before KERNLOAD - * (i386:4MB amd64:1MB). - * - It seems that heap in conventional memory(640KB) is not sufficient - * and we move it to high address as LOADER_SUPPORT_BZIP2. - * - BSS is placed in conventional memory. - */ -static char dcons_buffer[DCONS_BUF_SIZE + PAGE_SIZE]; - -struct console dconsole = { - "dcons", - "dumb console port", - 0, - dconsole_probe, - dconsole_init, - dconsole_putchar, - dconsole_getchar, - dconsole_ischar -}; - -#define DCONSOLE_AS_MULTI_CONSOLE 1 - -static void -dconsole_probe(struct console *cp) -{ - /* XXX check the BIOS equipment list? */ - cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); -#if DCONSOLE_AS_MULTI_CONSOLE - dconsole_init(0); - cp->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT); -#endif -} - -static int -dconsole_init(int arg) -{ - char buf[16], *dbuf; - int size; - - if (dcons_started && arg == 0) - return 0; - dcons_started = 1; - - size = DCONS_BUF_SIZE; - dbuf = (char *)round_page((vm_offset_t)&dcons_buffer[0]); - dcons_paddr = VTOP(dbuf); - sprintf(buf, "0x%08x", dcons_paddr); - setenv("dcons.addr", buf, 1); - - dcons_init((struct dcons_buf *)dbuf, size, sc); - sprintf(buf, "%d", size); - setenv("dcons.size", buf, 1); - fw_enable(); - return(0); -} - -static void -dconsole_putchar(int c) -{ - dcons_putc(&sc[0], c); -} - -static int -dconsole_getchar(void) -{ - fw_poll(); - return (dcons_checkc(&sc[0])); -} - -static int -dconsole_ischar(void) -{ - fw_poll(); - return (dcons_ischar(&sc[0])); -} diff --git a/stand/i386/libfirewire/firewire.c b/stand/i386/libfirewire/firewire.c deleted file mode 100644 index b9cb1ec0b19a..000000000000 --- a/stand/i386/libfirewire/firewire.c +++ /dev/null @@ -1,485 +0,0 @@ -/*- - * Copyright (c) 2004 Hidetoshi Shimokawa <simokawa@FreeBSD.ORG> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * FireWire disk device handling. - * - */ - -#include <stand.h> - -#include <machine/bootinfo.h> - -#include <stdarg.h> - -#include <bootstrap.h> -#include <btxv86.h> -#include <libi386.h> -#include <dev/firewire/firewire.h> -#include "fwohci.h" -#include <dev/dcons/dcons.h> - -/* XXX */ -#define BIT4x2(x,y) uint8_t y:4, x:4 -#define BIT16x2(x,y) uint32_t y:16, x:16 -#define _KERNEL -#include <dev/firewire/iec13213.h> - -extern uint32_t dcons_paddr; -extern struct console dconsole; - -struct crom_src_buf { - struct crom_src src; - struct crom_chunk root; - struct crom_chunk vendor; - struct crom_chunk hw; - /* for dcons */ - struct crom_chunk unit; - struct crom_chunk spec; - struct crom_chunk ver; -}; - -static int fw_init(void); -static int fw_strategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); -static int fw_open(struct open_file *f, ...); -static int fw_close(struct open_file *f); -static int fw_print(int verbose); -static void fw_cleanup(void); - -void fw_enable(void); - -struct devsw fwohci = { - "FW1394", /* 7 chars at most */ - DEVT_NET, - fw_init, - fw_strategy, - fw_open, - fw_close, - noioctl, - fw_print, - fw_cleanup -}; - -static struct fwohci_softc fwinfo[MAX_OHCI]; -static int fw_initialized = 0; - -static void -fw_probe(int index, struct fwohci_softc *sc) -{ - int err; - - sc->state = FWOHCI_STATE_INIT; - err = biospci_find_devclass( - 0x0c0010 /* Serial:FireWire:OHCI */, - index /* index */, - &sc->locator); - - if (err != 0) { - sc->state = FWOHCI_STATE_DEAD; - return; - } - - biospci_write_config(sc->locator, - 0x4 /* command */, - BIOSPCI_16BITS, - 0x6 /* enable bus master and memory mapped I/O */); - - biospci_read_config(sc->locator, 0x00 /*devid*/, BIOSPCI_32BITS, - &sc->devid); - biospci_read_config(sc->locator, 0x10 /*base_addr*/, BIOSPCI_32BITS, - &sc->base_addr); - - sc->handle = (uint32_t)PTOV(sc->base_addr); - sc->bus_id = OREAD(sc, OHCI_BUS_ID); - - return; -} - -static int -fw_init(void) -{ - int i, avail; - struct fwohci_softc *sc; - - if (fw_initialized) - return (0); - - avail = 0; - for (i = 0; i < MAX_OHCI; i ++) { - sc = &fwinfo[i]; - fw_probe(i, sc); - if (sc->state == FWOHCI_STATE_DEAD) - break; - avail ++; - break; - } - fw_initialized = 1; - - return (0); -} - - -/* - * Print information about OHCI chips - */ -static int -fw_print(int verbose) -{ - char line[80]; - int i, ret = 0; - struct fwohci_softc *sc; - - printf("%s devices:", fwohci.dv_name); - if ((ret = pager_output("\n")) != 0) - return (ret); - - for (i = 0; i < MAX_OHCI; i ++) { - sc = &fwinfo[i]; - if (sc->state == FWOHCI_STATE_DEAD) - break; - snprintf(line, sizeof(line), "%d: locator=0x%04x devid=0x%08x" - " base_addr=0x%08x handle=0x%08x bus_id=0x%08x\n", - i, sc->locator, sc->devid, - sc->base_addr, sc->handle, sc->bus_id); - ret = pager_output(line); - if (ret != 0) - break; - } - return (ret); -} - -static int -fw_open(struct open_file *f, ...) -{ -#if 0 - va_list ap; - struct i386_devdesc *dev; - struct open_disk *od; - int error; - - va_start(ap, f); - dev = va_arg(ap, struct i386_devdesc *); - va_end(ap); -#endif - - return (ENXIO); -} - -static int -fw_close(struct open_file *f) -{ - return (0); -} - -static void -fw_cleanup() -{ - struct dcons_buf *db; - - /* invalidate dcons buffer */ - if (dcons_paddr) { - db = (struct dcons_buf *)PTOV(dcons_paddr); - db->magic = 0; - } -} - -static int -fw_strategy(void *devdata, int rw, daddr_t dblk, size_t size, - char *buf, size_t *rsize) -{ - return (EIO); -} - -static void -fw_init_crom(struct fwohci_softc *sc) -{ - struct crom_src *src; - - printf("fw_init_crom\n"); - sc->crom_src_buf = (struct crom_src_buf *) - malloc(sizeof(struct crom_src_buf)); - if (sc->crom_src_buf == NULL) - return; - - src = &sc->crom_src_buf->src; - bzero(src, sizeof(struct crom_src)); - - /* BUS info sample */ - src->hdr.info_len = 4; - - src->businfo.bus_name = CSR_BUS_NAME_IEEE1394; - - src->businfo.irmc = 1; - src->businfo.cmc = 1; - src->businfo.isc = 1; - src->businfo.bmc = 1; - src->businfo.pmc = 0; - src->businfo.cyc_clk_acc = 100; - src->businfo.max_rec = sc->maxrec; - src->businfo.max_rom = MAXROM_4; -#define FW_GENERATION_CHANGEABLE 2 - src->businfo.generation = FW_GENERATION_CHANGEABLE; - src->businfo.link_spd = sc->speed; - - src->businfo.eui64.hi = sc->eui.hi; - src->businfo.eui64.lo = sc->eui.lo; - - STAILQ_INIT(&src->chunk_list); - - sc->crom_src = src; - sc->crom_root = &sc->crom_src_buf->root; -} - -static void -fw_reset_crom(struct fwohci_softc *sc) -{ - struct crom_src_buf *buf; - struct crom_src *src; - struct crom_chunk *root; - - printf("fw_reset\n"); - if (sc->crom_src_buf == NULL) - fw_init_crom(sc); - - buf = sc->crom_src_buf; - src = sc->crom_src; - root = sc->crom_root; - - STAILQ_INIT(&src->chunk_list); - - bzero(root, sizeof(struct crom_chunk)); - crom_add_chunk(src, NULL, root, 0); - crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */ - /* private company_id */ - crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE); -#ifdef __DragonFly__ - crom_add_simple_text(src, root, &buf->vendor, "DragonFly Project"); -#else - crom_add_simple_text(src, root, &buf->vendor, "FreeBSD Project"); -#endif -} - - -#define ADDR_HI(x) (((x) >> 24) & 0xffffff) -#define ADDR_LO(x) ((x) & 0xffffff) - -static void -dcons_crom(struct fwohci_softc *sc) -{ - struct crom_src_buf *buf; - struct crom_src *src; - struct crom_chunk *root; - - buf = sc->crom_src_buf; - src = sc->crom_src; - root = sc->crom_root; - - bzero(&buf->unit, sizeof(struct crom_chunk)); - - crom_add_chunk(src, root, &buf->unit, CROM_UDIR); - crom_add_entry(&buf->unit, CSRKEY_SPEC, CSRVAL_VENDOR_PRIVATE); - crom_add_simple_text(src, &buf->unit, &buf->spec, "FreeBSD"); - crom_add_entry(&buf->unit, CSRKEY_VER, DCONS_CSR_VAL_VER); - crom_add_simple_text(src, &buf->unit, &buf->ver, "dcons"); - crom_add_entry(&buf->unit, DCONS_CSR_KEY_HI, ADDR_HI(dcons_paddr)); - crom_add_entry(&buf->unit, DCONS_CSR_KEY_LO, ADDR_LO(dcons_paddr)); -} - -void -fw_crom(struct fwohci_softc *sc) -{ - struct crom_src *src; - void *newrom; - - fw_reset_crom(sc); - dcons_crom(sc); - - newrom = malloc(CROMSIZE); - src = &sc->crom_src_buf->src; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - if (bcmp(newrom, sc->config_rom, CROMSIZE) != 0) { - /* Bump generation and reload. */ - src->businfo.generation++; - - /* Handle generation count wraps. */ - if (src->businfo.generation < 2) - src->businfo.generation = 2; - - /* Recalculate CRC to account for generation change. */ - crom_load(src, (uint32_t *)newrom, CROMSIZE); - bcopy(newrom, (void *)sc->config_rom, CROMSIZE); - } - free(newrom); -} - -static int -fw_busreset(struct fwohci_softc *sc) -{ - int count; - - if (sc->state < FWOHCI_STATE_ENABLED) { - printf("fwohci not enabled\n"); - return(CMD_OK); - } - fw_crom(sc); - fwohci_ibr(sc); - count = 0; - while (sc->state< FWOHCI_STATE_NORMAL) { - fwohci_poll(sc); - count ++; - if (count > 1000) { - printf("give up to wait bus initialize\n"); - return (-1); - } - } - printf("poll count = %d\n", count); - return (0); -} - -void -fw_enable(void) -{ - struct fwohci_softc *sc; - int i; - - if (fw_initialized == 0) - fw_init(); - - for (i = 0; i < MAX_OHCI; i ++) { - sc = &fwinfo[i]; - if (sc->state != FWOHCI_STATE_INIT) - break; - - sc->config_rom = (uint32_t *) - (((uint32_t)sc->config_rom_buf - + (CROMSIZE - 1)) & ~(CROMSIZE - 1)); -#if 0 - printf("configrom: %08p %08p\n", - sc->config_rom_buf, sc->config_rom); -#endif - if (fwohci_init(sc, 0) == 0) { - sc->state = FWOHCI_STATE_ENABLED; - fw_busreset(sc); - } else - sc->state = FWOHCI_STATE_DEAD; - } -} - -void -fw_poll(void) -{ - struct fwohci_softc *sc; - int i; - - if (fw_initialized == 0) - return; - - for (i = 0; i < MAX_OHCI; i ++) { - sc = &fwinfo[i]; - if (sc->state < FWOHCI_STATE_ENABLED) - break; - fwohci_poll(sc); - } -} - -#if 0 /* for debug */ -static int -fw_busreset_cmd(int argc, char *argv[]) -{ - struct fwohci_softc *sc; - int i; - - for (i = 0; i < MAX_OHCI; i ++) { - sc = &fwinfo[i]; - if (sc->state < FWOHCI_STATE_INIT) - break; - fw_busreset(sc); - } - return(CMD_OK); -} - -static int -fw_poll_cmd(int argc, char *argv[]) -{ - fw_poll(); - return(CMD_OK); -} - -static int -fw_enable_cmd(int argc, char *argv[]) -{ - fw_print(0); - fw_enable(); - return(CMD_OK); -} - - -static int -dcons_enable(int argc, char *argv[]) -{ - dconsole.c_init(0); - fw_enable(); - dconsole.c_flags |= C_ACTIVEIN | C_ACTIVEOUT; - return(CMD_OK); -} - -static int -dcons_read(int argc, char *argv[]) -{ - char c; - while (dconsole.c_ready()) { - c = dconsole.c_in(); - printf("%c", c); - } - printf("\r\n"); - return(CMD_OK); -} - -static int -dcons_write(int argc, char *argv[]) -{ - int len, i; - if (argc < 2) - return(CMD_OK); - - len = strlen(argv[1]); - for (i = 0; i < len; i ++) - dconsole.c_out(argv[1][i]); - dconsole.c_out('\r'); - dconsole.c_out('\n'); - return(CMD_OK); -} -COMMAND_SET(firewire, "firewire", "enable firewire", fw_enable_cmd); -COMMAND_SET(fwbusreset, "fwbusreset", "firewire busreset", fw_busreset_cmd); -COMMAND_SET(fwpoll, "fwpoll", "firewire poll", fw_poll_cmd); -COMMAND_SET(dcons, "dcons", "enable dcons", dcons_enable); -COMMAND_SET(dread, "dread", "read from dcons", dcons_read); -COMMAND_SET(dwrite, "dwrite", "write to dcons", dcons_write); -#endif diff --git a/stand/i386/libfirewire/fwohci.c b/stand/i386/libfirewire/fwohci.c deleted file mode 100644 index 85e6173dc9be..000000000000 --- a/stand/i386/libfirewire/fwohci.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2003 Hidetoshi Shimokawa - * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the acknowledgement as bellow: - * - * This product includes software developed by K. Kobayashi and H. Shimokawa - * - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#include <stand.h> -#include <btxv86.h> -#include <bootstrap.h> - -#include <dev/firewire/firewire.h> -#include "fwohci.h" -#include <dev/firewire/fwohcireg.h> -#include <dev/firewire/firewire_phy.h> - -static uint32_t fwphy_wrdata ( struct fwohci_softc *, uint32_t, uint32_t); -static uint32_t fwphy_rddata ( struct fwohci_softc *, uint32_t); -int firewire_debug=0; - -#if 0 -#define device_printf(a, x, ...) printf("FW1394: " x, ## __VA_ARGS__) -#else -#define device_printf(a, x, ...) -#endif - -#define device_t int -#define DELAY(x) delay(x) - -#define MAX_SPEED 3 -#define MAXREC(x) (2 << (x)) -char *linkspeed[] = { - "S100", "S200", "S400", "S800", - "S1600", "S3200", "undef", "undef" -}; - -/* - * Communication with PHY device - */ -static uint32_t -fwphy_wrdata( struct fwohci_softc *sc, uint32_t addr, uint32_t data) -{ - uint32_t fun; - - addr &= 0xf; - data &= 0xff; - - fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA)); - OWRITE(sc, OHCI_PHYACCESS, fun); - DELAY(100); - - return(fwphy_rddata( sc, addr)); -} - -static uint32_t -fwphy_rddata(struct fwohci_softc *sc, u_int addr) -{ - uint32_t fun, stat; - u_int i, retry = 0; - - addr &= 0xf; -#define MAX_RETRY 100 -again: - OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL); - fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR); - OWRITE(sc, OHCI_PHYACCESS, fun); - for ( i = 0 ; i < MAX_RETRY ; i ++ ){ - fun = OREAD(sc, OHCI_PHYACCESS); - if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0) - break; - DELAY(100); - } - if(i >= MAX_RETRY) { - if (firewire_debug) - device_printf(sc->fc.dev, "phy read failed(1).\n"); - if (++retry < MAX_RETRY) { - DELAY(100); - goto again; - } - } - /* Make sure that SCLK is started */ - stat = OREAD(sc, FWOHCI_INTSTAT); - if ((stat & OHCI_INT_REG_FAIL) != 0 || - ((fun >> PHYDEV_REGADDR) & 0xf) != addr) { - if (firewire_debug) - device_printf(sc->fc.dev, "phy read failed(2).\n"); - if (++retry < MAX_RETRY) { - DELAY(100); - goto again; - } - } - if (firewire_debug || retry >= MAX_RETRY) - device_printf(sc->fc.dev, - "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry); -#undef MAX_RETRY - return((fun >> PHYDEV_RDDATA )& 0xff); -} - - -static int -fwohci_probe_phy(struct fwohci_softc *sc, device_t dev) -{ - uint32_t reg, reg2; - int e1394a = 1; - int nport, speed; -/* - * probe PHY parameters - * 0. to prove PHY version, whether compliance of 1394a. - * 1. to probe maximum speed supported by the PHY and - * number of port supported by core-logic. - * It is not actually available port on your PC . - */ - OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS); - DELAY(500); - - reg = fwphy_rddata(sc, FW_PHY_SPD_REG); - - if((reg >> 5) != 7 ){ - nport = reg & FW_PHY_NP; - speed = reg & FW_PHY_SPD >> 6; - if (speed > MAX_SPEED) { - device_printf(dev, "invalid speed %d (fixed to %d).\n", - speed, MAX_SPEED); - speed = MAX_SPEED; - } - device_printf(dev, - "Phy 1394 only %s, %d ports.\n", - linkspeed[speed], nport); - }else{ - reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG); - nport = reg & FW_PHY_NP; - speed = (reg2 & FW_PHY_ESPD) >> 5; - if (speed > MAX_SPEED) { - device_printf(dev, "invalid speed %d (fixed to %d).\n", - speed, MAX_SPEED); - speed = MAX_SPEED; - } - device_printf(dev, - "Phy 1394a available %s, %d ports.\n", - linkspeed[speed], nport); - - /* check programPhyEnable */ - reg2 = fwphy_rddata(sc, 5); -#if 0 - if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) { -#else /* XXX force to enable 1394a */ - if (e1394a) { -#endif - if (firewire_debug) - device_printf(dev, - "Enable 1394a Enhancements\n"); - /* enable EAA EMC */ - reg2 |= 0x03; - /* set aPhyEnhanceEnable */ - OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN); - OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY); - } else { - /* for safe */ - reg2 &= ~0x83; - } - reg2 = fwphy_wrdata(sc, 5, reg2); - } - sc->speed = speed; - - reg = fwphy_rddata(sc, FW_PHY_SPD_REG); - if((reg >> 5) == 7 ){ - reg = fwphy_rddata(sc, 4); - reg |= 1 << 6; - fwphy_wrdata(sc, 4, reg); - reg = fwphy_rddata(sc, 4); - } - return 0; -} - - -void -fwohci_reset(struct fwohci_softc *sc, device_t dev) -{ - int i, max_rec, speed; - uint32_t reg, reg2; - - /* Disable interrupts */ - OWRITE(sc, FWOHCI_INTMASKCLR, ~0); - - /* FLUSH FIFO and reset Transmitter/Receiver */ - OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET); - if (firewire_debug) - device_printf(dev, "resetting OHCI..."); - i = 0; - while(OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) { - if (i++ > 100) break; - DELAY(1000); - } - if (firewire_debug) - printf("done (loop=%d)\n", i); - - /* Probe phy */ - fwohci_probe_phy(sc, dev); - - /* Probe link */ - reg = OREAD(sc, OHCI_BUS_OPT); - reg2 = reg | OHCI_BUSFNC; - max_rec = (reg & 0x0000f000) >> 12; - speed = (reg & 0x00000007); - device_printf(dev, "Link %s, max_rec %d bytes.\n", - linkspeed[speed], MAXREC(max_rec)); - /* XXX fix max_rec */ - sc->maxrec = sc->speed + 8; - if (max_rec != sc->maxrec) { - reg2 = (reg2 & 0xffff0fff) | (sc->maxrec << 12); - device_printf(dev, "max_rec %d -> %d\n", - MAXREC(max_rec), MAXREC(sc->maxrec)); - } - if (firewire_debug) - device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2); - OWRITE(sc, OHCI_BUS_OPT, reg2); - - /* Initialize registers */ - OWRITE(sc, OHCI_CROMHDR, sc->config_rom[0]); - OWRITE(sc, OHCI_CROMPTR, VTOP(sc->config_rom)); -#if 0 - OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr); -#endif - OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND); - OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR); -#if 0 - OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID); -#endif - - /* Enable link */ - OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN); -} - -int -fwohci_init(struct fwohci_softc *sc, device_t dev) -{ - int i, mver; - uint32_t reg; - uint8_t ui[8]; - -/* OHCI version */ - reg = OREAD(sc, OHCI_VERSION); - mver = (reg >> 16) & 0xff; - device_printf(dev, "OHCI version %x.%x (ROM=%d)\n", - mver, reg & 0xff, (reg>>24) & 1); - if (mver < 1 || mver > 9) { - device_printf(dev, "invalid OHCI version\n"); - return (ENXIO); - } - -/* Available Isochronous DMA channel probe */ - OWRITE(sc, OHCI_IT_MASK, 0xffffffff); - OWRITE(sc, OHCI_IR_MASK, 0xffffffff); - reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK); - OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff); - OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff); - for (i = 0; i < 0x20; i++) - if ((reg & (1 << i)) == 0) - break; - device_printf(dev, "No. of Isochronous channels is %d.\n", i); - if (i == 0) - return (ENXIO); - -#if 0 -/* SID receive buffer must align 2^11 */ -#define OHCI_SIDSIZE (1 << 11) - sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE, - &sc->sid_dma, BUS_DMA_WAITOK); - if (sc->sid_buf == NULL) { - device_printf(dev, "sid_buf alloc failed."); - return ENOMEM; - } -#endif - - sc->eui.hi = OREAD(sc, FWOHCIGUID_H); - sc->eui.lo = OREAD(sc, FWOHCIGUID_L); - for( i = 0 ; i < 8 ; i ++) - ui[i] = FW_EUI64_BYTE(&sc->eui,i); - device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]); - fwohci_reset(sc, dev); - - return 0; -} - -void -fwohci_ibr(struct fwohci_softc *sc) -{ - uint32_t fun; - - device_printf(sc->dev, "Initiate bus reset\n"); - - /* - * Make sure our cached values from the config rom are - * initialised. - */ - OWRITE(sc, OHCI_CROMHDR, ntohl(sc->config_rom[0])); - OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->config_rom[2])); - - /* - * Set root hold-off bit so that non cyclemaster capable node - * shouldn't became the root node. - */ -#if 1 - fun = fwphy_rddata(sc, FW_PHY_IBR_REG); - fun |= FW_PHY_IBR; - fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun); -#else /* Short bus reset */ - fun = fwphy_rddata(sc, FW_PHY_ISBR_REG); - fun |= FW_PHY_ISBR; - fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun); -#endif -} - - -void -fwohci_sid(struct fwohci_softc *sc) -{ - uint32_t node_id; - int plen; - - node_id = OREAD(sc, FWOHCI_NODEID); - if (!(node_id & OHCI_NODE_VALID)) { -#if 0 - printf("Bus reset failure\n"); -#endif - return; - } - - /* Enable bus reset interrupt */ - OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R); - /* Allow async. request to us */ - OWRITE(sc, OHCI_AREQHI, 1 << 31); - /* XXX insecure ?? */ - OWRITE(sc, OHCI_PREQHI, 0x7fffffff); - OWRITE(sc, OHCI_PREQLO, 0xffffffff); - OWRITE(sc, OHCI_PREQUPPER, 0x10000); - /* Set ATRetries register */ - OWRITE(sc, OHCI_ATRETRY, 1<<(13+16) | 0xfff); -/* -** Checking whether the node is root or not. If root, turn on -** cycle master. -*/ - plen = OREAD(sc, OHCI_SID_CNT); - device_printf(fc->dev, "node_id=0x%08x, gen=%d, ", - node_id, (plen >> 16) & 0xff); - if (node_id & OHCI_NODE_ROOT) { - device_printf(sc->dev, "CYCLEMASTER mode\n"); - OWRITE(sc, OHCI_LNKCTL, - OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER); - } else { - device_printf(sc->dev, "non CYCLEMASTER mode\n"); - OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR); - OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER); - } - if (plen & OHCI_SID_ERR) { - device_printf(fc->dev, "SID Error\n"); - return; - } - device_printf(sc->dev, "bus reset phase done\n"); - sc->state = FWOHCI_STATE_NORMAL; -} - -static void -fwohci_intr_body(struct fwohci_softc *sc, uint32_t stat, int count) -{ -#undef OHCI_DEBUG -#ifdef OHCI_DEBUG -#if 0 - if(stat & OREAD(sc, FWOHCI_INTMASK)) -#else - if (1) -#endif - device_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n", - stat & OHCI_INT_EN ? "DMA_EN ":"", - stat & OHCI_INT_PHY_REG ? "PHY_REG ":"", - stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"", - stat & OHCI_INT_ERR ? "INT_ERR ":"", - stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"", - stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"", - stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"", - stat & OHCI_INT_CYC_START ? "CYC_START ":"", - stat & OHCI_INT_PHY_INT ? "PHY_INT ":"", - stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"", - stat & OHCI_INT_PHY_SID ? "SID ":"", - stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"", - stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"", - stat & OHCI_INT_DMA_IR ? "DMA_IR ":"", - stat & OHCI_INT_DMA_IT ? "DMA_IT " :"", - stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"", - stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"", - stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"", - stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"", - stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"", - stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"", - stat, OREAD(sc, FWOHCI_INTMASK) - ); -#endif -/* Bus reset */ - if(stat & OHCI_INT_PHY_BUS_R ){ - device_printf(fc->dev, "BUS reset\n"); - if (sc->state == FWOHCI_STATE_BUSRESET) - goto busresetout; - sc->state = FWOHCI_STATE_BUSRESET; - /* Disable bus reset interrupt until sid recv. */ - OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R); - - OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST); - OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC); - - OWRITE(sc, OHCI_CROMHDR, ntohl(sc->config_rom[0])); - OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->config_rom[2])); - } else if (sc->state == FWOHCI_STATE_BUSRESET) { - fwohci_sid(sc); - } -busresetout: - return; -} - -static uint32_t -fwochi_check_stat(struct fwohci_softc *sc) -{ - uint32_t stat; - - stat = OREAD(sc, FWOHCI_INTSTAT); - if (stat == 0xffffffff) { - device_printf(sc->fc.dev, - "device physically ejected?\n"); - return(stat); - } - if (stat) - OWRITE(sc, FWOHCI_INTSTATCLR, stat); - return(stat); -} - -void -fwohci_poll(struct fwohci_softc *sc) -{ - uint32_t stat; - - stat = fwochi_check_stat(sc); - if (stat != 0xffffffff) - fwohci_intr_body(sc, stat, 1); -} diff --git a/stand/i386/libfirewire/fwohci.h b/stand/i386/libfirewire/fwohci.h deleted file mode 100644 index 3c1d29013cda..000000000000 --- a/stand/i386/libfirewire/fwohci.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2007 Hidetoshi Shimokawa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the acknowledgement as bellow: - * - * This product includes software developed by K. Kobayashi and H. Shimokawa - * - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#define MAX_OHCI 5 -#define CROMSIZE 0x400 - -struct fwohci_softc { - uint32_t locator; - uint32_t devid; - uint32_t base_addr; - uint32_t bus_id; - uint32_t handle; - int32_t state; - struct crom_src_buf *crom_src_buf; - struct crom_src *crom_src; - struct crom_chunk *crom_root; - struct fw_eui64 eui; - int speed; - int maxrec; - uint32_t *config_rom; - char config_rom_buf[CROMSIZE*2]; /* double size for alignment */ -}; - -int fwohci_init(struct fwohci_softc *, int); -void fwohci_ibr(struct fwohci_softc *); -void fwohci_poll(struct fwohci_softc *); - -#define FWOHCI_STATE_DEAD (-1) -#define FWOHCI_STATE_INIT 0 -#define FWOHCI_STATE_ENABLED 1 -#define FWOHCI_STATE_BUSRESET 2 -#define FWOHCI_STATE_NORMAL 3 - -#define OREAD(f, o) (*(volatile uint32_t *)((f)->handle + (o))) -#define OWRITE(f, o, v) (*(volatile uint32_t *)((f)->handle + (o)) = (v)) - -#define OHCI_VERSION 0x00 -#define OHCI_ATRETRY 0x08 -#define OHCI_CROMHDR 0x18 -#define OHCI_BUS_ID 0x1c -#define OHCI_BUS_OPT 0x20 -#define OHCI_BUSIRMC (1U << 31) -#define OHCI_BUSCMC (1 << 30) -#define OHCI_BUSISC (1 << 29) -#define OHCI_BUSBMC (1 << 28) -#define OHCI_BUSPMC (1 << 27) -#define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\ - OHCI_BUSBMC | OHCI_BUSPMC - -#define OHCI_EUID_HI 0x24 -#define OHCI_EUID_LO 0x28 - -#define OHCI_CROMPTR 0x34 -#define OHCI_HCCCTL 0x50 -#define OHCI_HCCCTLCLR 0x54 -#define OHCI_AREQHI 0x100 -#define OHCI_AREQHICLR 0x104 -#define OHCI_AREQLO 0x108 -#define OHCI_AREQLOCLR 0x10c -#define OHCI_PREQHI 0x110 -#define OHCI_PREQHICLR 0x114 -#define OHCI_PREQLO 0x118 -#define OHCI_PREQLOCLR 0x11c -#define OHCI_PREQUPPER 0x120 - -#define OHCI_SID_BUF 0x64 -#define OHCI_SID_CNT 0x68 -#define OHCI_SID_ERR (1U << 31) -#define OHCI_SID_CNT_MASK 0xffc - -#define OHCI_IT_STAT 0x90 -#define OHCI_IT_STATCLR 0x94 -#define OHCI_IT_MASK 0x98 -#define OHCI_IT_MASKCLR 0x9c - -#define OHCI_IR_STAT 0xa0 -#define OHCI_IR_STATCLR 0xa4 -#define OHCI_IR_MASK 0xa8 -#define OHCI_IR_MASKCLR 0xac - -#define OHCI_LNKCTL 0xe0 -#define OHCI_LNKCTLCLR 0xe4 - -#define OHCI_PHYACCESS 0xec -#define OHCI_CYCLETIMER 0xf0 - -#define OHCI_DMACTL(off) (off) -#define OHCI_DMACTLCLR(off) (off + 4) -#define OHCI_DMACMD(off) (off + 0xc) -#define OHCI_DMAMATCH(off) (off + 0x10) - -#define OHCI_ATQOFF 0x180 -#define OHCI_ATQCTL OHCI_ATQOFF -#define OHCI_ATQCTLCLR (OHCI_ATQOFF + 4) -#define OHCI_ATQCMD (OHCI_ATQOFF + 0xc) -#define OHCI_ATQMATCH (OHCI_ATQOFF + 0x10) - -#define OHCI_ATSOFF 0x1a0 -#define OHCI_ATSCTL OHCI_ATSOFF -#define OHCI_ATSCTLCLR (OHCI_ATSOFF + 4) -#define OHCI_ATSCMD (OHCI_ATSOFF + 0xc) -#define OHCI_ATSMATCH (OHCI_ATSOFF + 0x10) - -#define OHCI_ARQOFF 0x1c0 -#define OHCI_ARQCTL OHCI_ARQOFF -#define OHCI_ARQCTLCLR (OHCI_ARQOFF + 4) -#define OHCI_ARQCMD (OHCI_ARQOFF + 0xc) -#define OHCI_ARQMATCH (OHCI_ARQOFF + 0x10) - -#define OHCI_ARSOFF 0x1e0 -#define OHCI_ARSCTL OHCI_ARSOFF -#define OHCI_ARSCTLCLR (OHCI_ARSOFF + 4) -#define OHCI_ARSCMD (OHCI_ARSOFF + 0xc) -#define OHCI_ARSMATCH (OHCI_ARSOFF + 0x10) - -#define OHCI_ITOFF(CH) (0x200 + 0x10 * (CH)) -#define OHCI_ITCTL(CH) (OHCI_ITOFF(CH)) -#define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 4) -#define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0xc) - -#define OHCI_IROFF(CH) (0x400 + 0x20 * (CH)) -#define OHCI_IRCTL(CH) (OHCI_IROFF(CH)) -#define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 4) -#define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0xc) -#define OHCI_IRMATCH(CH) (OHCI_IROFF(CH) + 0x10) diff --git a/stand/i386/libi386/Makefile b/stand/i386/libi386/Makefile index 1b23cd53d137..7205d3a61988 100644 --- a/stand/i386/libi386/Makefile +++ b/stand/i386/libi386/Makefile @@ -1,18 +1,36 @@ -# $FreeBSD$ - .include <bsd.init.mk> -LIB= i386 +LIB= i386 -SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c \ - biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \ - comconsole.c devicename.c elf32_freebsd.c \ - elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \ - i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.S \ - time.c vidconsole.c vbe.c amd64_tramp.S spinconsole.c -.PATH: ${ZFSSRC} -SRCS+= devicename_stubs.c -CFLAGS+= -I${ZFSSRC} +SRCS+= amd64_tramp.S +SRCS+= bio.c +SRCS+= biosacpi.c +SRCS+= biosdisk.c +SRCS+= biosmem.c +SRCS+= biosmemdisk.c +SRCS+= biospci.c +SRCS+= biospnp.c +SRCS+= biossmap.c +SRCS+= bootinfo.c +SRCS+= bootinfo32.c +SRCS+= bootinfo64.c +SRCS+= comconsole.c +SRCS+= devicename.c +SRCS+= elf32_freebsd.c +SRCS+= elf64_freebsd.c +SRCS+= i386_copy.c +SRCS+= i386_module.c +SRCS+= multiboot.c +SRCS+= multiboot_tramp.S +SRCS+= nullconsole.c +SRCS+= pxe.c +SRCS+= pxetramp.S +SRCS+= relocater_tramp.S +SRCS+= spinconsole.c +SRCS+= time.c +SRCS+= textvidc.c +SRCS+= vbe.c +SRCS+= vidconsole.c .PATH: ${SYSDIR}/teken SRCS+= teken.c @@ -22,12 +40,12 @@ SRCS+= teken.c BOOT_COMCONSOLE_PORT?= 0x3f8 CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT} -BOOT_COMCONSOLE_SPEED?= 9600 +BOOT_COMCONSOLE_SPEED?= 115200 CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED} .ifdef(BOOT_BIOSDISK_DEBUG) # Make the disk code more talkative -CFLAGS+= -DDISK_DEBUG +CFLAGS.biosdisk.c+= -DDISK_DEBUG .endif # terminal emulation @@ -39,13 +57,9 @@ CFLAGS.teken.c+= -I${SRCTOP}/sys/teken CFLAGS.bootinfo.c+= -I${SRCTOP}/sys/teken -I${SRCTOP}/contrib/pnglite CFLAGS.vbe.c+= -I${SRCTOP}/sys/teken -I${SRCTOP}/contrib/pnglite -# XXX: make alloca() useable -CFLAGS+= -Dalloca=__builtin_alloca +CFLAGS.textvidc.c+= -DTERM_EMU -CFLAGS+= -I${BOOTSRC}/ficl -I${BOOTSRC}/ficl/i386 \ - -I${LDRSRC} -I${BOOTSRC}/i386/common \ - -I${SYSDIR}/cddl/boot/zfs \ - -I${SYSDIR}/cddl/contrib/opensolaris/uts/common \ +CFLAGS+= -I${LDRSRC} -I${BOOTSRC}/i386/common \ -I${SYSDIR}/contrib/dev/acpica/include # Handle FreeBSD specific %b and %D printf format specifiers diff --git a/stand/i386/libi386/Makefile.depend b/stand/i386/libi386/Makefile.depend index df20c96b20e1..15a1f9c07f7c 100644 --- a/stand/i386/libi386/Makefile.depend +++ b/stand/i386/libi386/Makefile.depend @@ -1,10 +1,8 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ include \ include/xlocale \ - lib/libmd \ .include <dirdeps.mk> diff --git a/stand/i386/libi386/amd64_tramp.S b/stand/i386/libi386/amd64_tramp.S index 6359b90d5c9f..3ecdce528622 100644 --- a/stand/i386/libi386/amd64_tramp.S +++ b/stand/i386/libi386/amd64_tramp.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/i386/libi386/bio.c b/stand/i386/libi386/bio.c index 1bcb35f77aa1..357d6cbedf6e 100644 --- a/stand/i386/libi386/bio.c +++ b/stand/i386/libi386/bio.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "libi386.h" diff --git a/stand/i386/libi386/biosacpi.c b/stand/i386/libi386/biosacpi.c index 236c3fc45e7b..8ddd322b9f99 100644 --- a/stand/i386/libi386/biosacpi.c +++ b/stand/i386/libi386/biosacpi.c @@ -24,11 +24,8 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> -#include <machine/stdarg.h> +#include <sys/stdarg.h> #include <bootstrap.h> #include <btxv86.h> #include "libi386.h" @@ -56,6 +53,8 @@ biosacpi_detect(void) char buf[24]; int revision; + feature_enable(FEATURE_EARLY_ACPI); + /* locate and validate the RSDP */ if ((rsdp = biosacpi_find_rsdp()) == NULL) return; @@ -63,36 +62,24 @@ biosacpi_detect(void) /* * Report the RSDP to the kernel. While this can be found with * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. - * The old code used the 'hints' method to communite this to - * the kernel. However, while convenient, the 'hints' method - * is fragile and does not work when static hints are compiled - * into the kernel. Instead, move to setting different tunables - * that start with acpi. The old 'hints' can be removed before - * we branch for FreeBSD 12. */ sprintf(buf, "0x%08x", VTOP(rsdp)); - setenv("hint.acpi.0.rsdp", buf, 1); setenv("acpi.rsdp", buf, 1); revision = rsdp->Revision; if (revision == 0) revision = 1; sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); setenv("acpi.revision", buf, 1); strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); setenv("acpi.oem", buf, 1); sprintf(buf, "0x%08x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); setenv("acpi.rsdt", buf, 1); if (revision >= 2) { /* XXX extended checksum? */ sprintf(buf, "0x%016llx", rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); setenv("acpi.xsdt", buf, 1); sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); setenv("acpi.xsdt_length", buf, 1); } } diff --git a/stand/i386/libi386/biosdisk.c b/stand/i386/libi386/biosdisk.c index 2c52617f255d..9ad9b67f5b57 100644 --- a/stand/i386/libi386/biosdisk.c +++ b/stand/i386/libi386/biosdisk.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * BIOS disk device handling. * @@ -165,7 +162,7 @@ struct devsw biosfd = { .dv_close = bd_close, .dv_ioctl = bd_ioctl, .dv_print = fd_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, }; struct devsw bioscd = { @@ -177,7 +174,7 @@ struct devsw bioscd = { .dv_close = bd_close, .dv_ioctl = bd_ioctl, .dv_print = cd_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, }; struct devsw bioshd = { @@ -189,7 +186,9 @@ struct devsw bioshd = { .dv_close = bd_close, .dv_ioctl = bd_ioctl, .dv_print = bd_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; static bdinfo_list_t * @@ -1031,7 +1030,8 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, d_offset = dev->d_offset; } if (disk_blocks == 0) - disk_blocks = bd->bd_sectors - d_offset; + disk_blocks = bd->bd_sectors * (bd->bd_sectorsize / + BIOSDISK_SECSIZE) - d_offset; /* Validate source block address. */ if (dblk < d_offset || dblk >= d_offset + disk_blocks) @@ -1285,35 +1285,6 @@ bd_io(struct disk_devdesc *dev, bdinfo_t *bd, daddr_t dblk, int blks, } /* - * Return the BIOS geometry of a given "fixed drive" in a format - * suitable for the legacy bootinfo structure. Since the kernel is - * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we - * prefer to get the information directly, rather than rely on being - * able to put it together from information already maintained for - * different purposes and for a probably different number of drives. - * - * For valid drives, the geometry is expected in the format (31..0) - * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are - * indicated by returning the geometry of a "1.2M" PC-format floppy - * disk. And, incidentally, what is returned is not the geometry as - * such but the highest valid cylinder, head, and sector numbers. - */ -uint32_t -bd_getbigeom(int bunit) -{ - - v86.ctl = V86_FLAGS; - v86.addr = DISK_BIOS; - v86.eax = CMD_READ_PARAM; - v86.edx = 0x80 + bunit; - v86int(); - if (V86_CY(v86.efl)) - return (0x4f010f); - return (((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) | - (v86.edx & 0xff00) | (v86.ecx & 0x3f)); -} - -/* * Return a suitable dev_t value for (dev). * * In the case where it looks like (dev) is a SCSI disk, we allow the number of diff --git a/stand/i386/libi386/biosmem.c b/stand/i386/libi386/biosmem.c index 8596ce6abf44..fc612eda5d69 100644 --- a/stand/i386/libi386/biosmem.c +++ b/stand/i386/libi386/biosmem.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Obtain memory configuration information from the BIOS */ diff --git a/stand/i386/libi386/biosmemdisk.c b/stand/i386/libi386/biosmemdisk.c new file mode 100644 index 000000000000..208ae289950a --- /dev/null +++ b/stand/i386/libi386/biosmemdisk.c @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 2020 Richard Russo <russor@ruka.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Source of information: https://repo.or.cz/syslinux.git + * + * Implements the MEMDISK protocol from syslinux, found in doc/memdisk.txt + * (search MEMDISK info structure). Since we validate the pointer to the mBFT, a + * minimum version of 3.85 is needed. Note: All this could be done in the + * kernel, since we don't have hooks to use this inside the boot loader. The + * details of these structures can be found in memdisk/memdisk.inc (search + * for mBFT). + * + * The kernel could just grab the mBFT table, but instead relies on us finding + * it and setting the right env variables. + */ +#include <stand.h> +#include <machine/stdarg.h> +#include <bootstrap.h> +#include <btxv86.h> +#include "libi386.h" + +#include "platform/acfreebsd.h" +#include "acconfig.h" +#define ACPI_SYSTEM_XFACE +#include "actypes.h" +#include "actbl.h" + +struct memdisk_info { + uint32_t mdi_13h_hook_ptr; /* not included in mdi_length! */ + uint16_t mdi_length; + uint8_t mdi_minor; + uint8_t mdi_major; + uint32_t mdi_disk_ptr; + uint32_t mdi_disk_sectors; + uint32_t mdi_far_ptr_cmdline; + uint32_t mdi_old_int13h; + uint32_t mdi_old_int15h; + uint16_t mdi_dos_mem_before; + uint8_t mdi_boot_loader_id; + uint8_t mdi_sector_size; /* Code below assumes this is last */ +} __attribute__((packed)); + +struct safe_13h_hook { + char sh_jmp[3]; + char sh_id[8]; + char sh_vendor[8]; + uint16_t sh_next_offset; + uint16_t sh_next_segment; + uint32_t sh_flags; + uint32_t sh_mbft; +} __attribute__((packed)); + +/* + * Maximum length of INT 13 entries we'll chase. Real disks are on this list, + * potentially, so we may have to look through them to find the memdisk. + */ +#define MEMDISK_MAX 32 + +/* + * Scan for MEMDISK virtual block devices + */ +void +biosmemdisk_detect(void) +{ + char line[80], scratch[80]; + int hook = 0, count = 0, sector_size; + uint16_t segment, offset; + struct safe_13h_hook *probe; + ACPI_TABLE_HEADER *mbft; + uint8_t *cp, sum; + struct memdisk_info *mdi; + + /* + * Walk through the int13 handler linked list, looking for possible + * MEMDISKs. + * + * The max is arbitrary to ensure termination. + */ + offset = *(uint16_t *)PTOV(0x13 * 4); + segment = *(uint16_t *)PTOV(0x13 * 4 + 2); + while (hook < MEMDISK_MAX && !(segment == 0 && offset == 0)) { + /* + * Walk the linked list, making sure each node has the right + * signature and only looking at MEMDISK nodes. + */ + probe = (struct safe_13h_hook *)PTOV(segment * 16 + offset); + if (memcmp(probe->sh_id, "$INT13SF", sizeof(probe->sh_id)) != 0) { + printf("Found int 13h unsafe hook at %p (%x:%x)\n", + probe, segment, offset); + break; + } + if (memcmp(probe->sh_vendor, "MEMDISK ", sizeof(probe->sh_vendor)) != 0) + goto end_of_loop; + + /* + * If it is a memdisk, make sure the mBFT signature is correct + * and its checksum is right. + */ + mbft = (ACPI_TABLE_HEADER *)PTOV(probe->sh_mbft); + if (memcmp(mbft->Signature, "mBFT", sizeof(mbft->Signature)) != 0) + goto end_of_loop; + sum = 0; + cp = (uint8_t *)mbft; + for (int idx = 0; idx < mbft->Length; ++idx) + sum += *(cp + idx); + if (sum != 0) + goto end_of_loop; + + /* + * The memdisk info follows the ACPI_TABLE_HEADER in the mBFT + * section. If the sector size is present and non-zero use it + * otherwise assume 512. + */ + mdi = (struct memdisk_info *)PTOV(probe->sh_mbft + sizeof(*mbft)); + sector_size = 512; + if (mdi->mdi_length + sizeof(mdi->mdi_13h_hook_ptr) >= sizeof(*mdi) && + mdi->mdi_sector_size != 0) + sector_size = 1 << mdi->mdi_sector_size; + + printf("memdisk %d.%d disk at %#x (%d sectors = %d bytes)\n", + mdi->mdi_major, mdi->mdi_minor, mdi->mdi_disk_ptr, + mdi->mdi_disk_sectors, mdi->mdi_disk_sectors * sector_size); + + snprintf(line, sizeof(line), "hint.md.%d.physaddr", count); + snprintf(scratch, sizeof(scratch), "0x%08x", mdi->mdi_disk_ptr); + setenv(line, scratch, 1); + snprintf(line, sizeof(line), "hint.md.%d.len", count); + snprintf(scratch, sizeof(scratch), "%d", mdi->mdi_disk_sectors * sector_size); + setenv(line, scratch, 1); + count++; +end_of_loop: + hook++; + offset = probe->sh_next_offset; + segment = probe->sh_next_segment; + } +} diff --git a/stand/i386/libi386/biospci.c b/stand/i386/libi386/biospci.c index 968533e210c4..a89a6d30a1e8 100644 --- a/stand/i386/libi386/biospci.c +++ b/stand/i386/libi386/biospci.c @@ -26,15 +26,12 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * PnP enumerator using the PCI BIOS. */ #include <stand.h> -#include <machine/stdarg.h> +#include <sys/stdarg.h> #include <bootstrap.h> #include <isapnp.h> #include <btxv86.h> diff --git a/stand/i386/libi386/biospnp.c b/stand/i386/libi386/biospnp.c index 6cd381b2ee11..c01d2888a9f7 100644 --- a/stand/i386/libi386/biospnp.c +++ b/stand/i386/libi386/biospnp.c @@ -24,15 +24,12 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * PnP BIOS enumerator. */ #include <stand.h> -#include <machine/stdarg.h> +#include <sys/stdarg.h> #include <bootstrap.h> #include <isapnp.h> #include <btxv86.h> @@ -157,6 +154,7 @@ biospnp_enumerate(void) { uint8_t Node; struct pnp_devNode *devNodeBuffer; + uint8_t buffer[max(pnp_NodeSize, sizeof(*devNodeBuffer))]; int result; struct pnpinfo *pi; int count; @@ -165,7 +163,7 @@ biospnp_enumerate(void) if (biospnp_init()) return; - devNodeBuffer = (struct pnp_devNode *)alloca(pnp_NodeSize); + devNodeBuffer = (struct pnp_devNode *)buffer; Node = 0; count = 1000; while((Node != 0xff) && (count-- > 0)) { diff --git a/stand/i386/libi386/biossmap.c b/stand/i386/libi386/biossmap.c index e95ea64517d0..c281e6949c20 100644 --- a/stand/i386/libi386/biossmap.c +++ b/stand/i386/libi386/biossmap.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Obtain memory configuration information from the BIOS */ diff --git a/stand/i386/libi386/bootinfo.c b/stand/i386/libi386/bootinfo.c index bdf409b00ec0..b81d181a75bd 100644 --- a/stand/i386/libi386/bootinfo.c +++ b/stand/i386/libi386/bootinfo.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> @@ -38,25 +35,6 @@ __FBSDID("$FreeBSD$"); #include "vbe.h" #include "btxv86.h" -void -bi_load_vbe_data(struct preloaded_file *kfp) -{ - if (!kfp->f_tg_kernel_support) { - /* - * Loaded kernel does not have vt/vbe backend, - * switch console to text mode. - */ - if (vbe_available()) - bios_set_text_mode(VGA_TEXT_MODE); - return; - } - - if (vbe_available()) { - file_addmetadata(kfp, MODINFOMD_VBE_FB, - sizeof(gfx_state.tg_fb), &gfx_state.tg_fb); - } -} - int bi_getboothowto(char *kargs) { @@ -103,31 +81,3 @@ bi_setboothowto(int howto) boot_howto_to_env(howto); } - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -bi_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - i386_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - i386_copyin("", addr, 1); - addr++; - } - i386_copyin("", addr, 1); - addr++; - return(addr); -} diff --git a/stand/i386/libi386/bootinfo32.c b/stand/i386/libi386/bootinfo32.c index 23b02693cf48..6655e62f8065 100644 --- a/stand/i386/libi386/bootinfo32.c +++ b/stand/i386/libi386/bootinfo32.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> @@ -34,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <machine/bootinfo.h> #include <machine/metadata.h> #include "bootstrap.h" +#include "modinfo.h" #include "libi386.h" #include "btxv86.h" @@ -41,91 +39,7 @@ __FBSDID("$FreeBSD$"); #include "geliboot.h" #endif -static struct bootinfo bi; - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - i386_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long));\ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long));\ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -bi_copymodules32(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - MOD_ADDR(addr, fp->f_addr, c); - MOD_SIZE(addr, fp->f_size, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - MOD_END(addr, c); - return(addr); -} +static struct bootinfo *bi; /* * Load the information expected by an i386 kernel. @@ -167,18 +81,19 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(i386_fmtdev((void *)rootdev)); + getrootmount(devformat(&rootdev->dd)); /* Do legacy rootdev guessing */ /* XXX - use a default bootdev of 0. Is this ok??? */ bootdevnr = 0; + bi = calloc(sizeof(*bi), 1); switch(rootdev->dd.d_dev->dv_type) { case DEVT_CD: case DEVT_DISK: /* pass in the BIOS device number of the current disk */ - bi.bi_bios_dev = bd_unit2bios(rootdev); + bi->bi_bios_dev = bd_unit2bios(rootdev); bootdevnr = bd_getdev(rootdev); break; @@ -191,7 +106,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t rootdev->dd.d_dev->dv_type); } if (bootdevnr == -1) { - printf("root device %s invalid\n", i386_fmtdev(rootdev)); + printf("root device %s invalid\n", devformat(&rootdev->dd)); return (EINVAL); } free(rootdev); @@ -203,20 +118,18 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); addr = build_font_module(addr); /* copy our environment */ envp = addr; - addr = bi_copyenv(addr); + addr = md_copyenv(addr); /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf32 kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ @@ -231,8 +144,8 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t /* Figure out the size and location of the metadata */ *modulep = addr; - size = bi_copymodules32(0); - kernend = roundup(addr + size, PAGE_SIZE); + size = md_copymodules(0, false); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ @@ -240,7 +153,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t bcopy(&kernend, md->md_data, sizeof kernend); /* copy module list and metadata */ - (void)bi_copymodules32(addr); + (void)md_copymodules(addr, false); ssym = esym = 0; md = file_findmetadata(kfp, MODINFOMD_SSYM); @@ -255,27 +168,22 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t /* legacy bootinfo structure */ kernelname = getenv("kernelname"); i386_getdev(NULL, kernelname, &kernelpath); - bi.bi_version = BOOTINFO_VERSION; - bi.bi_kernelname = 0; /* XXX char * -> kernel name */ - bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ - bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */ - for (i = 0; i < N_BIOS_GEOM; i++) - bi.bi_bios_geom[i] = bd_getbigeom(i); - bi.bi_size = sizeof(bi); - bi.bi_memsizes_valid = 1; - bi.bi_basemem = bios_basemem / 1024; - bi.bi_extmem = bios_extmem / 1024; - bi.bi_envp = envp; - bi.bi_modulep = *modulep; - bi.bi_kernend = kernend; - bi.bi_kernelname = VTOP(kernelpath); - bi.bi_symtab = ssym; /* XXX this is only the primary kernel symtab */ - bi.bi_esymtab = esym; + bi->bi_version = BOOTINFO_VERSION; + bi->bi_size = sizeof(*bi); + bi->bi_memsizes_valid = 1; + bi->bi_basemem = bios_basemem / 1024; + bi->bi_extmem = bios_extmem / 1024; + bi->bi_envp = envp; + bi->bi_modulep = *modulep; + bi->bi_kernend = kernend; + bi->bi_kernelname = VTOP(kernelpath); + bi->bi_symtab = ssym; /* XXX this is only the primary kernel symtab */ + bi->bi_esymtab = esym; /* legacy boot arguments */ *howtop = howto | RB_BOOTINFO; *bootdevp = bootdevnr; - *bip = VTOP(&bi); + *bip = VTOP(bi); return(0); } diff --git a/stand/i386/libi386/bootinfo64.c b/stand/i386/libi386/bootinfo64.c index 1ffa4188d926..7d74a865ff40 100644 --- a/stand/i386/libi386/bootinfo64.c +++ b/stand/i386/libi386/bootinfo64.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> @@ -37,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <machine/psl.h> #include <machine/specialreg.h> #include "bootstrap.h" +#include "modinfo.h" #include "libi386.h" #include "btxv86.h" @@ -45,93 +43,6 @@ __FBSDID("$FreeBSD$"); #endif /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - i386_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(uint64_t));\ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(uint64_t)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(uint64_t));\ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -bi_copymodules64(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - uint64_t v; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - v = fp->f_addr; - MOD_ADDR(addr, v, c); - v = fp->f_size; - MOD_SIZE(addr, v, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - MOD_END(addr, c); - return(addr); -} - -/* * Check to see if this CPU supports long mode. */ static int @@ -216,7 +127,7 @@ bi_load64(char *args, vm_offset_t *modulep, } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(i386_fmtdev((void *)rootdev)); + getrootmount(devformat(&rootdev->dd)); addr = 0; /* find the last module in the chain */ @@ -225,16 +136,14 @@ bi_load64(char *args, vm_offset_t *modulep, addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); addr = build_font_module(addr); /* place the metadata before anything */ module = *modulep = addr; - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf64 kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ @@ -249,14 +158,14 @@ bi_load64(char *args, vm_offset_t *modulep, #endif bi_load_vbe_data(kfp); - size = bi_copymodules64(0); + size = md_copymodules(0, true); /* copy our environment */ - envp = roundup(addr + size, PAGE_SIZE); - addr = bi_copyenv(envp); + envp = md_align(addr + size); + addr = md_copyenv(envp); /* set kernend */ - kernend = roundup(addr, PAGE_SIZE); + kernend = md_align(addr); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ @@ -268,7 +177,7 @@ bi_load64(char *args, vm_offset_t *modulep, bcopy(&envp, md->md_data, sizeof envp); /* copy module list and metadata */ - (void)bi_copymodules64(*modulep); + (void)md_copymodules(*modulep, true); return(0); } diff --git a/stand/i386/libi386/comconsole.c b/stand/i386/libi386/comconsole.c index ed1f1aa08ed7..dc6bbcfe9806 100644 --- a/stand/i386/libi386/comconsole.c +++ b/stand/i386/libi386/comconsole.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <bootstrap.h> #include <machine/cpufunc.h> @@ -42,7 +39,7 @@ __FBSDID("$FreeBSD$"); #define COMPORT 0x3f8 #endif #ifndef COMSPEED -#define COMSPEED 9600 +#define COMSPEED 115200 #endif static void comc_probe(struct console *cp); @@ -143,8 +140,8 @@ comc_init(int arg) if ((comconsole.c_flags & (C_PRESENTIN | C_PRESENTOUT)) == (C_PRESENTIN | C_PRESENTOUT)) - return (CMD_OK); - return (CMD_ERROR); + return (0); + return (1); } static void @@ -324,12 +321,13 @@ comc_setup(int speed, int port) char intbuf[64]; int tries; - unsetenv("hw.uart.console"); comc_curspeed = speed; comc_port = port; if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == 0) return; + unsetenv("hw.uart.console"); + #define COMC_TEST 0xbb /* * Write byte to scratch register and read it out. diff --git a/stand/i386/libi386/devicename.c b/stand/i386/libi386/devicename.c index 061f2ba9ce9f..628b969ad132 100644 --- a/stand/i386/libi386/devicename.c +++ b/stand/i386/libi386/devicename.c @@ -24,17 +24,11 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include "bootstrap.h" #include "disk.h" #include "libi386.h" -#include "libzfs.h" - -static int i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path); /* * Point (dev) at an allocated device specifier for the device matching the @@ -44,7 +38,7 @@ static int i386_parsedev(struct i386_devdesc **dev, const char *devspec, const c int i386_getdev(void **vdev, const char *devspec, const char **path) { - struct i386_devdesc **dev = (struct i386_devdesc **)vdev; + struct devdesc **dev = (struct devdesc **)vdev; int rv; /* @@ -55,7 +49,7 @@ i386_getdev(void **vdev, const char *devspec, const char **path) (devspec[0] == '/') || (strchr(devspec, ':') == NULL)) { - if (((rv = i386_parsedev(dev, getenv("currdev"), NULL)) == 0) && + if (((rv = devparse(dev, getenv("currdev"), NULL)) == 0) && (path != NULL)) *path = devspec; return(rv); @@ -64,152 +58,5 @@ i386_getdev(void **vdev, const char *devspec, const char **path) /* * Try to parse the device name off the beginning of the devspec */ - return(i386_parsedev(dev, devspec, path)); -} - -/* - * Point (dev) at an allocated device specifier matching the string version - * at the beginning of (devspec). Return a pointer to the remaining - * text in (path). - * - * In all cases, the beginning of (devspec) is compared to the names - * of known devices in the device switch, and then any following text - * is parsed according to the rules applied to the device type. - * - * For disk-type devices, the syntax is: - * - * disk<unit>[s<slice>][<partition>]: - * - */ -static int -i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path) -{ - struct i386_devdesc *idev; - struct devsw *dv; - int i, unit, err; - char *cp; - const char *np; - - /* minimum length check */ - if (strlen(devspec) < 2) - return(EINVAL); - - /* look for a device that matches */ - for (i = 0, dv = NULL; devsw[i] != NULL; i++) { - if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) { - dv = devsw[i]; - break; - } - } - if (dv == NULL) - return(ENOENT); - - np = (devspec + strlen(dv->dv_name)); - idev = NULL; - err = 0; - - switch(dv->dv_type) { - case DEVT_NONE: - break; - - case DEVT_DISK: - idev = malloc(sizeof(struct i386_devdesc)); - if (idev == NULL) - return (ENOMEM); - - err = disk_parsedev((struct disk_devdesc *)idev, np, path); - if (err != 0) - goto fail; - break; - - case DEVT_ZFS: - idev = malloc(sizeof (struct zfs_devdesc)); - if (idev == NULL) - return (ENOMEM); - - err = zfs_parsedev((struct zfs_devdesc *)idev, np, path); - if (err != 0) - goto fail; - break; - - default: - idev = malloc(sizeof (struct devdesc)); - if (idev == NULL) - return (ENOMEM); - - unit = 0; - cp = (char *)np; - - if (*np && (*np != ':')) { - unit = strtol(np, &cp, 0); /* get unit number if present */ - if (cp == np) { - err = EUNIT; - goto fail; - } - } - - if (*cp && (*cp != ':')) { - err = EINVAL; - goto fail; - } - - idev->dd.d_unit = unit; - if (path != NULL) - *path = (*cp == 0) ? cp : cp + 1; - break; - } - idev->dd.d_dev = dv; - if (dev != NULL) - *dev = idev; - else - free(idev); - - return(0); - - fail: - free(idev); - return(err); -} - - -char * -i386_fmtdev(void *vdev) -{ - struct i386_devdesc *dev = (struct i386_devdesc *)vdev; - static char buf[128]; /* XXX device length constant? */ - - switch(dev->dd.d_dev->dv_type) { - case DEVT_NONE: - strcpy(buf, "(no device)"); - break; - - case DEVT_CD: - case DEVT_NET: - sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); - break; - - case DEVT_DISK: - return (disk_fmtdev(vdev)); - - case DEVT_ZFS: - return(zfs_fmtdev(vdev)); - } - return(buf); -} - - -/* - * Set currdev to suit the value being supplied in (value) - */ -int -i386_setcurrdev(struct env_var *ev, int flags, const void *value) -{ - struct i386_devdesc *ncurr; - int rv; - - if ((rv = i386_parsedev(&ncurr, value, NULL)) != 0) - return (rv); - free(ncurr); - - return (mount_currdev(ev, flags, value)); + return(devparse(dev, devspec, path)); } diff --git a/stand/i386/libi386/elf32_freebsd.c b/stand/i386/libi386/elf32_freebsd.c index 641e2733c3a2..ae5702e5e65f 100644 --- a/stand/i386/libi386/elf32_freebsd.c +++ b/stand/i386/libi386/elf32_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/exec.h> #include <sys/linker.h> diff --git a/stand/i386/libi386/elf64_freebsd.c b/stand/i386/libi386/elf64_freebsd.c index 1108a9e4d713..89cc249e9d96 100644 --- a/stand/i386/libi386/elf64_freebsd.c +++ b/stand/i386/libi386/elf64_freebsd.c @@ -24,15 +24,15 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> #include <sys/exec.h> #include <sys/linker.h> +#include <vm/vm.h> +#include <vm/pmap.h> #include <string.h> #include <machine/bootinfo.h> +#include <machine/pmap_pae.h> #include <machine/elf.h> #include <stand.h> @@ -46,16 +46,15 @@ static int elf64_obj_exec(struct preloaded_file *amp); struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; -#define PG_V 0x001 -#define PG_RW 0x002 -#define PG_PS 0x080 +/* + * i386's pmap_pae.h doesn't provide this, so + * just typedef our own. + */ +typedef pdpt_entry_t pml4_entry_t; -typedef uint64_t p4_entry_t; -typedef uint64_t p3_entry_t; -typedef uint64_t p2_entry_t; -extern p4_entry_t PT4[]; -extern p3_entry_t PT3[]; -extern p2_entry_t PT2[]; +extern pml4_entry_t PT4[]; +extern pdpt_entry_t PT3[]; +extern pd_entry_t PT2[]; uint32_t entry_hi; uint32_t entry_lo; @@ -94,11 +93,11 @@ elf64_exec(struct preloaded_file *fp) */ for (i = 0; i < 512; i++) { /* Each slot of the level 4 pages points to the same level 3 page */ - PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]); + PT4[i] = (pml4_entry_t)VTOP((uintptr_t)&PT3[0]); PT4[i] |= PG_V | PG_RW; /* Each slot of the level 3 pages points to the same level 2 page */ - PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); + PT3[i] = (pdpt_entry_t)VTOP((uintptr_t)&PT2[0]); PT3[i] |= PG_V | PG_RW; /* The level 2 page slots are mapped with 2MB pages for 1GB. */ diff --git a/stand/i386/libi386/i386_copy.c b/stand/i386/libi386/i386_copy.c index a1e7c734ebf3..44ca51f6b2ae 100644 --- a/stand/i386/libi386/i386_copy.c +++ b/stand/i386/libi386/i386_copy.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * MD primitives supporting placement of module data * diff --git a/stand/i386/libi386/i386_module.c b/stand/i386/libi386/i386_module.c index 78ab61ba9a59..26f2ed3eec40 100644 --- a/stand/i386/libi386/i386_module.c +++ b/stand/i386/libi386/i386_module.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * i386-specific module functionality. * diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h index a52a1190e7ec..caf565dd0656 100644 --- a/stand/i386/libi386/libi386.h +++ b/stand/i386/libi386/libi386.h @@ -22,30 +22,26 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ +#include "disk.h" +#ifdef LOADER_ZFS_SUPPORT +#include "libzfs.h" +#endif /* * i386 fully-qualified device descriptor. */ -struct i386_devdesc { - struct devdesc dd; /* Must be first. */ - union - { - struct - { - int slice; - int partition; - off_t offset; - } biosdisk; - struct +struct i386_devdesc +{ + union { - uint64_t pool_guid; - uint64_t root_guid; - } zfs; - } d_kind; + struct devdesc dd; + struct disk_devdesc disk; +#ifdef LOADER_ZFS_SUPPORT + struct zfs_devdesc zfs; +#endif + }; }; /* @@ -82,7 +78,6 @@ extern uint16_t relocator_a20_enabled; int i386_getdev(void **vdev, const char *devspec, const char **path); char *i386_fmtdev(void *vdev); -int i386_setcurrdev(struct env_var *ev, int flags, const void *value); extern struct devdesc currdev; /* our current device */ @@ -148,10 +143,11 @@ int i386_autoload(void); void bi_load_vbe_data(struct preloaded_file *kfp); int bi_getboothowto(char *kargs); void bi_setboothowto(int howto); -vm_offset_t bi_copyenv(vm_offset_t addr); int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernend); int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernend, int add_smap); void pxe_enable(void *pxeinfo); + +void biosmemdisk_detect(void); diff --git a/stand/i386/libi386/multiboot.c b/stand/i386/libi386/multiboot.c index 2d0a4a9b2274..e2bd44fe83f5 100644 --- a/stand/i386/libi386/multiboot.c +++ b/stand/i386/libi386/multiboot.c @@ -34,9 +34,6 @@ * http://www.gnu.org/software/grub/manual/multiboot/multiboot.html */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/exec.h> #include <sys/linker.h> @@ -51,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "multiboot.h" #include "libi386.h" +#include "modinfo.h" #include <btxv86.h> #define MULTIBOOT_SUPPORTED_FLAGS \ @@ -168,7 +166,7 @@ multiboot_exec(struct preloaded_file *fp) int error, mod_num; struct xen_header header; - CTASSERT(sizeof(header) <= PAGE_SIZE); + _Static_assert(sizeof(header) <= PAGE_SIZE, "header too large for page"); /* * Don't pass the memory size found by the bootloader, the memory @@ -259,7 +257,7 @@ multiboot_exec(struct preloaded_file *fp) * module 0 module 1 */ - fp = file_findfile(NULL, "elf kernel"); + fp = file_findfile(NULL, md_kerntype); if (fp == NULL) { printf("No FreeBSD kernel provided, aborting\n"); error = EINVAL; @@ -327,7 +325,7 @@ multiboot_obj_loadfile(char *filename, uint64_t dest, int error, mod_num; /* See if there's a multiboot kernel loaded */ - mfp = file_findfile(NULL, "elf multiboot kernel"); + mfp = file_findfile(NULL, md_kerntype_mb); if (mfp == NULL) return (EFTYPE); @@ -335,14 +333,14 @@ multiboot_obj_loadfile(char *filename, uint64_t dest, * We have a multiboot kernel loaded, see if there's a FreeBSD * kernel loaded also. */ - kfp = file_findfile(NULL, "elf kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) { /* * No kernel loaded, this must be it. The kernel has to * be loaded as a raw file, it will be processed by * Xen and correctly loaded as an ELF file. */ - rfp = file_loadraw(filename, "elf kernel", 0); + rfp = file_loadraw(filename, md_kerntype, 0); if (rfp == NULL) { printf( "Unable to load %s as a multiboot payload kernel\n", diff --git a/stand/i386/libi386/multiboot.h b/stand/i386/libi386/multiboot.h index 819fa2e5019f..d68f17b52810 100644 --- a/stand/i386/libi386/multiboot.h +++ b/stand/i386/libi386/multiboot.h @@ -18,7 +18,6 @@ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -* $FreeBSD$ */ #ifndef MULTIBOOT_HEADER diff --git a/stand/i386/libi386/multiboot_tramp.S b/stand/i386/libi386/multiboot_tramp.S index 0bd604365f23..b9c4a43fe1e6 100644 --- a/stand/i386/libi386/multiboot_tramp.S +++ b/stand/i386/libi386/multiboot_tramp.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #define ASM_FILE diff --git a/stand/i386/libi386/nullconsole.c b/stand/i386/libi386/nullconsole.c index ebb1e7edd2b6..2878512071ad 100644 --- a/stand/i386/libi386/nullconsole.c +++ b/stand/i386/libi386/nullconsole.c @@ -35,9 +35,6 @@ * OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <bootstrap.h> @@ -48,14 +45,13 @@ static int nullc_getchar(void); static int nullc_ischar(void); struct console nullconsole = { - "nullconsole", - "null port", - 0, - nullc_probe, - nullc_init, - nullc_putchar, - nullc_getchar, - nullc_ischar + .c_name = "nullconsole", + .c_desc = "null port", + .c_probe = nullc_probe, + .c_init = nullc_init, + .c_out = nullc_putchar, + .c_in = nullc_getchar, + .c_ready = nullc_ischar }; static void @@ -67,7 +63,7 @@ nullc_probe(struct console *cp) static int nullc_init(int arg) { - return(0); + return (0); } static void @@ -78,11 +74,11 @@ nullc_putchar(int c) static int nullc_getchar(void) { - return(-1); + return (-1); } static int nullc_ischar(void) { - return(0); + return (0); } diff --git a/stand/i386/libi386/pread.c b/stand/i386/libi386/pread.c index 870e2540150f..5a922e3bfc6b 100644 --- a/stand/i386/libi386/pread.c +++ b/stand/i386/libi386/pread.c @@ -33,9 +33,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* read into destination in flat addr space */ #include <stand.h> diff --git a/stand/i386/libi386/pxe.c b/stand/i386/libi386/pxe.c index e80a1961e191..aa392b83718c 100644 --- a/stand/i386/libi386/pxe.c +++ b/stand/i386/libi386/pxe.c @@ -26,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <errno.h> #include <stdbool.h> @@ -119,7 +116,7 @@ struct devsw pxedisk = { .dv_close = NULL, /* Will be set in pxe_init */ .dv_ioctl = noioctl, .dv_print = pxe_print, - .dv_cleanup = pxe_cleanup + .dv_cleanup = pxe_cleanup, }; /* diff --git a/stand/i386/libi386/pxe.h b/stand/i386/libi386/pxe.h index a51d72dae650..26c182c9ee88 100644 --- a/stand/i386/libi386/pxe.h +++ b/stand/i386/libi386/pxe.h @@ -25,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -62,7 +60,7 @@ typedef struct { uint16_t Seg_Addr; uint32_t Phy_Addr; uint16_t Seg_Size; -} SEGDESC_t; +} PACKED SEGDESC_t; typedef uint16_t SEGSEL_t; typedef uint16_t PXENV_STATUS_t; @@ -151,7 +149,6 @@ typedef struct { #define MAXNUM_MCADDR 8 typedef struct { - PXENV_STATUS_t Status; uint16_t MCastAddrCount; MAC_ADDR McastAddr[MAXNUM_MCADDR]; } PACKED t_PXENV_UNDI_MCAST_ADDRESS; diff --git a/stand/i386/libi386/pxetramp.S b/stand/i386/libi386/pxetramp.S index dcf1441aeb24..8654e3cb9979 100644 --- a/stand/i386/libi386/pxetramp.S +++ b/stand/i386/libi386/pxetramp.S @@ -12,7 +12,6 @@ # warranties of merchantability and fitness for a particular # purpose. # -# $FreeBSD$ # ph33r this diff --git a/stand/i386/libi386/relocater_tramp.S b/stand/i386/libi386/relocater_tramp.S index 6db4a7509b2c..a6ba42830f54 100644 --- a/stand/i386/libi386/relocater_tramp.S +++ b/stand/i386/libi386/relocater_tramp.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ diff --git a/stand/i386/libi386/spinconsole.c b/stand/i386/libi386/spinconsole.c index 1daac3586939..d4c22bdbb1c3 100644 --- a/stand/i386/libi386/spinconsole.c +++ b/stand/i386/libi386/spinconsole.c @@ -35,9 +35,6 @@ * OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <bootstrap.h> @@ -50,14 +47,13 @@ static int spinc_ischar(void); extern struct console *consoles[]; struct console spinconsole = { - "spinconsole", - "spin port", - 0, - spinc_probe, - spinc_init, - spinc_putchar, - spinc_getchar, - spinc_ischar + .c_name = "spinconsole", + .c_desc = "spin port", + .c_probe = spinc_probe, + .c_init = spinc_init, + .c_out = spinc_putchar, + .c_in = spinc_getchar, + .c_ready = spinc_ischar }; static struct console *parent = NULL; @@ -75,7 +71,7 @@ static int spinc_init(int arg) { - return(parent->c_init(arg)); + return (parent->c_init(arg)); } static void @@ -101,12 +97,12 @@ static int spinc_getchar(void) { - return(-1); + return (-1); } static int spinc_ischar(void) { - return(0); + return (0); } diff --git a/stand/i386/libi386/textvidc.c b/stand/i386/libi386/textvidc.c new file mode 100644 index 000000000000..1dd950bc4021 --- /dev/null +++ b/stand/i386/libi386/textvidc.c @@ -0,0 +1,644 @@ +/*- + * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) + * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp + */ + +#include <stand.h> +#include <bootstrap.h> +#include <btxv86.h> +#include <machine/psl.h> +#include "libi386.h" + +#if KEYBOARD_PROBE +#include <machine/cpufunc.h> + +static int probe_keyboard(void); +#endif +static void vidc_probe(struct console *cp); +static int vidc_init(int arg); +static void vidc_putchar(int c); +static int vidc_getchar(void); +static int vidc_ischar(void); + +static int vidc_started; + +void get_pos(int *x, int *y); + +#ifdef TERM_EMU +#define MAXARGS 8 +#define DEFAULT_FGCOLOR 7 +#define DEFAULT_BGCOLOR 0 + +void end_term(void); +void bail_out(int c); +void vidc_term_emu(int c); +void curs_move(int *_x, int *_y, int x, int y); +void write_char(int c, int fg, int bg); +void scroll_up(int rows, int fg, int bg); +void CD(void); +void CM(void); +void HO(void); + +static int args[MAXARGS], argc; +static int fg_c, bg_c, curx, cury; +static int esc; +#endif + + +struct console textvidc = { + .c_name = "vidconsole", + .c_desc = "internal video/keyboard", + .c_probe = vidc_probe, + .c_init = vidc_init, + .c_out = vidc_putchar, + .c_in = vidc_getchar, + .c_ready = vidc_ischar +}; + +static void +vidc_probe(struct console *cp) +{ + /* look for a keyboard */ +#if KEYBOARD_PROBE + if (probe_keyboard()) +#endif + { + cp->c_flags |= C_PRESENTIN; + } + + /* XXX for now, always assume we can do BIOS screen output */ + cp->c_flags |= C_PRESENTOUT; +} + +static int +vidc_init(int arg) +{ + int i; + + if (vidc_started && arg == 0) + return (0); + vidc_started = 1; +#ifdef TERM_EMU + /* Init terminal emulator */ + end_term(); + get_pos(&curx, &cury); + curs_move(&curx, &cury, curx, cury); + fg_c = DEFAULT_FGCOLOR; + bg_c = DEFAULT_BGCOLOR; +#endif + for (i = 0; i < 10 && vidc_ischar(); i++) + (void)vidc_getchar(); + return (0); /* XXX reinit? */ +} + +static void +vidc_biosputchar(int c) +{ + + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0xe00 | (c & 0xff); + v86.ebx = 0x7; + v86int(); +} + +static void +vidc_rawputchar(int c) +{ + int i; + + if (c == '\t') { + int n; +#ifndef TERM_EMU + int curx, cury; + + get_pos(&curx, &cury); +#endif + + n = 8 - ((curx + 8) % 8); + for (i = 0; i < n; i++) + vidc_rawputchar(' '); + } else { +#ifndef TERM_EMU + vidc_biosputchar(c); +#else + /* Emulate AH=0eh (teletype output) */ + switch(c) { + case '\a': + vidc_biosputchar(c); + return; + case '\r': + curx = 0; + curs_move(&curx, &cury, curx, cury); + return; + case '\n': + cury++; + if (cury > 24) { + scroll_up(1, fg_c, bg_c); + cury--; + } else { + curs_move(&curx, &cury, curx, cury); + } + return; + case '\b': + if (curx > 0) { + curx--; + curs_move(&curx, &cury, curx, cury); + /* write_char(' ', fg_c, bg_c); XXX destructive(!) */ + return; + } + return; + default: + write_char(c, fg_c, bg_c); + curx++; + if (curx > 79) { + curx = 0; + cury++; + } + if (cury > 24) { + curx = 0; + scroll_up(1, fg_c, bg_c); + cury--; + } + } + curs_move(&curx, &cury, curx, cury); +#endif + } +} + +/* Get cursor position on the screen. Result is in edx. Sets + * curx and cury appropriately. + */ +void +get_pos(int *x, int *y) +{ + + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0300; + v86.ebx = 0x0; + v86int(); + *x = v86.edx & 0x00ff; + *y = (v86.edx & 0xff00) >> 8; +} + +#ifdef TERM_EMU + +/* Move cursor to x rows and y cols (0-based). */ +void +curs_move(int *_x, int *_y, int x, int y) +{ + + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0200; + v86.ebx = 0x0; + v86.edx = ((0x00ff & y) << 8) + (0x00ff & x); + v86int(); + *_x = x; + *_y = y; + /* If there is ctrl char at this position, cursor would be invisible. + * Make it a space instead. + */ + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0800; + v86.ebx = 0x0; + v86int(); +#define isvisible(c) (((c) >= 32) && ((c) < 255)) + if (!isvisible(v86.eax & 0x00ff)) { + write_char(' ', fg_c, bg_c); + } +} + +/* Scroll up the whole window by a number of rows. If rows==0, + * clear the window. fg and bg are attributes for the new lines + * inserted in the window. + */ +void +scroll_up(int rows, int fgcol, int bgcol) +{ + + if (rows == 0) + rows = 25; + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0600 + (0x00ff & rows); + v86.ebx = (bgcol << 12) + (fgcol << 8); + v86.ecx = 0x0; + v86.edx = 0x184f; + v86int(); +} + +/* Write character and attribute at cursor position. */ +void +write_char(int c, int fgcol, int bgcol) +{ + + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0900 + (0x00ff & c); + v86.ebx = (bgcol << 4) + fgcol; + v86.ecx = 0x1; + v86int(); +} + +/**************************************************************/ +/* + * Screen manipulation functions. They use accumulated data in + * args[] and argc variables. + * + */ + +/* Clear display from current position to end of screen */ +void +CD(void) +{ + + get_pos(&curx, &cury); + if (curx > 0) { + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0600; + v86.ebx = (bg_c << 4) + fg_c; + v86.ecx = (cury << 8) + curx; + v86.edx = (cury << 8) + 79; + v86int(); + if (++cury > 24) { + end_term(); + return; + } + } + v86.ctl = 0; + v86.addr = 0x10; + v86.eax = 0x0600; + v86.ebx = (bg_c << 4) + fg_c; + v86.ecx = (cury << 8) + 0; + v86.edx = (24 << 8) + 79; + v86int(); + end_term(); +} + +/* Absolute cursor move to args[0] rows and args[1] columns + * (the coordinates are 1-based). + */ +void +CM(void) +{ + + if (args[0] > 0) + args[0]--; + if (args[1] > 0) + args[1]--; + curs_move(&curx, &cury, args[1], args[0]); + end_term(); +} + +/* Home cursor (left top corner) */ +void +HO(void) +{ + + argc = 1; + args[0] = args[1] = 1; + CM(); +} + +/* Clear internal state of the terminal emulation code */ +void +end_term(void) +{ + + esc = 0; + argc = -1; +} + +/* Gracefully exit ESC-sequence processing in case of misunderstanding */ +void +bail_out(int c) +{ + char buf[16], *ch; + int i; + + if (esc) { + vidc_rawputchar('\033'); + if (esc != '\033') + vidc_rawputchar(esc); + for (i = 0; i <= argc; ++i) { + sprintf(buf, "%d", args[i]); + ch = buf; + while (*ch) + vidc_rawputchar(*ch++); + } + } + vidc_rawputchar(c); + end_term(); +} + +static void +get_arg(int c) +{ + + if (argc < 0) + argc = 0; + args[argc] *= 10; + args[argc] += c - '0'; +} + +/* Emulate basic capabilities of cons25 terminal */ +void +vidc_term_emu(int c) +{ + static int ansi_col[] = { + 0, 4, 2, 6, 1, 5, 3, 7, + }; + int t; + int i; + + switch (esc) { + case 0: + switch (c) { + case '\033': + esc = c; + break; + default: + vidc_rawputchar(c); + break; + } + break; + + case '\033': + switch (c) { + case '[': + esc = c; + args[0] = 0; + argc = -1; + break; + default: + bail_out(c); + break; + } + break; + + case '[': + switch (c) { + case ';': + if (argc < 0) /* XXX */ + argc = 0; + else if (argc + 1 >= MAXARGS) + bail_out(c); + else + args[++argc] = 0; + break; + case 'H': + if (argc < 0) + HO(); + else if (argc == 1) + CM(); + else + bail_out(c); + break; + case 'J': + if (argc < 0) + CD(); + else + bail_out(c); + break; + case 'm': + if (argc < 0) { + fg_c = DEFAULT_FGCOLOR; + bg_c = DEFAULT_BGCOLOR; + } + for (i = 0; i <= argc; ++i) { + switch (args[i]) { + case 0: /* back to normal */ + fg_c = DEFAULT_FGCOLOR; + bg_c = DEFAULT_BGCOLOR; + break; + case 1: /* bold */ + fg_c |= 0x8; + break; + case 4: /* underline */ + case 5: /* blink */ + bg_c |= 0x8; + break; + case 7: /* reverse */ + t = fg_c; + fg_c = bg_c; + bg_c = t; + break; + case 22: /* normal intensity */ + fg_c &= ~0x8; + break; + case 24: /* not underline */ + case 25: /* not blinking */ + bg_c &= ~0x8; + break; + case 30: case 31: case 32: case 33: + case 34: case 35: case 36: case 37: + fg_c = ansi_col[args[i] - 30]; + break; + case 39: /* normal */ + fg_c = DEFAULT_FGCOLOR; + break; + case 40: case 41: case 42: case 43: + case 44: case 45: case 46: case 47: + bg_c = ansi_col[args[i] - 40]; + break; + case 49: /* normal */ + bg_c = DEFAULT_BGCOLOR; + break; + } + } + end_term(); + break; + default: + if (isdigit(c)) + get_arg(c); + else + bail_out(c); + break; + } + break; + + default: + bail_out(c); + break; + } +} +#endif + +static void +vidc_putchar(int c) +{ +#ifdef TERM_EMU + vidc_term_emu(c); +#else + vidc_rawputchar(c); +#endif +} + +static int +vidc_getchar(void) +{ + + if (vidc_ischar()) { + v86.ctl = 0; + v86.addr = 0x16; + v86.eax = 0x0; + v86int(); + return (v86.eax & 0xff); + } else { + return (-1); + } +} + +static int +vidc_ischar(void) +{ + + v86.ctl = V86_FLAGS; + v86.addr = 0x16; + v86.eax = 0x100; + v86int(); + return (!V86_ZR(v86.efl)); +} + +#if KEYBOARD_PROBE + +#define PROBE_MAXRETRY 5 +#define PROBE_MAXWAIT 400 +#define IO_DUMMY 0x84 +#define IO_KBD 0x060 /* 8042 Keyboard */ + +/* selected defines from kbdio.h */ +#define KBD_STATUS_PORT 4 /* status port, read */ +#define KBD_DATA_PORT 0 /* data port, read/write + * also used as keyboard command + * and mouse command port + */ +#define KBDC_ECHO 0x00ee +#define KBDS_ANY_BUFFER_FULL 0x0001 +#define KBDS_INPUT_BUFFER_FULL 0x0002 +#define KBD_ECHO 0x00ee + +/* 7 microsec delay necessary for some keyboard controllers */ +static void +delay7(void) +{ + /* + * I know this is broken, but no timer is available yet at this stage... + * See also comments in `delay1ms()'. + */ + inb(IO_DUMMY); + inb(IO_DUMMY); + inb(IO_DUMMY); + inb(IO_DUMMY); + inb(IO_DUMMY); + inb(IO_DUMMY); +} + +/* + * This routine uses an inb to an unused port, the time to execute that + * inb is approximately 1.25uS. This value is pretty constant across + * all CPU's and all buses, with the exception of some PCI implentations + * that do not forward this I/O address to the ISA bus as they know it + * is not a valid ISA bus address, those machines execute this inb in + * 60 nS :-(. + * + */ +static void +delay1ms(void) +{ + int i = 800; + while (--i >= 0) + (void)inb(0x84); +} + +/* + * We use the presence/absence of a keyboard to determine whether the internal + * console can be used for input. + * + * Perform a simple test on the keyboard; issue the ECHO command and see + * if the right answer is returned. We don't do anything as drastic as + * full keyboard reset; it will be too troublesome and take too much time. + */ +static int +probe_keyboard(void) +{ + int retry = PROBE_MAXRETRY; + int wait; + int i; + + while (--retry >= 0) { + /* flush any noise */ + while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) { + delay7(); + inb(IO_KBD + KBD_DATA_PORT); + delay1ms(); + } + + /* wait until the controller can accept a command */ + for (wait = PROBE_MAXWAIT; wait > 0; --wait) { + if (((i = inb(IO_KBD + KBD_STATUS_PORT)) + & (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0) + break; + if (i & KBDS_ANY_BUFFER_FULL) { + delay7(); + inb(IO_KBD + KBD_DATA_PORT); + } + delay1ms(); + } + if (wait <= 0) + continue; + + /* send the ECHO command */ + outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO); + + /* wait for a response */ + for (wait = PROBE_MAXWAIT; wait > 0; --wait) { + if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) + break; + delay1ms(); + } + if (wait <= 0) + continue; + + delay7(); + i = inb(IO_KBD + KBD_DATA_PORT); +#ifdef PROBE_KBD_BEBUG + printf("probe_keyboard: got 0x%x.\n", i); +#endif + if (i == KBD_ECHO) { + /* got the right answer */ + return (1); + } + } + + return (0); +} +#endif /* KEYBOARD_PROBE */ diff --git a/stand/i386/libi386/time.c b/stand/i386/libi386/time.c index 5b8a9c9017a7..8a84810d5a7d 100644 --- a/stand/i386/libi386/time.c +++ b/stand/i386/libi386/time.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <btxv86.h> #include "bootstrap.h" diff --git a/stand/i386/libi386/vbe.c b/stand/i386/libi386/vbe.c index 3caba3081f06..00b9ab7ae0dc 100644 --- a/stand/i386/libi386/vbe.c +++ b/stand/i386/libi386/vbe.c @@ -25,11 +25,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -#include <sys/cdefs.h> #include <stand.h> #include <sys/param.h> #include <machine/psl.h> @@ -87,6 +84,11 @@ static struct named_resolution { .height = 1080, }, { + .name = "1440p", + .width = 2560, + .height = 1440, + }, + { .name = "2160p", .alias = "4k", .width = 3840, diff --git a/stand/i386/libi386/vidconsole.c b/stand/i386/libi386/vidconsole.c index 1ec6b4f5393a..3938bd7822ea 100644 --- a/stand/i386/libi386/vidconsole.c +++ b/stand/i386/libi386/vidconsole.c @@ -24,19 +24,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp + * From: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <bootstrap.h> #include <btxv86.h> #include <gfx_fb.h> #include <teken.h> -#include <stdbool.h> #include "vbe.h" #include <dev/vt/hw/vga/vt_vga_reg.h> @@ -960,26 +956,7 @@ cons_update_mode(bool use_gfx_mode) a = teken_get_defattr(&gfx_state.tg_teken); attr = *a; - /* - * On first run, we set up the vidc_set_colors() - * callback. If the env is already set, we - * pick up fg and bg color values from the environment. - */ - ptr = getenv("teken.fg_color"); - if (ptr != NULL) { - attr.ta_fgcolor = strtol(ptr, NULL, 10); - ptr = getenv("teken.bg_color"); - attr.ta_bgcolor = strtol(ptr, NULL, 10); - - teken_set_defattr(&gfx_state.tg_teken, &attr); - } else { - snprintf(env, sizeof(env), "%d", attr.ta_fgcolor); - env_setenv("teken.fg_color", EV_VOLATILE, env, - vidc_set_colors, env_nounset); - snprintf(env, sizeof(env), "%d", attr.ta_bgcolor); - env_setenv("teken.bg_color", EV_VOLATILE, env, - vidc_set_colors, env_nounset); - } + gfx_fb_setcolors(&attr, vidc_set_colors, env_nounset); /* Improve visibility */ if (attr.ta_bgcolor == TC_WHITE) @@ -1049,7 +1026,7 @@ vidc_init(int arg) return (0); /* XXX reinit? */ } -void +static void vidc_biosputchar(int c) { diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile index 571e3b2cb653..96ad50a75509 100644 --- a/stand/i386/loader/Makefile +++ b/stand/i386/loader/Makefile @@ -1,13 +1,11 @@ -# $FreeBSD$ - HAVE_ZFS= ${MK_LOADER_ZFS} LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes -LOADER_EXT2FS_SUPPORT?= yes -LOADER_MSDOS_SUPPORT?= yes +LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no LOADER_UFS_SUPPORT?= yes LOADER_GZIP_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= yes @@ -18,18 +16,53 @@ LOADER?= loader_${LOADER_INTERP} PROG= ${LOADER}.sym INTERNALPROG= NEWVERSWHAT?= "bootstrap loader" x86 -VERSION_FILE= ${.CURDIR}/../loader/version +VERSION_FILE?= ${.CURDIR}/../loader/version +# +# There's 640k - 40k maximum space, less however much memory the BIOS uses. A +# non-random survey suggests that 20k-25k is a good value for 'most' machines. +# We also need to subtract maximum stack usage (20-25k). +# +# So 640k - 40k - 25k - 25k = 550k = 563,200 bytes, but use 560,000 below for +# some extra buffer for more complex setups and/or wider BIOS lomem variation. +# +# Some systems use more stack or have BIOS reserve more RAM (or both), and will +# need to set this lower in /etc/src.conf if the above buffer is too small. +# +# sudo dd if=/dev/mem bs=1 iseek=0x413 count=2 | hd -d +# +# will tell you how many kiB of lomem are available. +# +# We further reduce this to 500k, though, to give PXE an additional 64k of space +# so pxeloader will fit. If you have special needs that do not include pxeboot, +# you can safely set this as high as 560000 generally, or a bit higher if you +# have tight control over the machines you are booting on. +# +LOADERSIZE?= 500000 # Largest known safe size for loader.bin .PATH: ${BOOTSRC}/i386/loader # architecture-specific loader code -SRCS= main.c conf.c vers.c chain.c gfx_fb.c 8x16.c +SRCS+= chain.c +SRCS+= conf.c +SRCS+= gfx_bios.c +SRCS+= main.c +SRCS+= vers.c + +.if ${MK_LOADER_BIOS_TEXTONLY} == "no" +SRCS+= gfx_fb.c +SRCS+= 8x16.c CFLAGS.gfx_fb.c += -I${.CURDIR}/../libi386 CFLAGS.gfx_fb.c += -I$(SRCTOP)/sys/teken CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite CFLAGS.gfx_fb.c += -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib +CFLAGS.gfx_bios.c += -I$(SRCTOP)/sys/teken +CFLAGS.gfx_bios.c += -I${SRCTOP}/contrib/pnglite +.else +CFLAGS.gfx_bios.c += -DBIOS_TEXT_ONLY +CFLAGS.conf.c += -DBIOS_TEXT_ONLY +.endif # Include bcache code. HAVE_BCACHE= yes @@ -38,11 +71,6 @@ HAVE_BCACHE= yes HAVE_PNP= yes HAVE_ISABUS= yes -.if ${MK_LOADER_FIREWIRE} == "yes" -CFLAGS+= -DLOADER_FIREWIRE_SUPPORT -LIBFIREWIRE= ${BOOTOBJ}/i386/libfirewire/libfirewire.a -.endif - .if ${MK_LOADER_ZFS} == "yes" CFLAGS.main.c+= -I${SYSDIR}/contrib/openzfs/include CFLAGS.main.c+= -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs @@ -51,6 +79,7 @@ CFLAGS.main.c+= -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs .if exists(${.CURDIR}/help.i386) HELP_FILES= ${.CURDIR}/help.i386 .endif +HELP_FILENAME= loader.help.bios # Always add MI sources .include "${BOOTSRC}/loader.mk" @@ -61,7 +90,8 @@ ORG= 0x0 CFLAGS+= -Wall LDFLAGS+= -static ${LDFLAGS_ORG} -Wl,--gc-sections -.if ${LINKER_TYPE} == "lld" && ${LINKER_VERSION} >= 130000 +.if (${LINKER_TYPE} == "lld" && ${LINKER_VERSION} >= 130000) || \ + (${LINKER_TYPE} == "bfd" && ${LINKER_VERSION} >= 23700) # lld 13 and higher default to garbage collecting start/stop symbols, # completely ruining our linker sets. For now, work around it by # disabling this un-feature. @@ -79,12 +109,15 @@ CFLAGS+= -I${BOOTSRC}/i386 8x16.c: ${SRCTOP}/contrib/terminus/ter-u16b.bdf vtfontcvt -f compressed-source -o ${.TARGET} ${.ALLSRC} + ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN} btxld -v -f aout -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \ -b ${BTXKERN} ${LOADER}.bin ${LOADER}.bin: ${LOADER}.sym ${STRIPBIN} -R .comment -R .note -o ${.TARGET} ${.ALLSRC} + @set -- `ls -l ${.TARGET}` ; x=$$((${LOADERSIZE}-$$5)); \ + echo "$$x bytes available"; test $$x -ge 0 .if ${MK_LOADER_ZFS} == "yes" && ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP} LINKS+= ${BINDIR}/${LOADER} ${BINDIR}/zfsloader @@ -98,8 +131,8 @@ FILESMODE_${LOADER}= ${BINMODE} -b # Note: crt0.o needs to be first for pxeboot(8) to work. It assumes that the # startup code is located at the start of the loader and will jump # there. Although btx is more flexible than this, the emulated boot2 environment -# that pxeloader provides has none of that flexibility because it lacks access -# to the a.out/elf headers and assumes an entry point of 0. +# that pxeldr provides has none of that flexibility and assumes the entry point +# is 0. Finally, both pxeldr and cdboot assume they are loading an a.out file. # # We must add it to the LDFLAGS instead of the OBJS because the former won't try # to clean it. When it is in OBJS, this cleaning can lead to races where @@ -108,8 +141,12 @@ FILESMODE_${LOADER}= ${BINMODE} -b # files. LDFLAGS+= ${BTXCRT} -DPADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBI386} ${LIBSA32} -LDADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBI386} ${LIBSA32} +# Force the linker max page size to 4k so that we fit in the limited space even +# if someone has set a larger default linker max page size via /etc/src.conf. +LDFLAGS+= -Wl,-z,max-page-size=0x1000 + +DPADD= ${LDR_INTERP32} ${LIBI386} ${LIBSA32} +LDADD= ${LDR_INTERP32} ${LIBI386} ${LIBSA32} .if ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -DLOADER_PREFER_AMD64 diff --git a/stand/i386/loader/Makefile.depend b/stand/i386/loader/Makefile.depend index 8807f64e88d6..c687ef93d84e 100644 --- a/stand/i386/loader/Makefile.depend +++ b/stand/i386/loader/Makefile.depend @@ -1,12 +1,10 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - stand/${MACHINE_CPUARCH}/btx/btx \ - stand/${MACHINE_CPUARCH}/btx/btxldr \ - stand/${MACHINE_CPUARCH}/btx/lib \ - stand/${MACHINE_CPUARCH}/libi386 \ - stand/ficl \ + stand/i386/btx/btx \ + stand/i386/btx/btxldr \ + stand/i386/btx/lib \ + stand/i386/libi386 \ stand/libsa \ diff --git a/stand/i386/loader/Makefile.depend.options b/stand/i386/loader/Makefile.depend.options new file mode 100644 index 000000000000..7527fa4bda17 --- /dev/null +++ b/stand/i386/loader/Makefile.depend.options @@ -0,0 +1,10 @@ +DIRDEPS_OPTIONS = FORTH LOADER_LUA + +DIRDEPS.FORTH.yes += \ + stand/ficl \ + +DIRDEPS.LOADER_LUA.yes += \ + stand/liblua \ + stand/lua \ + +.include <dirdeps-options.mk> diff --git a/stand/i386/loader/chain.c b/stand/i386/loader/chain.c index d4e3936e13df..9d58f9f3de33 100644 --- a/stand/i386/loader/chain.c +++ b/stand/i386/loader/chain.c @@ -31,9 +31,6 @@ * read in to temporary space and relocate on exec, when btx is stopped. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/linker.h> diff --git a/stand/i386/loader/conf.c b/stand/i386/loader/conf.c index 35052b5423cd..bba33a2707d5 100644 --- a/stand/i386/loader/conf.c +++ b/stand/i386/loader/conf.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <bootstrap.h> #include "libi386/libi386.h" @@ -45,9 +42,6 @@ __FBSDID("$FreeBSD$"); * XXX as libi386 and biosboot merge, some of these can become linker sets. */ -#if defined(LOADER_FIREWIRE_SUPPORT) -extern struct devsw fwohci; -#endif extern struct devsw vdisk_dev; /* Exported for libsa */ @@ -58,9 +52,6 @@ struct devsw *devsw[] = { #if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT) &pxedisk, #endif -#if defined(LOADER_FIREWIRE_SUPPORT) - &fwohci, -#endif &vdisk_dev, #if defined(LOADER_ZFS_SUPPORT) &zfs_dev, @@ -136,20 +127,19 @@ struct file_format *file_formats[] = { * We don't prototype these in libi386.h because they require * data structures from bootstrap.h as well. */ +extern struct console textvidc; extern struct console vidconsole; extern struct console comconsole; -#if defined(LOADER_FIREWIRE_SUPPORT) -extern struct console dconsole; -#endif extern struct console nullconsole; extern struct console spinconsole; struct console *consoles[] = { +#ifdef BIOS_TEXT_ONLY /* Note: We need a forced commit for this */ + &textvidc, +#else &vidconsole, - &comconsole, -#if defined(LOADER_FIREWIRE_SUPPORT) - &dconsole, #endif + &comconsole, &nullconsole, &spinconsole, NULL diff --git a/stand/i386/loader/gfx_bios.c b/stand/i386/loader/gfx_bios.c new file mode 100644 index 000000000000..1581325a81e0 --- /dev/null +++ b/stand/i386/loader/gfx_bios.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * This file provides all the gfx glue, or stubs, so that we can build, if we + * want, two versions of the bios loader: one with graphics support and one + * without. This allows us to keep the calls in other places, like libraries + * that are tricky to compile twice. It also reduces the number of ifdefs we + * need to support the old text-only video console. This could also be two + * separate files, but it is short and having it all here helps to constrain + * dependency creap somewhat. + */ + +#include <stand.h> +#ifndef BIOS_TEXT_ONLY +#include "bootstrap.h" +#include "libi386/libi386.h" +#include "libi386/vbe.h" +#include <gfx_fb.h> +#endif + +#ifdef BIOS_TEXT_ONLY /* Note: likely need a forced commits when this changes */ +void autoload_font(bool bios); + +void +autoload_font(bool bios) +{ +} + +vm_offset_t build_font_module(vm_offset_t addr); + +vm_offset_t +build_font_module(vm_offset_t addr) +{ + return addr; +} + +struct preloaded_file; +void bi_load_vbe_data(struct preloaded_file *kfp); + +void bi_load_vbe_data(struct preloaded_file *kfp) +{ +} + +#else + +void +bi_load_vbe_data(struct preloaded_file *kfp) +{ + if (!kfp->f_tg_kernel_support) { + /* + * Loaded kernel does not have vt/vbe backend, + * switch console to text mode. + */ + if (vbe_available()) + bios_set_text_mode(VGA_TEXT_MODE); + return; + } + + if (vbe_available()) { + file_addmetadata(kfp, MODINFOMD_VBE_FB, + sizeof(gfx_state.tg_fb), &gfx_state.tg_fb); + } +} +#endif diff --git a/stand/i386/loader/loader.rc b/stand/i386/loader/loader.rc index 9f1ebe635971..4bac6ef6801d 100644 --- a/stand/i386/loader/loader.rc +++ b/stand/i386/loader/loader.rc @@ -1,5 +1,4 @@ \ Loader.rc -\ $FreeBSD$ \ \ Includes additional commands include /boot/loader.4th diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c index cb716d7a9f21..a70b3a253b90 100644 --- a/stand/i386/loader/main.c +++ b/stand/i386/loader/main.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * MD bootstrap main() and assorted miscellaneous * commands. @@ -53,33 +50,46 @@ __FBSDID("$FreeBSD$"); #include "libzfs.h" #endif -CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE); -CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO); -CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS); -CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE); +_Static_assert(sizeof(struct bootargs) == BOOTARGS_SIZE, "Bootarg size bad"); +_Static_assert(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO, "BA_BOOTINFO"); +_Static_assert(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS, "BA_BOOTFLAGS"); +_Static_assert(offsetof(struct bootinfo, bi_size) == BI_SIZE, "BI_SIZE"); /* Arguments passed in from the boot1/boot2 loader */ static struct bootargs *kargs; - static uint32_t initial_howto; static uint32_t initial_bootdev; static struct bootinfo *initial_bootinfo; -struct arch_switch archsw; /* MI/MD interface boundary */ - -static void extract_currdev(void); static int isa_inb(int port); static void isa_outb(int port, int value); + +#ifdef LOADER_ZFS_SUPPORT +struct zfs_boot_args *zargs; +static void i386_zfs_probe(void); +#endif + +struct arch_switch archsw = { /* MI/MD interface boundary */ + .arch_autoload = i386_autoload, + .arch_getdev = i386_getdev, + .arch_copyin = i386_copyin, + .arch_copyout = i386_copyout, + .arch_readin = i386_readin, + .arch_isainb = isa_inb, + .arch_isaoutb = isa_outb, + .arch_hypervisor = x86_hypervisor, +#ifdef LOADER_ZFS_SUPPORT + .arch_zfs_probe = i386_zfs_probe, +#endif +}; + +static void extract_currdev(void); void exit(int code); #ifdef LOADER_GELI_SUPPORT #include "geliboot.h" struct geli_boot_args *gargs; struct geli_boot_data *gbdata; #endif -#ifdef LOADER_ZFS_SUPPORT -struct zfs_boot_args *zargs; -static void i386_zfs_probe(void); -#endif /* XXX debugging */ extern char end[]; @@ -96,8 +106,6 @@ ptov(uintptr_t x) int main(void) { - int i; - /* Pick up arguments */ kargs = (void *)__args; initial_howto = kargs->howto; @@ -115,7 +123,7 @@ main(void) */ bios_getmem(); -#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \ +#if defined(LOADER_BZIP2_SUPPORT) || \ defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT) if (high_heap_size > 0) { heap_top = PTOV(high_heap_base + high_heap_size); @@ -166,7 +174,7 @@ main(void) /* Set up currdev variable to have hooks in place. */ env_setenv("currdev", EV_VOLATILE | EV_NOHOOK, "", - i386_setcurrdev, env_nounset); + gen_setcurrdev, env_nounset); /* * Initialise the block cache. Set the upper limit. @@ -188,19 +196,9 @@ main(void) bc_add(initial_bootdev); } - archsw.arch_autoload = i386_autoload; - archsw.arch_getdev = i386_getdev; - archsw.arch_copyin = i386_copyin; - archsw.arch_copyout = i386_copyout; - archsw.arch_readin = i386_readin; - archsw.arch_isainb = isa_inb; - archsw.arch_isaoutb = isa_outb; - archsw.arch_hypervisor = x86_hypervisor; #ifdef LOADER_ZFS_SUPPORT - archsw.arch_zfs_probe = i386_zfs_probe; - /* - * zfsboot and gptzfsboot have always passed KARGS_FLAGS_ZFS, + * gptzfsboot has always passed KARGS_FLAGS_ZFS, * so if that is set along with KARGS_FLAGS_EXTARG we know we * can interpret the extarg data as a struct zfs_boot_args. */ @@ -244,12 +242,7 @@ main(void) import_geli_boot_data(gbdata); #endif /* LOADER_GELI_SUPPORT */ - /* - * March through the device switch probing for things. - */ - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); + devinit(); printf("BIOS %dkB/%dkB available memory\n", bios_basemem / 1024, bios_extmem / 1024); @@ -258,6 +251,9 @@ main(void) initial_bootinfo->bi_extmem = bios_extmem / 1024; } + /* detect MEMDISK virtual disks */ + biosmemdisk_detect(); + /* detect SMBIOS for future reference */ smbios_detect(NULL); @@ -308,8 +304,8 @@ extract_currdev(void) new_currdev.dd.d_unit = 0; } else { /* we don't know what our boot device is */ - new_currdev.d_kind.biosdisk.slice = -1; - new_currdev.d_kind.biosdisk.partition = 0; + new_currdev.disk.d_slice = -1; + new_currdev.disk.d_partition = 0; biosdev = -1; } #ifdef LOADER_ZFS_SUPPORT @@ -322,8 +318,8 @@ extract_currdev(void) zargs->size >= offsetof(struct zfs_boot_args, primary_pool)) { /* sufficient data is provided */ - new_currdev.d_kind.zfs.pool_guid = zargs->pool; - new_currdev.d_kind.zfs.root_guid = zargs->root; + new_currdev.zfs.pool_guid = zargs->pool; + new_currdev.zfs.root_guid = zargs->root; if (zargs->size >= sizeof(*zargs) && zargs->primary_vdev != 0) { sprintf(buf, "%llu", zargs->primary_pool); @@ -333,8 +329,8 @@ extract_currdev(void) } } else { /* old style zfsboot block */ - new_currdev.d_kind.zfs.pool_guid = kargs->zfspool; - new_currdev.d_kind.zfs.root_guid = 0; + new_currdev.zfs.pool_guid = kargs->zfspool; + new_currdev.zfs.root_guid = 0; } new_currdev.dd.d_dev = &zfs_dev; @@ -350,14 +346,12 @@ extract_currdev(void) #endif } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) { /* The passed-in boot device is bad */ - new_currdev.d_kind.biosdisk.slice = -1; - new_currdev.d_kind.biosdisk.partition = 0; + new_currdev.disk.d_slice = -1; + new_currdev.disk.d_partition = 0; biosdev = -1; } else { - new_currdev.d_kind.biosdisk.slice = - B_SLICE(initial_bootdev) - 1; - new_currdev.d_kind.biosdisk.partition = - B_PARTITION(initial_bootdev); + new_currdev.disk.d_slice = B_SLICE(initial_bootdev) - 1; + new_currdev.disk.d_partition = B_PARTITION(initial_bootdev); biosdev = initial_bootinfo->bi_bios_dev; /* @@ -389,13 +383,10 @@ extract_currdev(void) #ifdef LOADER_ZFS_SUPPORT if (new_currdev.dd.d_dev->dv_type == DEVT_ZFS) - init_zfs_boot_options(zfs_fmtdev(&new_currdev)); + init_zfs_boot_options(devformat(&new_currdev.dd)); #endif - env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev), - i386_setcurrdev, env_nounset); - env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), - env_noset, env_nounset); + set_currdev(devformat(&new_currdev.dd)); } COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); @@ -462,7 +453,7 @@ i386_zfs_probe(void) for (dev.dd.d_unit = 0; bd_unit2bios(&dev) >= 0; dev.dd.d_unit++) { snprintf(devname, sizeof(devname), "%s%d:", bioshd.dv_name, dev.dd.d_unit); - zfs_probe_dev(devname, NULL); + zfs_probe_dev(devname, NULL, true); } } #endif diff --git a/stand/i386/loader/version b/stand/i386/loader/version index 7a2acaf1859a..82229ae6a06d 100644 --- a/stand/i386/loader/version +++ b/stand/i386/loader/version @@ -1,8 +1,4 @@ -$FreeBSD$ - -NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this -file is important. Make sure the current version number is on line 6. - +3.0: Lua scripts API stability 1.1: New calling conventions for fopen. 1.0: New semantics for finding the kernel, new boot. 0.8: Set/getenv & cia, copyin/out. diff --git a/stand/i386/loader_4th/Makefile b/stand/i386/loader_4th/Makefile index 3659f7efe673..2361952ccc5d 100644 --- a/stand/i386/loader_4th/Makefile +++ b/stand/i386/loader_4th/Makefile @@ -1,6 +1,5 @@ -# $FreeBSD$ - LOADER_INTERP=4th +INSTALL_LOADER_HELP_FILE=no .include "../loader/Makefile" diff --git a/stand/i386/loader_4th/Makefile.depend b/stand/i386/loader_4th/Makefile.depend index 8807f64e88d6..1d7ca65bf9ef 100644 --- a/stand/i386/loader_4th/Makefile.depend +++ b/stand/i386/loader_4th/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/loader_lua/Makefile b/stand/i386/loader_lua/Makefile index 3a4268440cf6..628aab34c0b8 100644 --- a/stand/i386/loader_lua/Makefile +++ b/stand/i386/loader_lua/Makefile @@ -1,6 +1,5 @@ -# $FreeBSD$ - LOADER_INTERP=lua +INSTALL_LOADER_HELP_FILE=no .include "../loader/Makefile" diff --git a/stand/i386/loader_lua/Makefile.depend b/stand/i386/loader_lua/Makefile.depend new file mode 100644 index 000000000000..993ab0638f4a --- /dev/null +++ b/stand/i386/loader_lua/Makefile.depend @@ -0,0 +1,11 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/i386/loader_simp/Makefile b/stand/i386/loader_simp/Makefile index 0c27d5673941..2e10a6595ed2 100644 --- a/stand/i386/loader_simp/Makefile +++ b/stand/i386/loader_simp/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_INTERP=simp .include "../loader/Makefile" diff --git a/stand/i386/mbr/Makefile b/stand/i386/mbr/Makefile index dca202cb815b..f9dd023ea9b9 100644 --- a/stand/i386/mbr/Makefile +++ b/stand/i386/mbr/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - PROG= mbr STRIP= BINMODE=${NOBINMODE} diff --git a/stand/i386/mbr/Makefile.depend b/stand/i386/mbr/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/mbr/Makefile.depend +++ b/stand/i386/mbr/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/mbr/mbr.S b/stand/i386/mbr/mbr.S index 3cfc20dd58e1..02843d84e6c2 100644 --- a/stand/i386/mbr/mbr.S +++ b/stand/i386/mbr/mbr.S @@ -13,8 +13,6 @@ # purpose. # -# $FreeBSD$ - # A 512 byte MBR boot manager that simply boots the active partition. .set LOAD,0x7c00 # Load address diff --git a/stand/i386/pmbr/Makefile b/stand/i386/pmbr/Makefile index e09bb610fc18..80b79f7b8c88 100644 --- a/stand/i386/pmbr/Makefile +++ b/stand/i386/pmbr/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - PROG= pmbr STRIP= BINMODE=${NOBINMODE} diff --git a/stand/i386/pmbr/Makefile.depend b/stand/i386/pmbr/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/i386/pmbr/Makefile.depend +++ b/stand/i386/pmbr/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/i386/pmbr/pmbr.S b/stand/i386/pmbr/pmbr.S index c394835757af..60b26df15720 100644 --- a/stand/i386/pmbr/pmbr.S +++ b/stand/i386/pmbr/pmbr.S @@ -27,7 +27,6 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD$ # # Partly from: src/sys/boot/i386/mbr/mbr.s 1.7 @@ -156,8 +155,10 @@ next_boot: addl $1,(%si) # Next LBA mov %es,%ax # Adjust segment for next addw $SECSIZE/16,%ax # sector cmp $0x9000,%ax # Don't load past 0x90000, - jae err_big # 545k should be enough for - mov %ax,%es # any boot code. :) + jb sz_ok # 545k should be enough for + call err_big # any boot code, but warn + mov $0x9000-SECSIZE/16,%ax # and truncate +sz_ok: mov %ax,%es jmp load_boot # # Move to the next partition. If we walk off the end of the sector, load @@ -204,17 +205,21 @@ getdrvparams: # # Various error message entry points. # -err_big: movw $msg_big,%si # "Boot loader too - jmp putstr # large" +err_big: movw $msg_big,%si # "Truncated + call putstr # to 545k" + ret err_pt: movw $msg_pt,%si # "Invalid partition - jmp putstr # table" + call putstr # table" +err_pt.1: jmp err_pt.1 # Await reset err_rd: movw $msg_rd,%si # "I/O error loading - jmp putstr # boot loader" + call putstr # boot loader" + jmp err_pt.1 err_noboot: movw $msg_noboot,%si # "Missing boot - jmp putstr # loader" + call putstr # loader" + jmp err_pt.1 # # Output an ASCIZ string to the console via the BIOS. # @@ -224,9 +229,9 @@ putstr.0: movw $0x7,%bx # Page:attribute putstr: lodsb # Get character testb %al,%al # End of string? jnz putstr.0 # No -putstr.1: jmp putstr.1 # Await reset + ret -msg_big: .asciz "Boot loader too large" +msg_big: .asciz "Loaded only 545k" msg_pt: .asciz "Invalid partition table" msg_rd: .asciz "I/O error loading boot loader" msg_noboot: .asciz "Missing boot loader" diff --git a/stand/i386/pxeldr/Makefile b/stand/i386/pxeldr/Makefile index 2184d391937f..715a13f19e6f 100644 --- a/stand/i386/pxeldr/Makefile +++ b/stand/i386/pxeldr/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= ${LDR} @@ -24,8 +22,18 @@ CFLAGS+=-DALWAYS_SERIAL CFLAGS+=-I${BOOTSRC}/i386/common +.if defined(PXEBOOT_DEFAULT_INTERP) +L=${PXEBOOT_DEFAULT_INTERP} +.else L=${LOADER_DEFAULT_INTERP} +.endif LOADERBIN= ${BOOTOBJ}/i386/loader_${L}/loader_${L}.bin +# pxeboot runs in an environment where there's 500k or less of space available +# due to space for packet buffers, network drivers, etc. While some environments +# may have a bit more, the limit of 500,000 (488k) provides enough margin to +# work in a huge array of environments. Larger values may work for specific +# environments. +PXEBOOTSIZE?=500000 CLEANFILES+= ${BOOT}.tmp @@ -38,7 +46,11 @@ LDFLAGS+=${LDFLAGS_BIN} CLEANFILES+= ${LOADER} +# Note: pxeldr.S assumes a.out and will require changes for ELF if the output +# format is changed to ELF. ${LOADER}: ${LOADERBIN} ${BTXLDR} ${BTXKERN} + @set -- `ls -l ${LOADERBIN}` ; x=$$((${PXEBOOTSIZE}-$$5)); \ + echo "$$x bytes available"; test $$x -ge 0 btxld -v -f aout -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \ -b ${BTXKERN} ${LOADERBIN} diff --git a/stand/i386/pxeldr/Makefile.depend b/stand/i386/pxeldr/Makefile.depend index 35b75b1ca42b..c3043b1105df 100644 --- a/stand/i386/pxeldr/Makefile.depend +++ b/stand/i386/pxeldr/Makefile.depend @@ -1,12 +1,9 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ include \ - stand/i386/btx/btx \ - stand/i386/btx/btxldr \ - stand/i386/loader \ - + ${BOOT_MACHINE_DIR}/btx/btx \ + ${BOOT_MACHINE_DIR}/btx/btxldr \ .include <dirdeps.mk> diff --git a/stand/i386/pxeldr/Makefile.depend.options b/stand/i386/pxeldr/Makefile.depend.options new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/stand/i386/pxeldr/Makefile.depend.options diff --git a/stand/i386/pxeldr/pxeboot.8 b/stand/i386/pxeldr/pxeboot.8 index 58b1f06bcd0f..e10e570edf54 100644 --- a/stand/i386/pxeldr/pxeboot.8 +++ b/stand/i386/pxeldr/pxeboot.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd February 15, 2021 .Dt PXEBOOT 8 .Os diff --git a/stand/i386/pxeldr/pxeldr.S b/stand/i386/pxeldr/pxeldr.S index 09e9fda7aa61..92824acea2be 100644 --- a/stand/i386/pxeldr/pxeldr.S +++ b/stand/i386/pxeldr/pxeldr.S @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/i386/zfsboot/Makefile b/stand/i386/zfsboot/Makefile deleted file mode 100644 index 243b5e99287c..000000000000 --- a/stand/i386/zfsboot/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -# $FreeBSD$ - -.include <bsd.init.mk> - -.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${BOOTSRC}/common - -FILES= zfsboot -MAN= zfsboot.8 - -BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 9600 -B2SIOFMT?= 0x3 - -REL1= 0x700 -ORG1= 0x7c00 -ORG2= 0x2000 - -CFLAGS+=-DBOOTPROG=\"zfsboot\" \ - -O1 \ - -DBOOT2 \ - -DLOADER_GPT_SUPPORT \ - -DLOADER_MBR_SUPPORT \ - -DLOADER_ZFS_SUPPORT \ - -DLOADER_UFS_SUPPORT \ - -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ - -DSIOFMT=${B2SIOFMT} \ - -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${LDRSRC} \ - -I${BOOTSRC}/i386/common \ - -I${BOOTSRC}/i386/libi386 \ - -I${ZFSSRC} \ - -I${SYSDIR}/crypto/skein \ - -I${SYSDIR}/cddl/boot/zfs \ - -I${SYSDIR}/contrib/openzfs/include \ - -I${SYSDIR}/contrib/openzfs/include/os/freebsd/spl \ - -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs \ - -I${SYSDIR}/cddl/contrib/opensolaris/common/lz4 \ - -I${BOOTSRC}/i386/boot2 \ - -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ - -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ - -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings - -CFLAGS.part.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib - -CFLAGS.gcc+= --param max-inline-insns-single=100 - -LD_FLAGS+=${LD_FLAGS_BIN} - -CLEANFILES+= zfsboot - -zfsboot: zfsboot1 zfsboot2 - cat zfsboot1 zfsboot2 > zfsboot - -CLEANFILES+= zfsboot1 zfsldr.out zfsldr.o - -zfsboot1: zfsldr.out - ${OBJCOPY} -S -O binary zfsldr.out ${.TARGET} - -zfsldr.out: zfsldr.o - ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} zfsldr.o - -OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o misc.o -CLEANFILES+= zfsboot2 zfsboot.ld zfsboot.ldr zfsboot.bin zfsboot.out \ - ${OBJS} - -# We currently allow 256k bytes for zfsboot - in practice it could be -# any size up to 3.5Mb but keeping it fixed size simplifies zfsldr. -# -BOOT2SIZE= 262144 - -# i386 standalone support library -LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a - -zfsboot2: zfsboot.ld - @set -- `ls -l ${.ALLSRC}`; x=$$((${BOOT2SIZE}-$$5)); \ - echo "$$x bytes available"; test $$x -ge 0 - ${DD} if=${.ALLSRC} of=${.TARGET} bs=${BOOT2SIZE} conv=sync - -zfsboot.ld: zfsboot.ldr zfsboot.bin ${BTXKERN} - btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l zfsboot.ldr \ - -o ${.TARGET} -P 1 zfsboot.bin - -zfsboot.ldr: - :> ${.TARGET} - -zfsboot.bin: zfsboot.out - ${OBJCOPY} -S -O binary zfsboot.out ${.TARGET} - -zfsboot.out: ${BTXCRT} ${OBJS} - ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBI386} ${LIBSA32} - -SRCS= zfsboot.c - -.include <bsd.prog.mk> diff --git a/stand/i386/zfsboot/zfsboot.8 b/stand/i386/zfsboot/zfsboot.8 deleted file mode 100644 index 7ed8ea7df010..000000000000 --- a/stand/i386/zfsboot/zfsboot.8 +++ /dev/null @@ -1,132 +0,0 @@ -.\" Copyright (c) 2014 Andriy Gapon <avg@FreeBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd March 27, 2018 -.Dt ZFSBOOT 8 -.Os -.Sh NAME -.Nm zfsboot -.Nd bootcode for ZFS on BIOS-based computers -.Sh DESCRIPTION -.Nm -is used on BIOS-based computers to boot from a filesystem in -a ZFS pool. -.Nm -is installed in two parts on a disk or a partition used by a ZFS pool. -The first part, a single-sector starter boot block, is installed -at the beginning of the disk or partition. -The second part, a main boot block, is installed at a special offset -within the disk or partition. -Both areas are reserved by the ZFS on-disk specification for boot use. -If -.Nm -is installed in a partition, then that partition should be made -bootable using appropriate configuration and boot blocks described in -.Xr boot 8 . -.Sh BOOTING -The -.Nm -boot process is very similar to that of -.Xr gptzfsboot 8 . -One significant difference is that -.Nm -does not currently support the GPT partitioning scheme. -Thus only whole disks and MBR partitions, traditionally referred to as -slices, are probed for ZFS disk labels. -See the BUGS section in -.Xr gptzfsboot 8 -for some limitations of the MBR scheme support. -.Sh USAGE -.Nm -supports all the same prompt and configuration file arguments as -.Xr gptzfsboot 8 . -.Sh FILES -.Bl -tag -width /boot/zfsboot -compact -.It Pa /boot/zfsboot -boot code binary -.It Pa /boot.config -parameters for the boot block -.Pq optional -.It Pa /boot/config -alternative parameters for the boot block -.Pq optional -.El -.Sh EXAMPLES -.Nm -is typically installed using -.Xr dd 1 . -To install -.Nm -on the -.Pa ada0 -drive: -.Bd -literal -offset indent -dd if=/boot/zfsboot of=/dev/ada0 count=1 -dd if=/boot/zfsboot of=/dev/ada0 iseek=1 oseek=1024 -.Ed -.Pp -If the drive is currently in use, the GEOM safety will prevent writes -and must be disabled before running the above commands: -.Bd -literal -offset indent -sysctl kern.geom.debugflags=0x10 -.Ed -.Pp -.Nm -can also be installed in an MBR slice: -.Bd -literal -offset indent -gpart create -s mbr ada0 -gpart add -t freebsd ada0 -gpart bootcode -b /boot/boot0 ada0 -gpart set -a active -i 1 ada0 -dd if=/dev/zero of=/dev/ada0s1 count=2 -dd if=/boot/zfsboot of=/dev/ada0s1 count=1 -dd if=/boot/zfsboot of=/dev/ada0s1 iseek=1 oseek=1024 -.Ed -.Pp -Note that commands to create and populate a pool are not shown -in the example above. -.Sh SEE ALSO -.Xr dd 1 , -.Xr boot.config 5 , -.Xr boot 8 , -.Xr gptzfsboot 8 , -.Xr loader 8 , -.Xr zpool 8 -.Sh HISTORY -.Nm -appeared in FreeBSD 7.3. -.Sh AUTHORS -This manual page was written by -.An Andriy Gapon Aq avg@FreeBSD.org . -.Sh BUGS -Installing -.Nm -with -.Xr dd 1 -is a hack. -ZFS needs a command to properly install -.Nm -onto a ZFS-controlled disk or partition. diff --git a/stand/i386/zfsboot/zfsldr.S b/stand/i386/zfsboot/zfsldr.S deleted file mode 100644 index bf43a5cbc364..000000000000 --- a/stand/i386/zfsboot/zfsldr.S +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - * - * $FreeBSD$ - */ - -/* Memory Locations */ - .set MEM_ARG,0x900 # Arguments - .set MEM_ORG,0x7c00 # Origin - .set MEM_BUF,0x8000 # Load area - .set MEM_BTX,0x9000 # BTX start - .set MEM_JMP,0x9010 # BTX entry point - .set MEM_USR,0xa000 # Client start - .set BDA_BOOT,0x472 # Boot howto flag - -/* Partition Constants */ - .set PRT_OFF,0x1be # Partition offset - .set PRT_NUM,0x4 # Partitions - .set PRT_BSD,0xa5 # Partition type - -/* Misc. Constants */ - .set SIZ_PAG,0x1000 # Page size - .set SIZ_SEC,0x200 # Sector size - .set COPY_BLKS,0x8 # Number of blocks - # to copy for boot2 (<= 15) - .set COPY_BLK_SZ,0x8000 # Copy in 32k blocks; must be - # a multiple of 16 bytes - .set NSECT,(COPY_BLK_SZ / SIZ_SEC * COPY_BLKS) - .globl start - .code16 - -/* - * Load the rest of zfsboot2 and BTX up, copy the parts to the right locations, - * and start it all up. - */ - -/* - * Setup the segment registers to flat addressing (segment 0) and setup the - * stack to end just below the start of our code. - */ -start: cld # String ops inc - xor %cx,%cx # Zero - mov %cx,%es # Address - mov %cx,%ds # data - mov %cx,%ss # Set up - mov $start,%sp # stack -/* - * Load the MBR and look for the first FreeBSD slice. We use the fake - * partition entry below that points to the MBR when we call read. - * The first pass looks for the first active FreeBSD slice. The - * second pass looks for the first non-active FreeBSD slice if the - * first one fails. - */ - call check_edd # Make sure EDD works - mov $part4,%si # Dummy partition - xor %eax,%eax # Read MBR - movl $MEM_BUF,%ebx # from first - call read # sector - mov $0x1,%cx # Two passes -main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table - movb $0x1,%dh # Partition -main.2: cmpb $PRT_BSD,0x4(%si) # Our partition type? - jne main.3 # No - jcxz main.5 # If second pass - testb $0x80,(%si) # Active? - jnz main.5 # Yes -main.3: add $0x10,%si # Next entry - incb %dh # Partition - cmpb $0x1+PRT_NUM,%dh # In table? - jb main.2 # Yes - dec %cx # Do two - jcxz main.1 # passes -/* - * If we get here, we didn't find any FreeBSD slices at all, so print an - * error message and die. - */ - mov $msg_part,%si # Message - jmp error # Error - -/* - * Ok, we have a slice and drive in %dx now, so use that to locate and - * load boot2. %si references the start of the slice we are looking - * for, so go ahead and load up the COPY_BLKS*COPY_BLK_SZ/SIZ_SEC sectors - * starting at sector 1024 (i.e. after the two vdev labels). We don't - * have do anything fancy here to allow for an extra copy of boot1 and - * a partition table (compare to this section of the UFS bootstrap) so we - * just load it all at 0x9000. The first part of boot2 is BTX, which wants - * to run at 0x9000. The boot2.bin binary starts right after the end of BTX, - * so we have to figure out where the start of it is and then move the - * binary to 0xc000. Normally, BTX clients start at MEM_USR, or 0xa000, - * but when we use btxld to create zfsboot2, we use an entry point of - * 0x2000. That entry point is relative to MEM_USR; thus boot2.bin - * starts at 0xc000. - * - * The load area and the target area for the client overlap so we have - * to use a decrementing string move. We also play segment register - * games with the destination address for the move so that the client - * can be larger than 16k (which would overflow the zero segment since - * the client starts at 0xc000). - */ -main.5: mov %dx,MEM_ARG # Save args - mov $NSECT,%cx # Sector count - movl $1024,%eax # Offset to boot2 - mov $MEM_BTX,%ebx # Destination buffer -main.6: pushal # Save params - call read # Read disk - popal # Restore - incl %eax # Advance to - add $SIZ_SEC,%ebx # next sector - loop main.6 # If not last, read another - - mov $MEM_BTX,%bx # BTX - mov 0xa(%bx),%si # Get BTX length and set - add %bx,%si # %si to start of boot2 - dec %si # Set %ds:%si to point at the - mov %si,%ax # last byte we want to copy - shr $4,%ax # from boot2, with %si made as - add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # small as possible. - and $0xf,%si # - mov %ax,%ds # - mov $(MEM_USR+2*SIZ_PAG)/16,%ax # Set %es:(-1) to point at - add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # the last byte we - mov %ax,%es # want to copy boot2 into. - mov $COPY_BLKS,%bx # Copy COPY_BLKS 32k blocks -copyloop: - add $COPY_BLK_SZ,%si # Adjust %ds:%si to point at - mov %ds,%ax # the end of the next 32k to - sub $COPY_BLK_SZ/16,%ax # copy from boot2 - mov %ax,%ds - mov $COPY_BLK_SZ-1,%di # Adjust %es:%di to point at - mov %es,%ax # the end of the next 32k into - sub $COPY_BLK_SZ/16,%ax # which we want boot2 copied - mov %ax,%es - mov $COPY_BLK_SZ,%cx # Copy 32k - std - rep movsb - dec %bx - jnz copyloop - mov %cx,%ds # Reset %ds and %es - mov %cx,%es - cld # Back to increment - -/* - * Enable A20 so we can access memory above 1 meg. - * Use the zero-valued %cx as a timeout for embedded hardware which do not - * have a keyboard controller. - */ -seta20: cli # Disable interrupts -seta20.1: dec %cx # Timeout? - jz seta20.3 # Yes - inb $0x64,%al # Get status - testb $0x2,%al # Busy? - jnz seta20.1 # Yes - movb $0xd1,%al # Command: Write - outb %al,$0x64 # output port -seta20.2: inb $0x64,%al # Get status - testb $0x2,%al # Busy? - jnz seta20.2 # Yes - movb $0xdf,%al # Enable - outb %al,$0x60 # A20 -seta20.3: sti # Enable interrupts - - jmp start+MEM_JMP-MEM_ORG # Start BTX - - -/* - * Read a sector from the disk. Sets up an EDD packet on the stack - * and passes it to read. We assume that the destination address is - * always segment-aligned. - * - * %eax - int - LBA to read in relative to partition start - * %ebx - ptr - destination address - * %dl - byte - drive to read from - * %si - ptr - MBR partition entry - */ -read: xor %ecx,%ecx # Get - addl 0x8(%si),%eax # LBA - adc $0,%ecx - pushl %ecx # Starting absolute block - pushl %eax # block number - shr $4,%ebx # Convert to segment - push %bx # Address of - push $0 # transfer buffer - push $0x1 # Read 1 sector - push $0x10 # Size of packet - mov %sp,%si # Packet pointer - mov $0x42,%ah # BIOS: Extended - int $0x13 # read - jc read.1 # If error, fail - lea 0x10(%si),%sp # Clear stack - ret # If success, return -read.1: mov %ah,%al # Format - mov $read_err,%di # error - call hex8 # code - mov $msg_read,%si # Set the error message and - # fall through to the error - # routine -/* - * Print out the error message pointed to by %ds:(%si) followed - * by a prompt, wait for a keypress, and then reboot the machine. - */ -error: callw putstr # Display message - mov $prompt,%si # Display - callw putstr # prompt - xorb %ah,%ah # BIOS: Get - int $0x16 # keypress - movw $0x1234, BDA_BOOT # Do a warm boot - ljmp $0xffff,$0x0 # reboot the machine -/* - * Display a null-terminated string using the BIOS output. - */ -putstr.0: mov $0x7,%bx # Page:attribute - movb $0xe,%ah # BIOS: Display - int $0x10 # character -putstr: lodsb # Get char - testb %al,%al # End of string? - jne putstr.0 # No - ret # To caller -/* - * Check to see if the disk supports EDD. zfsboot requires EDD and does not - * support older C/H/S disk I/O. - */ -check_edd: cmpb $0x80,%dl # Hard drive? - jb check_edd.1 # No, fail to boot - mov $0x55aa,%bx # Magic - push %dx # Save - movb $0x41,%ah # BIOS: Check - int $0x13 # extensions present - pop %dx # Restore - jc check_edd.1 # If error, fail - cmp $0xaa55,%bx # Magic? - jne check_edd.1 # No, so fail - testb $0x1,%cl # Packet interface? - jz check_edd.1 # No, so fail - ret # EDD ok, keep booting -check_edd.1: mov $msg_chs,%si # Warn that CHS is - jmp error # unsupported and fail -/* - * AL to hex, saving the result to [EDI]. - */ -hex8: push %ax # Save - shrb $0x4,%al # Do upper - call hex8.1 # 4 - pop %ax # Restore -hex8.1: andb $0xf,%al # Get lower 4 - cmpb $0xa,%al # Convert - sbbb $0x69,%al # to hex - das # digit - orb $0x20,%al # To lower case - stosb # Save char - ret # (Recursive) - -/* Messages */ - -msg_chs: .asciz "CHS not supported" -msg_read: .ascii "Read error: " -read_err: .asciz "XX" -msg_part: .asciz "Boot error" - -prompt: .asciz "\r\n" - - .org PRT_OFF,0x90 - -/* Partition table */ - - .fill 0x30,0x1,0x0 -part4: .byte 0x80, 0x00, 0x01, 0x00 - .byte 0xa5, 0xfe, 0xff, 0xff - .byte 0x00, 0x00, 0x00, 0x00 - .byte 0x50, 0xc3, 0x00, 0x00 # 50000 sectors long, bleh - - .word 0xaa55 # Magic number diff --git a/stand/images/Makefile b/stand/images/Makefile index 432b1daa851b..2f45b989e0a7 100644 --- a/stand/images/Makefile +++ b/stand/images/Makefile @@ -1,8 +1,7 @@ -# $FreeBSD$ - .include <bsd.init.mk> -FILES+= freebsd-brand-rev.png freebsd-brand.png freebsd-logo-rev.png +FILES+= freebsd-brand-rev.png freebsd-brand.png freebsd-install-brand-rev.png \ + freebsd-logo-rev.png FILESDIR= /boot/images diff --git a/stand/images/freebsd-install-brand-rev.png b/stand/images/freebsd-install-brand-rev.png Binary files differnew file mode 100644 index 000000000000..59d173d3f8b3 --- /dev/null +++ b/stand/images/freebsd-install-brand-rev.png diff --git a/stand/images/freebsd-logo-rev.png b/stand/images/freebsd-logo-rev.png Binary files differindex 5279b718218c..6e2088df4654 100644 --- a/stand/images/freebsd-logo-rev.png +++ b/stand/images/freebsd-logo-rev.png diff --git a/stand/kboot/Makefile b/stand/kboot/Makefile index 24ab77af66db..72dbabc00568 100644 --- a/stand/kboot/Makefile +++ b/stand/kboot/Makefile @@ -1,39 +1,7 @@ -# $FreeBSD$ - -LOADER_CD9660_SUPPORT?= yes -LOADER_MSDOS_SUPPORT?= no -LOADER_EXT2FS_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes -LOADER_NET_SUPPORT?= yes -LOADER_NFS_SUPPORT?= yes -LOADER_TFTP_SUPPORT?= no -LOADER_GZIP_SUPPORT?= yes -LOADER_BZIP2_SUPPORT?= no +NO_OBJ=t .include <bsd.init.mk> -PROG= loader.kboot -NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} -INSTALLFLAGS= -b - -# Architecture-specific loader code -SRCS= vers.c main.c host_syscalls.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c - -CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken - -.include "${BOOTSRC}/fdt.mk" - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH} -.include "${.CURDIR}/arch/${MACHINE_ARCH}/Makefile.inc" - -# Always add MI sources -.include "${BOOTSRC}/loader.mk" -.PATH: ${SYSDIR}/libkern -CFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch/${MACHINE_ARCH} - -CFLAGS+= -Wall - -DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} -LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} +SUBDIR+= libkboot .WAIT kboot -.include <bsd.prog.mk> +.include <bsd.subdir.mk> diff --git a/stand/kboot/Makefile.inc b/stand/kboot/Makefile.inc new file mode 100644 index 000000000000..90a1b9a17e3e --- /dev/null +++ b/stand/kboot/Makefile.inc @@ -0,0 +1,7 @@ +# Bring in the mini-libc that we wrote + +KBOOTSRC=${BOOTSRC}/kboot +CFLAGS+=-I${KBOOTSRC}/include -I${KBOOTSRC}/include/arch/${MACHINE_ARCH} +LIBKBOOT=${BOOTOBJ}/kboot/libkboot/libkboot.a + +.include "../Makefile.inc" diff --git a/stand/kboot/README b/stand/kboot/README new file mode 100644 index 000000000000..ad390a023bb9 --- /dev/null +++ b/stand/kboot/README @@ -0,0 +1,48 @@ +So to make a Linux initrd: + +(1) mkdir .../initrd +(2) mkdir -p .../initrd/boot/defaults +(3) cd src/stand; make install DESTDIR=.../initrd +(4) Copy kernel to .../initrd/boot/kernel +(5) cd .../initrd +(6) cp boot/loader.kboot init +(7) find . | sort | cpio -o -H newc | gzip > /tmp/initrd.cpio +(8) download or build your linux kernel +(9) qemu-system-x86_64 -kernel ~/vmlinuz-5.19.0-051900-generic \ + -initrd /tmp/initrd.cpio \ + -m 256m -nographic \ + -monitor telnet::4444,server,nowait -serial stdio \ + -append "console=ttyS0" + (though you may need more than 256M of ram to actually boot FreeBSD and do + anything interesting with it and the serial console to stdio bit hasn't + been the most stable recipe lately). + +Notes: +For #6 you might need to strip loader.kboot if you copy it directly and don't + use make install. +For #7 the sort is important, and you may need LC_ALL=C for its invocation +For #7 gzip is but one of many methods, but it's the simplest to do. +For #9, this means we can automate it using methods from + src/tools/boot/rootgen.sh when the time comes. +#9 also likely generalizes to other architectures +For #8, see https://kernel.ubuntu.com/~kernel-ppa/mainline/ to download + a kernel suitable for testing... For arm, I've been using the + non 64k page kernels and 5.19 seems to not suck. + +aarch64: +qemu-system-aarch64 -m 1024 -cpu cortex-a57 -M virt \ + -kernel ~/linuxboot/arm64/kernel/boot/vmlinuz-5.19.0-051900-generic \ + -initrd ~/linuxboot/arm64/initrd.img -m 256m -nographic \ + -monitor telnet::4444,server,nowait -serial stdio \ + -append "console=ttyAMA0" + +General + +Add -g -G to have gdb stop and wait for the debugger. This is useful for +debugging the trampoline (hbreak will set a hardware break that's durable across +code changes). If you set the breakpoint for the trampoline and it never hits, +then there's likely no RAM there and you got the PA to load to wrong. When +debugging the trampiline and up to that, use gdb /boot/loader. When debugging +the kernel, use kernel.full to get all the debugging. hbreak panic() is useful +on the latter since you'll see the original panic, not the panic you get from +there not being an early console. diff --git a/stand/kboot/arch/amd64/Makefile.inc b/stand/kboot/arch/amd64/Makefile.inc deleted file mode 100644 index fb954e798599..000000000000 --- a/stand/kboot/arch/amd64/Makefile.inc +++ /dev/null @@ -1,8 +0,0 @@ -SRCS+= conf.c host_syscall.S amd64_tramp.S elf64_freebsd.c - -CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include -# load address. set in linker script -RELOC?= 0x0 -CFLAGS+= -DRELOC=${RELOC} - -LDFLAGS= -nostdlib -static -T ${.CURDIR}/arch/${MACHINE_ARCH}/ldscript.amd64 diff --git a/stand/kboot/arch/amd64/elf64_freebsd.c b/stand/kboot/arch/amd64/elf64_freebsd.c deleted file mode 100644 index a45a0db32e44..000000000000 --- a/stand/kboot/arch/amd64/elf64_freebsd.c +++ /dev/null @@ -1,345 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * Copyright (c) 2014 The FreeBSD Foundation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#define __ELF_WORD_SIZE 64 -#include <sys/param.h> -#include <sys/exec.h> -#include <sys/linker.h> -#include <string.h> -#include <machine/elf.h> -#include <stand.h> -#include <vm/vm.h> -#include <vm/pmap.h> - -#ifdef EFI -#include <efi.h> -#include <efilib.h> -#endif - -#include "bootstrap.h" - -#include "platform/acfreebsd.h" -#include "acconfig.h" -#define ACPI_SYSTEM_XFACE -#include "actypes.h" -#include "actbl.h" - -#ifdef EFI -#include "loader_efi.h" -#endif - -#ifdef EFI -static EFI_GUID acpi_guid = ACPI_TABLE_GUID; -static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; -#endif - -#ifdef EFI -#define LOADER_PAGE_SIZE EFI_PAGE_SIZE -#else -#define LOADER_PAGE_SIZE 8192 -#endif - -extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); - -static int elf64_exec(struct preloaded_file *amp); -static int elf64_obj_exec(struct preloaded_file *amp); - -static struct file_format amd64_elf = { - .l_load = elf64_loadfile, - .l_exec = elf64_exec, -}; -static struct file_format amd64_elf_obj = { - .l_load = elf64_obj_loadfile, - .l_exec = elf64_obj_exec, -}; - -#if 0 -extern struct file_format multiboot2; -extern struct file_format multiboot2_obj; -#endif - -struct file_format *file_formats[] = { -#if 0 - &multiboot2, - &multiboot2_obj, -#endif - &amd64_elf, - &amd64_elf_obj, - NULL -}; - -#ifdef EFI -static pml4_entry_t *PT4; -static pdp_entry_t *PT3; -static pdp_entry_t *PT3_l, *PT3_u; -static pd_entry_t *PT2; -static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; - -extern EFI_PHYSICAL_ADDRESS staging; - -static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, - uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry); -#endif - -extern uintptr_t amd64_tramp; -extern uint32_t amd64_tramp_size; - -/* - * There is an ELF kernel and one or more ELF modules loaded. - * We wish to start executing the kernel image, so make such - * preparations as are required, and do so. - */ -static int -elf64_exec(struct preloaded_file *fp) -{ -#ifdef EFI - struct file_metadata *md; - Elf_Ehdr *ehdr; - vm_offset_t modulep, kernend, trampcode, trampstack; - int err, i; - ACPI_TABLE_RSDP *rsdp; - char buf[24]; - int revision; - bool copy_auto; - -#ifdef EFI - copy_auto = copy_staging == COPY_STAGING_AUTO; - if (copy_auto) - copy_staging = fp->f_kernphys_relocatable ? - COPY_STAGING_DISABLE : COPY_STAGING_ENABLE; -#else - copy_auto = COPY_STAGING_DISABLE; /* XXX */ -#endif - - /* - * Report the RSDP to the kernel. While this can be found with - * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. - * The old code used the 'hints' method to communite this to - * the kernel. However, while convenient, the 'hints' method - * is fragile and does not work when static hints are compiled - * into the kernel. Instead, move to setting different tunables - * that start with acpi. The old 'hints' can be removed before - * we branch for FreeBSD 12. - */ - -#ifdef EFI - rsdp = efi_get_table(&acpi20_guid); - if (rsdp == NULL) { - rsdp = efi_get_table(&acpi_guid); - } -#else - rsdp = NULL; -#warning "write me" -#endif - if (rsdp != NULL) { - sprintf(buf, "0x%016llx", (unsigned long long)rsdp); - setenv("hint.acpi.0.rsdp", buf, 1); - setenv("acpi.rsdp", buf, 1); - revision = rsdp->Revision; - if (revision == 0) - revision = 1; - sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); - setenv("acpi.revision", buf, 1); - strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); - buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); - setenv("acpi.oem", buf, 1); - sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); - setenv("acpi.rsdt", buf, 1); - if (revision >= 2) { - /* XXX extended checksum? */ - sprintf(buf, "0x%016llx", - (unsigned long long)rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); - setenv("acpi.xsdt", buf, 1); - sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); - setenv("acpi.xsdt_length", buf, 1); - } - } - - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) - return (EFTYPE); - ehdr = (Elf_Ehdr *)&(md->md_data); - - trampcode = copy_staging == COPY_STAGING_ENABLE ? - (vm_offset_t)0x0000000040000000 /* 1G */ : - (vm_offset_t)0x0000000100000000; /* 4G */; -#ifdef EFI - err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, - (EFI_PHYSICAL_ADDRESS *)&trampcode); - if (EFI_ERROR(err)) { - printf("Unable to allocate trampoline\n"); - if (copy_auto) - copy_staging = COPY_STAGING_AUTO; - return (ENOMEM); - } -#else -#warning "Write me" -#endif - bzero((void *)trampcode, LOADER_PAGE_SIZE); - trampstack = trampcode + LOADER_PAGE_SIZE - 8; - bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size); - trampoline = (void *)trampcode; - - if (copy_staging == COPY_STAGING_ENABLE) { - PT4 = (pml4_entry_t *)0x0000000040000000; -#ifdef EFI - err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, - (EFI_PHYSICAL_ADDRESS *)&PT4); - if (EFI_ERROR(err)) { - printf("Unable to allocate trampoline page table\n"); - BS->FreePages(trampcode, 1); - if (copy_auto) - copy_staging = COPY_STAGING_AUTO; - return (ENOMEM); - } -#else -#warning "Write me" -#endif - bzero(PT4, 3 * LOADER_PAGE_SIZE); - PT3 = &PT4[512]; - PT2 = &PT3[512]; - - /* - * This is kinda brutal, but every single 1GB VM - * memory segment points to the same first 1GB of - * physical memory. But it is more than adequate. - */ - for (i = 0; i < NPTEPG; i++) { - /* - * Each slot of the L4 pages points to the - * same L3 page. - */ - PT4[i] = (pml4_entry_t)PT3; - PT4[i] |= PG_V | PG_RW; - - /* - * Each slot of the L3 pages points to the - * same L2 page. - */ - PT3[i] = (pdp_entry_t)PT2; - PT3[i] |= PG_V | PG_RW; - - /* - * The L2 page slots are mapped with 2MB pages for 1GB. - */ - PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024); - PT2[i] |= PG_V | PG_RW | PG_PS; - } - } else { - PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */ -#ifdef EFI - err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9, - (EFI_PHYSICAL_ADDRESS *)&PT4); - if (EFI_ERROR(err)) { - printf("Unable to allocate trampoline page table\n"); - BS->FreePages(trampcode, 9); - if (copy_auto) - copy_staging = COPY_STAGING_AUTO; - return (ENOMEM); - } -#else -#warning "Write me" -#endif - - bzero(PT4, 9 * LOADER_PAGE_SIZE); - - PT3_l = &PT4[NPML4EPG * 1]; - PT3_u = &PT4[NPML4EPG * 2]; - PT2_l0 = &PT4[NPML4EPG * 3]; - PT2_l1 = &PT4[NPML4EPG * 4]; - PT2_l2 = &PT4[NPML4EPG * 5]; - PT2_l3 = &PT4[NPML4EPG * 6]; - PT2_u0 = &PT4[NPML4EPG * 7]; - PT2_u1 = &PT4[NPML4EPG * 8]; - - /* 1:1 mapping of lower 4G */ - PT4[0] = (pml4_entry_t)PT3_l | PG_V | PG_RW; - PT3_l[0] = (pdp_entry_t)PT2_l0 | PG_V | PG_RW; - PT3_l[1] = (pdp_entry_t)PT2_l1 | PG_V | PG_RW; - PT3_l[2] = (pdp_entry_t)PT2_l2 | PG_V | PG_RW; - PT3_l[3] = (pdp_entry_t)PT2_l3 | PG_V | PG_RW; - for (i = 0; i < 4 * NPDEPG; i++) { - PT2_l0[i] = ((pd_entry_t)i << PDRSHIFT) | PG_V | - PG_RW | PG_PS; - } - - /* mapping of kernel 2G below top */ - PT4[NPML4EPG - 1] = (pml4_entry_t)PT3_u | PG_V | PG_RW; - PT3_u[NPDPEPG - 2] = (pdp_entry_t)PT2_u0 | PG_V | PG_RW; - PT3_u[NPDPEPG - 1] = (pdp_entry_t)PT2_u1 | PG_V | PG_RW; - /* compat mapping of phys @0 */ - PT2_u0[0] = PG_PS | PG_V | PG_RW; - /* this maps past staging area */ - for (i = 1; i < 2 * NPDEPG; i++) { - PT2_u0[i] = ((pd_entry_t)staging + - ((pd_entry_t)i - 1) * NBPDR) | - PG_V | PG_RW | PG_PS; - } - } - - printf("staging %#lx (%scopying) tramp %p PT4 %p\n", - staging, copy_staging == COPY_STAGING_ENABLE ? "" : "not ", - trampoline, PT4); - printf("Start @ 0x%lx ...\n", ehdr->e_entry); - -#ifdef EFI - efi_time_fini(); -#endif - err = bi_load(fp->f_args, &modulep, &kernend, true); - if (err != 0) { -#ifdef EFI - efi_time_init(); -#endif - if (copy_auto) - copy_staging = COPY_STAGING_AUTO; - return (err); - } - - dev_cleanup(); - - trampoline(trampstack, copy_staging == COPY_STAGING_ENABLE ? - efi_copy_finish : efi_copy_finish_nop, kernend, modulep, - PT4, ehdr->e_entry); -#endif - - panic("exec returned"); -} - -static int -elf64_obj_exec(struct preloaded_file *fp) -{ - - return (EFTYPE); -} diff --git a/stand/kboot/arch/amd64/syscall_nr.h b/stand/kboot/arch/amd64/syscall_nr.h deleted file mode 100644 index 193368364bf3..000000000000 --- a/stand/kboot/arch/amd64/syscall_nr.h +++ /dev/null @@ -1,15 +0,0 @@ -#define SYS_read 0 -#define SYS_write 1 -#define SYS_open 2 -#define SYS_close 3 -#define SYS_gettimeofday 96 -#define SYS_reboot 169 -#define SYS_mmap 9 -#define SYS_uname 63 -#define SYS_lseek 8 -#define SYS_getdents 78 -#define SYS_select 23 -#define __NR_kexec_load 246 - -#define KEXEC_ARCH_X86_64 62 -#define KEXEC_ARCH KEXEC_ARCH_X86_64 diff --git a/stand/kboot/arch/powerpc64/Makefile.inc b/stand/kboot/arch/powerpc64/Makefile.inc deleted file mode 100644 index 3c2fb6e18a16..000000000000 --- a/stand/kboot/arch/powerpc64/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ -CFLAGS+= -mcpu=powerpc64 - -SRCS+= conf.c ppc64_elf_freebsd.c host_syscall.S kerneltramp.S -SRCS+= ucmpdi2.c - -# load address. set in linker script -RELOC?= 0x0 -CFLAGS+= -DRELOC=${RELOC} - -LDFLAGS= -nostdlib -static -T ${.CURDIR}/arch/${MACHINE_ARCH}/ldscript.powerpc - -MK_PIE= no -# Maybe bogus? -CFLAGS+= -DAIM diff --git a/stand/kboot/arch/powerpc64/conf.c b/stand/kboot/arch/powerpc64/conf.c deleted file mode 100644 index 9862611c68d8..000000000000 --- a/stand/kboot/arch/powerpc64/conf.c +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * Copyright (C) 1999 Michael Smith <msmith@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include "bootstrap.h" - -#if defined(LOADER_NET_SUPPORT) -#include "dev_net.h" -#endif - -extern struct devsw hostdisk; - -/* - * We could use linker sets for some or all of these, but - * then we would have to control what ended up linked into - * the bootstrap. So it's easier to conditionalise things - * here. - * - * XXX rename these arrays to be consistent and less namespace-hostile - */ - -/* Exported for libsa */ -struct devsw *devsw[] = { -#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) - &hostdisk, -#endif -#if defined(LOADER_NET_SUPPORT) - &netdev, -#endif - NULL -}; - -struct fs_ops *file_system[] = { -#if defined(LOADER_UFS_SUPPORT) - &ufs_fsops, -#endif -#if defined(LOADER_CD9660_SUPPORT) - &cd9660_fsops, -#endif -#if defined(LOADER_EXT2FS_SUPPORT) - &ext2fs_fsops, -#endif -#if defined(LOADER_NFS_SUPPORT) - &nfs_fsops, -#endif -#if defined(LOADER_TFTP_SUPPORT) - &tftp_fsops, -#endif -#if defined(LOADER_GZIP_SUPPORT) - &gzipfs_fsops, -#endif -#if defined(LOADER_BZIP2_SUPPORT) - &bzipfs_fsops, -#endif - &dosfs_fsops, - NULL -}; - -extern struct netif_driver kbootnet; - -struct netif_driver *netif_drivers[] = { -#if 0 /* XXX */ -#if defined(LOADER_NET_SUPPORT) - &kbootnet, -#endif -#endif - NULL, -}; - -/* Exported for PowerPC only */ -/* - * Sort formats so that those that can detect based on arguments - * rather than reading the file go first. - */ - -extern struct file_format ppc_elf64; - -struct file_format *file_formats[] = { - &ppc_elf64, - NULL -}; - -/* - * Consoles - */ -extern struct console hostconsole; - -struct console *consoles[] = { - &hostconsole, - NULL -}; - diff --git a/stand/kboot/arch/powerpc64/ldscript.powerpc b/stand/kboot/arch/powerpc64/ldscript.powerpc deleted file mode 100644 index 729113695105..000000000000 --- a/stand/kboot/arch/powerpc64/ldscript.powerpc +++ /dev/null @@ -1,111 +0,0 @@ -/* $FreeBSD: user/nwhitehorn/kboot/powerpc/kboot/ldscript.powerpc 272888 2014-10-10 06:24:09Z bapt $ */ - -OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", - "elf32-powerpc-freebsd") -OUTPUT_ARCH(powerpc:common) -ENTRY(_start) -SEARCH_DIR(/usr/lib); -PROVIDE (__stack = 0); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x100000; - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0 - _etext = .; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rela.text : - { *(.rela.text) *(.rela.gnu.linkonce.t*) } - .rela.data : - { *(.rela.data) *(.rela.gnu.linkonce.d*) } - .rela.rodata : - { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } - .rela.got : { *(.rela.got) } - .rela.got1 : { *(.rela.got1) } - .rela.got2 : { *(.rela.got2) } - .rela.ctors : { *(.rela.ctors) } - .rela.dtors : { *(.rela.dtors) } - .rela.init : { *(.rela.init) } - .rela.fini : { *(.rela.fini) } - .rela.bss : { *(.rela.bss) } - .rela.plt : { *(.rela.plt) } - .rela.sbss : { *(.rela.sbss) } - .rela.sbss2 : { *(.rela.sbss2) } - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0 - _etext = .; - PROVIDE (etext = .); - .init : { *(.init) } =0 - .fini : { *(.fini) } =0 - .rodata : { *(.rodata) *(.gnu.linkonce.r*) } - .rodata1 : { *(.rodata1) } - .sbss2 : { *(.sbss2) } - /* Adjust the address for the data segment to the next page up. */ - . = ((. + 0x1000) & ~(0x1000 - 1)); - .data : - { - *(.data) - *(.gnu.linkonce.d*) - CONSTRUCTORS - } - .data1 : { *(.data1) } - .got1 : { *(.got1) } - .dynamic : { *(.dynamic) } - /* Put .ctors and .dtors next to the .got2 section, so that the pointers - get relocated with -mrelocatable. Also put in the .fixup pointers. - The current compiler no longer needs this, but keep it around for 2.7.2 */ - PROVIDE (_GOT2_START_ = .); - .got2 : { *(.got2) } - PROVIDE (__CTOR_LIST__ = .); - .ctors : { *(.ctors) } - PROVIDE (__CTOR_END__ = .); - PROVIDE (__DTOR_LIST__ = .); - .dtors : { *(.dtors) } - PROVIDE (__DTOR_END__ = .); - PROVIDE (_FIXUP_START_ = .); - .fixup : { *(.fixup) } - PROVIDE (_FIXUP_END_ = .); - PROVIDE (_GOT2_END_ = .); - PROVIDE (_GOT_START_ = .); - .got : { *(.got) } - .got.plt : { *(.got.plt) } - PROVIDE (_GOT_END_ = .); - _edata = .; - PROVIDE (edata = .); - .sbss : - { - PROVIDE (__sbss_start = .); - *(.sbss) - *(.scommon) - *(.dynsbss) - PROVIDE (__sbss_end = .); - } - .plt : { *(.plt) } - .bss : - { - PROVIDE (__bss_start = .); - *(.dynbss) - *(.bss) - *(COMMON) - } - . = ALIGN(4096); - _end = . ; - PROVIDE (end = .); -} - diff --git a/stand/kboot/arch/powerpc64/syscall_nr.h b/stand/kboot/arch/powerpc64/syscall_nr.h deleted file mode 100644 index 2854124153a2..000000000000 --- a/stand/kboot/arch/powerpc64/syscall_nr.h +++ /dev/null @@ -1,15 +0,0 @@ -#define SYS_read 3 -#define SYS_write 4 -#define SYS_open 5 -#define SYS_close 6 -#define SYS_gettimeofday 78 -#define SYS_reboot 88 -#define SYS_mmap 90 -#define SYS_uname 120 -#define SYS_llseek 140 -#define SYS_getdents 141 -#define SYS_select 142 -#define __NR_kexec_load 268 - -#define KEXEC_ARCH_PPC64 21 -#define KEXEC_ARCH KEXEC_ARCH_PPC64 diff --git a/stand/kboot/host_syscalls.c b/stand/kboot/host_syscalls.c deleted file mode 100644 index 53be0c166374..000000000000 --- a/stand/kboot/host_syscalls.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "host_syscall.h" -#include "syscall_nr.h" -#include <stand.h> - -ssize_t -host_read(int fd, void *buf, size_t nbyte) -{ - return host_syscall(SYS_read, fd, (uintptr_t)buf, nbyte); - /* XXX original overrode errors */ -} - -ssize_t -host_write(int fd, const void *buf, size_t nbyte) -{ - return host_syscall(SYS_write, fd, (uintptr_t)buf, nbyte); -} - -int -host_open(const char *path, int flags, int mode) -{ - return host_syscall(SYS_open, (uintptr_t)path, flags, mode); - /* XXX original overrode errors */ -} - -ssize_t -host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence) -{ -#ifdef SYS_llseek - return host_syscall(SYS_llseek, fd, offset_high, offset_lo, (uintptr_t)result, whence); -#else - int64_t rv = host_syscall(SYS_lseek, fd, - (int64_t)((uint64_t)offset_high << 32 | (uint32_t)offset_lo), whence); - if (rv > 0) - *result = (uint64_t)rv; - return (rv); -#endif -} - -int -host_close(int fd) -{ - return host_syscall(SYS_close, fd); -} - -void * -host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off) -{ - return (void *)host_syscall(SYS_mmap, (uintptr_t)addr, len, prot, flags, fd, off); -} - -int -host_uname(struct old_utsname *uts) -{ - return host_syscall(SYS_uname, (uintptr_t)uts); -} - -int -host_gettimeofday(struct host_timeval *a, void *b) -{ - return host_syscall(SYS_gettimeofday, (uintptr_t)a, (uintptr_t)b); -} - -int -host_select(int nfds, long *readfds, long *writefds, long *exceptfds, - struct host_timeval *timeout) -{ - return host_syscall(SYS_select, nfds, (uintptr_t)readfds, (uintptr_t)writefds, (uintptr_t)exceptfds, (uintptr_t)timeout, 0); -} - -int -kexec_load(uint32_t start, int nsegs, uint32_t segs) -{ - return host_syscall(__NR_kexec_load, start, nsegs, segs, KEXEC_ARCH << 16); -} - -int -host_reboot(int magic1, int magic2, int cmd, uintptr_t arg) -{ - return host_syscall(SYS_reboot, magic1, magic2, cmd, arg); -} - -int -host_getdents(int fd, void *dirp, int count) -{ - return host_syscall(SYS_getdents, fd, (uintptr_t)dirp, count); -} diff --git a/stand/kboot/hostdisk.c b/stand/kboot/hostdisk.c deleted file mode 100644 index 3c36f2d3bce6..000000000000 --- a/stand/kboot/hostdisk.c +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * Copyright (C) 2014 Nathan Whitehorn - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <stdarg.h> -#include "bootstrap.h" -#include "host_syscall.h" - -static int hostdisk_init(void); -static int hostdisk_strategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); -static int hostdisk_open(struct open_file *f, ...); -static int hostdisk_close(struct open_file *f); -static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data); -static int hostdisk_print(int verbose); - -struct devsw hostdisk = { - "/dev", - DEVT_DISK, - hostdisk_init, - hostdisk_strategy, - hostdisk_open, - hostdisk_close, - hostdisk_ioctl, - hostdisk_print, -}; - -static int -hostdisk_init(void) -{ - - return (0); -} - -static int -hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, - char *buf, size_t *rsize) -{ - struct devdesc *desc = devdata; - daddr_t pos; - int n; - uint64_t res; - uint32_t posl, posh; - - pos = dblk * 512; - - posl = pos & 0xffffffff; - posh = (pos >> 32) & 0xffffffff; - if (host_llseek(desc->d_unit, posh, posl, &res, 0) < 0) { - printf("Seek error\n"); - return (EIO); - } - n = host_read(desc->d_unit, buf, size); - - if (n < 0) - return (EIO); - - *rsize = n; - return (0); -} - -static int -hostdisk_open(struct open_file *f, ...) -{ - struct devdesc *desc; - va_list vl; - - va_start(vl, f); - desc = va_arg(vl, struct devdesc *); - va_end(vl); - - desc->d_unit = host_open(desc->d_opendata, O_RDONLY, 0); - - if (desc->d_unit <= 0) { - printf("hostdisk_open: couldn't open %s: %d\n", - (char *)desc->d_opendata, desc->d_unit); - return (ENOENT); - } - - return (0); -} - -static int -hostdisk_close(struct open_file *f) -{ - struct devdesc *desc = f->f_devdata; - - host_close(desc->d_unit); - return (0); -} - -static int -hostdisk_ioctl(struct open_file *f, u_long cmd, void *data) -{ - - return (EINVAL); -} - -static int -hostdisk_print(int verbose) -{ - return (0); -} - diff --git a/stand/kboot/include/arch/aarch64/stat_arch.h b/stand/kboot/include/arch/aarch64/stat_arch.h new file mode 100644 index 000000000000..9b52fe60c449 --- /dev/null +++ b/stand/kboot/include/arch/aarch64/stat_arch.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * SPDX-License-Identifier: MIT + * + * Note: From the musl project + */ + +typedef int host_nlink_t; + +struct host_kstat { + host_dev_t st_dev; + host_ino_t st_ino; + host_mode_t st_mode; + host_nlink_t st_nlink; + host_uid_t st_uid; + host_gid_t st_gid; + host_dev_t st_rdev; + unsigned long __pad; + host_off_t st_size; + host_blksize_t st_blksize; + int __pad2; + host_blkcnt_t st_blocks; + long st_atime_sec; + long st_atime_nsec; + long st_mtime_sec; + long st_mtime_nsec; + long st_ctime_sec; + long st_ctime_nsec; + unsigned __pad_for_future[2]; +}; diff --git a/stand/kboot/include/arch/aarch64/syscall_nr.h b/stand/kboot/include/arch/aarch64/syscall_nr.h new file mode 100644 index 000000000000..5c776db81d03 --- /dev/null +++ b/stand/kboot/include/arch/aarch64/syscall_nr.h @@ -0,0 +1,26 @@ +/* + * This file is in the public domain. It only recounts facts in the only way + * possible. + */ +#define SYS_close 57 +#define SYS_dup 23 +#define SYS_exit 93 +#define SYS_fstat 80 +#define SYS_getdents64 61 +#define SYS_getpid 172 +#define SYS_gettimeofday 169 +#define SYS_ioctl 29 +#define SYS_lseek 62 +#define SYS_kexec_load 104 +#define SYS_mkdirat 34 +#define SYS_mmap 222 +#define SYS_mount 40 +#define SYS_munmap 215 +#define SYS_newfstatat 79 +#define SYS_openat 56 +#define SYS_pselect6 72 +#define SYS_read 63 +#define SYS_reboot 142 +#define SYS_symlinkat 36 +#define SYS_uname 160 +#define SYS_write 64 diff --git a/stand/kboot/include/arch/aarch64/termios_arch.h b/stand/kboot/include/arch/aarch64/termios_arch.h new file mode 100644 index 000000000000..5db0b9831cdb --- /dev/null +++ b/stand/kboot/include/arch/aarch64/termios_arch.h @@ -0,0 +1,7 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "termios_gen.h" diff --git a/stand/kboot/include/arch/amd64/stat_arch.h b/stand/kboot/include/arch/amd64/stat_arch.h new file mode 100644 index 000000000000..74946abd2cda --- /dev/null +++ b/stand/kboot/include/arch/amd64/stat_arch.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * SPDX-License-Identifier: MIT + * + * Note: From the musl project + */ + +typedef uint64_t host_nlink_t; + +struct host_kstat { + host_dev_t st_dev; + host_ino_t st_ino; + host_nlink_t st_nlink; + + host_mode_t st_mode; + host_uid_t st_uid; + host_gid_t st_gid; + unsigned int __pad0; + host_dev_t st_rdev; + host_off_t st_size; + host_blksize_t st_blksize; + host_blkcnt_t st_blocks; + + long st_atime_sec; + long st_atime_nsec; + long st_mtime_sec; + long st_mtime_nsec; + long st_ctime_sec; + long st_ctime_nsec; + long __pad_for_future[3]; +}; + diff --git a/stand/kboot/include/arch/amd64/syscall_nr.h b/stand/kboot/include/arch/amd64/syscall_nr.h new file mode 100644 index 000000000000..705b39c62f44 --- /dev/null +++ b/stand/kboot/include/arch/amd64/syscall_nr.h @@ -0,0 +1,26 @@ +/* + * This file is in the public domain. It only recounts facts in the only way + * possible. + */ +#define SYS_close 3 +#define SYS_dup 32 +#define SYS_exit 60 +#define SYS_getdents64 217 +#define SYS_getpid 39 +#define SYS_gettimeofday 96 +#define SYS_ioctl 16 +#define SYS_kexec_load 246 +#define SYS_lseek 8 +#define SYS_mkdirat 258 +#define SYS_mmap 9 +#define SYS_mount 165 +#define SYS_munmap 11 +#define SYS_newfstat 5 +#define SYS_newfstatat 262 +#define SYS_openat 257 +#define SYS_pselect6 270 +#define SYS_read 0 +#define SYS_reboot 169 +#define SYS_symlinkat 266 +#define SYS_uname 63 +#define SYS_write 1 diff --git a/stand/kboot/include/arch/amd64/termios_arch.h b/stand/kboot/include/arch/amd64/termios_arch.h new file mode 100644 index 000000000000..5db0b9831cdb --- /dev/null +++ b/stand/kboot/include/arch/amd64/termios_arch.h @@ -0,0 +1,7 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "termios_gen.h" diff --git a/stand/kboot/include/arch/powerpc64/stat_arch.h b/stand/kboot/include/arch/powerpc64/stat_arch.h new file mode 100644 index 000000000000..103849b0e82b --- /dev/null +++ b/stand/kboot/include/arch/powerpc64/stat_arch.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * SPDX-License-Identifier: MIT + * + * Note: From the musl project + */ + +typedef uint64_t host_nlink_t; + +struct host_kstat { + host_dev_t st_dev; + host_ino_t st_ino; + host_nlink_t st_nlink; + host_mode_t st_mode; + host_uid_t st_uid; + host_gid_t st_gid; + host_dev_t st_rdev; + host_off_t st_size; + host_blksize_t st_blksize; + host_blkcnt_t st_blocks; + long st_atime_sec; + long st_atime_nsec; + long st_mtime_sec; + long st_mtime_nsec; + long st_ctime_sec; + long st_ctime_nsec; + long __pad_for_future[3]; +}; diff --git a/stand/kboot/include/arch/powerpc64/syscall_nr.h b/stand/kboot/include/arch/powerpc64/syscall_nr.h new file mode 100644 index 000000000000..50946a4f058c --- /dev/null +++ b/stand/kboot/include/arch/powerpc64/syscall_nr.h @@ -0,0 +1,26 @@ +/* + * This file is in the public domain. It only recounts facts in the only way + * possible. + */ +#define SYS_close 6 +#define SYS_dup 41 +#define SYS_exit 1 +#define SYS_fstat 108 +#define SYS_getdents64 202 +#define SYS_getpid 20 +#define SYS_gettimeofday 78 +#define SYS_ioctl 54 +#define SYS_kexec_load 268 +#define SYS_llseek 140 +#define SYS_mkdirat 287 +#define SYS_mmap 90 +#define SYS_mount 21 +#define SYS_munmap 91 +#define SYS_newfstatat 291 +#define SYS_openat 286 +#define SYS_pselect6 280 +#define SYS_read 3 +#define SYS_reboot 88 +#define SYS_symlinkat 295 +#define SYS_uname 120 +#define SYS_write 4 diff --git a/stand/kboot/include/arch/powerpc64/termios_arch.h b/stand/kboot/include/arch/powerpc64/termios_arch.h new file mode 100644 index 000000000000..7b9e8f15a8ca --- /dev/null +++ b/stand/kboot/include/arch/powerpc64/termios_arch.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * SPDX-License-Identifier: MIT + * + * Note: From the musl project, stripped down and repackaged with HOST_/host_ prepended + */ + +#undef HOST_NCCS +#define HOST_NCCS 19 +struct host_termios { + host_tcflag_t c_iflag; + host_tcflag_t c_oflag; + host_tcflag_t c_cflag; + host_tcflag_t c_lflag; + host_cc_t c_cc[HOST_NCCS]; + host_cc_t c_line; + host_speed_t __c_ispeed; + host_speed_t __c_ospeed; +}; + +#define HOST_VINTR 0 +#define HOST_VQUIT 1 +#define HOST_VERASE 2 +#define HOST_VKILL 3 +#define HOST_VEOF 4 +#define HOST_VMIN 5 +#define HOST_VEOL 6 +#define HOST_VTIME 7 +#define HOST_VEOL2 8 +#define HOST_VSWTC 9 +#define HOST_VWERASE 10 +#define HOST_VREPRINT 11 +#define HOST_VSUSP 12 +#define HOST_VSTART 13 +#define HOST_VSTOP 14 +#define HOST_VLNEXT 15 +#define HOST_VDISCARD 16 + +#define HOST_IGNBRK 0000001 +#define HOST_BRKINT 0000002 +#define HOST_IGNPAR 0000004 +#define HOST_PARMRK 0000010 +#define HOST_INPCK 0000020 +#define HOST_ISTRIP 0000040 +#define HOST_INLCR 0000100 +#define HOST_IGNCR 0000200 +#define HOST_ICRNL 0000400 +#define HOST_IXON 0001000 +#define HOST_IXOFF 0002000 +#define HOST_IXANY 0004000 +#define HOST_IUCLC 0010000 +#define HOST_IMAXBEL 0020000 +#define HOST_IUTF8 0040000 + +#define HOST_OPOST 0000001 +#define HOST_ONLCR 0000002 +#define HOST_OLCUC 0000004 +#define HOST_OCRNL 0000010 +#define HOST_ONOCR 0000020 +#define HOST_ONLRET 0000040 +#define HOST_OFILL 0000100 +#define HOST_OFDEL 0000200 +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) +#define HOST_NLDLY 0001400 +#define HOST_NL0 0000000 +#define HOST_NL1 0000400 +#define HOST_NL2 0001000 +#define HOST_NL3 0001400 +#define HOST_TABDLY 0006000 +#define HOST_TAB0 0000000 +#define HOST_TAB1 0002000 +#define HOST_TAB2 0004000 +#define HOST_TAB3 0006000 +#define HOST_CRDLY 0030000 +#define HOST_CR0 0000000 +#define HOST_CR1 0010000 +#define HOST_CR2 0020000 +#define HOST_CR3 0030000 +#define HOST_FFDLY 0040000 +#define HOST_FF0 0000000 +#define HOST_FF1 0040000 +#define HOST_BSDLY 0100000 +#define HOST_BS0 0000000 +#define HOST_BS1 0100000 +#endif + +#define HOST_VTDLY 0200000 +#define HOST_VT0 0000000 +#define HOST_VT1 0200000 + +#define HOST_B0 0000000 +#define HOST_B50 0000001 +#define HOST_B75 0000002 +#define HOST_B110 0000003 +#define HOST_B134 0000004 +#define HOST_B150 0000005 +#define HOST_B200 0000006 +#define HOST_B300 0000007 +#define HOST_B600 0000010 +#define HOST_B1200 0000011 +#define HOST_B1800 0000012 +#define HOST_B2400 0000013 +#define HOST_B4800 0000014 +#define HOST_B9600 0000015 +#define HOST_B19200 0000016 +#define HOST_B38400 0000017 + +#define HOST_B57600 00020 +#define HOST_B115200 00021 +#define HOST_B230400 00022 +#define HOST_B460800 00023 +#define HOST_B500000 00024 +#define HOST_B576000 00025 +#define HOST_B921600 00026 +#define HOST_B1000000 00027 +#define HOST_B1152000 00030 +#define HOST_B1500000 00031 +#define HOST_B2000000 00032 +#define HOST_B2500000 00033 +#define HOST_B3000000 00034 +#define HOST_B3500000 00035 +#define HOST_B4000000 00036 + +#define HOST_CSIZE 00001400 +#define HOST_CS5 00000000 +#define HOST_CS6 00000400 +#define HOST_CS7 00001000 +#define HOST_CS8 00001400 +#define HOST_CSTOPB 00002000 +#define HOST_CREAD 00004000 +#define HOST_PARENB 00010000 +#define HOST_PARODD 00020000 +#define HOST_HUPCL 00040000 +#define HOST_CLOCAL 00100000 + +#define HOST_ECHOE 0x00000002 +#define HOST_ECHOK 0x00000004 +#define HOST_ECHO 0x00000008 +#define HOST_ECHONL 0x00000010 +#define HOST_ISIG 0x00000080 +#define HOST_ICANON 0x00000100 +#define HOST_IEXTEN 0x00000400 +#define HOST_TOSTOP 0x00400000 +#define HOST_NOFLSH 0x80000000 + +#define HOST_TCOOFF 0 +#define HOST_TCOON 1 +#define HOST_TCIOFF 2 +#define HOST_TCION 3 + +#define HOST_TCIFLUSH 0 +#define HOST_TCOFLUSH 1 +#define HOST_TCIOFLUSH 2 + +#define HOST_TCSANOW 0 +#define HOST_TCSADRAIN 1 +#define HOST_TCSAFLUSH 2 + +#define HOST_EXTA 0000016 +#define HOST_EXTB 0000017 +#define HOST_CBAUD 00377 +#define HOST_CBAUDEX 0000020 +#define HOST_CIBAUD 077600000 +#define HOST_CMSPAR 010000000000 +#define HOST_CRTSCTS 020000000000 + +#define HOST_XCASE 0x00004000 +#define HOST_ECHOCTL 0x00000040 +#define HOST_ECHOPRT 0x00000020 +#define HOST_ECHOKE 0x00000001 +#define HOST_FLUSHO 0x00800000 +#define HOST_PENDIN 0x20000000 +#define HOST_EXTPROC 0x10000000 + +#define HOST_XTABS 00006000 +#define HOST_TIOCSER_TEMT 1 + +#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) ) +#define _IOC_NONE 1U +#define _IOC_WRITE 4U +#define _IOC_READ 2U + +#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0) +#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c)) +#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c)) +#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c)) + +#define HOST_TCGETS _IOR('t', 19, char[44]) +#define HOST_TCSETS _IOW('t', 20, char[44]) +#define HOST_TCSETSW _IOW('t', 21, char[44]) +#define HOST_TCSETSF _IOW('t', 22, char[44]) diff --git a/stand/kboot/include/efi.h b/stand/kboot/include/efi.h new file mode 100644 index 000000000000..26a6cf8944ca --- /dev/null +++ b/stand/kboot/include/efi.h @@ -0,0 +1,27 @@ +/*- + * Copyright (c) 2024, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <sys/efi.h> +#include <machine/metadata.h> + +/* Note, we mix and match FreeBSD types and EFI standard defined types */ + +typedef void (*efi_map_entry_cb)(struct efi_md *, void *argp); + +struct preloaded_file; + +bool efi_read_from_pa(uint64_t pa, uint32_t map_size, uint32_t desc_size, uint32_t vers); +void efi_read_from_sysfs(void); +void efi_set_systbl(uint64_t tbl); +void foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp); +void print_efi_map(struct efi_map_header *efihdr); +void efi_bi_loadsmap(struct preloaded_file *kfp); + +extern uint32_t efi_map_size; +extern vm_paddr_t efi_map_phys_src; /* From DTB */ +extern vm_paddr_t efi_map_phys_dst; /* From our memory map metadata module */ diff --git a/stand/kboot/include/host_syscall.h b/stand/kboot/include/host_syscall.h new file mode 100644 index 000000000000..68106093ce1f --- /dev/null +++ b/stand/kboot/include/host_syscall.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Rewritten from the original host_syscall.h Copyright (C) 2014 Nathan Whitehorn + */ + +#ifndef _HOST_SYSCALL_H +#define _HOST_SYSCALL_H + +#include <stand.h> +#include <assert.h> + +long host_syscall(int number, ...); + +/* + * Sizes taken from musl's include/alltypes.h.in and expanded for LP64 hosts + */ +typedef uint64_t host_dev_t; +typedef uint64_t host_ino_t; +typedef unsigned int host_mode_t; +typedef unsigned int host_uid_t; +typedef unsigned int host_gid_t; +typedef int64_t host_off_t; +typedef long host_blksize_t; +typedef int64_t host_blkcnt_t; + +#include "stat_arch.h" + +/* + * stat flags + * These are arch independent and match the values in nolib and uapi headers + * with HOST_ prepended. + */ +#define HOST_S_IFMT 0170000 +#define HOST_S_IFIFO 0010000 +#define HOST_S_IFCHR 0020000 +#define HOST_S_IFDIR 0040000 +#define HOST_S_IFBLK 0060000 +#define HOST_S_IFREG 0100000 +#define HOST_S_IFLNK 0120000 +#define HOST_S_IFSOCK 0140000 + +#define HOST_S_ISBLK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFBLK) +#define HOST_S_ISCHR(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFCHR) +#define HOST_S_ISDIR(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFDIR) +#define HOST_S_ISFIFO(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFIFO) +#define HOST_S_ISLNK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFLNK) +#define HOST_S_ISREG(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFREG) +#define HOST_S_ISSOCK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFSOCK) + +/* + * Constants for open, fcntl, etc + * + * Note: Some of these are arch dependent on Linux, but are the same for + * powerpc, x86, arm*, and riscv. We should be futureproof, though, since these + * are the 'generic' values and only older architectures (no longer supported by + * FreeBSD) vary. + * + * These are from tools/include/uapi/asm-generic/fcntl.h and use the octal + * notation. Beware, hex is used in other places creating potential confsion. + */ +#define HOST_O_RDONLY 0 +#define HOST_O_WRONLY 1 +#define HOST_O_RDWR 2 +#define HOST_O_CREAT 00100 +#define HOST_O_EXCL 00200 +#define HOST_O_NOCTTY 00400 +#define HOST_O_TRUNC 01000 +#define HOST_O_APPEND 02000 +#define HOST_O_NONBLOCK 04000 + +#define HOST_AT_FDCWD -100 /* Relative to current directory */ + +/* + * Data types + */ +struct old_utsname { + char sysname[65]; + char nodename[65]; + char release[65]; + char version[65]; + char machine[65]; +}; + +struct host_timeval { + time_t tv_sec; + long tv_usec; +}; + +/* + * Must match Linux's values see linux/tools/include/uapi/asm-generic/mman-common.h + * and linux/tools/include/linux/mman.h + * + * And pre-pend HOST_ here. + */ +#define HOST_PROT_READ 0x1 +#define HOST_PROT_WRITE 0x2 +#define HOST_PROT_EXEC 0x4 + +#define HOST_MAP_SHARED 0x01 +#define HOST_MAP_PRIVATE 0x02 +#define HOST_MAP_FIXED 0x10 +#define HOST_MAP_ANONYMOUS 0x20 + +#define HOST_MAP_FAILED ((void *)-1) + +/* Mount flags from uapi */ +#define MS_RELATIME (1 << 21) + +#define HOST_REBOOT_MAGIC1 0xfee1dead +#define HOST_REBOOT_MAGIC2 672274793 +#define HOST_REBOOT_CMD_KEXEC 0x45584543 + +/* + * Values from linux/tools/include/uapi/linux/kexec.h + */ + +/* + * Values match ELF architecture types. + */ +#define HOST_KEXEC_ARCH_X86_64 (62 << 16) +#define HOST_KEXEC_ARCH_PPC64 (21 << 16) +#define HOST_KEXEC_ARCH_ARM (40 << 16) +#define HOST_KEXEC_ARCH_AARCH64 (183 << 16) +#define HOST_KEXEC_ARCH_RISCV (243 << 16) + +/* Arbitrary cap on segments */ +#define HOST_KEXEC_SEGMENT_MAX 16 + +struct host_kexec_segment { + void *buf; + int bufsz; + void *mem; + int memsz; +}; + +struct host_dirent64 { + uint64_t d_ino; /* 64-bit inode number */ + int64_t d_off; /* 64-bit offset to next structure */ + unsigned short d_reclen; /* Size of this dirent */ + unsigned char d_type; /* File type */ + char d_name[]; /* Filename (null-terminated) */ +}; + +/* d_type values */ +#define HOST_DT_UNKNOWN 0 +#define HOST_DT_FIFO 1 +#define HOST_DT_CHR 2 +#define HOST_DT_DIR 4 +#define HOST_DT_BLK 6 +#define HOST_DT_REG 8 +#define HOST_DT_LNK 10 +#define HOST_DT_SOCK 12 +#define HOST_DT_WHT 14 + +/* + * System Calls + */ +int host_close(int fd); +int host_dup(int fd); +int host_exit(int code); +int host_fstat(int fd, struct host_kstat *sb); +int host_getdents64(int fd, void *dirp, int count); +int host_getpid(void); +int host_gettimeofday(struct host_timeval *a, void *b); +int host_ioctl(int fd, unsigned long request, unsigned long arg); +int host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags); +ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence); +int host_mkdir(const char *, host_mode_t); +void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off); +int host_mount(const char *src, const char *target, const char *type, + unsigned long flags, void *data); +int host_munmap(void *addr, size_t len); +int host_open(const char *path, int flags, int mode); +ssize_t host_read(int fd, void *buf, size_t nbyte); +int host_reboot(int, int, int, uintptr_t); +int host_select(int nfds, long *readfds, long *writefds, long *exceptfds, + struct host_timeval *timeout); +int host_stat(const char *path, struct host_kstat *sb); +int host_symlink(const char *path1, const char *path2); +int host_uname(struct old_utsname *); +ssize_t host_write(int fd, const void *buf, size_t nbyte); + +/* + * Wrappers / one-liners + */ +#define host_getmem(size) \ + host_mmap(0, size, HOST_PROT_READ | HOST_PROT_WRITE, \ + HOST_MAP_PRIVATE | HOST_MAP_ANONYMOUS, -1, 0); + +/* + * Since we have to interface with the 'raw' system call, we have to cope with + * Linux's conventions. To run on the most architectures possible, they don't + * return errors through some CPU flag, but instead, return a negative value for + * an error, and a positive one for success. However, there's some issues since + * addresses have to be returned, some of which are also negative, so Linus + * declared that no successful result could be -4096 to 0. This implements + * that quirk so we can check return values easily. + */ +static __inline bool +is_linux_error(long e) +{ + return (e < 0 && e >= -4096); +} + +/* + * Translate Linux errno to FreeBSD errno. The two system have idenitcal errors + * for 1-34. After that, they differ. Linux also has errno that don't map + * exactly to FreeBSD's errno, plus the Linux errno are arch dependent > + * 34. Since we just need to do this for simple cases, use the simple mapping + * function where -1 to -34 are translated to 1 to 34 and all others are EINVAL. + * Pass the linux return value, which will be the -errno. Linux returns these + * values as a 'long' which has to align to CPU register size, so accept that + * size as the error so the assert can catch more values. + */ +static __inline int +host_to_stand_errno(long e) +{ + assert(is_linux_error(e)); + + return((-e) > 34 ? EINVAL : (-e)); +} +#endif diff --git a/stand/kboot/include/seg.h b/stand/kboot/include/seg.h new file mode 100644 index 000000000000..5ca30670bdd1 --- /dev/null +++ b/stand/kboot/include/seg.h @@ -0,0 +1,24 @@ +/*- + * Copyright (c) 2024, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +struct memory_segments +{ + uint64_t start; + uint64_t end; + uint64_t type; /* MD defined */ +}; + +#define SYSTEM_RAM 1 +void init_avail(void); +void need_avail(int n); +void add_avail(uint64_t start, uint64_t end, uint64_t type); +void remove_avail(uint64_t start, uint64_t end, uint64_t type); +uint64_t first_avail(uint64_t align, uint64_t min_size, uint64_t type); +void print_avail(void); +bool populate_avail_from_iomem(void); +uint64_t space_avail(uint64_t start); diff --git a/stand/kboot/include/termios.h b/stand/kboot/include/termios.h new file mode 100644 index 000000000000..f5763292e7d5 --- /dev/null +++ b/stand/kboot/include/termios.h @@ -0,0 +1,24 @@ +#ifndef _TERMIOS_H +#define _TERMIOS_H + +typedef unsigned char host_cc_t; +typedef unsigned int host_speed_t; +typedef unsigned int host_tcflag_t; + +#define HOST_NCCS 32 + +#include "termios_arch.h" + +#define HOST_TCSANOW 0 +#define HOST_TCSADRAIN 1 +#define HOST_TCSAFLUSH 2 + +int host_tcgetattr (int, struct host_termios *); +int host_tcsetattr (int, int, const struct host_termios *); + +void host_cfmakeraw(struct host_termios *); +int host_cfsetispeed(struct host_termios *, host_speed_t); +int host_cfsetospeed(struct host_termios *, host_speed_t); +int host_cfsetspeed(struct host_termios *, host_speed_t); + +#endif diff --git a/stand/kboot/include/termios_gen.h b/stand/kboot/include/termios_gen.h new file mode 100644 index 000000000000..6e26338d4496 --- /dev/null +++ b/stand/kboot/include/termios_gen.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * SPDX-License-Identifier: MIT + * + * Note: From the musl project, stripped down and repackaged with HOST_/host_ prepended + */ + +struct host_termios { + host_tcflag_t c_iflag; + host_tcflag_t c_oflag; + host_tcflag_t c_cflag; + host_tcflag_t c_lflag; + host_cc_t c_line; + host_cc_t c_cc[HOST_NCCS]; + host_speed_t __c_ispeed; + host_speed_t __c_ospeed; +}; + +#define HOST_VINTR 0 +#define HOST_VQUIT 1 +#define HOST_VERASE 2 +#define HOST_VKILL 3 +#define HOST_VEOF 4 +#define HOST_VTIME 5 +#define HOST_VMIN 6 +#define HOST_VSWTC 7 +#define HOST_VSTART 8 +#define HOST_VSTOP 9 +#define HOST_VSUSP 10 +#define HOST_VEOL 11 +#define HOST_VREPRINT 12 +#define HOST_VDISCARD 13 +#define HOST_VWERASE 14 +#define HOST_VLNEXT 15 +#define HOST_VEOL2 16 + +#define HOST_IGNBRK 0000001 +#define HOST_BRKINT 0000002 +#define HOST_IGNPAR 0000004 +#define HOST_PARMRK 0000010 +#define HOST_INPCK 0000020 +#define HOST_ISTRIP 0000040 +#define HOST_INLCR 0000100 +#define HOST_IGNCR 0000200 +#define HOST_ICRNL 0000400 +#define HOST_IUCLC 0001000 +#define HOST_IXON 0002000 +#define HOST_IXANY 0004000 +#define HOST_IXOFF 0010000 +#define HOST_IMAXBEL 0020000 +#define HOST_IUTF8 0040000 + +#define HOST_OPOST 0000001 +#define HOST_OLCUC 0000002 +#define HOST_ONLCR 0000004 +#define HOST_OCRNL 0000010 +#define HOST_ONOCR 0000020 +#define HOST_ONLRET 0000040 +#define HOST_OFILL 0000100 +#define HOST_OFDEL 0000200 +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) +#define HOST_NLDLY 0000400 +#define HOST_NL0 0000000 +#define HOST_NL1 0000400 +#define HOST_CRDLY 0003000 +#define HOST_CR0 0000000 +#define HOST_CR1 0001000 +#define HOST_CR2 0002000 +#define HOST_CR3 0003000 +#define HOST_TABDLY 0014000 +#define HOST_TAB0 0000000 +#define HOST_TAB1 0004000 +#define HOST_TAB2 0010000 +#define HOST_TAB3 0014000 +#define HOST_BSDLY 0020000 +#define HOST_BS0 0000000 +#define HOST_BS1 0020000 +#define HOST_FFDLY 0100000 +#define HOST_FF0 0000000 +#define HOST_FF1 0100000 +#endif + +#define HOST_VTDLY 0040000 +#define HOST_VT0 0000000 +#define HOST_VT1 0040000 + +#define HOST_B0 0000000 +#define HOST_B50 0000001 +#define HOST_B75 0000002 +#define HOST_B110 0000003 +#define HOST_B134 0000004 +#define HOST_B150 0000005 +#define HOST_B200 0000006 +#define HOST_B300 0000007 +#define HOST_B600 0000010 +#define HOST_B1200 0000011 +#define HOST_B1800 0000012 +#define HOST_B2400 0000013 +#define HOST_B4800 0000014 +#define HOST_B9600 0000015 +#define HOST_B19200 0000016 +#define HOST_B38400 0000017 + +#define HOST_B57600 0010001 +#define HOST_B115200 0010002 +#define HOST_B230400 0010003 +#define HOST_B460800 0010004 +#define HOST_B500000 0010005 +#define HOST_B576000 0010006 +#define HOST_B921600 0010007 +#define HOST_B1000000 0010010 +#define HOST_B1152000 0010011 +#define HOST_B1500000 0010012 +#define HOST_B2000000 0010013 +#define HOST_B2500000 0010014 +#define HOST_B3000000 0010015 +#define HOST_B3500000 0010016 +#define HOST_B4000000 0010017 + +#define HOST_CSIZE 0000060 +#define HOST_CS5 0000000 +#define HOST_CS6 0000020 +#define HOST_CS7 0000040 +#define HOST_CS8 0000060 +#define HOST_CSTOPB 0000100 +#define HOST_CREAD 0000200 +#define HOST_PARENB 0000400 +#define HOST_PARODD 0001000 +#define HOST_HUPCL 0002000 +#define HOST_CLOCAL 0004000 + +#define HOST_ISIG 0000001 +#define HOST_ICANON 0000002 +#define HOST_ECHO 0000010 +#define HOST_ECHOE 0000020 +#define HOST_ECHOK 0000040 +#define HOST_ECHONL 0000100 +#define HOST_NOFLSH 0000200 +#define HOST_TOSTOP 0000400 +#define HOST_IEXTEN 0100000 + +#define HOST_TCOOFF 0 +#define HOST_TCOON 1 +#define HOST_TCIOFF 2 +#define HOST_TCION 3 + +#define HOST_TCIFLUSH 0 +#define HOST_TCOFLUSH 1 +#define HOST_TCIOFLUSH 2 + +#define HOST_TCSANOW 0 +#define HOST_TCSADRAIN 1 +#define HOST_TCSAFLUSH 2 + +#define HOST_EXTA 0000016 +#define HOST_EXTB 0000017 +#define HOST_CBAUD 0010017 +#define HOST_CBAUDEX 0010000 +#define HOST_CIBAUD 002003600000 +#define HOST_CMSPAR 010000000000 +#define HOST_CRTSCTS 020000000000 + +#define HOST_XCASE 0000004 +#define HOST_ECHOCTL 0001000 +#define HOST_ECHOPRT 0002000 +#define HOST_ECHOKE 0004000 +#define HOST_FLUSHO 0010000 +#define HOST_PENDIN 0040000 +#define HOST_EXTPROC 0200000 + +#define HOST_XTABS 0014000 + +#define HOST_TCGETS 0x5401 +#define HOST_TCSETS 0x5402 +#define HOST_TCSETSW 0x5403 +#define HOST_TCSETSF 0x5404 diff --git a/stand/kboot/include/util.h b/stand/kboot/include/util.h new file mode 100644 index 000000000000..dabf3d1ba9fb --- /dev/null +++ b/stand/kboot/include/util.h @@ -0,0 +1,15 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +/* dfk.c: */ +bool data_from_kernel(const char *sym, void *buf, size_t len); + +/* util.c: */ +bool file2str(const char *fn, char *buffer, size_t buflen); +bool file2u32(const char *fn, uint32_t *val); +bool file2u64(const char *fn, uint64_t *val); diff --git a/stand/kboot/kboot/Makefile b/stand/kboot/kboot/Makefile new file mode 100644 index 000000000000..19bae09df5ea --- /dev/null +++ b/stand/kboot/kboot/Makefile @@ -0,0 +1,73 @@ +LOADER_DISK_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= yes +LOADER_MSDOS_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_ZFS_SUPPORT?= yes +LOADER_NET_SUPPORT?= no +LOADER_NFS_SUPPORT?= no +LOADER_TFTP_SUPPORT?= no +LOADER_GZIP_SUPPORT?= no +LOADER_BZIP2_SUPPORT?= no + +.include <bsd.init.mk> + +PROG= loader.kboot +NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} +INSTALLFLAGS= -b + +# Architecture-specific loader code +SRCS= \ + bootinfo.c \ + conf.c \ + hostcons.c \ + hostdisk.c \ + hostfs.c \ + init.c \ + main.c \ + vers.c + +.if ${MK_FDT} != "no" +SRCS+= kbootfdt.c +.endif + +.if ${MK_LOADER_ZFS} != "no" +CFLAGS+= -I${ZFSSRC} +CFLAGS+= -I${SYSDIR}/contrib/openzfs/include +CFLAGS+= -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs +HAVE_ZFS=yes +.endif + +HELP_FILENAME= loader.help.kboot + +.include "${BOOTSRC}/fdt.mk" + +# We share bootinfo.c with efi +.PATH: ${BOOTSRC}/efi/loader + +# Note: Since we're producing a userland binary, we key off of MACHINE_ARCH +# instead of the more normal MACHINE since the changes between different flavors +# of MACHINE_ARCH are large enough in Linux that it's easier that way. +.PATH: ${.CURDIR}/arch/${MACHINE_ARCH} +.include "${.CURDIR}/arch/${MACHINE_ARCH}/Makefile.inc" + +# Bring in our ldscript +LDFLAGS= -nostdlib -static -T ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}.ldscript + +# Always add MI sources +.include "${BOOTSRC}/loader.mk" +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch/${MACHINE_ARCH} + +CFLAGS+= -Wall + +DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBSAFDT} ${LIBSA} ${LIBKBOOT} +LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBSAFDT} ${LIBSA} ${LIBKBOOT} + +# Add our own lua bindings until they are universal +.if ${LOADER_INTERP} == "lua" +SRCS+= \ + lua_bindings.c +CFLAGS.lua_bindings.c+= -I${FLUALIB}/libhash +.endif + +.include <bsd.prog.mk> diff --git a/stand/kboot/kboot/arch/aarch64/Makefile.inc b/stand/kboot/kboot/arch/aarch64/Makefile.inc new file mode 100644 index 000000000000..3e856f5322b3 --- /dev/null +++ b/stand/kboot/kboot/arch/aarch64/Makefile.inc @@ -0,0 +1,10 @@ +SRCS+= tramp.S exec.c load_addr.c fdt_arch.c + +.PATH: ${BOOTSRC}/arm64/libarm64 +CFLAGS+=-I${BOOTSRC}/arm64/libarm64 +SRCS+= cache.c + +CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include +# load address. set in linker script +RELOC?= 0x0 +CFLAGS+= -DRELOC=${RELOC} diff --git a/stand/kboot/kboot/arch/aarch64/aarch64.ldscript b/stand/kboot/kboot/arch/aarch64/aarch64.ldscript new file mode 100644 index 000000000000..dd551247125b --- /dev/null +++ b/stand/kboot/kboot/arch/aarch64/aarch64.ldscript @@ -0,0 +1,60 @@ +OUTPUT_FORMAT("elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x401000; + ImageBase = .; + .hash : { *(.hash) } /* this MUST come first! */ + . = ALIGN(4096); + .eh_frame : + { + *(.eh_frame) + } + . = ALIGN(4096); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0xCCCCCCCC + . = ALIGN(4096); + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + . = ALIGN(4096); + __gp = .; + .sdata : { + *(.got.plt .got) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela.dyn : { + *(.rela.data*) + *(.rela.got) + *(.rela.stab) + *(.relaset_*) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } +} diff --git a/stand/kboot/kboot/arch/aarch64/exec.c b/stand/kboot/kboot/arch/aarch64/exec.c new file mode 100644 index 000000000000..df3e922dfe11 --- /dev/null +++ b/stand/kboot/kboot/arch/aarch64/exec.c @@ -0,0 +1,289 @@ +/*- + * Copyright (c) 2006 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stand.h> +#include <string.h> + +#include <sys/param.h> +#include <sys/linker.h> +#include <machine/elf.h> + +#ifdef EFI +#include <efi.h> +#include <efilib.h> +#include "loader_efi.h" +#else +#include "host_syscall.h" +#endif +#include <machine/metadata.h> + +#include "bootstrap.h" +#include "efi.h" +#include "kboot.h" + +#include "platform/acfreebsd.h" +#include "acconfig.h" +#define ACPI_SYSTEM_XFACE +#include "actypes.h" +#include "actbl.h" + +#include "cache.h" + +#ifndef EFI +#define LOADER_PAGE_SIZE PAGE_SIZE +#endif + +#ifdef EFI +static EFI_GUID acpi_guid = ACPI_TABLE_GUID; +static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; +#endif + +static int elf64_exec(struct preloaded_file *amp); +static int elf64_obj_exec(struct preloaded_file *amp); + +bool do_mem_map = false; + +/* Usually provided by loader_efi.h -- maybe just delete? */ +#ifndef EFI +int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, + bool exit_bs); +#endif + +static struct file_format arm64_elf = { + elf64_loadfile, + elf64_exec +}; + +struct file_format *file_formats[] = { + &arm64_elf, + NULL +}; + +#ifndef EFI +extern uintptr_t tramp; +extern uint32_t tramp_size; +extern uint32_t tramp_data_offset; + +struct trampoline_data { + uint64_t entry; // 0 (PA where kernel loaded) + uint64_t modulep; // 8 module metadata + uint64_t memmap_src; // 16 Linux-provided memory map PA + uint64_t memmap_dst; // 24 Module data copy PA + uint64_t memmap_len; // 32 Length to copy +}; +#endif + +static int +elf64_exec(struct preloaded_file *fp) +{ + vm_offset_t modulep, kernendp; +#ifdef EFI + vm_offset_t clean_addr; + size_t clean_size; + void (*entry)(vm_offset_t); +#else + vm_offset_t trampolinebase; + vm_offset_t staging; + void *trampcode; + uint64_t *trampoline; + struct trampoline_data *trampoline_data; + int nseg; + void *kseg; +#endif + struct file_metadata *md; + Elf_Ehdr *ehdr; + int error; +#ifdef EFI + ACPI_TABLE_RSDP *rsdp; + char buf[24]; + int revision; + + /* + * Report the RSDP to the kernel. The old code used the 'hints' method + * to communite this to the kernel. However, while convenient, the + * 'hints' method is fragile and does not work when static hints are + * compiled into the kernel. Instead, move to setting different tunables + * that start with acpi. The old 'hints' can be removed before we branch + * for FreeBSD 15. + */ + rsdp = efi_get_table(&acpi20_guid); + if (rsdp == NULL) { + rsdp = efi_get_table(&acpi_guid); + } + if (rsdp != NULL) { + sprintf(buf, "0x%016llx", (unsigned long long)rsdp); + setenv("hint.acpi.0.rsdp", buf, 1); + setenv("acpi.rsdp", buf, 1); + revision = rsdp->Revision; + if (revision == 0) + revision = 1; + sprintf(buf, "%d", revision); + setenv("hint.acpi.0.revision", buf, 1); + setenv("acpi.revision", buf, 1); + strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); + buf[sizeof(rsdp->OemId)] = '\0'; + setenv("hint.acpi.0.oem", buf, 1); + setenv("acpi.oem", buf, 1); + sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); + setenv("hint.acpi.0.rsdt", buf, 1); + setenv("acpi.rsdt", buf, 1); + if (revision >= 2) { + /* XXX extended checksum? */ + sprintf(buf, "0x%016llx", + (unsigned long long)rsdp->XsdtPhysicalAddress); + setenv("hint.acpi.0.xsdt", buf, 1); + setenv("acpi.xsdt", buf, 1); + sprintf(buf, "%d", rsdp->Length); + setenv("hint.acpi.0.xsdt_length", buf, 1); + setenv("acpi.xsdt_length", buf, 1); + } + } +#else + vm_offset_t rsdp; + rsdp = acpi_rsdp(); + if (rsdp != 0) { + char buf[24]; + + printf("Found ACPI 2.0 at %#016lx\n", rsdp); + sprintf(buf, "0x%016llx", (unsigned long long)rsdp); + setenv("hint.acpi.0.rsdp", buf, 1); /* For 13.1R bootability */ + setenv("acpi.rsdp", buf, 1); + /* Nobody uses the rest of that stuff */ + } + + + // XXX Question: why not just use malloc? + trampcode = host_getmem(LOADER_PAGE_SIZE); + if (trampcode == NULL) { + printf("Unable to allocate trampoline\n"); + return (ENOMEM); + } + bzero((void *)trampcode, LOADER_PAGE_SIZE); + bcopy((void *)&tramp, (void *)trampcode, tramp_size); + trampoline = (void *)trampcode; + + /* + * Figure out where to put it. + * + * Linux does not allow us to kexec_load into any part of memory. Find + * the first available chunk of physical memory where loading is + * possible (staging). + * + * The kernel is loaded at the 'base' address in continguous physical + * memory. We use the 2MB in front of the kernel as a place to put our + * trampoline, but that's really overkill since we only need ~100 bytes. + * The arm64 kernel's entry requirements are only 'load the kernel at a + * 2MB alignment' and it figures out the rest, creates the right page + * tables, etc. + */ + staging = kboot_get_phys_load_segment(); + printf("Load address at %#jx\n", (uintmax_t)staging); + printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset); +#endif + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return(EFTYPE); + + ehdr = (Elf_Ehdr *)&(md->md_data); +#ifdef EFI + entry = efi_translate(ehdr->e_entry); + + efi_time_fini(); +#endif + error = bi_load(fp->f_args, &modulep, &kernendp, true); + if (error != 0) { +#ifdef EFI + efi_time_init(); +#endif + return (error); + } + + dev_cleanup(); + +#ifdef EFI + /* Clean D-cache under kernel area and invalidate whole I-cache */ + clean_addr = (vm_offset_t)efi_translate(fp->f_addr); + clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr; + + cpu_flush_dcache((void *)clean_addr, clean_size); + cpu_inval_icache(); + + (*entry)(modulep); + +#else + /* Linux will flush the caches, just pass this data into our trampoline and go */ + trampoline_data = (void *)trampoline + tramp_data_offset; + memset(trampoline_data, 0, sizeof(*trampoline_data)); + trampoline_data->entry = ehdr->e_entry - fp->f_addr + staging; + trampoline_data->modulep = modulep; + printf("Modulep = %jx\n", (uintmax_t)modulep); + if (efi_map_phys_src != 0) { + md = file_findmetadata(fp, MODINFOMD_EFI_MAP); + if (md == NULL || md->md_addr == 0) { + printf("Need to copy EFI MAP, but EFI MAP not found. %p\n", md); + } else { + printf("Metadata EFI map loaded at VA %lx\n", md->md_addr); + efi_map_phys_dst = md->md_addr + staging + + roundup2(sizeof(struct efi_map_header), 16) - fp->f_addr; + trampoline_data->memmap_src = efi_map_phys_src; + trampoline_data->memmap_dst = efi_map_phys_dst; + trampoline_data->memmap_len = efi_map_size - roundup2(sizeof(struct efi_map_header), 16); + printf("Copying UEFI Memory Map data from %#lx to %#lx %ld bytes\n", + efi_map_phys_src, + trampoline_data->memmap_dst, + trampoline_data->memmap_len); + } + } + /* + * Copy the trampoline to the ksegs. Since we're just bouncing off of + * this into the kernel, no need to preserve the pages. On arm64, the + * kernel sets up the initial page table, so we don't have to preserve + * the memory used for the trampoline past when it calls the kernel. + */ + printf("kernendp = %#llx\n", (long long)kernendp); + trampolinebase = staging + (kernendp - fp->f_addr); + printf("trampolinebase = %#llx\n", (long long)trampolinebase); + archsw.arch_copyin((void *)trampcode, kernendp, tramp_size); + printf("Trampoline bouncing to %#llx\n", (long long)trampoline_data->entry); + + kboot_kseg_get(&nseg, &kseg); + error = host_kexec_load(trampolinebase, nseg, kseg, HOST_KEXEC_ARCH_AARCH64); + if (error != 0) + panic("kexec_load returned error: %d", error); + host_reboot(HOST_REBOOT_MAGIC1, HOST_REBOOT_MAGIC2, HOST_REBOOT_CMD_KEXEC, 0); +#endif + + panic("exec returned"); +} + +static int +elf64_obj_exec(struct preloaded_file *fp) +{ + + printf("%s called for preloaded file %p (=%s):\n", __func__, fp, + fp->f_name); + return (ENOSYS); +} diff --git a/stand/kboot/kboot/arch/aarch64/fdt_arch.c b/stand/kboot/kboot/arch/aarch64/fdt_arch.c new file mode 100644 index 000000000000..bc480808d14f --- /dev/null +++ b/stand/kboot/kboot/arch/aarch64/fdt_arch.c @@ -0,0 +1,14 @@ +/*- + * Copyright (c) 2022 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/types.h> +#include "kboot.h" + +void +fdt_arch_fixups(void *fdtp) +{ + /* Unsure what to pass fixup */ +} diff --git a/stand/kboot/kboot/arch/aarch64/load_addr.c b/stand/kboot/kboot/arch/aarch64/load_addr.c new file mode 100644 index 000000000000..c458adc8dd05 --- /dev/null +++ b/stand/kboot/kboot/arch/aarch64/load_addr.c @@ -0,0 +1,143 @@ +/*- + * Copyright (c) 2022 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/param.h> +#include <machine/metadata.h> +#include <sys/linker.h> +#include <fdt_platform.h> +#include <libfdt.h> + +#include "kboot.h" +#include "efi.h" + +static bool +do_memory_from_fdt(int fd) +{ + struct stat sb; + char *buf = NULL; + int len, offset; + uint32_t sz, ver, esz; + uint64_t mmap_pa; + const uint32_t *u32p; + const uint64_t *u64p; + + if (fstat(fd, &sb) < 0) + return false; + buf = malloc(sb.st_size); + if (buf == NULL) + return false; + len = read(fd, buf, sb.st_size); + /* NB: we're reading this from sysfs, so mismatch OK */ + if (len <= 0) + goto errout; + + /* + * Look for /chosen to find these values: + * linux,uefi-system-table PA of the UEFI System Table. + * linux,uefi-mmap-start PA of the UEFI memory map + * linux,uefi-mmap-size Size of mmap + * linux,uefi-mmap-desc-size Size of each entry of mmap + * linux,uefi-mmap-desc-ver Format version, should be 1 + */ + offset = fdt_path_offset(buf, "/chosen"); + if (offset <= 0) + goto errout; + u64p = fdt_getprop(buf, offset, "linux,uefi-system-table", &len); + if (u64p == NULL) + goto errout; + efi_set_systbl(fdt64_to_cpu(*u64p)); + u32p = fdt_getprop(buf, offset, "linux,uefi-mmap-desc-ver", &len); + if (u32p == NULL) + goto errout; + ver = fdt32_to_cpu(*u32p); + u32p = fdt_getprop(buf, offset, "linux,uefi-mmap-desc-size", &len); + if (u32p == NULL) + goto errout; + esz = fdt32_to_cpu(*u32p); + u32p = fdt_getprop(buf, offset, "linux,uefi-mmap-size", &len); + if (u32p == NULL) + goto errout; + sz = fdt32_to_cpu(*u32p); + u64p = fdt_getprop(buf, offset, "linux,uefi-mmap-start", &len); + if (u64p == NULL) + goto errout; + mmap_pa = fdt64_to_cpu(*u64p); + free(buf); + + printf("UEFI MMAP: Ver %d Ent Size %d Tot Size %d PA %#lx\n", + ver, esz, sz, mmap_pa); + + efi_read_from_pa(mmap_pa, sz, esz, ver); + return true; + +errout: + free(buf); + return false; +} + +bool +enumerate_memory_arch(void) +{ + int fd = -1; + bool rv = false; + + /* + * FDT publishes the parameters for the memory table in a series of + * nodes in the DTB. One of them is the physical address for the memory + * table. Try to open the fdt nblob to find this information if we can + * and try to grab things from memory. If we return rv == TRUE then + * we found it. The global efi_map_phys_src is set != 0 when we know + * the PA but can't read it. + */ + fd = open("host:/sys/firmware/fdt", O_RDONLY); + if (fd != -1) { + rv = do_memory_from_fdt(fd); + close(fd); + } + + /* + * One would think that one could use the raw EFI map to find memory + * that's free to boot the kernel with. However, Linux reserves some + * areas that it needs to properly. I'm not sure if the printf should be + * a panic, but for now, so I can debug (maybe at the loader prompt), + * I'm printing and carrying on. + */ + if (!rv) { + printf("Could not obtain UEFI memory tables, expect failure\n"); + } + + populate_avail_from_iomem(); + print_avail(); + + return true; +} + +uint64_t +kboot_get_phys_load_segment(void) +{ +#define HOLE_SIZE (64ul << 20) +#define KERN_ALIGN (2ul << 20) + static uint64_t s = 0; + + if (s != 0) + return (s); + + print_avail(); + s = first_avail(KERN_ALIGN, HOLE_SIZE, SYSTEM_RAM); + printf("KBOOT GET PHYS Using %#llx\n", (long long)s); + if (s != 0) + return (s); + s = 0x40000000 | 0x4200000; /* should never get here */ + /* XXX PANIC? XXX */ + printf("Falling back to the crazy address %#lx which works in qemu\n", s); + return (s); +} + +void +bi_loadsmap(struct preloaded_file *kfp) +{ + efi_bi_loadsmap(kfp); +} diff --git a/stand/kboot/kboot/arch/aarch64/tramp.S b/stand/kboot/kboot/arch/aarch64/tramp.S new file mode 100644 index 000000000000..c0004006796d --- /dev/null +++ b/stand/kboot/kboot/arch/aarch64/tramp.S @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * This is the trampoline that starts the FreeBSD kernel. Since the Linux kernel + * calls this routine with no args, and has a different environment than the boot + * loader provides and that the kernel expects, this code is responsible for setting + * all that up and calling the normal kernel entry point. It's analogous to the + * "purgatory" code in the linux kernel. Details about these operations are + * contained in comments below. On aarch64, the kernel will start all the APs so + * we don't have to worry about them here. + */ + +/* + * Keep in sync with exec.c. Kexec starts aarch64_tramp w/o any + * parameters, so store them here. + * + * struct trampoline_data { + * uint64_t entry; // 0 (PA where kernel loaded) + * uint64_t modulep; // 8 module metadata + * uint64_t memmap_src; // 16 Linux-provided memory map PA + * uint64_t memmap_dst; // 24 Module data copy PA + * uint64_t memmap_len; // 32 Length to copy + * }; + * + * FreeBSD's arm64 entry point is _start which assumes: + * MMU on with an identity map, or off + * D-Cache: off + * I-Cache: on or off + * We are loaded at a 2MiB aligned address + * Module data (modulep) pointer in x0 + * + * The rest of the boot loader tells Linux to land the kernel in its final + * location with the needed alignment, etc. It does this, and then we take over. + * + * The linux kernel will helpfully turn off the MMU, flush the caches, disables + * them, etc. It calls the tramp with two args: FDT blob address in x0 and the + * EL2 vectors in x1. Currently, we make use of neither of these parameters: we + * pass whatever dtb we think we need as part of the module data and we're a bit + * weak on hypervisor support at the moment. _start's requirements are all + * satisifed. + * + * This trampoline sets up the arguments the kernel expects and jumps to the + * kernel _start address. We pass the modulep pointer in x0, as _start + * expects. We assume that the various cache flushing, invalidation, etc that + * linux did during or after copying the data down is sufficient, though we may + * need to be mindful of cache flushing if we run in EL2 (TBD). + * + * Note, if TRAMP_MEMMAP_SRC is non-zero, then we have to copy the Linux + * provided UEFI memory map. It's easier to do that here. In kboot we couldn't + * access the physical memory, and it's a chicken and egg problem later in the + * kernel. + */ + +#define TRAMP_ENTRY 0 +#define TRAMP_MODULEP 8 +#define TRAMP_MEMMAP_SRC 16 +#define TRAMP_MEMMAP_DST 24 +#define TRAMP_MEMMAP_LEN 32 +#define TRAMP_TOTAL 40 + + .text + .globl tramp +tramp: + adr x8, trampoline_data + ldr x10, [x8, #TRAMP_MEMMAP_SRC] + cmp x10, xzr + b.eq 9f + + /* + * Copy over the memory map into area we have reserved for it. Assume + * the copy is a multiple of 8, since we know table entries are made up + * of several 64-bit quantities. + */ + ldp x11, x12, [x8, #TRAMP_MEMMAP_DST] /* x12 = len */ +1: + ldr x13, [x10], #8 + str x13, [x11], #8 + subs x12, x12, #8 + b.hi 1b +9: + ldp x9, x0, [x8, #TRAMP_ENTRY] /* x0 = modulep */ + br x9 + + .p2align 4 +trampoline_data: + .space TRAMP_TOTAL +#define TMPSTACKSIZE 48 /* 16 bytes for args +8 for pushq/popfq + 24 spare */ + .space TMPSTACKSIZE +tramp_end: /* padding doubles as stack */ + + .data + .globl tramp_size +tramp_size: + .long tramp_end-tramp + .globl tramp_data_offset +tramp_data_offset: + .long trampoline_data-tramp + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/kboot/arch/amd64/Makefile.inc b/stand/kboot/kboot/arch/amd64/Makefile.inc new file mode 100644 index 000000000000..edb8a1de0bba --- /dev/null +++ b/stand/kboot/kboot/arch/amd64/Makefile.inc @@ -0,0 +1,3 @@ +SRCS+= amd64_tramp.S elf64_freebsd.c load_addr.c fdt_arch.c + +CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include diff --git a/stand/kboot/arch/amd64/ldscript.amd64 b/stand/kboot/kboot/arch/amd64/amd64.ldscript index bbfe47cd4ef5..f8ba7b05a55a 100644 --- a/stand/kboot/arch/amd64/ldscript.amd64 +++ b/stand/kboot/kboot/arch/amd64/amd64.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) @@ -35,17 +34,6 @@ SECTIONS *(COMMON) } . = ALIGN(4096); - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } - . = ALIGN(4096); __gp = .; .sdata : { *(.got.plt .got) diff --git a/stand/kboot/kboot/arch/amd64/amd64_tramp.S b/stand/kboot/kboot/arch/amd64/amd64_tramp.S new file mode 100644 index 000000000000..d3b2d5ecaf77 --- /dev/null +++ b/stand/kboot/kboot/arch/amd64/amd64_tramp.S @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 2022 Netflix, Inc + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This is the trampoline that starts the FreeBSD kernel. Since the Linux kernel + * calls this routine with no args, and has a different environment than the + * boot loader provides and that the kernel expects, this code is responsible + * for setting all that up and calling the normal kernel entry point. It's + * analogous to the "purgatory" code in the linux kernel. Details about these + * operations are contained in comments below. On amd64, the kernel starts all + * the APs so we don't have to worry about them here. + */ + +/* + * Keep in sync with elf64_freebsd.c. Kexec starts tramp w/o any parameters, so + * store them here. This is constructed to be a useful stack: + * + * struct trampoline_data { + * // %rsp points here on start and we pop the args off and then retq to 'entry' + * uint64_t memmap_src; // Linux-provided memory map PA + * uint64_t memmap_dst; // Module data copy PA + * uint64_t memmap_len; // Length to copy + * uint64_t pt4; // Page table address to pop + * uint64_t entry; // return address to jump to kernel + * uint32_t fill1; // 0 + * uint32_t modulep; // 4 module metadata + * uint32_t kernend; // 8 kernel end + * uint32_t fill2; // 12 + * }; + * + * loader.kboot will construct a stack that btext expects, which is arguments on + * the stack, not in registers, and these args are 32-bit not 64. The extra stuff + * is data the trampoline code consumes. + * + * Processor is already in long mode when we're called, paging is enabled and + * boot loader loads things such that: + * - kernel mapped at KERNBASE, aligned to 2MB, below 4GB, contiguous memory + * - %cr3 tells us our PA later in boot, so we install it before jumping + * to the kernel. + * - there is a 2M hole at KERNBASE (KERNSTART = KERNBASE + 2M) + * - kernel is mapped with 2M superpages + * - The kernel, modules and metadata is in first 4GB which is unity mapped + * - There's additional memory after loader provided data for early allocations + * + * Unlike coming directly from loader.efi, we don't support copying the staging + * area. We tell Linux to land the kernel in its final location with the needed + * alignment, etc. We copy the trampoline code to 1MB offset above KERNBASE + * since that memory is otherwise free and safely above the lower 1MB swamp we + * inherited from IBM PC, though this code makes no assumptions about where that + * might be. + * + * Thus, the trampoline just needs to set %rsp to that stack pop the systab + * patch value, pop the %cr3 value, set it and then retq to jump to the kernel + * with its stack args filled in. Since the handoff to this code used to be + * from 32-bit code, it uses the i386 calling conventions which put the + * arguments on the stack. The kernel's btext routine expects this setup. + */ + + .text + .globl tramp +tramp: + cli /* Make sure we don't get interrupted. */ + cld /* Copy in a sane direction */ + leaq stack_start(%rip), %rsp /* Setup our pre-filled-in stack */ + + /* + * If we have a EFI memory map, copy it over. These data are always + * on the stack, so we pop them all off before testing to skip the copy. + */ + popq %rsi /* memmap_src */ + popq %rdi /* memmap_dst */ + popq %rcx /* memmap_size */ + testq %rsi, %rsi + je no_map_copy + rep movsb /* Make the copy */ + +no_map_copy: + popq %rax /* Pop off the PT4 ptr for %cr3 */ + movq %rax, %cr3 /* set the page table */ + retq /* Return addr and args already on stack */ +/* + * The following is the stack for the above code. The stack will increase in + * address as things are popped off of it, so we start with the stack pointing + * to tramp_pt4. + */ + .p2align 3 /* Stack has to be 8 byte aligned */ +trampoline_data: +stack_start: /* %rsp at start. */ +tramp_memmap_src: + .quad 0 /* SRC PA (data from Linux) */ +tramp_memmap_dst: + .quad 0 /* DST PA (data to FreeBSD's metadata */ +tramp_memmap_len: + .quad 0 /* Length */ +tramp_pt4: .quad 0 /* New %cr3 value */ +tramp_entry: .quad 0 /* Entry to kernel (btext) */ + /* %rsp points here on entry to amd64 kernel's btext */ + .long 0 /* 0 filler, ignored (current loaders set to 0) */ +tramp_modulep: .long 0 /* 4 moudlep */ +tramp_kernend: .long 0 /* 8 kernend */ + .long 0 /* 12 alignment filler (also 0) */ +tramp_end: + + .data + .type tramp_size,@object + .globl tramp_size +tramp_size: + .long tramp_end-tramp + .size tramp_size, 4 + + .type tramp_data_offset,@object + .globl tramp_data_offset +tramp_data_offset: + .long trampoline_data-tramp + .size tramp_data_offset, 4 + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/kboot/arch/amd64/elf64_freebsd.c b/stand/kboot/kboot/arch/amd64/elf64_freebsd.c new file mode 100644 index 000000000000..576839e29734 --- /dev/null +++ b/stand/kboot/kboot/arch/amd64/elf64_freebsd.c @@ -0,0 +1,481 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define __ELF_WORD_SIZE 64 +#include <sys/param.h> +#include <sys/exec.h> +#include <sys/linker.h> +#include <string.h> +#include <machine/elf.h> +#include <stand.h> +#include <vm/vm.h> +#include <vm/pmap.h> + +#ifdef EFI +#include <efi.h> +#include <efilib.h> +#else +#include "host_syscall.h" +#endif + +#include "bootstrap.h" +#include "kboot.h" +#include "efi.h" + +#include "platform/acfreebsd.h" +#include "acconfig.h" +#define ACPI_SYSTEM_XFACE +#include "actypes.h" +#include "actbl.h" + +#ifdef EFI +#include "loader_efi.h" + +static EFI_GUID acpi_guid = ACPI_TABLE_GUID; +static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; +#else +/* Usually provided by loader_efi.h */ +extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, + bool exit_bs); +#endif + +#ifdef EFI +#define LOADER_PAGE_SIZE EFI_PAGE_SIZE +#else +#define LOADER_PAGE_SIZE PAGE_SIZE +#endif + +static int elf64_exec(struct preloaded_file *amp); +static int elf64_obj_exec(struct preloaded_file *amp); + +static struct file_format amd64_elf = { + .l_load = elf64_loadfile, + .l_exec = elf64_exec, +}; +static struct file_format amd64_elf_obj = { + .l_load = elf64_obj_loadfile, + .l_exec = elf64_obj_exec, +}; + +#ifdef EFI +extern struct file_format multiboot2; +extern struct file_format multiboot2_obj; +#endif + +struct file_format *file_formats[] = { +#ifdef EFI + &multiboot2, + &multiboot2_obj, +#endif + &amd64_elf, + &amd64_elf_obj, + NULL +}; + +#ifndef EFI +/* + * We create the stack that we want. We store any memory map table that we have + * top copy (the metadata has already been filled in). We pop these args off and + * copy if neeed be. Then, we have the address of the page tables we make on top + * (so we pop that off and set %cr3). We have the entry point to the kernel + * (which retq pops off) This leaves the stack that the btext wants: offset 4 is + * modulep and offset8 is kernend, with the filler bytes to keep this + * aligned. This also makes the trampoline very simple: pop some args, maybe copy + * pop the page table and then return into btext as defined in the kernel. + */ +struct trampoline_data { + uint64_t memmap_src; // Linux-provided memory map PA + uint64_t memmap_dst; // Module data copy PA + uint64_t memmap_len; // Length to copy + uint64_t pt4; // Page table address to pop + uint64_t entry; // return address to jump to kernel + uint32_t fill1; // 0 + uint32_t modulep; // 4 module metadata + uint32_t kernend; // 8 kernel end + uint32_t fill2; // 12 +}; +_Static_assert(sizeof(struct trampoline_data) == 56, "Bad size for trampoline data"); +#endif + +static pml4_entry_t *PT4; +static pdp_entry_t *PT3_l, *PT3_u; +static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; + +#ifdef EFI +static pdp_entry_t *PT3; +static pd_entry_t *PT2; + +static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, + uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry); +#endif + +extern uintptr_t tramp; +extern uint32_t tramp_size; +#ifndef EFI +extern uint32_t tramp_data_offset; +#endif + +/* + * There is an ELF kernel and one or more ELF modules loaded. + * We wish to start executing the kernel image, so make such + * preparations as are required, and do so. + */ +static int +elf64_exec(struct preloaded_file *fp) +{ + struct file_metadata *md; + Elf_Ehdr *ehdr; + vm_offset_t modulep, kernend; + int err, i; + char buf[24]; +#ifdef EFI + ACPI_TABLE_RSDP *rsdp = NULL; + int revision; + int copy_auto; + vm_offset_t trampstack, trampcode; +#else + vm_offset_t rsdp = 0; + void *trampcode; + int nseg; + void *kseg; + vm_offset_t trampolinebase; + uint64_t *trampoline; + struct trampoline_data *trampoline_data; + vm_offset_t staging; + int error; +#endif + +#ifdef EFI + copy_auto = copy_staging == COPY_STAGING_AUTO; + if (copy_auto) + copy_staging = fp->f_kernphys_relocatable ? + COPY_STAGING_DISABLE : COPY_STAGING_ENABLE; +#else + /* + * Figure out where to put it. + * + * Linux does not allow us to do kexec_load into any part of memory. Ask + * kboot_get_phys_load_segment to resolve the first available chunk of + * physical memory where loading is possible (staging). + * + * The kernel is loaded at the 'base' address in continguous physical + * pages (using 2MB super pages). The first such page is unused by the + * kernel and serves as a good place to put not only the trampoline, but + * the page table pages that the trampoline needs to setup the proper + * kernel starting environment. + */ + staging = trampolinebase = kboot_get_phys_load_segment(); + trampolinebase += 1ULL << 20; /* Copy trampoline to base + 1MB, kernel will wind up at 2MB */ + printf("Load address at %#jx\n", (uintmax_t)trampolinebase); + printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset); +#endif + + /* + * Report the RSDP to the kernel. While this can be found with + * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. + */ +#ifdef EFI + rsdp = efi_get_table(&acpi20_guid); + if (rsdp == NULL) { + rsdp = efi_get_table(&acpi_guid); + } +#else + rsdp = acpi_rsdp(); +#endif + if (rsdp != 0) { + sprintf(buf, "0x%016llx", (unsigned long long)rsdp); + setenv("acpi.rsdp", buf, 1); + } + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return (EFTYPE); + ehdr = (Elf_Ehdr *)&(md->md_data); + +#ifdef EFI + trampcode = copy_staging == COPY_STAGING_ENABLE ? + (vm_offset_t)G(1) : (vm_offset_t)G(4); + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, + (EFI_PHYSICAL_ADDRESS *)&trampcode); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline\n"); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (ENOMEM); + } + trampstack = trampcode + LOADER_PAGE_SIZE - 8; +#else + // XXX Question: why not just use malloc? + trampcode = host_getmem(LOADER_PAGE_SIZE); + if (trampcode == NULL) { + printf("Unable to allocate trampoline\n"); + return (ENOMEM); + } +#endif + bzero((void *)trampcode, LOADER_PAGE_SIZE); + bcopy((void *)&tramp, (void *)trampcode, tramp_size); + trampoline = (void *)trampcode; + +#ifdef EFI + if (copy_staging == COPY_STAGING_ENABLE) { + PT4 = (pml4_entry_t *)G(1); + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, + (EFI_PHYSICAL_ADDRESS *)&PT4); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline page table\n"); + BS->FreePages(trampcode, 1); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (ENOMEM); + } + bzero(PT4, 3 * LOADER_PAGE_SIZE); + PT3 = &PT4[512]; + PT2 = &PT3[512]; + + /* + * This is kinda brutal, but every single 1GB VM + * memory segment points to the same first 1GB of + * physical memory. But it is more than adequate. + */ + for (i = 0; i < NPTEPG; i++) { + /* + * Each slot of the L4 pages points to the + * same L3 page. + */ + PT4[i] = (pml4_entry_t)PT3; + PT4[i] |= PG_V | PG_RW; + + /* + * Each slot of the L3 pages points to the + * same L2 page. + */ + PT3[i] = (pdp_entry_t)PT2; + PT3[i] |= PG_V | PG_RW; + + /* + * The L2 page slots are mapped with 2MB pages for 1GB. + */ + PT2[i] = (pd_entry_t)i * M(2); + PT2[i] |= PG_V | PG_RW | PG_PS; + } + } else { + PT4 = (pml4_entry_t *)G(4); + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9, + (EFI_PHYSICAL_ADDRESS *)&PT4); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline page table\n"); + BS->FreePages(trampcode, 9); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (ENOMEM); + } + bzero(PT4, 9 * LOADER_PAGE_SIZE); + + PT3_l = &PT4[NPML4EPG * 1]; + PT3_u = &PT4[NPML4EPG * 2]; + PT2_l0 = &PT4[NPML4EPG * 3]; + PT2_l1 = &PT4[NPML4EPG * 4]; + PT2_l2 = &PT4[NPML4EPG * 5]; + PT2_l3 = &PT4[NPML4EPG * 6]; + PT2_u0 = &PT4[NPML4EPG * 7]; + PT2_u1 = &PT4[NPML4EPG * 8]; + + /* 1:1 mapping of lower 4G */ + PT4[0] = (pml4_entry_t)PT3_l | PG_V | PG_RW; + PT3_l[0] = (pdp_entry_t)PT2_l0 | PG_V | PG_RW; + PT3_l[1] = (pdp_entry_t)PT2_l1 | PG_V | PG_RW; + PT3_l[2] = (pdp_entry_t)PT2_l2 | PG_V | PG_RW; + PT3_l[3] = (pdp_entry_t)PT2_l3 | PG_V | PG_RW; + for (i = 0; i < 4 * NPDEPG; i++) { + PT2_l0[i] = ((pd_entry_t)i << PDRSHIFT) | PG_V | + PG_RW | PG_PS; + } + + /* mapping of kernel 2G below top */ + PT4[NPML4EPG - 1] = (pml4_entry_t)PT3_u | PG_V | PG_RW; + PT3_u[NPDPEPG - 2] = (pdp_entry_t)PT2_u0 | PG_V | PG_RW; + PT3_u[NPDPEPG - 1] = (pdp_entry_t)PT2_u1 | PG_V | PG_RW; + /* compat mapping of phys @0 */ + PT2_u0[0] = PG_PS | PG_V | PG_RW; + /* this maps past staging area */ + for (i = 1; i < 2 * NPDEPG; i++) { + PT2_u0[i] = ((pd_entry_t)staging + + ((pd_entry_t)i - 1) * NBPDR) | + PG_V | PG_RW | PG_PS; + } + } +#else + { + vm_offset_t pabase, pa_pt3_l, pa_pt3_u, pa_pt2_l0, pa_pt2_l1, pa_pt2_l2, pa_pt2_l3, pa_pt2_u0, pa_pt2_u1; + + /* We'll find a place for these later */ + PT4 = (pml4_entry_t *)host_getmem(9 * LOADER_PAGE_SIZE); + bzero(PT4, 9 * LOADER_PAGE_SIZE); + + PT3_l = &PT4[NPML4EPG * 1]; + PT3_u = &PT4[NPML4EPG * 2]; + PT2_l0 = &PT4[NPML4EPG * 3]; + PT2_l1 = &PT4[NPML4EPG * 4]; + PT2_l2 = &PT4[NPML4EPG * 5]; + PT2_l3 = &PT4[NPML4EPG * 6]; + PT2_u0 = &PT4[NPML4EPG * 7]; + PT2_u1 = &PT4[NPML4EPG * 8]; + + pabase = trampolinebase + LOADER_PAGE_SIZE; + pa_pt3_l = pabase + LOADER_PAGE_SIZE * 1; + pa_pt3_u = pabase + LOADER_PAGE_SIZE * 2; + pa_pt2_l0 = pabase + LOADER_PAGE_SIZE * 3; + pa_pt2_l1 = pabase + LOADER_PAGE_SIZE * 4; + pa_pt2_l2 = pabase + LOADER_PAGE_SIZE * 5; + pa_pt2_l3 = pabase + LOADER_PAGE_SIZE * 6; + pa_pt2_u0 = pabase + LOADER_PAGE_SIZE * 7; + pa_pt2_u1 = pabase + LOADER_PAGE_SIZE * 8; + + /* 1:1 mapping of lower 4G */ + PT4[0] = (pml4_entry_t)pa_pt3_l | PG_V | PG_RW; + PT3_l[0] = (pdp_entry_t)pa_pt2_l0 | PG_V | PG_RW; + PT3_l[1] = (pdp_entry_t)pa_pt2_l1 | PG_V | PG_RW; + PT3_l[2] = (pdp_entry_t)pa_pt2_l2 | PG_V | PG_RW; + PT3_l[3] = (pdp_entry_t)pa_pt2_l3 | PG_V | PG_RW; + for (i = 0; i < 4 * NPDEPG; i++) { /* we overflow PT2_l0 into _l1, etc */ + PT2_l0[i] = ((pd_entry_t)i << PDRSHIFT) | PG_V | + PG_RW | PG_PS; + } + + /* mapping of kernel 2G below top */ + PT4[NPML4EPG - 1] = (pml4_entry_t)pa_pt3_u | PG_V | PG_RW; + PT3_u[NPDPEPG - 2] = (pdp_entry_t)pa_pt2_u0 | PG_V | PG_RW; + PT3_u[NPDPEPG - 1] = (pdp_entry_t)pa_pt2_u1 | PG_V | PG_RW; + /* compat mapping of phys @0 */ + PT2_u0[0] = PG_PS | PG_V | PG_RW; + /* this maps past staging area */ + /* + * Kernel uses the KERNSTART (== KERNBASE + 2MB) entry to figure + * out where we loaded the kernel. This is PT2_u0[1] (since + * these map 2MB pages. So the PA that this maps has to be + * kboot's staging + 2MB. For UEFI we do 'i - 1' since we load + * the kernel right at staging (and assume the first address we + * load is 2MB in efi_copyin). However for kboot, staging + 1 * + * NBPDR == staging + 2MB which is where the kernel starts. Our + * trampoline need not be mapped into the kernel space since we + * execute PA==VA for that, and the trampoline can just go away + * once the kernel is called. + * + * Staging should likely be as low as possible, though, because + * all the 'early' allocations are at kernend (which the kernel + * calls physfree). + */ + for (i = 1; i < 2 * NPDEPG; i++) { /* we overflow PT2_u0 into _u1 */ + PT2_u0[i] = ((pd_entry_t)staging + + ((pd_entry_t)i) * NBPDR) | + PG_V | PG_RW | PG_PS; + if (i < 10) printf("Mapping %d to %#lx staging %#lx\n", i, PT2_u0[i], staging); + } + } +#endif + +#ifdef EFI + printf("staging %#lx (%scopying) tramp %p PT4 %p\n", + staging, copy_staging == COPY_STAGING_ENABLE ? "" : "not ", + trampoline, PT4); +#else + printf("staging %#lx tramp %p PT4 %p\n", staging, (void *)trampolinebase, + (void *)trampolinebase + LOADER_PAGE_SIZE); +#endif + printf("Start @ 0x%lx ...\n", ehdr->e_entry); + +#ifdef EFI + efi_time_fini(); +#endif + err = bi_load(fp->f_args, &modulep, &kernend, true); + if (err != 0) { +#ifdef EFI + efi_time_init(); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; +#endif + return (err); + } + + dev_cleanup(); + +#ifdef EFI + trampoline(trampstack, copy_staging == COPY_STAGING_ENABLE ? + efi_copy_finish : efi_copy_finish_nop, kernend, modulep, + PT4, ehdr->e_entry); +#else + trampoline_data = (void *)trampoline + tramp_data_offset; + trampoline_data->entry = ehdr->e_entry; /* VA since we start MMU with KERNBASE, etc */ + if (efi_map_phys_src != 0) { + md = file_findmetadata(fp, MODINFOMD_EFI_MAP); + if (md == NULL || md->md_addr == 0) { + printf("Need to copy EFI MAP, but EFI MAP not found. %p\n", md); + } else { + printf("Metadata EFI map loaded at VA %lx\n", md->md_addr); + efi_map_phys_dst = md->md_addr + staging + /* md_addr is taging relative */ + roundup2(sizeof(struct efi_map_header), 16); /* Skip header */ + trampoline_data->memmap_src = efi_map_phys_src; + trampoline_data->memmap_dst = efi_map_phys_dst; + trampoline_data->memmap_len = efi_map_size - roundup2(sizeof(struct efi_map_header), 16); + printf("Copying UEFI Memory Map data from %#lx to %#lx %ld bytes\n", + trampoline_data->memmap_src, + trampoline_data->memmap_dst, + trampoline_data->memmap_len); + } + } + /* + * So we compute the VA of the module data by modulep + KERNBASE.... + * need to make sure that that address is mapped right. We calculate + * the start of available memory to allocate via kernend (which is + * calculated with a phyaddr of "kernend + PA(PT_u0[1])"), so we better + * make sure we're not overwriting the last 2MB of the kernel :). + */ + trampoline_data->pt4 = trampolinebase + LOADER_PAGE_SIZE; + trampoline_data->modulep = modulep; /* Offset from KERNBASE */ + trampoline_data->kernend = kernend; /* Offset from the load address */ + trampoline_data->fill1 = trampoline_data->fill2 = 0; + printf("Modulep = %lx kernend %lx\n", modulep, kernend); + /* NOTE: when copyting in, it's relative to the start of our 'area' not an abs addr */ + /* Copy the trampoline to the ksegs */ + archsw.arch_copyin((void *)trampcode, trampolinebase - staging, tramp_size); + /* Copy the page table to the ksegs */ + archsw.arch_copyin(PT4, trampoline_data->pt4 - staging, 9 * LOADER_PAGE_SIZE); + + kboot_kseg_get(&nseg, &kseg); + error = host_kexec_load(trampolinebase, nseg, kseg, HOST_KEXEC_ARCH_X86_64); + if (error != 0) + panic("kexec_load returned error: %d", error); + host_reboot(HOST_REBOOT_MAGIC1, HOST_REBOOT_MAGIC2, HOST_REBOOT_CMD_KEXEC, 0); +#endif + + panic("exec returned"); +} + +static int +elf64_obj_exec(struct preloaded_file *fp) +{ + + return (EFTYPE); +} diff --git a/stand/kboot/host_syscall.h b/stand/kboot/kboot/arch/amd64/fdt_arch.c index f6f22a736d53..eefb76b1f92c 100644 --- a/stand/kboot/host_syscall.h +++ b/stand/kboot/kboot/arch/amd64/fdt_arch.c @@ -1,6 +1,5 @@ /*- - * Copyright (C) 2014 Nathan Whitehorn - * All rights reserved. + * Copyright (c) 2022 Netflix, Inc * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,41 +20,13 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ -#ifndef _HOST_SYSCALL_H -#define _HOST_SYSCALL_H - -#include <stand.h> - -long host_syscall(int number, ...); - -ssize_t host_read(int fd, void *buf, size_t nbyte); -ssize_t host_write(int fd, const void *buf, size_t nbyte); -int host_open(const char *path, int flags, int mode); -ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence); -int host_close(int fd); -void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off); -#define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x22 /* ANON */, -1, 0); -struct old_utsname { - char sysname[65]; - char nodename[65]; - char release[65]; - char version[65]; - char machine[65]; -}; -int host_uname(struct old_utsname *); -struct host_timeval { - time_t tv_sec; - long tv_usec; -}; -int host_gettimeofday(struct host_timeval *a, void *b); -int host_select(int nfds, long *readfds, long *writefds, long *exceptfds, - struct host_timeval *timeout); -int kexec_load(uint32_t start, int nsegs, uint32_t segs); -int host_reboot(int, int, int, uintptr_t); -int host_getdents(int fd, void *dirp, int count); +#include <sys/types.h> +#include "kboot.h" -#endif +void +fdt_arch_fixups(void *fdtp) +{ + /* amd64 doesn't pass in a FDT, so nothing to fix */ +} diff --git a/stand/kboot/kboot/arch/amd64/load_addr.c b/stand/kboot/kboot/arch/amd64/load_addr.c new file mode 100644 index 000000000000..8f4414d32342 --- /dev/null +++ b/stand/kboot/kboot/arch/amd64/load_addr.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2022 Netflix, Inc + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <machine/pc/bios.h> +#include <machine/metadata.h> + +#include "stand.h" +#include "host_syscall.h" +#include "efi.h" +#include "kboot.h" +#include "bootstrap.h" + +/* + * Abbreviated x86 Linux struct boot_param for the so-called zero-page. + * We have to use this to get systab and memmap since neither of those + * are exposed in a sane way. We only define what we need and pad for + * everything else to minimize cross-coupling. + * + * Transcribed in FreeBSD-ese from Linux's asm/bootparam.h for x86 as of + * 6.15, but these details haven't changed in a long time. + */ + +struct linux_efi_info { + uint32_t efi_loader_signature; /* 0x00 */ + uint32_t efi_systab; /* 0x04 */ + uint32_t efi_memdesc_size; /* 0x08 */ + uint32_t efi_memdesc_version; /* 0x0c */ + uint32_t efi_memmap; /* 0x10 */ + uint32_t efi_memmap_size; /* 0x14 */ + uint32_t efi_systab_hi; /* 0x18 */ + uint32_t efi_memmap_hi; /* 0x1c */ +} __packed; + +struct linux_boot_params { + uint8_t _pad1[0x1c0]; /* 0x000 */ + struct linux_efi_info efi_info; /* 0x1c0 */ + uint8_t _pad2[0x1000 - 0x1c0 - sizeof(struct linux_efi_info)]; /* 0x1e0 */ +} __packed; /* Total size 4k, the page size on x86 */ + +bool +enumerate_memory_arch(void) +{ + struct linux_boot_params bp; + + /* + * Sadly, there's no properly exported data for the EFI memory map nor + * the system table. systab is passed in from the original boot loader. + * memmap is obtained from boot time services (which are long gone) and + * then modified and passed to SetVirtualAddressMap. Even though the + * latter is in runtime services, it can only be called once and Linux + * has already called it. So unless we can dig all this out from the + * Linux kernel, there's no other wy to get it. A proper way would be to + * publish these in /sys/firmware/efi, but that's not done yet. We can + * only get the runtime subset and can't get systbl at all from today's + * (6.15) Linux kernel. Linux's pandora boot loader will copy this same + * information when it calls the new kernel, but since we don't use the + * bzImage kexec vector, we have to harvest it here. + */ + if (data_from_kernel("boot_params", &bp, sizeof(bp))) { + uint64_t systbl, memmap; + + systbl = (uint64_t)bp.efi_info.efi_systab_hi << 32 | + bp.efi_info.efi_systab; + memmap = (uint64_t)bp.efi_info.efi_memmap_hi << 32 | + bp.efi_info.efi_memmap; + + efi_set_systbl(systbl); + efi_read_from_pa(memmap, bp.efi_info.efi_memmap_size, + bp.efi_info.efi_memdesc_size, bp.efi_info.efi_memdesc_version); + printf("UEFI SYSTAB PA: %#lx\n", systbl); + printf("UEFI MMAP: Ver %d Ent Size %d Tot Size %d PA %#lx\n", + bp.efi_info.efi_memdesc_version, bp.efi_info.efi_memdesc_size, + bp.efi_info.efi_memmap_size, memmap); + } + /* + * So, we can't use the EFI map for this, so we have to fall back to + * the proc iomem stuff to at least get started... + */ + if (!populate_avail_from_iomem()) { + printf("Populate from avail also failed.\n"); + return (false); + } else { + printf("Populate worked...\n"); + } + print_avail(); + return (true); +} + +/* XXX refactor with aarch64 */ +uint64_t +kboot_get_phys_load_segment(void) +{ +#define HOLE_SIZE (64ul << 20) +#define KERN_ALIGN (2ul << 20) + static uint64_t s = 0; + + if (s != 0) + return (s); + + print_avail(); + s = first_avail(KERN_ALIGN, HOLE_SIZE, SYSTEM_RAM); + printf("KBOOT GET PHYS Using %#llx\n", (long long)s); + if (s != 0) + return (s); + s = 0x40000000 | 0x4200000; /* should never get here */ + /* XXX PANIC? XXX */ + printf("Falling back to the crazy address %#lx which works in qemu\n", s); + return (s); +} + +void +bi_loadsmap(struct preloaded_file *kfp) +{ + efi_bi_loadsmap(kfp); +} diff --git a/stand/kboot/arch/amd64/multiboot2.h b/stand/kboot/kboot/arch/amd64/multiboot2.h index bf673da66c2c..bf673da66c2c 100644 --- a/stand/kboot/arch/amd64/multiboot2.h +++ b/stand/kboot/kboot/arch/amd64/multiboot2.h diff --git a/stand/kboot/kboot/arch/powerpc64/Makefile.inc b/stand/kboot/kboot/arch/powerpc64/Makefile.inc new file mode 100644 index 000000000000..11a67a93d9e0 --- /dev/null +++ b/stand/kboot/kboot/arch/powerpc64/Makefile.inc @@ -0,0 +1,5 @@ +CFLAGS+= -mcpu=powerpc64 + +SRCS+= ppc64_elf_freebsd.c kerneltramp.S load_addr.c fdt_arch.c + +MK_PIE= no diff --git a/stand/kboot/kbootfdt.c b/stand/kboot/kboot/arch/powerpc64/fdt_arch.c index 14bc94326fe6..dc5f0fbd8fb6 100644 --- a/stand/kboot/kbootfdt.c +++ b/stand/kboot/kboot/arch/powerpc64/fdt_arch.c @@ -23,83 +23,15 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <fdt_platform.h> #include <libfdt.h> -#include "bootstrap.h" -#include "host_syscall.h" - -static void -add_node_to_fdt(void *buffer, const char *path, int fdt_offset) -{ - int child_offset, fd, pfd, error, dentsize; - char subpath[512]; - void *propbuf; - ssize_t proplen; - - struct host_dent { - unsigned long d_fileno; - unsigned long d_off; - unsigned short d_reclen; - char d_name[]; - /* uint8_t d_type; */ - }; - char dents[2048]; - struct host_dent *dent; - int d_type; - - fd = host_open(path, O_RDONLY, 0); - while (1) { - dentsize = host_getdents(fd, dents, sizeof(dents)); - if (dentsize <= 0) - break; - for (dent = (struct host_dent *)dents; - (char *)dent < dents + dentsize; - dent = (struct host_dent *)((void *)dent + dent->d_reclen)) { - sprintf(subpath, "%s/%s", path, dent->d_name); - if (strcmp(dent->d_name, ".") == 0 || - strcmp(dent->d_name, "..") == 0) - continue; - d_type = *((char *)(dent) + dent->d_reclen - 1); - if (d_type == 4 /* DT_DIR */) { - child_offset = fdt_add_subnode(buffer, fdt_offset, - dent->d_name); - if (child_offset < 0) { - printf("Error %d adding node %s/%s, skipping\n", - child_offset, path, dent->d_name); - continue; - } - - add_node_to_fdt(buffer, subpath, child_offset); - } else { - propbuf = malloc(1024); - proplen = 0; - pfd = host_open(subpath, O_RDONLY, 0); - if (pfd > 0) { - proplen = host_read(pfd, propbuf, 1024); - host_close(pfd); - } - error = fdt_setprop(buffer, fdt_offset, dent->d_name, - propbuf, proplen); - free(propbuf); - if (error) - printf("Error %d adding property %s to " - "node %d\n", error, dent->d_name, - fdt_offset); - } - } - } - - host_close(fd); -} +#include "kboot.h" /* Fix up wrong values added to the device tree by prom_init() in Linux */ -static void -fdt_linux_fixups(void *fdtp) +void +fdt_arch_fixups(void *fdtp) { int offset, len; const void *prop; @@ -155,36 +87,3 @@ fdt_linux_fixups(void *fdtp) } } } - -int -fdt_platform_load_dtb(void) -{ - void *buffer; - size_t buflen = 409600; - - buffer = malloc(buflen); - fdt_create_empty_tree(buffer, buflen); - add_node_to_fdt(buffer, "/proc/device-tree", - fdt_path_offset(buffer, "/")); - fdt_linux_fixups(buffer); - - fdt_pack(buffer); - - fdt_load_dtb_addr(buffer); - free(buffer); - - return (0); -} - -void -fdt_platform_load_overlays(void) -{ - -} - -void -fdt_platform_fixups(void) -{ - -} - diff --git a/stand/kboot/arch/powerpc64/kerneltramp.S b/stand/kboot/kboot/arch/powerpc64/kerneltramp.S index 15fdfc26bd90..e9678dc02e72 100644 --- a/stand/kboot/arch/powerpc64/kerneltramp.S +++ b/stand/kboot/kboot/arch/powerpc64/kerneltramp.S @@ -9,7 +9,6 @@ * to the absolute address 0x60. Here we implement a loop waiting on the release * of a lock by the kernel at 0x40. * - * $FreeBSD$ */ #include <machine/asm.h> @@ -100,3 +99,5 @@ endkerneltramp: .data CNAME(szkerneltramp): .long endkerneltramp - CNAME(kerneltramp) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/kboot/arch/powerpc64/load_addr.c b/stand/kboot/kboot/arch/powerpc64/load_addr.c new file mode 100644 index 000000000000..71662796f284 --- /dev/null +++ b/stand/kboot/kboot/arch/powerpc64/load_addr.c @@ -0,0 +1,228 @@ +/*- + * Copyright (C) 2010-2014 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/endian.h> + +#include "stand.h" +#include "host_syscall.h" +#include "kboot.h" + +struct region_desc { + uint64_t start; + uint64_t end; +}; + +/* + * Find a good place to load the kernel, subject to the PowerPC's constraints + * + * This excludes ranges that are marked as reserved. + * And 0..end of kernel + * + * It then tries to find the memory exposed from the DTB, which it assumes is one + * contiguous range. It adds everything not in that list to the excluded list. + * + * Sort, dedup, and it finds the first region and uses that as the load_segment + * and returns that. All addresses are offset by this amount. + */ +uint64_t +kboot_get_phys_load_segment(void) +{ + int fd; + uint64_t entry[2]; + static uint64_t load_segment = ~(0UL); + uint64_t val_64; + uint32_t val_32; + struct region_desc rsvd_reg[32]; + int rsvd_reg_cnt = 0; + int ret, a, b; + uint64_t start, end; + + if (load_segment == ~(0UL)) { + + /* Default load address is 0x00000000 */ + load_segment = 0UL; + + /* Read reserved regions */ + fd = host_open("/proc/device-tree/reserved-ranges", O_RDONLY, 0); + if (fd >= 0) { + while (host_read(fd, &entry[0], sizeof(entry)) == sizeof(entry)) { + rsvd_reg[rsvd_reg_cnt].start = be64toh(entry[0]); + rsvd_reg[rsvd_reg_cnt].end = + be64toh(entry[1]) + rsvd_reg[rsvd_reg_cnt].start - 1; + rsvd_reg_cnt++; + } + host_close(fd); + } + /* Read where the kernel ends */ + fd = host_open("/proc/device-tree/chosen/linux,kernel-end", O_RDONLY, 0); + if (fd >= 0) { + ret = host_read(fd, &val_64, sizeof(val_64)); + + if (ret == sizeof(uint64_t)) { + rsvd_reg[rsvd_reg_cnt].start = 0; + rsvd_reg[rsvd_reg_cnt].end = be64toh(val_64) - 1; + } else { + memcpy(&val_32, &val_64, sizeof(val_32)); + rsvd_reg[rsvd_reg_cnt].start = 0; + rsvd_reg[rsvd_reg_cnt].end = be32toh(val_32) - 1; + } + rsvd_reg_cnt++; + + host_close(fd); + } + /* Read memory size (SOCKET0 only) */ + fd = host_open("/proc/device-tree/memory@0/reg", O_RDONLY, 0); + if (fd < 0) + fd = host_open("/proc/device-tree/memory/reg", O_RDONLY, 0); + if (fd >= 0) { + ret = host_read(fd, &entry, sizeof(entry)); + + /* Memory range in start:length format */ + entry[0] = be64toh(entry[0]); + entry[1] = be64toh(entry[1]); + + /* Reserve everything what is before start */ + if (entry[0] != 0) { + rsvd_reg[rsvd_reg_cnt].start = 0; + rsvd_reg[rsvd_reg_cnt].end = entry[0] - 1; + rsvd_reg_cnt++; + } + /* Reserve everything what is after end */ + if (entry[1] != 0xffffffffffffffffUL) { + rsvd_reg[rsvd_reg_cnt].start = entry[0] + entry[1]; + rsvd_reg[rsvd_reg_cnt].end = 0xffffffffffffffffUL; + rsvd_reg_cnt++; + } + + host_close(fd); + } + + /* Sort entries in ascending order (bubble) */ + for (a = rsvd_reg_cnt - 1; a > 0; a--) { + for (b = 0; b < a; b++) { + if (rsvd_reg[b].start > rsvd_reg[b + 1].start) { + struct region_desc tmp; + tmp = rsvd_reg[b]; + rsvd_reg[b] = rsvd_reg[b + 1]; + rsvd_reg[b + 1] = tmp; + } + } + } + + /* Join overlapping/adjacent regions */ + for (a = 0; a < rsvd_reg_cnt - 1; ) { + + if ((rsvd_reg[a + 1].start >= rsvd_reg[a].start) && + ((rsvd_reg[a + 1].start - 1) <= rsvd_reg[a].end)) { + /* We have overlapping/adjacent regions! */ + rsvd_reg[a].end = + MAX(rsvd_reg[a].end, rsvd_reg[a + a].end); + + for (b = a + 1; b < rsvd_reg_cnt - 1; b++) + rsvd_reg[b] = rsvd_reg[b + 1]; + rsvd_reg_cnt--; + } else + a++; + } + + /* Find the first free region */ + if (rsvd_reg_cnt > 0) { + start = 0; + end = rsvd_reg[0].start; + for (a = 0; a < rsvd_reg_cnt - 1; a++) { + if ((start >= rsvd_reg[a].start) && + (start <= rsvd_reg[a].end)) { + start = rsvd_reg[a].end + 1; + end = rsvd_reg[a + 1].start; + } else + break; + } + + if (start != end) { + uint64_t align = 64UL*1024UL*1024UL; + + /* Align both to 64MB boundary */ + start = (start + align - 1UL) & ~(align - 1UL); + end = ((end + 1UL) & ~(align - 1UL)) - 1UL; + + if (start < end) + load_segment = start; + } + } + } + + return (load_segment); +} + +#if 0 +/* + * XXX this appears to be unused, but may have been for selecting the allowed + * kernels ABIs. It's been unused since the first commit, which suggests an + * error in bringing this into the tree. + */ +uint8_t +kboot_get_kernel_machine_bits(void) +{ + static uint8_t bits = 0; + struct old_utsname utsname; + int ret; + + if (bits == 0) { + /* Default is 32-bit kernel */ + bits = 32; + + /* Try to get system type */ + memset(&utsname, 0, sizeof(utsname)); + ret = host_uname(&utsname); + if (ret == 0) { + if (strcmp(utsname.machine, "ppc64") == 0) + bits = 64; + else if (strcmp(utsname.machine, "ppc64le") == 0) + bits = 64; + } + } + + return (bits); +} +#endif + +/* Need to transition from current hacky FDT way to this code */ +bool enumerate_memory_arch(void) +{ + /* + * For now, we dig it out of the FDT, plus we need to pass all data into + * the kernel via the (adjusted) FDT we find. + */ + setenv("usefdt", "1", 1); + + return true; +} + +void +bi_loadsmap(struct preloaded_file *kfp) +{ + /* passed in via the DTB */ +} diff --git a/stand/powerpc/ofw/ldscript.powerpc b/stand/kboot/kboot/arch/powerpc64/powerpc64.ldscript index 5fa27eaf6a13..f9fcc37f02d8 100644 --- a/stand/powerpc/ofw/ldscript.powerpc +++ b/stand/kboot/kboot/arch/powerpc64/powerpc64.ldscript @@ -1,19 +1,13 @@ -/* $FreeBSD$ */ - OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", "elf32-powerpc-freebsd") OUTPUT_ARCH(powerpc:common) ENTRY(_start) SEARCH_DIR(/usr/lib); PROVIDE (__stack = 0); -PHDRS -{ - text PT_LOAD; -} SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0x02c00000 + SIZEOF_HEADERS; + . = 0x100000; .interp : { *(.interp) } :text .hash : { *(.hash) } .dynsym : { *(.dynsym) } @@ -57,6 +51,7 @@ SECTIONS .sbss2 : { *(.sbss2) } /* Adjust the address for the data segment to the next page up. */ . = ((. + 0x1000) & ~(0x1000 - 1)); + .data.rel.ro : { *(.data.rel.ro*) } .data : { *(.data) @@ -107,6 +102,7 @@ SECTIONS *(.bss) *(COMMON) } + . = ALIGN(4096); _end = . ; PROVIDE (end = .); /* Stabs debugging sections. */ @@ -139,4 +135,3 @@ SECTIONS .debug_varnames 0 : { *(.debug_varnames) } /* These must appear regardless of . */ } - diff --git a/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c b/stand/kboot/kboot/arch/powerpc64/ppc64_elf_freebsd.c index adbdc7fca915..ae398e357df2 100644 --- a/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c +++ b/stand/kboot/kboot/arch/powerpc64/ppc64_elf_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> @@ -39,7 +36,10 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include "bootstrap.h" +#include "syscall_nr.h" #include "host_syscall.h" +#include "modinfo.h" +#include "kboot.h" extern char end[]; extern void *kerneltramp; @@ -54,8 +54,6 @@ struct trampoline_data { uint32_t mdp_size; }; -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); - int ppc64_elf_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) @@ -91,21 +89,18 @@ ppc64_elf_exec(struct preloaded_file *fp) /* * Figure out where to put it. * - * Linux does not allow to do kexec_load into - * any part of memory. Ask arch_loadaddr to - * resolve the first available chunk of physical - * memory where loading is possible (load_addr). + * Linux does not allow us to do kexec_load into any part of memory. Ask + * kboot_get_phys_load_segment to resolve the first available chunk of + * physical memory where loading is possible (load_addr). * - * Memory organization is shown below. - * It is assumed, that text segment offset of - * kernel ELF (KERNPHYSADDR) is non-zero, - * which is true for PPC/PPC64 architectures, - * where default is 0x100000. + * Memory organization is shown below. It is assumed, that text segment + * offset of kernel ELF (KERNPHYSADDR) is non-zero, which is true for + * PPC/PPC64 architectures, where default is 0x100000. * * load_addr: trampoline code * load_addr + KERNPHYSADDR: kernel text segment */ - trampolinebase = archsw.arch_loadaddr(LOAD_RAW, NULL, 0); + trampolinebase = kboot_get_phys_load_segment(); printf("Load address at %#jx\n", (uintmax_t)trampolinebase); printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset); @@ -148,16 +143,14 @@ ppc64_elf_exec(struct preloaded_file *fp) archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp); free(trampoline); - if (archsw.arch_kexec_kseg_get == NULL) - panic("architecture did not provide kexec segment mapping"); - archsw.arch_kexec_kseg_get(&nseg, &kseg); + kboot_kseg_get(&nseg, &kseg); - error = kexec_load(trampolinebase, nseg, (uintptr_t)kseg); + error = host_kexec_load(trampolinebase, nseg, kseg, HOST_KEXEC_ARCH_PPC64); if (error != 0) panic("kexec_load returned error: %d", error); - error = host_reboot(0xfee1dead, 672274793, - 0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, (uintptr_t)NULL); + error = host_reboot(HOST_REBOOT_MAGIC1, HOST_REBOOT_MAGIC2, HOST_REBOOT_CMD_KEXEC, + (uintptr_t)NULL); if (error != 0) panic("reboot returned error: %d", error); @@ -169,3 +162,13 @@ struct file_format ppc_elf64 = ppc64_elf_loadfile, ppc64_elf_exec }; + +/* + * Sort formats so that those that can detect based on arguments rather than + * reading the file first. + */ + +struct file_format *file_formats[] = { + &ppc_elf64, + NULL +}; diff --git a/stand/kboot/arch/amd64/conf.c b/stand/kboot/kboot/conf.c index b840d008a347..5d384c5270e6 100644 --- a/stand/kboot/arch/amd64/conf.c +++ b/stand/kboot/kboot/conf.c @@ -24,17 +24,18 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" #if defined(LOADER_NET_SUPPORT) #include "dev_net.h" #endif +#ifdef LOADER_ZFS_SUPPORT +#include "libzfs.h" +#endif extern struct devsw hostdisk; +extern struct devsw host_dev; /* * We could use linker sets for some or all of these, but @@ -53,9 +54,15 @@ struct devsw *devsw[] = { #if defined(LOADER_NET_SUPPORT) &netdev, #endif + &host_dev, +#if defined(LOADER_ZFS_SUPPORT) + &zfs_dev, /* Must be last */ +#endif NULL }; +extern struct fs_ops hostfs_fsops; + struct fs_ops *file_system[] = { #if defined(LOADER_UFS_SUPPORT) &ufs_fsops, @@ -78,7 +85,13 @@ struct fs_ops *file_system[] = { #if defined(LOADER_BZIP2_SUPPORT) &bzipfs_fsops, #endif +#if defined(LOADER_MSDOS_SUPPORT) &dosfs_fsops, +#endif +#if defined(LOADER_ZFS_SUPPORT) + &zfs_fsops, +#endif + &hostfs_fsops, NULL }; diff --git a/stand/kboot/hostcons.c b/stand/kboot/kboot/hostcons.c index 31dceb019973..9c09a2721891 100644 --- a/stand/kboot/hostcons.c +++ b/stand/kboot/kboot/hostcons.c @@ -23,30 +23,29 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include "bootstrap.h" #include "host_syscall.h" +#include "termios.h" static void hostcons_probe(struct console *cp); static int hostcons_init(int arg); static void hostcons_putchar(int c); -static int hostcons_getchar(); -static int hostcons_poll(); +static int hostcons_getchar(void); +static int hostcons_poll(void); struct console hostconsole = { - "host", - "Host Console", - 0, - hostcons_probe, - hostcons_init, - hostcons_putchar, - hostcons_getchar, - hostcons_poll, + .c_name = "host", + .c_desc = "Host Console", + .c_probe = hostcons_probe, + .c_init = hostcons_init, + .c_out = hostcons_putchar, + .c_in = hostcons_getchar, + .c_ready = hostcons_poll, }; +static struct host_termios old_settings; + static void hostcons_probe(struct console *cp) { @@ -57,9 +56,12 @@ hostcons_probe(struct console *cp) static int hostcons_init(int arg) { + struct host_termios new_settings; - /* XXX: set nonblocking */ - /* tcsetattr(~(ICANON | ECHO)) */ + host_tcgetattr(0, &old_settings); + new_settings = old_settings; + host_cfmakeraw(&new_settings); + host_tcsetattr(0, HOST_TCSANOW, &new_settings); return (0); } @@ -73,7 +75,7 @@ hostcons_putchar(int c) } static int -hostcons_getchar() +hostcons_getchar(void) { uint8_t ch; int rv; @@ -85,7 +87,7 @@ hostcons_getchar() } static int -hostcons_poll() +hostcons_poll(void) { struct host_timeval tv = {0,0}; long fds = 1 << 0; @@ -94,4 +96,3 @@ hostcons_poll() ret = host_select(32, &fds, NULL, NULL, &tv); return (ret > 0); } - diff --git a/stand/kboot/kboot/hostdisk.c b/stand/kboot/kboot/hostdisk.c new file mode 100644 index 000000000000..a9117d4c1c9d --- /dev/null +++ b/stand/kboot/kboot/hostdisk.c @@ -0,0 +1,622 @@ +/*- + * Copyright (C) 2014 Nathan Whitehorn + * All rights reserved. + * Copyright 2022 Netflix, Inc + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/disk.h> +#include <stdarg.h> +#include <paths.h> +#include "host_syscall.h" +#include "kboot.h" +#include "bootstrap.h" +#ifdef LOADER_ZFS_SUPPORT +#include "libzfs.h" +#include <sys/zfs_bootenv.h> +#endif + +static int hostdisk_init(void); +static int hostdisk_strategy(void *devdata, int flag, daddr_t dblk, + size_t size, char *buf, size_t *rsize); +static int hostdisk_open(struct open_file *f, ...); +static int hostdisk_close(struct open_file *f); +static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data); +static int hostdisk_print(int verbose); +static char *hostdisk_fmtdev(struct devdesc *vdev); +static bool hostdisk_match(struct devsw *devsw, const char *devspec); +static int hostdisk_parsedev(struct devdesc **idev, const char *devspec, const char **path); + +struct devsw hostdisk = { + .dv_name = "/dev", + .dv_type = DEVT_HOSTDISK, + .dv_init = hostdisk_init, + .dv_strategy = hostdisk_strategy, + .dv_open = hostdisk_open, + .dv_close = hostdisk_close, + .dv_ioctl = hostdisk_ioctl, + .dv_print = hostdisk_print, + .dv_cleanup = nullsys, + .dv_fmtdev = hostdisk_fmtdev, + .dv_match = hostdisk_match, + .dv_parsedev = hostdisk_parsedev, +}; + +/* + * We need to walk through the /sys/block directories looking for + * block devices that we can use. + */ +#define SYSBLK "/sys/block" + +#define HOSTDISK_MIN_SIZE (16ul << 20) /* 16MB */ + +typedef STAILQ_HEAD(, hdinfo) hdinfo_list_t; +typedef struct hdinfo { + STAILQ_ENTRY(hdinfo) hd_link; /* link in device list */ + hdinfo_list_t hd_children; + struct hdinfo *hd_parent; + const char *hd_dev; + uint64_t hd_size; /* In bytes */ + uint64_t hd_sectors; + uint64_t hd_sectorsize; + int hd_flags; +#define HDF_HAS_ZPOOL 1 /* We found a zpool here and uuid valid */ + uint64_t hd_zfs_uuid; +} hdinfo_t; + +#define dev2hd(d) ((hdinfo_t *)d->d_opendata) +#define hd_name(hd) ((hd->hd_dev + 5)) + +static hdinfo_list_t hdinfo = STAILQ_HEAD_INITIALIZER(hdinfo); + +typedef bool fef_cb_t(struct host_dirent64 *, void *); +#define FEF_RECURSIVE 1 + +static bool +foreach_file(const char *dir, fef_cb_t cb, void *argp, u_int flags) +{ + char dents[2048]; + int fd, dentsize; + struct host_dirent64 *dent; + + fd = host_open(dir, O_RDONLY, 0); + if (fd < 0) { + printf("Can't open %s\n", dir);/* XXX */ + return (false); + } + while (1) { + dentsize = host_getdents64(fd, dents, sizeof(dents)); + if (dentsize <= 0) + break; + for (dent = (struct host_dirent64 *)dents; + (char *)dent < dents + dentsize; + dent = (struct host_dirent64 *)((void *)dent + dent->d_reclen)) { + if (!cb(dent, argp)) + break; + } + } + host_close(fd); + return (true); +} + +static void +hostdisk_add_part(hdinfo_t *hd, const char *drv, uint64_t secs) +{ + hdinfo_t *md; + char *dev; + + printf("hd %s adding %s %ju\n", hd->hd_dev, drv, (uintmax_t)secs); + if ((md = calloc(1, sizeof(*md))) == NULL) + return; + if (asprintf(&dev, "/dev/%s", drv) == -1) { + printf("hostdisk: no memory\n"); + free(md); + return; + } + md->hd_dev = dev; + md->hd_sectors = secs; + md->hd_sectorsize = hd->hd_sectorsize; + md->hd_size = md->hd_sectors * md->hd_sectorsize; + md->hd_parent = hd; + STAILQ_INSERT_TAIL(&hd->hd_children, md, hd_link); +} + +static bool +hostdisk_one_part(struct host_dirent64 *dent, void *argp) +{ + hdinfo_t *hd = argp; + char szfn[1024]; + uint64_t sz; + + /* Need to skip /dev/ at start of hd_name */ + if (strncmp(dent->d_name, hd_name(hd), strlen(hd_name(hd))) != 0) + return (true); + /* Find out how big this is -- no size not a disk */ + snprintf(szfn, sizeof(szfn), "%s/%s/%s/size", SYSBLK, + hd_name(hd), dent->d_name); + if (!file2u64(szfn, &sz)) + return true; + hostdisk_add_part(hd, dent->d_name, sz); + return true; +} + +static void +hostdisk_add_parts(hdinfo_t *hd) +{ + char fn[1024]; + + snprintf(fn, sizeof(fn), "%s/%s", SYSBLK, hd_name(hd)); + foreach_file(fn, hostdisk_one_part, hd, 0); +} + +static void +hostdisk_add_drive(const char *drv, uint64_t secs) +{ + hdinfo_t *hd = NULL; + char *dev = NULL; + char fn[1024]; + + if ((hd = calloc(1, sizeof(*hd))) == NULL) + return; + if (asprintf(&dev, "/dev/%s", drv) == -1) { + printf("hostdisk: no memory\n"); + free(hd); + return; + } + hd->hd_dev = dev; + hd->hd_sectors = secs; + snprintf(fn, sizeof(fn), "%s/%s/queue/hw_sector_size", + SYSBLK, drv); + if (!file2u64(fn, &hd->hd_sectorsize)) + goto err; + hd->hd_size = hd->hd_sectors * hd->hd_sectorsize; + if (hd->hd_size < HOSTDISK_MIN_SIZE) + goto err; + hd->hd_flags = 0; + STAILQ_INIT(&hd->hd_children); + printf("/dev/%s: %ju %ju %ju\n", + drv, hd->hd_size, hd->hd_sectors, hd->hd_sectorsize); + STAILQ_INSERT_TAIL(&hdinfo, hd, hd_link); + hostdisk_add_parts(hd); + return; +err: + free(dev); + free(hd); + return; +} + +/* Find a disk / partition by its filename */ + +static hdinfo_t * +hostdisk_find(const char *fn) +{ + hdinfo_t *hd, *md; + + STAILQ_FOREACH(hd, &hdinfo, hd_link) { + if (strcmp(hd->hd_dev, fn) == 0) + return (hd); + STAILQ_FOREACH(md, &hd->hd_children, hd_link) { + if (strcmp(md->hd_dev, fn) == 0) + return (md); + } + } + return (NULL); +} + + +static bool +hostdisk_one_disk(struct host_dirent64 *dent, void *argp __unused) +{ + char szfn[1024]; + uint64_t sz; + + /* + * Skip . and .. + */ + if (strcmp(dent->d_name, ".") == 0 || + strcmp(dent->d_name, "..") == 0) + return (true); + + /* Find out how big this is -- no size not a disk */ + snprintf(szfn, sizeof(szfn), "%s/%s/size", SYSBLK, + dent->d_name); + if (!file2u64(szfn, &sz)) + return (true); + hostdisk_add_drive(dent->d_name, sz); + return (true); +} + +static void +hostdisk_fake_one_disk(char *override) +{ + hdinfo_t *hd = NULL; + struct host_kstat sb; + + if (host_stat(override, &sb) != 0) + return; + if (!HOST_S_ISREG(sb.st_mode)) + return; + if (sb.st_size == 0) + return; + if ((hd = calloc(1, sizeof(*hd))) == NULL) + return; + if ((hd->hd_dev = strdup(override)) == NULL) + goto err; + hd->hd_size = sb.st_size; + hd->hd_sectorsize = 512; /* XXX configurable? */ + hd->hd_sectors = hd->hd_size / hd->hd_sectorsize; + if (hd->hd_size < HOSTDISK_MIN_SIZE) + goto err; + hd->hd_flags = 0; + STAILQ_INIT(&hd->hd_children); + printf("%s: %ju %ju %ju\n", + hd->hd_dev, hd->hd_size, hd->hd_sectors, hd->hd_sectorsize); + STAILQ_INSERT_TAIL(&hdinfo, hd, hd_link); + return; +err: + free(__DECONST(void *, hd->hd_dev)); + free(hd); +} + +static void +hostdisk_find_block_devices(void) +{ + char *override; + + override=getenv("hostdisk_override"); + if (override != NULL) + hostdisk_fake_one_disk(override); + else + foreach_file(SYSBLK, hostdisk_one_disk, NULL, 0); +} + +static int +hostdisk_init(void) +{ + hostdisk_find_block_devices(); + + return (0); +} + +static int +hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, + char *buf, size_t *rsize) +{ + struct devdesc *desc = devdata; + daddr_t pos; + int n; + uint64_t res; + uint32_t posl, posh; + + pos = dblk * 512; + + posl = pos & 0xffffffffu; + posh = (pos >> 32) & 0xffffffffu; + if (host_llseek(desc->d_unit, posh, posl, &res, 0) < 0) + return (EIO); + if (flag & F_READ) + n = host_read(desc->d_unit, buf, size); + else if (flag & F_WRITE) + n = host_write(desc->d_unit, buf, size); + else + return (EINVAL); + + if (n < 0) + return (EIO); + + *rsize = n; + return (0); +} + +static int +hostdisk_open(struct open_file *f, ...) +{ + struct devdesc *desc; + const char *fn; + va_list vl; + + va_start(vl, f); + desc = va_arg(vl, struct devdesc *); + va_end(vl); + + fn = dev2hd(desc)->hd_dev; + desc->d_unit = host_open(fn, O_RDWR, 0); + if (desc->d_unit <= 0) { + printf("hostdisk_open: couldn't open %s: %d\n", fn, errno); + return (ENOENT); + } + + return (0); +} + +static int +hostdisk_close(struct open_file *f) +{ + struct devdesc *desc = f->f_devdata; + + host_close(desc->d_unit); + return (0); +} + +static int +hostdisk_ioctl(struct open_file *f, u_long cmd, void *data) +{ + struct devdesc *desc = f->f_devdata; + hdinfo_t *hd = dev2hd(desc); + + switch (cmd) { + case DIOCGSECTORSIZE: + *(u_int *)data = hd->hd_sectorsize; + break; + case DIOCGMEDIASIZE: + *(uint64_t *)data = hd->hd_size; + break; + default: + return (ENOTTY); + } + return (0); +} + +static int +hostdisk_print(int verbose) +{ + char line[80]; + hdinfo_t *hd, *md; + int ret = 0; + + printf("%s devices:", hostdisk.dv_name); + if (pager_output("\n") != 0) + return (1); + + STAILQ_FOREACH(hd, &hdinfo, hd_link) { + snprintf(line, sizeof(line), + " %s: %ju X %ju: %ju bytes\n", + hd->hd_dev, + (uintmax_t)hd->hd_sectors, + (uintmax_t)hd->hd_sectorsize, + (uintmax_t)hd->hd_size); + if ((ret = pager_output(line)) != 0) + break; + STAILQ_FOREACH(md, &hd->hd_children, hd_link) { + snprintf(line, sizeof(line), + " %s: %ju X %ju: %ju bytes\n", + md->hd_dev, + (uintmax_t)md->hd_sectors, + (uintmax_t)md->hd_sectorsize, + (uintmax_t)md->hd_size); + if ((ret = pager_output(line)) != 0) + goto done; + } + } + +done: + return (ret); +} + +static char * +hostdisk_fmtdev(struct devdesc *vdev) +{ + static char name[DEV_DEVLEN]; + + snprintf(name, sizeof(name), "%s:", dev2hd(vdev)->hd_dev); + return (name); +} + +static bool +hostdisk_match(struct devsw *devsw, const char *devspec) +{ + hdinfo_t *hd; + const char *colon; + char *cp; + + colon = strchr(devspec, ':'); + if (colon == NULL) + return false; + cp = strdup(devspec); + cp[colon - devspec] = '\0'; + hd = hostdisk_find(cp); + free(cp); + return (hd != NULL); +} + +static int +hostdisk_parsedev(struct devdesc **idev, const char *devspec, const char **path) +{ + const char *cp; + struct devdesc *dev; + hdinfo_t *hd; + int len; + char *fn; + + /* Must have a : in it */ + cp = strchr(devspec, ':'); + if (cp == NULL) + return (EINVAL); + /* XXX Stat the /dev or defer error handling to open(2) call? */ + if (path != NULL) + *path = cp + 1; + len = cp - devspec; + fn = strdup(devspec); + fn[len] = '\0'; + hd = hostdisk_find(fn); + if (hd == NULL) { + printf("Can't find hdinfo for %s\n", fn); + free(fn); + return (EINVAL); + } + free(fn); + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return (ENOMEM); + dev->d_unit = 0; + dev->d_dev = &hostdisk; + dev->d_opendata = hd; + *idev = dev; + return (0); +} + +/* XXX refactor */ +static bool +sanity_check_currdev(void) +{ + struct stat st; + + return (stat(PATH_DEFAULTS_LOADER_CONF, &st) == 0 || +#ifdef PATH_BOOTABLE_TOKEN + stat(PATH_BOOTABLE_TOKEN, &st) == 0 || /* non-standard layout */ +#endif + stat(PATH_KERNEL, &st) == 0); +} + +static const char * +hostdisk_try_one(hdinfo_t *hd) +{ + char *fn; + + if (asprintf(&fn, "%s:", hd->hd_dev) == -1) + return (NULL); + set_currdev(fn); + printf("Trying %s\n", fn); + if (sanity_check_currdev()) + return (fn); + printf("Failed %s\n", fn); + free(fn); + return (NULL); +} + +const char * +hostdisk_gen_probe(void) +{ + hdinfo_t *hd, *md; + const char *rv = NULL; + + STAILQ_FOREACH(hd, &hdinfo, hd_link) { + /* try whole disk */ + if (hd->hd_flags & HDF_HAS_ZPOOL) + continue; + rv = hostdisk_try_one(hd); + if (rv != NULL) + return (rv); + + /* try all partitions */ + STAILQ_FOREACH(md, &hd->hd_children, hd_link) { + if (md->hd_flags & HDF_HAS_ZPOOL) + continue; + rv = hostdisk_try_one(md); + if (rv != NULL) + return (rv); + } + } + return (NULL); +} + +#ifdef LOADER_ZFS_SUPPORT +static bool +hostdisk_zfs_check_one(hdinfo_t *hd) +{ + char *fn; + bool found = false; + uint64_t pool_uuid; + + if (asprintf(&fn, "%s:", hd->hd_dev) == -1) + return (false); + pool_uuid = 0; + zfs_probe_dev(fn, &pool_uuid, false); + if (pool_uuid != 0) { + found = true; + hd->hd_flags |= HDF_HAS_ZPOOL; + hd->hd_zfs_uuid = pool_uuid; + } + free(fn); + + return (found); +} + +void +hostdisk_zfs_probe(void) +{ + hdinfo_t *hd, *md; + + STAILQ_FOREACH(hd, &hdinfo, hd_link) { + if (hostdisk_zfs_check_one(hd)) + continue; + STAILQ_FOREACH(md, &hd->hd_children, hd_link) { + hostdisk_zfs_check_one(md); + } + } +} + +/* This likely shoud move to libsa/zfs/zfs.c and be used by at least EFI booting */ +static bool +probe_zfs_currdev(uint64_t pool_guid) +{ + char *devname; + struct zfs_devdesc currdev; + char buf[VDEV_PAD_SIZE]; + + currdev.dd.d_dev = &zfs_dev; + currdev.dd.d_unit = 0; + currdev.pool_guid = pool_guid; + currdev.root_guid = 0; + devname = devformat(&currdev.dd); + printf("Setting currdev to %s\n", devname); + set_currdev(devname); + init_zfs_boot_options(devname); + + if (zfs_get_bootonce(&currdev, OS_BOOTONCE, buf, sizeof(buf)) == 0) { + printf("zfs bootonce: %s\n", buf); + set_currdev(buf); + setenv("zfs-bootonce", buf, 1); + } + (void)zfs_attach_nvstore(&currdev); + + return (sanity_check_currdev()); +} + +static bool +hostdisk_zfs_try_default(hdinfo_t *hd) +{ + return (probe_zfs_currdev(hd->hd_zfs_uuid)); +} + +bool +hostdisk_zfs_find_default(void) +{ + hdinfo_t *hd, *md; + + STAILQ_FOREACH(hd, &hdinfo, hd_link) { + if (hd->hd_flags & HDF_HAS_ZPOOL) { + if (hostdisk_zfs_try_default(hd)) + return (true); + continue; + } + STAILQ_FOREACH(md, &hd->hd_children, hd_link) { + if (md->hd_flags & HDF_HAS_ZPOOL) { + if (hostdisk_zfs_try_default(md)) + return (true); + } + } + } + return (false); +} +#endif diff --git a/stand/kboot/kboot/hostfs.c b/stand/kboot/kboot/hostfs.c new file mode 100644 index 000000000000..cfd3476b3c84 --- /dev/null +++ b/stand/kboot/kboot/hostfs.c @@ -0,0 +1,287 @@ +/*- + * Copyright (c) 2022 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/types.h> +#include "stand.h" +#include "host_syscall.h" +#include "kboot.h" + +#define HOST_PATH_MAX 1025 + +extern struct devsw host_dev; + +const char *hostfs_root = "/"; + +enum FTYPE { + regular, + dir, +}; + +typedef struct _hostfs_file { + enum FTYPE hf_type; + int hf_fd; + /* The following are only used for FTYPE == dir */ + char hf_dents[2048]; + char *hf_curdent; + int hf_dentlen; /* Valid part of hf_dents */ +} hostfs_file; + +static hostfs_file * +hostfs_alloc(void) +{ + hostfs_file *hf; + + hf = malloc(sizeof(*hf)); + if (hf != NULL) + memset(hf, 0, sizeof(*hf)); + return (hf); +} + +static void +hostfs_free(hostfs_file *hf) +{ + free(hf); +} + +static int +hostfs_open(const char *fn, struct open_file *f) +{ + hostfs_file *hf; + struct host_kstat ksb; + char path[HOST_PATH_MAX]; + + if (f->f_dev != &host_dev) { + return (EINVAL); + } + + /* + * Normally, we root everything at hostfs_root. However, there are two + * exceptions that make it easier to write code. First is /sys and /proc + * are special Linux filesystems, so we pass those paths + * through. Second, if the path starts with //, then we strip off the + * first / and pass it through (in a weird way, this is actually in + * POSIX: hosts are allowed to do specail things with paths that start + * with two //, but one or three or more are required to be treated as + * one). + */ + if (strncmp("/sys/", fn, 5) == 0 || strncmp("/proc/", fn, 6) == 0) + strlcpy(path, fn, sizeof(path)); + else if (fn[0] == '/' && fn[1] == '/' && fn[2] != '/') + strlcpy(path, fn + 1, sizeof(path)); + else + snprintf(path, sizeof(path), "%s/%s", hostfs_root, fn); + hf = hostfs_alloc(); + hf->hf_fd = host_open(path, HOST_O_RDONLY, 0); + if (hf->hf_fd < 0) { + hostfs_free(hf); + return (EINVAL); + } + + if (host_fstat(hf->hf_fd, &ksb) < 0) { + hostfs_free(hf); + return (EINVAL); + } + if (S_ISDIR(hf->hf_fd)) { + hf->hf_type = dir; + } else { + hf->hf_type = regular; + } + f->f_fsdata = hf; + return (0); +} + +static int +hostfs_close(struct open_file *f) +{ + hostfs_file *hf = f->f_fsdata; + + host_close(hf->hf_fd); + hostfs_free(hf); + f->f_fsdata = NULL; + + return (0); +} + +static int +hostfs_read(struct open_file *f, void *start, size_t size, size_t *resid) +{ + hostfs_file *hf = f->f_fsdata; + ssize_t sz; + + sz = host_read(hf->hf_fd, start, size); + if (sz < 0) + return (host_to_stand_errno(sz)); + *resid = size - sz; + + return (0); +} + +static off_t +hostfs_seek(struct open_file *f, off_t offset, int whence) +{ + hostfs_file *hf = f->f_fsdata; + uint32_t offl, offh; + long err; + uint64_t res; + + /* + * Assumes Linux host with 'reduced' system call wrappers. Also assume + * host and libstand have same whence encoding (safe since it all comes + * from V7 later ISO-C). Also assumes we have to support powerpc still, + * it's interface is weird for legacy reasons.... + */ + res = (uint64_t)offset; + offl = res & 0xfffffffful; + offh = (res >> 32) & 0xfffffffful; + err = host_llseek(hf->hf_fd, offh, offl, &res, whence); + /* + * Since we're interfacing to the raw linux system call, we have to + * carefully check. We have to translate the errno value from the host + * to libsa's conventions. + */ + if (is_linux_error(err)) { + errno = host_to_stand_errno(err); + return (-1); + } + return (res); +} + +static int +hostfs_stat(struct open_file *f, struct stat *sb) +{ + struct host_kstat ksb; + hostfs_file *hf = f->f_fsdata; + + if (host_fstat(hf->hf_fd, &ksb) < 0) + return (EINVAL); + /* + * Translate Linux stat info to lib stand's notion (which uses FreeBSD's + * stat structure, missing fields are zero and commented below). + */ + memset(sb, 0, sizeof(*sb)); + sb->st_dev = ksb.st_dev; + sb->st_ino = ksb.st_ino; + sb->st_nlink = ksb.st_nlink; + sb->st_mode = ksb.st_mode; + sb->st_uid = ksb.st_uid; + sb->st_gid = ksb.st_gid; + sb->st_rdev = ksb.st_rdev; + /* No st_?time_ext on i386 */ + sb->st_atim.tv_sec = ksb.st_atime_sec; + sb->st_atim.tv_nsec = ksb.st_atime_nsec; + sb->st_mtim.tv_sec = ksb.st_mtime_sec; + sb->st_mtim.tv_nsec = ksb.st_mtime_nsec; + sb->st_ctim.tv_sec = ksb.st_ctime_sec; + sb->st_ctim.tv_nsec = ksb.st_ctime_nsec; + /* No st_birthtim */ + sb->st_size = ksb.st_size; + sb->st_blocks = ksb.st_blocks; + sb->st_blksize = ksb.st_blksize; + /* no st_flags */ + /* no st_get */ + + return (0); +} + +static int +hostfs_readdir(struct open_file *f, struct dirent *d) +{ + hostfs_file *hf = f->f_fsdata; + int dentlen; + struct host_dirent64 *dent; + + if (hf->hf_curdent == NULL) { + dentlen = host_getdents64(hf->hf_fd, hf->hf_dents, sizeof(hf->hf_dents)); + if (dentlen <= 0) + return (EINVAL); + hf->hf_dentlen = dentlen; + hf->hf_curdent = hf->hf_dents; + } + dent = (struct host_dirent64 *)hf->hf_curdent; + d->d_fileno = dent->d_ino; + d->d_type = dent->d_type; /* HOST_DT_XXXX == DX_XXXX for all values */ + strlcpy(d->d_name, dent->d_name, sizeof(d->d_name)); /* d_name is NUL terminated */ + d->d_namlen = strlen(d->d_name); + hf->hf_curdent += dent->d_reclen; + if (hf->hf_curdent >= hf->hf_dents + hf->hf_dentlen) { + hf->hf_curdent = NULL; + hf->hf_dentlen = 0; + } + + return (0); +} + +struct fs_ops hostfs_fsops = { + .fs_name = "host", + .fo_open = hostfs_open, + .fo_close = hostfs_close, + .fo_read = hostfs_read, + .fo_write = null_write, + .fo_seek = hostfs_seek, + .fo_stat = hostfs_stat, + .fo_readdir = hostfs_readdir +}; + +/* + * Generic "null" host device. This goes hand and hand with the host fs object + * + * XXXX This and userboot for bhyve both use exactly the same code, modulo some + * formatting nits. Make them common. We mostly use it to 'gate' the open of the + * filesystem to only this device. + */ + +static int +host_dev_init(void) +{ + return (0); +} + +static int +host_dev_print(int verbose) +{ + char line[80]; + + printf("%s devices:", host_dev.dv_name); + if (pager_output("\n") != 0) + return (1); + + snprintf(line, sizeof(line), " host%d: Host filesystem\n", 0); + return (pager_output(line)); +} + +/* + * 'Open' the host device. + */ +static int +host_dev_open(struct open_file *f, ...) +{ + return (0); +} + +static int +host_dev_close(struct open_file *f) +{ + return (0); +} + +static int +host_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, + char *buf, size_t *rsize) +{ + return (ENOSYS); +} + +struct devsw host_dev = { + .dv_name = "host", + .dv_type = DEVT_NET, + .dv_init = host_dev_init, + .dv_strategy = host_dev_strategy, + .dv_open = host_dev_open, + .dv_close = host_dev_close, + .dv_ioctl = noioctl, + .dv_print = host_dev_print, + .dv_cleanup = NULL +}; diff --git a/stand/kboot/kboot/init.c b/stand/kboot/kboot/init.c new file mode 100644 index 000000000000..e707f65096d7 --- /dev/null +++ b/stand/kboot/kboot/init.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Mini-init(8) so we can run as init/pid 1 in a LinuxBoot environment. + */ + +#include "stand.h" +#include "host_syscall.h" +#include "kboot.h" + +/* + * Create a 'standard' early boot environment. Cribbed from the things that + * sysvinit, u-root, and initramfs-tools do. This is a minimal environment + * for modern Linux systems, though the /tmp, /run and /var stuff can likely + * be done inside the initrd image itself (as can creating the mount points + * for /proc, /dev and /sys). + * + * Note: We ignore errors here. There's no stderr to report them to yet. These + * operations generally can't fail, but if they do, we may not have the ability + * to report them later. + */ +static void +init_fs_env(void) +{ + /* + * Create directories for mandatory filesystems and mount them. + */ + host_mkdir("/proc", 0555); + host_mount("proc", "/proc", "proc", MS_RELATIME, ""); + host_mkdir("/sys", 0555); + host_mount("sysfs", "/sys", "sysfs", MS_RELATIME, ""); + host_mkdir("/dev", 0755); + host_mount("devtmpfs", "/dev", "devtmpfs", MS_RELATIME, + "mode=0755,nr_inodes=0"); + + /* + * Create compat links: /dev/fd lives in /proc, and needs some help to + * get setup. + */ + host_symlink("/proc/self/fd", "/dev/fd"); + host_symlink("fd/0", "/dev/stdin"); + host_symlink("fd/1", "/dev/stdout"); + host_symlink("fd/2", "/dev/stderr"); + + + /* + * Unsure if we need this, but create a sane /tmp just in case that's useful. + * and point /run over to it. + */ + host_mkdir("/tmp", 01777); + host_mount("tmpfs", "/tmp", "tmpfs", MS_RELATIME, "size=10%,mode=1777"); + host_symlink("/tmp", "/run"); + + /* + * Unsure the loader needs /var and /var/log, but they are easy to + * create. + */ + host_mkdir("/var", 0555); + host_mkdir("/var/lock", 0555); + host_symlink("/tmp", "/var/tmp"); +} + +static void +init_tty(void) +{ + int fd; + + /* + * sysvinit asks the linux kernel to convert the CTRL-ALT-DEL to a SIGINT, + * but we skip that. + */ + + /* + * Setup /dev/console as stdin/out/err + */ + host_close(0); + host_close(1); + host_close(2); + fd = host_open("/dev/console", HOST_O_RDWR | HOST_O_NOCTTY, 0); + host_dup(fd); + host_dup(fd); +#if 0 + /* + * I think we may need to put it in 'raw' mode, but maybe not. Linux + * sysvinit sets it into 'sane' mode with several tweaks. Not enabled at + * the moment since host console initialization seems sufficient. + */ + struct host_termios tty; + + host_cfmakeraw(&tty); + host_tcsetattr(fd, HOST_TCANOW, &tty); + host_tcflush(fd, HOST_TCIOFLUSH) +#endif +} + +static void +init_sig(void) +{ + /* + * since we're running as init, we need to catch some signals + */ + + /* + * setup signals here + * + * sysvinit catches a lot of signals, but the boot loader needn't catch + * so many since we don't do as much as it does. If we need to, put the + * signal catching / ignoring code here. If we implement a 'shell' + * function to spawn a sub-shell, we'll likely need to do a lot more. + */ +} + +void +do_init(void) +{ + /* + * Only pid 1 is init + */ + if (host_getpid() != 1) + return; + + init_fs_env(); + init_tty(); + init_sig(); +} diff --git a/stand/kboot/kboot/kboot.h b/stand/kboot/kboot/kboot.h new file mode 100644 index 000000000000..cbacf8d1e453 --- /dev/null +++ b/stand/kboot/kboot/kboot.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef KBOOT_H +#define KBOOT_H + +#define DEVT_HOSTDISK 1234 + +bool enumerate_memory_arch(void); +struct preloaded_file; +void bi_loadsmap(struct preloaded_file *kfp); + +bool has_acpi(void); +vm_offset_t acpi_rsdp(void); + +void do_init(void); + +/* Per-platform fdt fixup */ +void fdt_arch_fixups(void *fdtp); + +uint64_t kboot_get_phys_load_segment(void); +uint8_t kboot_get_kernel_machine_bits(void); + +/* main.c */ +void kboot_kseg_get(int *nseg, void **ptr); + +/* hostdisk.c */ +extern const char *hostfs_root; +const char *hostdisk_gen_probe(void); +void hostdisk_zfs_probe(void); +bool hostdisk_zfs_find_default(void); + +#include "seg.h" +#include "util.h" + +#endif /* KBOOT_H */ diff --git a/stand/kboot/kboot/kbootfdt.c b/stand/kboot/kboot/kbootfdt.c new file mode 100644 index 000000000000..e4c378423585 --- /dev/null +++ b/stand/kboot/kboot/kbootfdt.c @@ -0,0 +1,133 @@ +/*- + * Copyright (C) 2014 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <fdt_platform.h> +#include <libfdt.h> +#include "bootstrap.h" +#include "host_syscall.h" +#include "kboot.h" + +static void +add_node_to_fdt(void *buffer, const char *path, int fdt_offset) +{ + int child_offset, fd, pfd, error, dentsize; + char subpath[512]; + void *propbuf; + ssize_t proplen; + + char dents[2048]; + struct host_dirent64 *dent; + int d_type; + + fd = host_open(path, O_RDONLY, 0); + while (1) { + dentsize = host_getdents64(fd, dents, sizeof(dents)); + if (dentsize <= 0) + break; + for (dent = (struct host_dirent64 *)dents; + (char *)dent < dents + dentsize; + dent = (struct host_dirent64 *)((void *)dent + dent->d_reclen)) { + sprintf(subpath, "%s/%s", path, dent->d_name); + if (strcmp(dent->d_name, ".") == 0 || + strcmp(dent->d_name, "..") == 0) + continue; + d_type = dent->d_type; + if (d_type == HOST_DT_DIR) { + child_offset = fdt_add_subnode(buffer, fdt_offset, + dent->d_name); + if (child_offset < 0) { + printf("Error %d adding node %s/%s, skipping\n", + child_offset, path, dent->d_name); + continue; + } + add_node_to_fdt(buffer, subpath, child_offset); + } else { + propbuf = malloc(1024); + proplen = 0; + pfd = host_open(subpath, O_RDONLY, 0); + if (pfd > 0) { + proplen = host_read(pfd, propbuf, 1024); + host_close(pfd); + } + error = fdt_setprop(buffer, fdt_offset, dent->d_name, + propbuf, proplen); + free(propbuf); + if (error) + printf("Error %d adding property %s to " + "node %d\n", error, dent->d_name, + fdt_offset); + } + } + } + + host_close(fd); +} + +int +fdt_platform_load_dtb(void) +{ + void *buffer; + size_t buflen = 409600; + int fd, err = 0; + + /* + * Should load /sys/firmware/fdt if it exists, otherwise we walk the + * tree from /proc/device-tree. The former is much easier than the + * latter and also the newer interface. But as long as we support the + * PS3 boot, we'll need the latter due to that kernel's age. + */ + buffer = malloc(buflen); + fd = host_open("/sys/firmware/fdt", O_RDONLY, 0); + if (fd >= 0) { + err = host_read(fd, buffer, buflen); + close(fd); + } + if (fd < 0 || err < 0) { + fdt_create_empty_tree(buffer, buflen); + add_node_to_fdt(buffer, "/proc/device-tree", + fdt_path_offset(buffer, "/")); + } + fdt_arch_fixups(buffer); + + fdt_pack(buffer); + + fdt_load_dtb_addr(buffer); + free(buffer); + + return (0); +} + +void +fdt_platform_load_overlays(void) +{ + fdt_load_dtb_overlays(NULL); +} + +void +fdt_platform_fixups(void) +{ + fdt_apply_overlays(); +} diff --git a/stand/kboot/kboot/lua_bindings.c b/stand/kboot/kboot/lua_bindings.c new file mode 100644 index 000000000000..ca5d0253c21f --- /dev/null +++ b/stand/kboot/kboot/lua_bindings.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "lua.h" +#include "lauxlib.h" +#include "lutils.h" +#include "lhash.h" + +static void +lua_hash_bindings(lua_State *L) +{ + luaL_requiref(L, "hash", luaopen_hash, 1); + lua_pop(L, 1); /* Remove lib */ +} + +LUA_COMPILE_SET(lua_hash_bindings); diff --git a/stand/kboot/kboot/main.c b/stand/kboot/kboot/main.c new file mode 100644 index 000000000000..4a136b42a4a1 --- /dev/null +++ b/stand/kboot/kboot/main.c @@ -0,0 +1,706 @@ +/*- + * Copyright (C) 2010-2014 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stand.h> +#include <sys/param.h> +#include <sys/boot.h> +#ifdef LOADER_FDT_SUPPORT +#include <fdt_platform.h> +#endif + +#include <machine/cpufunc.h> +#include <bootstrap.h> +#include "host_syscall.h" +#include "kboot.h" +#include "stand.h" +#include <smbios.h> + +int kboot_getdev(void **vdev, const char *devspec, const char **path); +ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len); +ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len); +ssize_t kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); +int kboot_autoload(void); +static void kboot_zfs_probe(void); + +struct arch_switch archsw = { + .arch_getdev = kboot_getdev, + .arch_copyin = kboot_copyin, + .arch_copyout = kboot_copyout, + .arch_readin = kboot_readin, + .arch_autoload = kboot_autoload, + .arch_zfs_probe = kboot_zfs_probe, +}; + +extern int command_fdt_internal(int argc, char *argv[]); + +/* + * On amd64, KERNSTART is where the first actual kernel page is mapped, after + * the compatibility mapping. We reserve 2MB at the start of the address space + * for the page tables, etc, and so need to offset this there (and only there). + * The loader needs to know about this so we can pad everything to the proper + * place in PA. Ideally, we'd include vmparam.h to figure this out, but the + * macros it uses are not easily available in this compile environment, so we + * hard code that knowledge here. + */ +#if defined(__amd64__) +#define KERN_PADDING (2 << 20) +#else +#define KERN_PADDING 0 +#endif + +#define PA_INVAL (vm_offset_t)-1 +static vm_offset_t pa_start = PA_INVAL; +static vm_offset_t offset; + +static uint64_t commit_limit; +static uint64_t committed_as; +static uint64_t mem_avail; + +static void +memory_limits(void) +{ + int fd; + char buf[128]; + + /* + * To properly size the slabs, we need to find how much memory we can + * commit to using. commit_limit is the max, while commited_as is the + * current total. We can use these later to allocate the largetst amount + * of memory possible so we can support larger ram disks than we could + * by using fixed segment sizes. We also grab the memory available so + * we don't use more than 49% of that. + */ + fd = open("host:/proc/meminfo", O_RDONLY); + if (fd != -1) { + while (fgetstr(buf, sizeof(buf), fd) > 0) { + if (strncmp(buf, "MemAvailable:", 13) == 0) { + mem_avail = strtoll(buf + 13, NULL, 0); + mem_avail <<= 10; /* Units are kB */ + } else if (strncmp(buf, "CommitLimit:", 12) == 0) { + commit_limit = strtoll(buf + 13, NULL, 0); + commit_limit <<= 10; /* Units are kB */ + } else if (strncmp(buf, "Committed_AS:", 13) == 0) { + committed_as = strtoll(buf + 14, NULL, 0); + committed_as <<= 10; /* Units are kB */ + } + } + } else { + /* Otherwise, on FreeBSD host, for testing 32GB host: */ + mem_avail = 31ul << 30; /* 31GB free */ + commit_limit = mem_avail * 9 / 10; /* 90% comittable */ + committed_as = 20ul << 20; /* 20MB used */ + } + printf("Commit limit: %lld Committed bytes %lld Available %lld\n", + (long long)commit_limit, (long long)committed_as, + (long long)mem_avail); + close(fd); +} + +/* + * NB: getdev should likely be identical to this most places, except maybe + * we should move to storing the length of the platform devdesc. + */ +int +kboot_getdev(void **vdev, const char *devspec, const char **path) +{ + struct devdesc **dev = (struct devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no device, go with the + * current device. + */ + if (devspec == NULL || strchr(devspec, ':') == NULL) { + if (((rv = devparse(dev, getenv("currdev"), NULL)) == 0) && + (path != NULL)) + *path = devspec; + return (rv); + } + + /* + * Try to parse the device name off the beginning of the devspec + */ + return (devparse(dev, devspec, path)); +} + +static int +parse_args(int argc, const char **argv) +{ + int howto = 0; + + /* + * When run as init, sometimes argv[0] is a EFI-ESP path, other times + * it's the name of the init program, and sometimes it's a placeholder + * string, so we exclude it here. For the other args, look for DOS-like + * and Unix-like absolte paths and exclude parsing it if we find that, + * otherwise parse it as a command arg (so looking for '-X', 'foo' or + * 'foo=bar'). This is a little different than EFI where it argv[0] + * often times is the first argument passed in. There are cases when + * linux-booting via EFI that we have the EFI path we used to run + * bootXXX.efi as the arguments to init, so we need to exclude the paths + * there as well. + */ + for (int i = 1; i < argc; i++) { + if (argv[i][0] != '\\' && argv[i][0] != '/') { + howto |= boot_parse_arg(argv[i]); + } + } + + return (howto); +} + +static vm_offset_t rsdp; + +static vm_offset_t +kboot_rsdp_from_efi(void) +{ + char buffer[512 + 1]; + char *walker, *ep; + + if (!file2str("/sys/firmware/efi/systab", buffer, sizeof(buffer))) + return (0); /* Not an EFI system */ + ep = buffer + strlen(buffer); + walker = buffer; + while (walker < ep) { + if (strncmp("ACPI20=", walker, 7) == 0) + return((vm_offset_t)strtoull(walker + 7, NULL, 0)); + if (strncmp("ACPI=", walker, 5) == 0) + return((vm_offset_t)strtoull(walker + 5, NULL, 0)); + walker += strcspn(walker, "\n") + 1; + } + return (0); +} + +static void +find_acpi(void) +{ + rsdp = kboot_rsdp_from_efi(); +#if 0 /* maybe for amd64 */ + if (rsdp == 0) + rsdp = find_rsdp_arch(); +#endif +} + +vm_offset_t +acpi_rsdp(void) +{ + return (rsdp); +} + +bool +has_acpi(void) +{ + return rsdp != 0; +} + +/* + * SMBIOS support. We map the physical memory address we get into a VA in this + * address space with mmap with 64k pages. Once we're done, we cleanup any + * mappings we made. + */ + +#define MAX_MAP 10 +#define PAGE (64<<10) + +static struct mapping +{ + uintptr_t pa; + caddr_t va; +} map[MAX_MAP]; +static bool smbios_mmap_file; +static int smbios_fd; +static int nmap; + +caddr_t ptov(uintptr_t pa) +{ + caddr_t va; + uintptr_t pa2; + struct mapping *m = map; + + if (smbios_mmap_file) + pa2 = rounddown(pa, PAGE); + else + pa2 = pa; + for (int i = 0; i < nmap; i++, m++) { + if (m->pa == pa2) { + return (m->va + pa - m->pa); + } + } + if (!smbios_mmap_file) + panic("Out of bounds smbios access"); + if (nmap == MAX_MAP) + panic("Too many maps for smbios"); + + /* + * host_mmap returns small negative numbers on errors, can't return an + * error here, so we have to panic. The Linux wrapper will set errno + * based on this and then return HOST_MAP_FAILED. Since we're calling + * the raw system call we have to do that ourselves. + */ + va = host_mmap(0, PAGE, HOST_PROT_READ, HOST_MAP_SHARED, smbios_fd, pa2); + if (is_linux_error((long)va)) + panic("smbios mmap offset %#jx failed", (uintmax_t)pa2); + m = &map[nmap++]; + m->pa = pa2; + m->va = va; + return (m->va + pa - m->pa); +} + +static void +smbios_cleanup(void) +{ + for (int i = 0; i < nmap; i++) { + host_munmap(map[i].va, PAGE); + } +} + +static vm_offset_t +kboot_find_smbios(void) +{ + char buffer[512 + 1]; + char *walker, *ep; + + if (!file2str("/sys/firmware/efi/systab", buffer, sizeof(buffer))) + return (0); /* Not an EFI system */ + ep = buffer + strlen(buffer); + walker = buffer; + while (walker <= ep) { + /* + * Linux outputs the v3 table first if present, so we will + * choose it in priority. + */ + if (strncmp("SMBIOS3=", walker, 8) == 0) + return((vm_offset_t)strtoull(walker + 8, NULL, 0)); + if (strncmp("SMBIOS=", walker, 7) == 0) + return((vm_offset_t)strtoull(walker + 7, NULL, 0)); + walker += strcspn(walker, "\n") + 1; + } + return (0); +} + +static void +find_smbios(void) +{ + char buf[40]; + void *dmi_data; + uintptr_t pa; + caddr_t va; + + pa = kboot_find_smbios(); + printf("SMBIOS at %#jx\n", (uintmax_t)pa); + if (pa == 0) + return; + + dmi_data = NULL; + smbios_fd = host_open("/sys/firmware/dmi/tables/DMI", O_RDONLY, 0); + if (smbios_fd >= 0) { + struct host_kstat sb; + struct mapping *m; + + if (host_fstat(smbios_fd, &sb) < 0) { + host_close(smbios_fd); + goto try_dev_mem; + } + + dmi_data = malloc(sb.st_size); + if (dmi_data == NULL) { + host_close(smbios_fd); + goto try_dev_mem; + } + + host_read(smbios_fd, dmi_data, sb.st_size); + + m = &map[nmap++]; + m->pa = pa; + m->va = dmi_data; + smbios_mmap_file = false; + } else { +try_dev_mem: + smbios_fd = host_open("/dev/mem", O_RDONLY, 0); + if (smbios_fd < 0) { + printf("Can't open /sys/firmware/dmi/tables/DMI or " + "/dev/mem to read smbios\n"); + return; + } + smbios_mmap_file = true; + } + snprintf(buf, sizeof(buf), "%#jx", (uintmax_t)pa); + setenv("hint.smbios.0.mem", buf, 1); + + va = ptov(pa); + printf("Start of smbios at pa %p va %p\n", (void *)pa, va); + smbios_detect(va); + smbios_cleanup(); + free(dmi_data); + host_close(smbios_fd); +} + +static void +parse_file(const char *fn) +{ + struct stat st; + int fd = -1; + char *env = NULL; + + if (stat(fn, &st) != 0) + return; + fd = open(fn, O_RDONLY); + if (fd == -1) + return; + env = malloc(st.st_size + 1); + if (env == NULL) + goto out; + if (read(fd, env, st.st_size) != st.st_size) + goto out; + env[st.st_size] = '\0'; + boot_parse_cmdline(env); +out: + free(env); + close(fd); +} + + +int +main(int argc, const char **argv) +{ + void *heapbase; + const size_t heapsize = 64*1024*1024; + const char *bootdev; + + /* Give us a sane world if we're running as init */ + do_init(); + + /* + * Setup the heap, 64MB is minimum for ZFS booting + */ + heapbase = host_getmem(heapsize); + setheap(heapbase, heapbase + heapsize); + + /* + * Set up console so we get error messages. + */ + cons_probe(); + + /* + * Find acpi and smbios, if they exists. This allows command line and + * later scripts to override if necessary. + */ + find_acpi(); + find_smbios(); + + /* Parse the command line args -- ignoring for now the console selection */ + parse_args(argc, argv); + + hostfs_root = getenv("hostfs_root"); + if (hostfs_root == NULL) + hostfs_root = "/"; + + /* Initialize all the devices */ + devinit(); + + /* Figure out where we're booting from */ + bootdev = getenv("bootdev"); + if (bootdev == NULL) + bootdev = hostdisk_gen_probe(); +#if defined(LOADER_ZFS_SUPPORT) + if (bootdev == NULL || strcmp(bootdev, "zfs:") == 0) { + /* + * Pseudo device that says go find the right ZFS pool. This will be + * the first pool that we find that passes the sanity checks (eg looks + * like it might be vbootable) and sets currdev to the right thing based + * on active BEs, etc + */ + if (hostdisk_zfs_find_default()) + bootdev = getenv("currdev"); + } +#endif + if (bootdev == NULL) + bootdev = "host:/"; + if (bootdev != NULL) { + /* + * Otherwise, honor what's on the command line. If we've been + * given a specific ZFS partition, then we'll honor it w/o BE + * processing that would otherwise pick a different snapshot to + * boot than the default one in the pool. + */ + set_currdev(bootdev); + } else { + panic("Bootdev is still NULL"); + } + + printf("Boot device: %s with hostfs_root %s\n", bootdev, hostfs_root); + + printf("\n%s", bootprog_info); + + setenv("LINES", "24", 1); + + memory_limits(); + enumerate_memory_arch(); + + interact(); /* doesn't return */ + + return (0); +} + +void +exit(int code) +{ + host_exit(code); + __unreachable(); +} + +void +delay(int usecs) +{ + struct host_timeval tvi, tv; + uint64_t ti, t; + host_gettimeofday(&tvi, NULL); + ti = tvi.tv_sec*1000000 + tvi.tv_usec; + do { + host_gettimeofday(&tv, NULL); + t = tv.tv_sec*1000000 + tv.tv_usec; + } while (t < ti + usecs); +} + +time_t +getsecs(void) +{ + struct host_timeval tv; + host_gettimeofday(&tv, NULL); + return (tv.tv_sec); +} + +time_t +time(time_t *tloc) +{ + time_t rv; + + rv = getsecs(); + if (tloc != NULL) + *tloc = rv; + + return (rv); +} + +struct host_kexec_segment loaded_segments[HOST_KEXEC_SEGMENT_MAX]; +int nkexec_segments = 0; + +#define SEGALIGN (1ul<<20) + +static ssize_t +get_phys_buffer(vm_offset_t dest, const size_t len, void **buf) +{ + int i = 0; + const size_t segsize = 64*1024*1024; + size_t sz, amt, l; + + if (nkexec_segments == HOST_KEXEC_SEGMENT_MAX) + panic("Tried to load too many kexec segments"); + for (i = 0; i < nkexec_segments; i++) { + if (dest >= (vm_offset_t)loaded_segments[i].mem && + dest < (vm_offset_t)loaded_segments[i].mem + + loaded_segments[i].bufsz) /* Need to use bufsz since memsz is in use size */ + goto out; + } + + sz = segsize; + if (nkexec_segments == 0) { + /* how much space does this segment have */ + sz = space_avail(dest); + /* Clip to 45% of available memory (need 2 copies) */ + sz = MIN(sz, rounddown2(mem_avail * 45 / 100, SEGALIGN)); + printf("limit to 45%% of mem_avail %zd\n", sz); + /* And only use 95% of what we can allocate */ + sz = MIN(sz, + rounddown2((commit_limit - committed_as) * 95 / 100, SEGALIGN)); + printf("Allocating %zd MB for first segment\n", sz >> 20); + } + + loaded_segments[nkexec_segments].buf = host_getmem(sz); + loaded_segments[nkexec_segments].bufsz = sz; + loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,SEGALIGN); + loaded_segments[nkexec_segments].memsz = 0; + + i = nkexec_segments; + nkexec_segments++; + +out: + /* + * Keep track of the highest amount used in a segment + */ + amt = dest - (vm_offset_t)loaded_segments[i].mem; + l = min(len,loaded_segments[i].bufsz - amt); + *buf = loaded_segments[i].buf + amt; + if (amt + l > loaded_segments[i].memsz) + loaded_segments[i].memsz = amt + l; + return (l); +} + +ssize_t +kboot_copyin(const void *src, vm_offset_t dest, const size_t len) +{ + ssize_t segsize, remainder; + void *destbuf; + + if (pa_start == PA_INVAL) { + pa_start = kboot_get_phys_load_segment(); + offset = dest; + get_phys_buffer(pa_start, len, &destbuf); + } + + remainder = len; + do { + segsize = get_phys_buffer(dest + pa_start + KERN_PADDING - offset, remainder, &destbuf); + bcopy(src, destbuf, segsize); + remainder -= segsize; + src += segsize; + dest += segsize; + } while (remainder > 0); + + return (len); +} + +ssize_t +kboot_copyout(vm_offset_t src, void *dest, const size_t len) +{ + ssize_t segsize, remainder; + void *srcbuf; + + remainder = len; + do { + segsize = get_phys_buffer(src + pa_start + KERN_PADDING - offset, remainder, &srcbuf); + bcopy(srcbuf, dest, segsize); + remainder -= segsize; + src += segsize; + dest += segsize; + } while (remainder > 0); + + return (len); +} + +ssize_t +kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) +{ + void *buf; + size_t resid, chunk, get; + ssize_t got; + vm_offset_t p; + + p = dest; + + chunk = min(PAGE_SIZE, len); + buf = malloc(chunk); + if (buf == NULL) { + printf("kboot_readin: buf malloc failed\n"); + return (0); + } + + for (resid = len; resid > 0; resid -= got, p += got) { + get = min(chunk, resid); + got = VECTX_READ(fd, buf, get); + if (got <= 0) { + if (got < 0) + printf("kboot_readin: read failed\n"); + break; + } + + kboot_copyin(buf, p, got); + } + + free (buf); + return (len - resid); +} + +int +kboot_autoload(void) +{ + + return (0); +} + +void +kboot_kseg_get(int *nseg, void **ptr) +{ + printf("kseg_get: %d segments\n", nkexec_segments); + printf("VA SZ PA MEMSZ\n"); + printf("---------------- -------- ---------------- -----\n"); + for (int a = 0; a < nkexec_segments; a++) { + /* + * Truncate each segment to just what we've used in the segment, + * rounded up to the next page. + */ + loaded_segments[a].memsz = roundup2(loaded_segments[a].memsz,PAGE_SIZE); + loaded_segments[a].bufsz = loaded_segments[a].memsz; + printf("%016jx %08jx %016jx %08jx\n", + (uintmax_t)loaded_segments[a].buf, + (uintmax_t)loaded_segments[a].bufsz, + (uintmax_t)loaded_segments[a].mem, + (uintmax_t)loaded_segments[a].memsz); + } + + *nseg = nkexec_segments; + *ptr = &loaded_segments[0]; +} + +static void +kboot_zfs_probe(void) +{ +#if defined(LOADER_ZFS_SUPPORT) + /* + * Open all the disks and partitions we can find to see if there are ZFS + * pools on them. + */ + hostdisk_zfs_probe(); +#endif +} + +#ifdef LOADER_FDT_SUPPORT +/* + * Since proper fdt command handling function is defined in fdt_loader_cmd.c, + * and declaring it as extern is in contradiction with COMMAND_SET() macro + * (which uses static pointer), we're defining wrapper function, which + * calls the proper fdt handling routine. + */ +static int +command_fdt(int argc, char *argv[]) +{ + + return (command_fdt_internal(argc, argv)); +} + +COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt); +#endif + +/* + * Support quitting. + */ +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return (CMD_OK); +} + +COMMAND_SET(quit, "quit", "exit the program", command_quit); diff --git a/stand/kboot/kboot/version b/stand/kboot/kboot/version new file mode 100644 index 000000000000..be162b693ada --- /dev/null +++ b/stand/kboot/kboot/version @@ -0,0 +1,2 @@ +3.0: Lua scripts API stability +0.1: Initial kboot/PowerPC version. diff --git a/stand/kboot/libkboot/Makefile b/stand/kboot/libkboot/Makefile new file mode 100644 index 000000000000..1c91636cc69b --- /dev/null +++ b/stand/kboot/libkboot/Makefile @@ -0,0 +1,24 @@ +.include <bsd.init.mk> + +LIB= kboot +WARNS?= 4 + +.PATH: ${.CURDIR}/arch/${MACHINE_ARCH} +CFLAGS+=-I${.CURDIR} -I${.CURDIR}/arch/${MACHINE_ARCH} +CFLAGS+=-I${LDRSRC} + +SRCS= crt1.c +SRCS+= dfk.c +SRCS+= host_syscall.S +SRCS+= host_syscalls.c +SRCS+= seg.c +SRCS+= termios.c +SRCS+= util.c + +.if ${MACHINE_ARCH} != "powerpc64" +SRCS+= efi.c +.endif + +.sinclude "${.CURDIR}/arch/${MACHINE_ARCH}/Makefile.inc" + +.include <bsd.lib.mk> diff --git a/stand/kboot/libkboot/arch/aarch64/host_syscall.S b/stand/kboot/libkboot/arch/aarch64/host_syscall.S new file mode 100644 index 000000000000..3b1c345f2cf6 --- /dev/null +++ b/stand/kboot/libkboot/arch/aarch64/host_syscall.S @@ -0,0 +1,20 @@ +#include <machine/asm.h> + +/* + * Emulate the Linux system call interface. System call number in x8. + * Args in x0, x1, x2, x3, x4 and x5. Return in x0. + */ +ENTRY(host_syscall) + mov x8, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + mov x5, x6 + svc 0 + ret +/* Note: We're exposing the raw return value to the caller */ +END(host_syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/libkboot/arch/aarch64/start_arch.h b/stand/kboot/libkboot/arch/aarch64/start_arch.h new file mode 100644 index 000000000000..467ba054c9f0 --- /dev/null +++ b/stand/kboot/libkboot/arch/aarch64/start_arch.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Provides a _start routine that calls a _start_c routine that takes a pointer + * to the stack as documented in crt1.c. We skip the pointer to _DYNAMIC since + * we don't support dynamic libraries, at all. And while _start_c is our own + * thing and doesn't have a second arg, we comport to the calling conventions + * that glibc and musl have by passing x1 as 0 for the dynamic pointer. We + * likely could call main directly with only a few more lines of code, but this + * is simple enough and concentrates all the expressable in C stuff there. We + * also generate eh_frames should we need to debug things (it doesn't change the + * genreated code, but leaves enough breadcrumbs to keep gdb happy) + */ + +__asm__( +".text\n" /* ENTRY(_start) -- can't expand and stringify, so by hand */ +".align 2\n" +".global _start\n" +".type _start, #function\n" +"_start:\n" +".cfi_startproc\n" +/* + * Linux zeros all registers so x29 (frame pointer) and x30 (link register) are 0. + */ +" mov x0, sp\n" /* Pointer to argc, etc kernel left on the stack */ +" and sp, x0, #-16\n" /* Align stack to 16-byte boundary */ +" b _start_c\n" /* Our MI code takes it from here */ +/* NORETURN */ +".ltorg\n" /* END(_start) */ +".cfi_endproc\n" +".size _start, .-_start\n" +); diff --git a/stand/kboot/arch/amd64/host_syscall.S b/stand/kboot/libkboot/arch/amd64/host_syscall.S index 5bf0fca0cec1..0869bfe245f6 100644 --- a/stand/kboot/arch/amd64/host_syscall.S +++ b/stand/kboot/libkboot/arch/amd64/host_syscall.S @@ -27,3 +27,5 @@ ENTRY(host_syscall) ret /* Note: We're exposing the raw return value to the caller */ END(host_syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/libkboot/arch/amd64/start_arch.h b/stand/kboot/libkboot/arch/amd64/start_arch.h new file mode 100644 index 000000000000..818a5b277c10 --- /dev/null +++ b/stand/kboot/libkboot/arch/amd64/start_arch.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Provides a _start routine that calls a _start_c routine that takes a pointer + * to the stack as documented in crt1.c. We skip the pointer to _DYNAMIC since + * we don't support dynamic libraries, at all. And while _start_c is our own + * thing, we comport to the calling conventions that glibc and musl have and + * make sure the second argument (%esi) is 0 for _DYNAMIC placeholder. We + * likely could call main directly with only a few more lines of code, but this + * is simple enough and concentrates all the expressable in C stuff there. We + * also generate eh_frames should we need to debug things (it doesn't change the + * genreated code, but leaves enough breadcrumbs to keep gdb happy). + */ + +__asm__( +".text\n" /* ENTRY(_start) */ +".p2align 4,0x90\n" +".global _start\n" +".type _start, @function\n" +"_start:\n" +".cfi_startproc\n" +" xor %rbp, %rbp\n" /* Clear out the stack frame pointer */ +" mov %rsp, %rdi\n" /* Pass pointer to current stack with argc, argv and envp on it */ +" xor %rsi, %rsi\n" /* No dynamic pointer for us, to keep it simple */ +" andq $-16, %rsp\n" /* Align stack to 16-byte boundary */ +" call _start_c\n" /* Our MI code takes it from here and won't return */ +/* NORETURN */ +".size _start, . - _start\n" /* END(_start) */ +".cfi_endproc" +); diff --git a/stand/kboot/libkboot/arch/powerpc64/Makefile.inc b/stand/kboot/libkboot/arch/powerpc64/Makefile.inc new file mode 100644 index 000000000000..4cafaee28847 --- /dev/null +++ b/stand/kboot/libkboot/arch/powerpc64/Makefile.inc @@ -0,0 +1,4 @@ +CFLAGS+= -mcpu=powerpc64 + +.PATH: ${SYSDIR}/libkern +SRCS+= ucmpdi2.c diff --git a/stand/kboot/arch/powerpc64/host_syscall.S b/stand/kboot/libkboot/arch/powerpc64/host_syscall.S index f9108065ebfa..84fde2041704 100644 --- a/stand/kboot/arch/powerpc64/host_syscall.S +++ b/stand/kboot/libkboot/arch/powerpc64/host_syscall.S @@ -30,3 +30,5 @@ ENTRY(host_syscall) blr /* Note: We're exposing the raw return value to the caller */ END(host_syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/libkboot/arch/powerpc64/start_arch.h b/stand/kboot/libkboot/arch/powerpc64/start_arch.h new file mode 100644 index 000000000000..498de29ad0fe --- /dev/null +++ b/stand/kboot/libkboot/arch/powerpc64/start_arch.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Due to the PowerPC ABI, We can call main directly from here, so do so. + * + * Note: there may be some static initializers that aren't called, but we don't + * worry about that elsewhere. This is a stripped down environment. + * + * I think we could also do something like + * + * mflr r0 + * stw r0,4(r1) + * stwu r1,-16(r1) + * b _start_c + * + * But my powerpc assembler fu is quite lacking... + */ + +#define __unused __attribute__((__unused__)) + +void +_start(int argc, const char **argv, char **env, void *obj __unused, + void (*cleanup)(void) __unused) +{ + main(argc, argv, env); +} diff --git a/stand/kboot/libkboot/crt1.c b/stand/kboot/libkboot/crt1.c new file mode 100644 index 000000000000..67ddacccfd26 --- /dev/null +++ b/stand/kboot/libkboot/crt1.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * MI part of the C startup code. We take a long * pointer (we assume long is + * the same size as a pointer, as the Linux world is wont to do). We get a + * pointer to the stack with the main args on it. We don't bother decoding the + * aux vector, but may need to do so in the future. + * + * The long *p points to: + * + * +--------------------+ + * | argc | Small address + * +--------------------+ + * | argv[0] | argv + * +--------------------+ + * | argv[1] | + * +--------------------+ + * ... + * +--------------------+ + * | NULL | &argv[argc] + * +--------------------+ + * | envp[0] | envp + * +--------------------+ + * | envp[1] | + * +--------------------+ + * ... + * +--------------------+ + * | NULL | + * +--------------------+ + * | aux type | AT_xxxx + * +--------------------+ + * | aux value | + * +--------------------+ + * | aux type | AT_xxxx + * +--------------------+ + * | aux value | + * +--------------------+ + * | aux type | AT_xxxx + * +--------------------+ + * | aux value | + * +--------------------+ + *... + * +--------------------+ + * | NULL | + * +--------------------+ + * + * The AUX vector contains additional information for the process to know from + * the kernel (not parsed currently). AT_xxxx constants are small (< 50). + */ + +extern void _start_c(long *); +extern int main(int, const char **, char **); + +#include "start_arch.h" + +void *stack_upper_limit; + +void +_start_c(long *p) +{ + int argc; + const char **argv; + char **envp; + + stack_upper_limit = p; /* Save the upper limit of call stack */ + argc = p[0]; + argv = (const char **)(p + 1); + envp = (char **)argv + argc + 1; + + /* Note: we don't ensure that fd 0, 1, and 2 are sane at this level */ + /* Also note: we expect main to exit, not return off the end */ + main(argc, argv, envp); +} diff --git a/stand/kboot/libkboot/dfk.c b/stand/kboot/libkboot/dfk.c new file mode 100644 index 000000000000..09f4512f5c99 --- /dev/null +++ b/stand/kboot/libkboot/dfk.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2025 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Common macros to allow compiling this as a Linux binary or in libsa. + */ +#ifdef _STANDALONE +#include "stand.h" +/* Not ideal, but these are missing in libsa */ +#define perror(msg) printf("ERROR %d: %s\n", errno, msg) +#define fprintf(x, ...) printf( __VA_ARGS__ ) +#include <machine/elf.h> +#include <sys/param.h> +#include "util.h" +#else +#include <elf.h> +#include <errno.h> +#include <fcntl.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <asm/bootparam.h> + +#define PAGE_SIZE 4096 +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +#define ELF_TARG_CLASS ELFCLASS64 +#define ELF_TARG_MACH EM_X86_64 +#define ELF_TARG_DATA ELFDATA2LSB +#endif + +#define KCORE_PATH "/proc/kcore" +#define KALLSYMS_PATH "/proc/kallsyms" + +struct elf_file +{ + uint8_t buf[PAGE_SIZE]; + int fd; +}; + +// All the line_buffer stuff can be replaced by fgetstr() + +struct line_buffer +{ + int fd; + char buf[PAGE_SIZE]; + char *pos; + char *eos; +}; + +/* + * We just assume we have to fill if we are called. + */ +static bool +lb_fill(struct line_buffer *lb) +{ + ssize_t rv; + + lb->pos = lb->eos = lb->buf; // Reset to no data condition + rv = read(lb->fd, lb->buf, sizeof(lb->buf)); + if (rv <= 0) + return (false); + lb->pos = lb->buf; + lb->eos = lb->buf + rv; + return (true); +} + +static bool +lb_fini(struct line_buffer *lb) +{ + close(lb->fd); + return (true); +} + +static bool +lb_init(struct line_buffer *lb, const char *fn) +{ + lb->fd = open(fn, O_RDONLY); + if (lb->fd == -1) + return (false); + lb->pos = lb->eos = lb->buf; + if (!lb_fill(lb)) { + lb_fini(lb); + return (false); + } + return (true); +} + +// True -> data returned +// False -> EOF / ERROR w/o data +static bool +lb_1line(struct line_buffer *lb, char *buffer, size_t buflen) +{ + char *bufeos = buffer + buflen - 1; // point at byte for NUL at eos + char *walker = buffer; + + while (walker < bufeos) { // < to exclude space for NUL + if (lb->pos >= lb->eos) { // Refill empty buffer + if (!lb_fill(lb)) { // Hit EOF / error + if (walker > buffer) // Have data? return it + break; + // No data, signal EOF/Error + return (false); + } + } + *walker = *lb->pos++; + if (*walker == '\n') + break; + walker++; + } + /* + * We know walker <= bufeos, so NUL will fit. + */ + *++walker = '\0'; + return (true); +} + +/* + * Scan /proc/kallsyms to find @symbol and return the value it finds there. + */ +unsigned long +symbol_addr(const char *symbol) +{ + struct line_buffer lb; + unsigned long addr; + char line[256]; + + if (!lb_init(&lb, KALLSYMS_PATH)) + return (0); + while (lb_1line(&lb, line, sizeof(line))) { + char *val, *name, *x, t; + + /* + * Parse lines of the form + * val<sp>t<sp>name\n + * looking for one with t in [dDbB] (so data) name == symbol, + * skipping lines that don't match the pattern. + */ + val = line; + x = strchr(val, ' '); + if (x == NULL) + continue; /* No 1st <sp> */ + *x++ = '\0'; + t = *x++; + if (strchr("dDbB", t) == NULL) + continue; /* Only data types */ + if (*x++ != ' ') + continue; /* No 2nd <sp> */ + name = x; + x = strchr(x, '\n'); + if (x == NULL) + continue; /* No traling newline */ + *x++ = '\0'; + if (strcmp(name, symbol) == 0) { + unsigned long v; + char *eop = NULL; + lb_fini(&lb); + v = strtoul(val, &eop, 16); + if (*eop == '\0') + return (v); + return (0); /* PARSE ERROR -- what to do? */ + } + /* No match, try next */ + } + + lb_fini(&lb); + return (0); +} + +/* + * Parse /proc/kcore to find if we can get the data for @len bytes that are + * mapped in the kernel at VA @addr. It's a CORE file in ELF format that the + * kernel exports for the 'safe' areas to touch. We can read random kernel + * varaibles, but we can't read arbitrary addresses since it doesn't export + * the direct map. + */ +bool +read_at_address(unsigned long addr, void *buf, size_t len) +{ + struct elf_file ef; + Elf64_Ehdr *hdr; + Elf64_Phdr *phdr; + ssize_t rv; + + bzero(&ef, sizeof(ef)); + ef.fd = open(KCORE_PATH, O_RDONLY); + if (ef.fd == -1) { + perror("open " KCORE_PATH "\n"); + return (false); + } + + /* + * Read in the first page. ELF files have a header that says how many + * sections are in the file, whre they are, etc. All the Phdr are in the + * first page. Read it, verify the headers, then loop through these Phdr + * to find the address where addr is mapped to read it. + */ + rv = read(ef.fd, ef.buf, sizeof(ef.buf)); + if (rv != sizeof(ef.buf)) { + perror("short hdr read\n"); + close(ef.fd); + return (false); + } + hdr = (Elf64_Ehdr *)&ef.buf; + if (!IS_ELF(*hdr)) { + fprintf(stderr, "Not Elf\n"); + close(ef.fd); + return (false); + } + if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */ + hdr->e_ident[EI_DATA] != ELF_TARG_DATA || + hdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */ + hdr->e_version != EV_CURRENT || + hdr->e_machine != ELF_TARG_MACH || /* Machine ? */ + hdr->e_type != ET_CORE) { + fprintf(stderr, "Not what I expect\n"); + close(ef.fd); + return (false); + } + + phdr = (Elf64_Phdr *)(ef.buf + hdr->e_phoff); + for (int i = 0; i < hdr->e_phnum; i++) { + if (phdr[i].p_type != PT_LOAD) + continue; + if (addr < phdr[i].p_vaddr || + addr >= phdr[i].p_vaddr + phdr[i].p_filesz) + continue; + lseek(ef.fd, (off_t)phdr[i].p_offset + addr - phdr[i].p_vaddr, + SEEK_SET); + rv = read(ef.fd, buf, len); + if (rv != len) + perror("Can't read buffer\n"); + close(ef.fd); + return (rv == len); + } + + close(ef.fd); + return (false); +} + +/* + * Read a value from the Linux kernel. We lookup @sym and read @len bytes into + * @buf. Returns true if we got it, false on an error. + */ +bool +data_from_kernel(const char *sym, void *buf, size_t len) +{ + unsigned long addr; + + addr = symbol_addr(sym); + if (addr == 0) { + fprintf(stderr, "Can't find symbol %s", sym); + return (false); + } + if (!read_at_address(addr, buf, len)) { + fprintf(stderr, "Can't read from kernel"); + return (false); + } + return (true); +} + +#ifndef _STANDALONE +/* + * Silly little test case to test on a random Linux system. + */ +int +main(int argc, char **argv) +{ + struct boot_params bp; + + if (data_from_kernel("boot_params", &bp, sizeof(bp))) { + fprintf(stderr, "Something went wrong\n"); + } else { + printf("sig %#x systab %#lx memmap %#lx mmapsize %d md_size %d md_vers %d\n", + bp.efi_info.efi_loader_signature, + (long)(bp.efi_info.efi_systab | ((long)bp.efi_info.efi_systab_hi << 32)), + (long)(bp.efi_info.efi_memmap | ((long)bp.efi_info.efi_memmap_hi << 32)), + bp.efi_info.efi_memmap_size, bp.efi_info.efi_memdesc_size, + bp.efi_info.efi_memdesc_version); + } +} +#endif diff --git a/stand/kboot/libkboot/efi.c b/stand/kboot/libkboot/efi.c new file mode 100644 index 000000000000..3f1055f6d538 --- /dev/null +++ b/stand/kboot/libkboot/efi.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/param.h> +#include <sys/linker.h> +#include "stand.h" +#include "bootstrap.h" +#include "efi.h" +#include "seg.h" +#include "util.h" + +vm_paddr_t efi_systbl_phys; +struct efi_map_header *efi_map_hdr; +uint32_t efi_map_size; +vm_paddr_t efi_map_phys_src; /* From DTB */ +vm_paddr_t efi_map_phys_dst; /* From our memory map metadata module */ + +void +efi_set_systbl(uint64_t tbl) +{ + efi_systbl_phys = tbl; +} + +#if 0 +/* Note: This is useless since runtime-map is a subset */ +void +efi_read_from_sysfs(void) +{ + uint32_t efisz, sz, map_size; + int entries = 0; + struct efi_md *map; /* Really an array */ + char *buf; + struct stat sb; + char fn[100]; + + /* + * Count the number of entries we have. They are numbered from 0 + * through entries - 1. + */ + do { + printf("Looking at index %d\n", entries); + snprintf(fn, sizeof(fn), "/sys/firmware/efi/runtime-map/%d/phys_addr", entries++); + } while (stat(fn, &sb) == 0); + + /* + * We incremented entries one past the first failure, so we need to + * adjust the count and the test for 'nothing found' is against 1. + */ + if (entries == 1) + goto err; + entries--; + + /* XXX lots of copied code, refactor? */ + map_size = sizeof(struct efi_md) * entries; + efisz = roundup2(sizeof(*efi_map_hdr), 16); + sz = efisz + map_size; + buf = malloc(efisz + map_size); + if (buf == NULL) + return; + efi_map_hdr = (struct efi_map_header *)buf; + efi_map_size = sz; + map = (struct efi_md *)(buf + efisz); + bzero(map, sz); + efi_map_hdr->memory_size = map_size; + efi_map_hdr->descriptor_size = sizeof(struct efi_md); + efi_map_hdr->descriptor_version = EFI_MEMORY_DESCRIPTOR_VERSION; + for (int i = 0; i < entries; i++) { + struct efi_md *m; + + printf("Populating index %d\n", i); + m = map + i; + snprintf(fn, sizeof(fn), "/sys/firmware/efi/runtime-map/%d/type", i); + if (!file2u32(fn, &m->md_type)) + goto err; + snprintf(fn, sizeof(fn), "/sys/firmware/efi/runtime-map/%d/phys_addr", i); + if (!file2u64(fn, &m->md_phys)) + goto err; + snprintf(fn, sizeof(fn), "/sys/firmware/efi/runtime-map/%d/virt_addr", i); + if (!file2u64(fn, &m->md_virt)) + goto err; + snprintf(fn, sizeof(fn), "/sys/firmware/efi/runtime-map/%d/num_pages", i); + if (!file2u64(fn, &m->md_pages)) + goto err; + snprintf(fn, sizeof(fn), "/sys/firmware/efi/runtime-map/%d/attribute", i); + if (!file2u64(fn, &m->md_attr)) + goto err; + } + efi_map_phys_src = 0; + printf("UEFI MAP:\n"); + print_efi_map(efi_map_hdr); + printf("DONE\n"); + return; +err: + printf("Parse error in reading current memory map\n"); +} +#endif + +/* + * We may have no ability to read the PA that this map is in, so pass + * the address to FreeBSD via a rather odd flag entry as the first map + * so early boot can copy the memory map into this space and have the + * rest of the code cope. + */ +bool +efi_read_from_pa(uint64_t pa, uint32_t map_size, uint32_t desc_size, uint32_t vers) +{ + uint32_t efisz, sz; + char *buf; + int fd2, len; + struct efi_md *map; /* Really an array */ + + /* + * We may have no ability to read the PA that this map is in, so pass + * the address to FreeBSD via a rather odd flag entry as the first map + * so early boot can copy the memory map into this space and have the + * rest of the code cope. We also have to round the size of the header + * to 16 byte boundary. + */ + efisz = roundup2(sizeof(*efi_map_hdr), 16); + sz = efisz + map_size; + buf = malloc(efisz + map_size); + if (buf == NULL) + return false; + efi_map_hdr = (struct efi_map_header *)buf; + efi_map_size = sz; + map = (struct efi_md *)(buf + efisz); + bzero(map, sz); + efi_map_hdr->memory_size = map_size; + efi_map_hdr->descriptor_size = desc_size; + efi_map_hdr->descriptor_version = vers; + + /* + * Try to read in the actual UEFI map. This may fail, and that's OK. We just + * won't print the map. + */ + fd2 = open("host:/dev/mem", O_RDONLY); + if (fd2 < 0) + goto no_read; + if (lseek(fd2, pa, SEEK_SET) < 0) + goto no_read; + len = read(fd2, map, sz); + if (len != sz) + goto no_read; + efi_map_phys_src = 0; /* Mark MODINFOMD_EFI_MAP as valid */ + close(fd2); + printf("UEFI MAP:\n"); + print_efi_map(efi_map_hdr); + return (true); + +no_read: /* Just get it the trampoline */ + efi_map_phys_src = pa; + close(fd2); + return (true); +} + +void +foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp) +{ + struct efi_md *map, *p; + size_t efisz; + int ndesc, i; + + /* + * Memory map data provided by UEFI via the GetMemoryMap + * Boot Services API. + */ + efisz = roundup2(sizeof(struct efi_map_header), 16); + map = (struct efi_md *)((uint8_t *)efihdr + efisz); + + if (efihdr->descriptor_size == 0) + return; + ndesc = efihdr->memory_size / efihdr->descriptor_size; + + for (i = 0, p = map; i < ndesc; i++, + p = efi_next_descriptor(p, efihdr->descriptor_size)) { + cb(p, argp); + } +} + +/* XXX REFACTOR WITH KERNEL */ +static void +print_efi_map_entry(struct efi_md *p, void *argp __unused) +{ + const char *type; + static const char *types[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "BootServicesCode", + "BootServicesData", + "RuntimeServicesCode", + "RuntimeServicesData", + "ConventionalMemory", + "UnusableMemory", + "ACPIReclaimMemory", + "ACPIMemoryNVS", + "MemoryMappedIO", + "MemoryMappedIOPortSpace", + "PalCode", + "PersistentMemory" + }; + + if (p->md_type < nitems(types)) + type = types[p->md_type]; + else + type = "<INVALID>"; + printf("%23s %012lx %012lx %08lx ", type, p->md_phys, + p->md_virt, p->md_pages); + if (p->md_attr & EFI_MD_ATTR_UC) + printf("UC "); + if (p->md_attr & EFI_MD_ATTR_WC) + printf("WC "); + if (p->md_attr & EFI_MD_ATTR_WT) + printf("WT "); + if (p->md_attr & EFI_MD_ATTR_WB) + printf("WB "); + if (p->md_attr & EFI_MD_ATTR_UCE) + printf("UCE "); + if (p->md_attr & EFI_MD_ATTR_WP) + printf("WP "); + if (p->md_attr & EFI_MD_ATTR_RP) + printf("RP "); + if (p->md_attr & EFI_MD_ATTR_XP) + printf("XP "); + if (p->md_attr & EFI_MD_ATTR_NV) + printf("NV "); + if (p->md_attr & EFI_MD_ATTR_MORE_RELIABLE) + printf("MORE_RELIABLE "); + if (p->md_attr & EFI_MD_ATTR_RO) + printf("RO "); + if (p->md_attr & EFI_MD_ATTR_RT) + printf("RUNTIME"); + printf("\n"); +} + +void +print_efi_map(struct efi_map_header *efihdr) +{ + printf("%23s %12s %12s %8s %4s\n", + "Type", "Physical", "Virtual", "#Pages", "Attr"); + + foreach_efi_map_entry(efihdr, print_efi_map_entry, NULL); +} + +void +efi_bi_loadsmap(struct preloaded_file *kfp) +{ + /* + * Make a note of a systbl. This is nearly mandatory on AARCH64. + */ + if (efi_systbl_phys) + file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof(efi_systbl_phys), &efi_systbl_phys); + + /* + * If we have efi_map_hdr, then it's a pointer to the PA where this + * memory map lives. The trampoline code will copy it over. If we don't + * have it, panic because /proc/iomem isn't sufficient and there's no + * hope. + */ + if (efi_map_hdr != NULL) { + file_addmetadata(kfp, MODINFOMD_EFI_MAP, efi_map_size, efi_map_hdr); + return; + } + + panic("Can't get UEFI memory map, nor a pointer to it, can't proceed.\n"); +} diff --git a/stand/kboot/libkboot/host_syscalls.c b/stand/kboot/libkboot/host_syscalls.c new file mode 100644 index 000000000000..551ff6b777d6 --- /dev/null +++ b/stand/kboot/libkboot/host_syscalls.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022-2024, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "host_syscall.h" +#include "syscall_nr.h" +#include <stand.h> + +/* + * Various trivial wrappers for Linux system calls. Please keep sorted + * alphabetically. + */ + +int +host_close(int fd) +{ + return host_syscall(SYS_close, fd); +} + +int +host_dup(int fd) +{ + return host_syscall(SYS_dup, fd); +} + +int +host_exit(int code) +{ + return host_syscall(SYS_exit, code); +} + +/* Same system call with different names on different Linux architectures due to history */ +int +host_fstat(int fd, struct host_kstat *sb) +{ +#ifdef SYS_newfstat + return host_syscall(SYS_newfstat, fd, (uintptr_t)sb); +#else + return host_syscall(SYS_fstat, fd, (uintptr_t)sb); +#endif +} + +int +host_getdents64(int fd, void *dirp, int count) +{ + return host_syscall(SYS_getdents64, fd, (uintptr_t)dirp, count); +} + +int +host_getpid(void) +{ + return host_syscall(SYS_getpid); +} + +int +host_gettimeofday(struct host_timeval *a, void *b) +{ + return host_syscall(SYS_gettimeofday, (uintptr_t)a, (uintptr_t)b); +} + +int +host_ioctl(int fd, unsigned long request, unsigned long arg) +{ + return host_syscall(SYS_ioctl, fd, request, arg); +} + +ssize_t +host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence) +{ +#ifdef SYS_llseek + return host_syscall(SYS_llseek, fd, offset_high, offset_lo, (uintptr_t)result, whence); +#else + int64_t rv = host_syscall(SYS_lseek, fd, + (int64_t)((uint64_t)offset_high << 32 | (uint32_t)offset_lo), whence); + if (rv > 0) + *result = (uint64_t)rv; + return (rv); +#endif +} + +int +host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags) +{ + return host_syscall(SYS_kexec_load, entry, nsegs, segs, flags); +} + +int +host_mkdir(const char *path, host_mode_t mode) +{ + return host_syscall(SYS_mkdirat, HOST_AT_FDCWD, (uintptr_t)path, mode); +} + +void * +host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off) +{ + return (void *)host_syscall(SYS_mmap, (uintptr_t)addr, len, prot, flags, fd, off); +} + +int +host_mount(const char *src, const char *target, const char *type, unsigned long flags, + void *data) +{ + return host_syscall(SYS_mount, src, target, type, flags, data); +} + +int +host_munmap(void *addr, size_t len) +{ + return host_syscall(SYS_munmap, (uintptr_t)addr, len); +} + +int +host_open(const char *path, int flags, int mode) +{ + return host_syscall(SYS_openat, HOST_AT_FDCWD, (uintptr_t)path, flags, mode); + /* XXX original overrode errors */ +} + +ssize_t +host_read(int fd, void *buf, size_t nbyte) +{ + return host_syscall(SYS_read, fd, (uintptr_t)buf, nbyte); + /* XXX original overrode errors */ +} + +int +host_reboot(int magic1, int magic2, int cmd, uintptr_t arg) +{ + return host_syscall(SYS_reboot, magic1, magic2, cmd, arg); +} + +int +host_select(int nfds, long *readfds, long *writefds, long *exceptfds, + struct host_timeval *timeout) +{ + struct timespec ts = { .tv_sec = timeout->tv_sec, .tv_nsec = timeout->tv_usec * 1000 }; + + /* + * Note, final arg is a sigset_argpack since most arch can only have 6 + * syscall args. Since we're not masking signals, though, we can just + * pass a NULL. + */ + return host_syscall(SYS_pselect6, nfds, (uintptr_t)readfds, (uintptr_t)writefds, + (uintptr_t)exceptfds, (uintptr_t)&ts, (uintptr_t)NULL); +} + +int +host_stat(const char *path, struct host_kstat *sb) +{ + return host_syscall(SYS_newfstatat, HOST_AT_FDCWD, (uintptr_t)path, (uintptr_t)sb, 0); +} + +int +host_symlink(const char *path1, const char *path2) +{ + return host_syscall(SYS_symlinkat, HOST_AT_FDCWD, path1, path2); +} + +int +host_uname(struct old_utsname *uts) +{ + return host_syscall(SYS_uname, (uintptr_t)uts); +} + +ssize_t +host_write(int fd, const void *buf, size_t nbyte) +{ + return host_syscall(SYS_write, fd, (uintptr_t)buf, nbyte); +} diff --git a/stand/kboot/libkboot/seg.c b/stand/kboot/libkboot/seg.c new file mode 100644 index 000000000000..708170b6c381 --- /dev/null +++ b/stand/kboot/libkboot/seg.c @@ -0,0 +1,368 @@ +/*- + * Copyright (c) 2023, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "stand.h" +#include "seg.h" + +#include <sys/param.h> + +static struct memory_segments *segs; +static int nr_seg = 0; +static int segalloc = 0; + +void +init_avail(void) +{ + if (segs) + free(segs); + nr_seg = 0; + segalloc = 16; + free(segs); + segs = malloc(sizeof(*segs) * segalloc); + if (segs == NULL) + panic("not enough memory to get memory map\n"); +} + +/* + * Make sure at least n items can be accessed in the segs array. Note the + * realloc here will invalidate cached pointers (potentially), so addresses + * into the segs array must be recomputed after this call. + */ +void +need_avail(int n) +{ + if (n <= segalloc) + return; + + while (n > segalloc) + segalloc *= 2; + segs = realloc(segs, segalloc * sizeof(*segs)); + if (segs == NULL) + panic("not enough memory to get memory map\n"); +} + +/* + * Always called for a new range, so always just append a range, + * unless it's continuous with the prior range. + */ +void +add_avail(uint64_t start, uint64_t end, uint64_t type) +{ + /* + * This range is contiguous with the previous range, and is + * the same type: we can collapse the two. + */ + if (nr_seg >= 1 && + segs[nr_seg - 1].end + 1 == start && + segs[nr_seg - 1].type == type) { + segs[nr_seg - 1].end = end; + return; + } + + /* + * Otherwise we need to add a new range at the end, but don't need to + * adjust the current end. + */ + need_avail(nr_seg + 1); + segs[nr_seg].start = start; + segs[nr_seg].end = end; + segs[nr_seg].type = type; + nr_seg++; +} + +/* + * All or part of a prior entry needs to be modified. Given the structure of the + * code, we know that it will always be modifying the last time and/or extending + * the one before it if its contiguous. + */ +void +remove_avail(uint64_t start, uint64_t end, uint64_t type) +{ + struct memory_segments *s; + + /* + * simple case: we are extending a previously removed item. + */ + if (nr_seg >= 2) { + s = &segs[nr_seg - 2]; + if (s->end + 1 == start && + s->type == type) { + s->end = end; + /* Now adjust the ending element */ + s++; + if (s->end == end) { + /* we've used up the 'free' space */ + nr_seg--; + return; + } + /* Otherwise adjust the 'free' space */ + s->start = end + 1; + return; + } + } + + /* + * OK, we have four cases: + * (1) The new chunk is at the start of the free space, but didn't catch the above + * folding for whatever reason (different type, start of space). In this case, + * we allocate 1 additional item. The current end is copied to the new end. The + * current end is set to <start, end, type> and the new end's start is set to end + 1. + * (2) The new chunk is in the middle of the free space. In this case we allocate 2 + * additional items. We copy the current end to the new end, set the new end's start + * to end + 1, the old end's end to start - 1 and the new item is <start, end, type> + * (3) The new chunk is at the end of the current end. In this case we allocate 1 more + * and adjust the current end's end to start - 1 and set the new end to <start, end, type>. + * (4) The new chunk is exactly the current end, except for type. In this case, we just adjust + * the type. + * We can assume we always have at least one chunk since that's created with new_avail() above + * necessarily before we are called to subset it. + */ + s = &segs[nr_seg - 1]; + if (s->start == start) { + if (s->end == end) { /* (4) */ + s->type = type; + return; + } + /* chunk at start of old chunk -> (1) */ + need_avail(nr_seg + 1); + s = &segs[nr_seg - 1]; /* Realloc may change pointers */ + s[1] = s[0]; + s->start = start; + s->end = end; + s->type = type; + s[1].start = end + 1; + nr_seg++; + return; + } + if (s->end == end) { /* At end of old chunk (3) */ + need_avail(nr_seg + 1); + s = &segs[nr_seg - 1]; /* Realloc may change pointers */ + s[1] = s[0]; + s->end = start - 1; + s[1].start = start; + s[1].type = type; + nr_seg++; + return; + } + /* In the middle, need to split things up (2) */ + need_avail(nr_seg + 2); + s = &segs[nr_seg - 1]; /* Realloc may change pointers */ + s[2] = s[1] = s[0]; + s->end = start - 1; + s[1].start = start; + s[1].end = end; + s[1].type = type; + s[2].start = end + 1; + nr_seg += 2; +} + +void +print_avail(void) +{ + printf("Found %d RAM segments:\n", nr_seg); + + for (int i = 0; i < nr_seg; i++) { + printf("%#jx-%#jx type %lu\n", + (uintmax_t)segs[i].start, + (uintmax_t)segs[i].end, + (u_long)segs[i].type); + } +} + +uint64_t +first_avail(uint64_t align, uint64_t min_size, uint64_t memtype) +{ + uint64_t s, len; + + for (int i = 0; i < nr_seg; i++) { + if (segs[i].type != memtype) /* Not candidate */ + continue; + s = roundup(segs[i].start, align); + if (s >= segs[i].end) /* roundup past end */ + continue; + len = segs[i].end - s + 1; + if (len >= min_size) { + printf("Found a big enough hole at in seg %d at %#jx (%#jx-%#jx)\n", + i, + (uintmax_t)s, + (uintmax_t)segs[i].start, + (uintmax_t)segs[i].end); + return (s); + } + } + + return (0); +} + +enum types { + system_ram = SYSTEM_RAM, + firmware_reserved, + linux_code, + linux_data, + linux_bss, + unknown, +}; + +static struct kv +{ + uint64_t type; + char * name; + int flags; +#define KV_KEEPER 1 +} str2type_kv[] = { + { linux_code, "Kernel code", KV_KEEPER }, + { linux_data, "Kernel data", KV_KEEPER }, + { linux_bss, "Kernel bss", KV_KEEPER }, + { firmware_reserved, "Reserved" }, +}; + +static const char * +parse_line(const char *line, uint64_t *startp, uint64_t *endp) +{ + const char *walker; + char *next; + uint64_t start, end; + + /* + * Each line is a range followed by a description of the form: + * <hex-number><dash><hex-number><space><colon><space><string> + * Bail if we have any parsing errors. + */ + walker = line; + start = strtoull(walker, &next, 16); + if (start == ULLONG_MAX || walker == next) + return (NULL); + walker = next; + if (*walker != '-') + return (NULL); + walker++; + end = strtoull(walker, &next, 16); + if (end == ULLONG_MAX || walker == next) + return (NULL); + walker = next; + /* Now eat the ' : ' in front of the string we want to return */ + if (strncmp(walker, " : ", 3) != 0) + return (NULL); + *startp = start; + *endp = end; + return (walker + 3); +} + +static struct kv * +kvlookup(const char *str, struct kv *kvs, size_t nkv) +{ + for (int i = 0; i < nkv; i++) + if (strcmp(kvs[i].name, str) == 0) + return (&kvs[i]); + + return (NULL); +} + +/* Trim trailing whitespace */ +static void +chop(char *line) +{ + char *ep = line + strlen(line) - 1; + + while (ep >= line && isspace(*ep)) + *ep-- = '\0'; +} + +#define SYSTEM_RAM_STR "System RAM" +#define RESERVED "reserved" + +bool +populate_avail_from_iomem(void) +{ + int fd; + char buf[128]; + const char *str; + uint64_t start, end; + struct kv *kv; + + fd = open("host:/proc/iomem", O_RDONLY); + if (fd == -1) { + printf("Can't get memory map\n"); + init_avail(); + // Hack: 32G of RAM starting at 4G + add_avail(4ull << 30, 36ull << 30, system_ram); + return false; + } + + if (fgetstr(buf, sizeof(buf), fd) < 0) + goto out; /* Nothing to do ???? */ + init_avail(); + chop(buf); + while (true) { + /* + * Look for top level items we understand. Skip anything that's + * a continuation, since we don't care here. If we care, we'll + * consume them all when we recognize that top level item. + */ + if (buf[0] == ' ') /* Continuation lines? Ignore */ + goto next_line; + str = parse_line(buf, &start, &end); + if (str == NULL) /* Malformed -> ignore */ + goto next_line; + /* + * All we care about is System RAM + */ + if (strncmp(str, SYSTEM_RAM_STR, sizeof(SYSTEM_RAM_STR) - 1) == 0) + add_avail(start, end, system_ram); + else if (strncmp(str, RESERVED, sizeof(RESERVED) - 1) == 0) + add_avail(start, end, firmware_reserved); + else + goto next_line; /* Ignore hardware */ + while (fgetstr(buf, sizeof(buf), fd) >= 0 && buf[0] == ' ') { + chop(buf); + str = parse_line(buf, &start, &end); + if (str == NULL) + break; + kv = kvlookup(str, str2type_kv, nitems(str2type_kv)); + if (kv == NULL) /* failsafe for new types: igonre */ + remove_avail(start, end, unknown); + else if ((kv->flags & KV_KEEPER) == 0) + remove_avail(start, end, kv->type); + /* Else no need to adjust since it's a keeper */ + } + + /* + * if buf[0] == ' ' then we know that the fgetstr failed and we + * should break. Otherwise fgetstr succeeded and we have a + * buffer we need to examine for being a top level item. + */ + if (buf[0] == ' ') + break; + chop(buf); + continue; /* buf has next top level line to parse */ +next_line: + if (fgetstr(buf, sizeof(buf), fd) < 0) + break; + } + +out: + close(fd); + return true; +} + +/* + * Return the amount of space available in the segment that @start@ lives in, + * from @start@ to the end of the segment. + */ +uint64_t +space_avail(uint64_t start) +{ + for (int i = 0; i < nr_seg; i++) { + if (start >= segs[i].start && start <= segs[i].end) + return segs[i].end - start; + } + + /* + * Properly used, we should never get here. Unsure if this should be a + * panic or not. + */ + return 0; +} diff --git a/stand/kboot/libkboot/termios.c b/stand/kboot/libkboot/termios.c new file mode 100644 index 000000000000..cd25b252f735 --- /dev/null +++ b/stand/kboot/libkboot/termios.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2005-2020 Rich Felker, et al. + * + * SPDX-License-Identifier: MIT + * + * Note: From the musl project, stripped down and repackaged with HOST_/host_ prepended + */ + +#include <sys/types.h> +#include "termios.h" +#include "host_syscall.h" + +int +host_tcgetattr(int fd, struct host_termios *tio) +{ + if (host_ioctl(fd, HOST_TCGETS, (uintptr_t)tio)) + return -1; + return 0; +} + +int +host_tcsetattr(int fd, int act, const struct host_termios *tio) +{ + if (act < 0 || act > 2) { + errno = EINVAL; /* XXX ?? */ + return -1; + } + return host_ioctl(fd, HOST_TCSETS+act, (uintptr_t)tio); +} + +void +host_cfmakeraw(struct host_termios *t) +{ + t->c_iflag &= ~(HOST_IGNBRK | HOST_BRKINT | HOST_PARMRK | HOST_ISTRIP | + HOST_INLCR | HOST_IGNCR | HOST_ICRNL | HOST_IXON); + t->c_oflag &= ~HOST_OPOST; + t->c_lflag &= ~(HOST_ECHO | HOST_ECHONL | HOST_ICANON | HOST_ISIG | + HOST_IEXTEN); + t->c_cflag &= ~(HOST_CSIZE | HOST_PARENB); + t->c_cflag |= HOST_CS8; + t->c_cc[HOST_VMIN] = 1; + t->c_cc[HOST_VTIME] = 0; +} + +int host_cfsetospeed(struct host_termios *tio, host_speed_t speed) +{ + if (speed & ~HOST_CBAUD) { +// errno = EINVAL; /* XXX ? */ + return -1; + } + tio->c_cflag &= ~HOST_CBAUD; + tio->c_cflag |= speed; + return 0; +} + +int host_cfsetispeed(struct host_termios *tio, host_speed_t speed) +{ + return speed ? host_cfsetospeed(tio, speed) : 0; +} + +int +host_cfsetspeed(struct host_termios *tio, host_speed_t speed) +{ + return host_cfsetospeed(tio, speed); /* weak alias in musl */ +} + diff --git a/stand/kboot/libkboot/util.c b/stand/kboot/libkboot/util.c new file mode 100644 index 000000000000..c7fe8b542643 --- /dev/null +++ b/stand/kboot/libkboot/util.c @@ -0,0 +1,59 @@ +/*- + * Copyright 2022 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "stand.h" +#include "host_syscall.h" +#include "util.h" + +bool +file2str(const char *fn, char *buffer, size_t buflen) +{ + int fd; + ssize_t len; + + fd = host_open(fn, HOST_O_RDONLY, 0); + if (fd == -1) + return false; + len = host_read(fd, buffer, buflen - 1); + if (len < 0) { + host_close(fd); + return false; + } + buffer[len] = '\0'; + /* + * Trim trailing white space + */ + while (isspace(buffer[len - 1])) + buffer[--len] = '\0'; + host_close(fd); + return true; +} + +bool +file2u64(const char *fn, uint64_t *val) +{ + unsigned long long v; + char buffer[80]; + + if (!file2str(fn, buffer, sizeof(buffer))) + return false; + v = strtoull(buffer, NULL, 0); /* XXX check return values? */ + *val = v; + return true; +} + +bool +file2u32(const char *fn, uint32_t *val) +{ + unsigned long v; + char buffer[80]; + + if (!file2str(fn, buffer, sizeof(buffer))) + return false; + v = strtoul(buffer, NULL, 0); /* XXX check return values? */ + *val = v; + return true; +} diff --git a/stand/kboot/main.c b/stand/kboot/main.c deleted file mode 100644 index 9b99c859070b..000000000000 --- a/stand/kboot/main.c +++ /dev/null @@ -1,501 +0,0 @@ -/*- - * Copyright (C) 2010-2014 Nathan Whitehorn - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <sys/endian.h> -#include <sys/param.h> -#include <fdt_platform.h> - -#include <machine/cpufunc.h> -#include <bootstrap.h> -#include "host_syscall.h" - - -struct arch_switch archsw; -extern void *_end; - -int kboot_getdev(void **vdev, const char *devspec, const char **path); -ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len); -ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len); -ssize_t kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); -int kboot_autoload(void); -uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr); -static void kboot_kseg_get(int *nseg, void **ptr); - -extern int command_fdt_internal(int argc, char *argv[]); - -struct region_desc { - uint64_t start; - uint64_t end; -}; - -static uint64_t -kboot_get_phys_load_segment(void) -{ - int fd; - uint64_t entry[2]; - static uint64_t load_segment = ~(0UL); - uint64_t val_64; - uint32_t val_32; - struct region_desc rsvd_reg[32]; - int rsvd_reg_cnt = 0; - int ret, a, b; - uint64_t start, end; - - if (load_segment == ~(0UL)) { - - /* Default load address is 0x00000000 */ - load_segment = 0UL; - - /* Read reserved regions */ - fd = host_open("/proc/device-tree/reserved-ranges", O_RDONLY, 0); - if (fd >= 0) { - while (host_read(fd, &entry[0], sizeof(entry)) == sizeof(entry)) { - rsvd_reg[rsvd_reg_cnt].start = be64toh(entry[0]); - rsvd_reg[rsvd_reg_cnt].end = - be64toh(entry[1]) + rsvd_reg[rsvd_reg_cnt].start - 1; - rsvd_reg_cnt++; - } - host_close(fd); - } - /* Read where the kernel ends */ - fd = host_open("/proc/device-tree/chosen/linux,kernel-end", O_RDONLY, 0); - if (fd >= 0) { - ret = host_read(fd, &val_64, sizeof(val_64)); - - if (ret == sizeof(uint64_t)) { - rsvd_reg[rsvd_reg_cnt].start = 0; - rsvd_reg[rsvd_reg_cnt].end = be64toh(val_64) - 1; - } else { - memcpy(&val_32, &val_64, sizeof(val_32)); - rsvd_reg[rsvd_reg_cnt].start = 0; - rsvd_reg[rsvd_reg_cnt].end = be32toh(val_32) - 1; - } - rsvd_reg_cnt++; - - host_close(fd); - } - /* Read memory size (SOCKET0 only) */ - fd = host_open("/proc/device-tree/memory@0/reg", O_RDONLY, 0); - if (fd < 0) - fd = host_open("/proc/device-tree/memory/reg", O_RDONLY, 0); - if (fd >= 0) { - ret = host_read(fd, &entry, sizeof(entry)); - - /* Memory range in start:length format */ - entry[0] = be64toh(entry[0]); - entry[1] = be64toh(entry[1]); - - /* Reserve everything what is before start */ - if (entry[0] != 0) { - rsvd_reg[rsvd_reg_cnt].start = 0; - rsvd_reg[rsvd_reg_cnt].end = entry[0] - 1; - rsvd_reg_cnt++; - } - /* Reserve everything what is after end */ - if (entry[1] != 0xffffffffffffffffUL) { - rsvd_reg[rsvd_reg_cnt].start = entry[0] + entry[1]; - rsvd_reg[rsvd_reg_cnt].end = 0xffffffffffffffffUL; - rsvd_reg_cnt++; - } - - host_close(fd); - } - - /* Sort entries in ascending order (bubble) */ - for (a = rsvd_reg_cnt - 1; a > 0; a--) { - for (b = 0; b < a; b++) { - if (rsvd_reg[b].start > rsvd_reg[b + 1].start) { - struct region_desc tmp; - tmp = rsvd_reg[b]; - rsvd_reg[b] = rsvd_reg[b + 1]; - rsvd_reg[b + 1] = tmp; - } - } - } - - /* Join overlapping/adjacent regions */ - for (a = 0; a < rsvd_reg_cnt - 1; ) { - - if ((rsvd_reg[a + 1].start >= rsvd_reg[a].start) && - ((rsvd_reg[a + 1].start - 1) <= rsvd_reg[a].end)) { - /* We have overlapping/adjacent regions! */ - rsvd_reg[a].end = - MAX(rsvd_reg[a].end, rsvd_reg[a + a].end); - - for (b = a + 1; b < rsvd_reg_cnt - 1; b++) - rsvd_reg[b] = rsvd_reg[b + 1]; - rsvd_reg_cnt--; - } else - a++; - } - - /* Find the first free region */ - if (rsvd_reg_cnt > 0) { - start = 0; - end = rsvd_reg[0].start; - for (a = 0; a < rsvd_reg_cnt - 1; a++) { - if ((start >= rsvd_reg[a].start) && - (start <= rsvd_reg[a].end)) { - start = rsvd_reg[a].end + 1; - end = rsvd_reg[a + 1].start; - } else - break; - } - - if (start != end) { - uint64_t align = 64UL*1024UL*1024UL; - - /* Align both to 64MB boundary */ - start = (start + align - 1UL) & ~(align - 1UL); - end = ((end + 1UL) & ~(align - 1UL)) - 1UL; - - if (start < end) - load_segment = start; - } - } - } - - return (load_segment); -} - -uint8_t -kboot_get_kernel_machine_bits(void) -{ - static uint8_t bits = 0; - struct old_utsname utsname; - int ret; - - if (bits == 0) { - /* Default is 32-bit kernel */ - bits = 32; - - /* Try to get system type */ - memset(&utsname, 0, sizeof(utsname)); - ret = host_uname(&utsname); - if (ret == 0) { - if (strcmp(utsname.machine, "ppc64") == 0) - bits = 64; - else if (strcmp(utsname.machine, "ppc64le") == 0) - bits = 64; - } - } - - return (bits); -} - -int -kboot_getdev(void **vdev, const char *devspec, const char **path) -{ - int i; - const char *devpath, *filepath; - struct devsw *dv; - struct devdesc *desc; - - if (strchr(devspec, ':') != NULL) { - devpath = devspec; - filepath = strchr(devspec, ':') + 1; - } else { - devpath = getenv("currdev"); - filepath = devspec; - } - - for (i = 0; (dv = devsw[i]) != NULL; i++) { - if (strncmp(dv->dv_name, devpath, strlen(dv->dv_name)) == 0) - goto found; - } - return (ENOENT); - -found: - if (path != NULL && filepath != NULL) - *path = filepath; - else if (path != NULL) - *path = strchr(devspec, ':') + 1; - - if (vdev != NULL) { - desc = malloc(sizeof(*desc)); - desc->d_dev = dv; - desc->d_unit = 0; - desc->d_opendata = strdup(devpath); - *vdev = desc; - } - - return (0); -} - -int -main(int argc, const char **argv) -{ - void *heapbase; - const size_t heapsize = 15*1024*1024; - const char *bootdev; - - /* - * Set the heap to one page after the end of the loader. - */ - heapbase = host_getmem(heapsize); - setheap(heapbase, heapbase + heapsize); - - /* - * Set up console. - */ - cons_probe(); - - /* Choose bootdev if provided */ - if (argc > 1) - bootdev = argv[1]; - else - bootdev = ""; - - printf("Boot device: %s\n", bootdev); - - archsw.arch_getdev = kboot_getdev; - archsw.arch_copyin = kboot_copyin; - archsw.arch_copyout = kboot_copyout; - archsw.arch_readin = kboot_readin; - archsw.arch_autoload = kboot_autoload; - archsw.arch_loadaddr = kboot_loadaddr; - archsw.arch_kexec_kseg_get = kboot_kseg_get; - - printf("\n%s", bootprog_info); - - setenv("currdev", bootdev, 1); - setenv("loaddev", bootdev, 1); - setenv("LINES", "24", 1); - setenv("usefdt", "1", 1); - - interact(); /* doesn't return */ - - return (0); -} - -void -exit(int code) -{ - while (1); /* XXX: host_exit */ - __unreachable(); -} - -void -delay(int usecs) -{ - struct host_timeval tvi, tv; - uint64_t ti, t; - host_gettimeofday(&tvi, NULL); - ti = tvi.tv_sec*1000000 + tvi.tv_usec; - do { - host_gettimeofday(&tv, NULL); - t = tv.tv_sec*1000000 + tv.tv_usec; - } while (t < ti + usecs); -} - -time_t -getsecs(void) -{ - struct host_timeval tv; - host_gettimeofday(&tv, NULL); - return (tv.tv_sec); -} - -time_t -time(time_t *tloc) -{ - time_t rv; - - rv = getsecs(); - if (tloc != NULL) - *tloc = rv; - - return (rv); -} - -struct kexec_segment { - void *buf; - int bufsz; - void *mem; - int memsz; -}; - -struct kexec_segment loaded_segments[128]; -int nkexec_segments = 0; - -static ssize_t -get_phys_buffer(vm_offset_t dest, const size_t len, void **buf) -{ - int i = 0; - const size_t segsize = 4*1024*1024; - - for (i = 0; i < nkexec_segments; i++) { - if (dest >= (vm_offset_t)loaded_segments[i].mem && - dest < (vm_offset_t)loaded_segments[i].mem + - loaded_segments[i].memsz) - goto out; - } - - loaded_segments[nkexec_segments].buf = host_getmem(segsize); - loaded_segments[nkexec_segments].bufsz = segsize; - loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,segsize); - loaded_segments[nkexec_segments].memsz = segsize; - - i = nkexec_segments; - nkexec_segments++; - -out: - *buf = loaded_segments[i].buf + (dest - - (vm_offset_t)loaded_segments[i].mem); - return (min(len,loaded_segments[i].bufsz - (dest - - (vm_offset_t)loaded_segments[i].mem))); -} - -ssize_t -kboot_copyin(const void *src, vm_offset_t dest, const size_t len) -{ - ssize_t segsize, remainder; - void *destbuf; - - remainder = len; - do { - segsize = get_phys_buffer(dest, remainder, &destbuf); - bcopy(src, destbuf, segsize); - remainder -= segsize; - src += segsize; - dest += segsize; - } while (remainder > 0); - - return (len); -} - -ssize_t -kboot_copyout(vm_offset_t src, void *dest, const size_t len) -{ - ssize_t segsize, remainder; - void *srcbuf; - - remainder = len; - do { - segsize = get_phys_buffer(src, remainder, &srcbuf); - bcopy(srcbuf, dest, segsize); - remainder -= segsize; - src += segsize; - dest += segsize; - } while (remainder > 0); - - return (len); -} - -ssize_t -kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) -{ - void *buf; - size_t resid, chunk, get; - ssize_t got; - vm_offset_t p; - - p = dest; - - chunk = min(PAGE_SIZE, len); - buf = malloc(chunk); - if (buf == NULL) { - printf("kboot_readin: buf malloc failed\n"); - return (0); - } - - for (resid = len; resid > 0; resid -= got, p += got) { - get = min(chunk, resid); - got = VECTX_READ(fd, buf, get); - if (got <= 0) { - if (got < 0) - printf("kboot_readin: read failed\n"); - break; - } - - kboot_copyin(buf, p, got); - } - - free (buf); - return (len - resid); -} - -int -kboot_autoload(void) -{ - - return (0); -} - -uint64_t -kboot_loadaddr(u_int type, void *data, uint64_t addr) -{ - - if (type == LOAD_ELF) - addr = roundup(addr, PAGE_SIZE); - else - addr += kboot_get_phys_load_segment(); - - return (addr); -} - -static void -kboot_kseg_get(int *nseg, void **ptr) -{ -#if 0 - int a; - - for (a = 0; a < nkexec_segments; a++) { - printf("kseg_get: %jx %jx %jx %jx\n", - (uintmax_t)loaded_segments[a].buf, - (uintmax_t)loaded_segments[a].bufsz, - (uintmax_t)loaded_segments[a].mem, - (uintmax_t)loaded_segments[a].memsz); - } -#endif - - *nseg = nkexec_segments; - *ptr = &loaded_segments[0]; -} - -void -_start(int argc, const char **argv, char **env) -{ - main(argc, argv); -} - -/* - * Since proper fdt command handling function is defined in fdt_loader_cmd.c, - * and declaring it as extern is in contradiction with COMMAND_SET() macro - * (which uses static pointer), we're defining wrapper function, which - * calls the proper fdt handling routine. - */ -static int -command_fdt(int argc, char *argv[]) -{ - - return (command_fdt_internal(argc, argv)); -} - -COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt); diff --git a/stand/kboot/version b/stand/kboot/version deleted file mode 100644 index b24d6ea8e47a..000000000000 --- a/stand/kboot/version +++ /dev/null @@ -1,6 +0,0 @@ -$FreeBSD: user/nwhitehorn/kboot/powerpc/kboot/version 224106 2011-07-16 19:01:09Z nwhitehorn $ - -NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this -file is important. Make sure the current version number is on line 6. - -0.1: Initial kboot/PowerPC version. diff --git a/stand/kshim/bsd_busspace.c b/stand/kshim/bsd_busspace.c index 778c4494d96c..fc35ffcb9a0c 100644 --- a/stand/kshim/bsd_busspace.c +++ b/stand/kshim/bsd_busspace.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * diff --git a/stand/kshim/bsd_global.h b/stand/kshim/bsd_global.h index 63bba757736d..4f4bb4e499bd 100644 --- a/stand/kshim/bsd_global.h +++ b/stand/kshim/bsd_global.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * diff --git a/stand/kshim/bsd_kernel.c b/stand/kshim/bsd_kernel.c index 5d47c799921b..455ae570d8ae 100644 --- a/stand/kshim/bsd_kernel.c +++ b/stand/kshim/bsd_kernel.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * @@ -206,16 +205,14 @@ bus_release_resource(device_t dev, int type, int rid, struct resource *r) return (EINVAL); } -int -bus_generic_attach(device_t dev) +void +bus_attach_children(device_t dev) { device_t child; TAILQ_FOREACH(child, &dev->dev_children, dev_link) { device_probe_and_attach(child); } - - return (0); } bus_space_tag_t @@ -557,27 +554,8 @@ static const char unknown_string[] = { "unknown" }; static TAILQ_HEAD(, module_data) module_head = TAILQ_HEAD_INITIALIZER(module_head); - -static uint8_t -devclass_equal(const char *a, const char *b) -{ - char ta, tb; - - if (a == b) - return (1); - - while (1) { - ta = *a; - tb = *b; - if (ta != tb) - return (0); - if (ta == 0) - break; - a++; - b++; - } - return (1); -} +static TAILQ_HEAD(, devclass) devclasses = + TAILQ_HEAD_INITIALIZER(devclasses); int bus_generic_resume(device_t dev) @@ -665,7 +643,7 @@ device_get_unit(device_t dev) } int -bus_generic_detach(device_t dev) +bus_detach_children(device_t dev) { device_t child; int error; @@ -680,6 +658,17 @@ bus_generic_detach(device_t dev) return (0); } +int +bus_generic_detach(device_t dev) +{ + int error; + + error = bus_detach_children(dev); + if (error == 0) + error = device_delete_children(dev); + return (error); +} + const char * device_get_nameunit(device_t dev) { @@ -689,58 +678,50 @@ device_get_nameunit(device_t dev) return (unknown_string); } -static uint8_t -devclass_create(devclass_t *dc_pp) +static devclass_t +devclass_create(const char *classname) { - if (dc_pp == NULL) { - return (1); - } - if (dc_pp[0] == NULL) { - dc_pp[0] = malloc(sizeof(**(dc_pp)), - M_DEVBUF, M_WAITOK | M_ZERO); + devclass_t dc; - if (dc_pp[0] == NULL) { - return (1); - } + dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK | M_ZERO); + if (dc == NULL) { + return (NULL); } - return (0); + dc->name = classname; + TAILQ_INSERT_TAIL(&devclasses, dc, link); + return (dc); } -static const struct module_data * +static devclass_t devclass_find_create(const char *classname) { - const struct module_data *mod; + devclass_t dc; - TAILQ_FOREACH(mod, &module_head, entry) { - if (devclass_equal(mod->mod_name, classname)) { - if (devclass_create(mod->devclass_pp)) { - continue; - } - return (mod); - } - } - return (NULL); + dc = devclass_find(classname); + if (dc == NULL) + dc = devclass_create(classname); + return (dc); } static uint8_t -devclass_add_device(const struct module_data *mod, device_t dev) +devclass_add_device(devclass_t dc, device_t dev) { device_t *pp_dev; device_t *end; uint8_t unit; - pp_dev = mod->devclass_pp[0]->dev_list; + pp_dev = dc->dev_list; end = pp_dev + DEVCLASS_MAXUNIT; unit = 0; while (pp_dev != end) { if (*pp_dev == NULL) { *pp_dev = dev; + dev->dev_class = dc; dev->dev_unit = unit; - dev->dev_module = mod; snprintf(dev->dev_nameunit, sizeof(dev->dev_nameunit), - "%s%d", device_get_name(dev), unit); + "%s%d", dc->name, unit); return (0); } pp_dev++; @@ -751,26 +732,26 @@ devclass_add_device(const struct module_data *mod, device_t dev) } static void -devclass_delete_device(const struct module_data *mod, device_t dev) +devclass_delete_device(devclass_t dc, device_t dev) { - if (mod == NULL) { + if (dc == NULL) { return; } - mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL; - dev->dev_module = NULL; + dc->dev_list[dev->dev_unit] = NULL; + dev->dev_class = NULL; } static device_t make_device(device_t parent, const char *name) { device_t dev = NULL; - const struct module_data *mod = NULL; + devclass_t dc = NULL; if (name) { - mod = devclass_find_create(name); + dc = devclass_find_create(name); - if (!mod) { + if (!dc) { DPRINTF("%s:%d:%s: can't find device " "class %s\n", __FILE__, __LINE__, @@ -790,7 +771,7 @@ make_device(device_t parent, const char *name) if (name) { dev->dev_fixed_class = 1; - if (devclass_add_device(mod, dev)) { + if (devclass_add_device(dc, dev)) { goto error; } } @@ -846,7 +827,8 @@ device_delete_child(device_t dev, device_t child) } } - devclass_delete_device(child->dev_module, child); + if (child->dev_class != NULL) + devclass_delete_device(child->dev_class, child); if (dev != NULL) { /* remove child from parent */ @@ -903,7 +885,7 @@ device_get_method(device_t dev, const char *what) mtod = dev->dev_module->driver->methods; while (mtod->func != NULL) { - if (devclass_equal(mtod->desc, what)) { + if (strcmp(mtod->desc, what) == 0) { return (mtod->func); } mtod++; @@ -914,7 +896,7 @@ device_get_method(device_t dev, const char *what) const char * device_get_name(device_t dev) { - if (dev == NULL) + if (dev == NULL || dev->dev_module == NULL) return (unknown_string); return (dev->dev_module->driver->name); @@ -945,16 +927,34 @@ device_probe_and_attach(device_t dev) { const struct module_data *mod; const char *bus_name_parent; - - bus_name_parent = device_get_name(device_get_parent(dev)); + devclass_t dc; if (dev->dev_attached) return (0); /* fail-safe */ - if (dev->dev_fixed_class) { + /* + * Find a module for our device, if any + */ + bus_name_parent = device_get_name(device_get_parent(dev)); + + TAILQ_FOREACH(mod, &module_head, entry) { + if (strcmp(mod->bus_name, bus_name_parent) != 0) + continue; + + dc = devclass_find(mod->mod_name); - mod = dev->dev_module; + /* Does this device need assigning to the new devclass? */ + if (dev->dev_class != dc) { + if (dev->dev_fixed_class) + continue; + if (dev->dev_class != NULL) + devclass_delete_device(dev->dev_class, dev); + if (devclass_add_device(dc, dev)) { + continue; + } + } + dev->dev_module = mod; if (DEVICE_PROBE(dev) <= 0) { if (device_allocate_softc(dev) == 0) { @@ -966,40 +966,11 @@ device_probe_and_attach(device_t dev) } } } - device_detach(dev); - - goto error; - } - /* - * Else find a module for our device, if any - */ - - TAILQ_FOREACH(mod, &module_head, entry) { - if (devclass_equal(mod->bus_name, bus_name_parent)) { - if (devclass_create(mod->devclass_pp)) { - continue; - } - if (devclass_add_device(mod, dev)) { - continue; - } - if (DEVICE_PROBE(dev) <= 0) { - - if (device_allocate_softc(dev) == 0) { + /* else try next driver */ - if (DEVICE_ATTACH(dev) == 0) { - /* success */ - dev->dev_attached = 1; - return (0); - } - } - } - /* else try next driver */ - - device_detach(dev); - } + device_detach(dev); } -error: return (ENODEV); } @@ -1018,9 +989,10 @@ device_detach(device_t dev) dev->dev_attached = 0; } device_set_softc(dev, NULL); + dev->dev_module = NULL; if (dev->dev_fixed_class == 0) - devclass_delete_device(mod, dev); + devclass_delete_device(dev->dev_class, dev); return (0); } @@ -1096,11 +1068,11 @@ devclass_get_device(devclass_t dc, int unit) devclass_t devclass_find(const char *classname) { - const struct module_data *mod; + devclass_t dc; - TAILQ_FOREACH(mod, &module_head, entry) { - if (devclass_equal(mod->driver->name, classname)) - return (mod->devclass_pp[0]); + TAILQ_FOREACH(dc, &devclasses, link) { + if (strcmp(dc->name, classname) == 0) + return (dc); } return (NULL); } @@ -1111,6 +1083,7 @@ module_register(void *data) struct module_data *mdata = data; TAILQ_INSERT_TAIL(&module_head, mdata, entry); + (void)devclass_find_create(mdata->mod_name); } /*------------------------------------------------------------------------* @@ -1353,12 +1326,13 @@ usb_pci_mod_load(void *arg) { uint32_t x; - usb_pci_root = device_add_child(NULL, "pci", -1); + usb_pci_root = device_add_child(NULL, "pci", DEVICE_UNIT_ANY); if (usb_pci_root == NULL) return; for (x = 0; x != USB_PCI_USB_MAX; x++) { - usb_pci_dev[x] = device_add_child(usb_pci_root, usb_pci_devices[x], -1); + usb_pci_dev[x] = device_add_child(usb_pci_root, + usb_pci_devices[x], DEVICE_UNIT_ANY); if (usb_pci_dev[x] == NULL) continue; if (device_probe_and_attach(usb_pci_dev[x])) { diff --git a/stand/kshim/bsd_kernel.h b/stand/kshim/bsd_kernel.h index a5653667da53..25a779d5ea0c 100644 --- a/stand/kshim/bsd_kernel.h +++ b/stand/kshim/bsd_kernel.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2011 Hans Petter Selasky. All rights reserved. * @@ -88,11 +87,11 @@ struct sysctl_req { #define MOD_UNLOAD 2 #define DEVMETHOD(what,func) { #what, (void *)&func } #define DEVMETHOD_END {0,0} -#define EARLY_DRIVER_MODULE(a, b, c, d, e, f, g) DRIVER_MODULE(a, b, c, d, e, f) -#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \ +#define EARLY_DRIVER_MODULE(a, b, c, d, e, f) DRIVER_MODULE(a, b, c, d, e) +#define DRIVER_MODULE(name, busname, driver, evh, arg) \ static struct module_data bsd_##name##_##busname##_driver_mod = { \ evh, arg, #busname, #name, #busname "/" #name, \ - &driver, &devclass, { 0, 0 } }; \ + &driver, { 0, 0 } }; \ SYSINIT(bsd_##name##_##busname##_driver_mod, SI_SUB_DRIVERS, \ SI_ORDER_MIDDLE, module_register, \ &bsd_##name##_##busname##_driver_mod) @@ -136,6 +135,7 @@ SYSINIT_ENTRY(uniq##_entry, "sysuninit", (subs), \ #define cold 0 #define BUS_PROBE_GENERIC 0 #define BUS_PROBE_DEFAULT (-20) +#define DEVICE_UNIT_ANY -1 #define CALLOUT_RETURNUNLOCKED 0x1 #undef ffs #define ffs(x) __builtin_ffs(x) @@ -407,6 +407,7 @@ struct device { TAILQ_HEAD(device_list, device) dev_children; TAILQ_ENTRY(device) dev_link; + devclass_t dev_class; struct device *dev_parent; const struct module_data *dev_module; void *dev_sc; @@ -430,6 +431,8 @@ struct device { }; struct devclass { + TAILQ_ENTRY(devclass) link; + const char *name; device_t dev_list[DEVCLASS_MAXUNIT]; }; @@ -446,7 +449,6 @@ struct module_data { const char *mod_name; const char *long_name; const struct driver *driver; - struct devclass **devclass_pp; TAILQ_ENTRY(module_data) entry; }; @@ -647,7 +649,8 @@ int bus_release_resource(device_t, int, int, struct resource *); void bus_release_resources(device_t, const struct resource_spec *, struct resource **); struct resource *bus_alloc_resource_any(device_t, int, int *, unsigned int); -int bus_generic_attach(device_t); +void bus_attach_children(device_t); +int bus_detach_children(device_t); bus_space_tag_t rman_get_bustag(struct resource *); bus_space_handle_t rman_get_bushandle(struct resource *); u_long rman_get_size(struct resource *); diff --git a/stand/kshim/kshim.mk b/stand/kshim/kshim.mk index 7e9b00d562d8..3ce222945e87 100644 --- a/stand/kshim/kshim.mk +++ b/stand/kshim/kshim.mk @@ -1,5 +1,4 @@ # -# $FreeBSD$ # # Copyright (c) 2013 Hans Petter Selasky. # Copyright (c) 2014 SRI International diff --git a/stand/kshim/sysinit.h b/stand/kshim/sysinit.h index a7a450ee4cf2..d74ab9e3af59 100644 --- a/stand/kshim/sysinit.h +++ b/stand/kshim/sysinit.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * diff --git a/stand/liblua/Makefile b/stand/liblua/Makefile index 385f1493bd38..ce7eb89fe494 100644 --- a/stand/liblua/Makefile +++ b/stand/liblua/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> .PATH: ${LUASRC} @@ -24,9 +22,12 @@ SRCS+= lauxlib.c lbaselib.c lstrlib.c loadlib.c # Our utilities. SRCS+= lerrno.c lpager.c lstd.c lutils.c +SRCS+= gfx_utils.c .PATH: ${FLUASRC}/modules SRCS+= lfs.c +.PATH: ${FLUALIB}/libhash +SRCS+= lhash.c WARNS?= 3 @@ -35,7 +36,8 @@ CFLAGS+= -ffreestanding -nostdlib -DLUA_USE_POSIX CFLAGS+= -fno-stack-protector -D__BSD_VISIBLE CFLAGS+= -I${BOOTSRC}/include -I${LIBLUASRC} -I${LUASRC} -I${LDRSRC} -CFLAGS.lutils.c+= -I${SRCTOP}/sys/teken -I${SRCTOP}/contrib/pnglite +CFLAGS.gfx_utils.c+= -I${SRCTOP}/sys/teken -I${SRCTOP}/contrib/pnglite +CFLAGS.lhash.c+= -I${FLUALIB}/libhash -I${SRCTOP}/sys/crypto/sha2 .if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0 CFLAGS+= -fPIC diff --git a/stand/liblua/Makefile.depend b/stand/liblua/Makefile.depend new file mode 100644 index 000000000000..18537add9fe3 --- /dev/null +++ b/stand/liblua/Makefile.depend @@ -0,0 +1,11 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + stand/libsa \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/liblua/float.h b/stand/liblua/float.h index fa958597bb55..0cdfdad0757e 100644 --- a/stand/liblua/float.h +++ b/stand/liblua/float.h @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/liblua/gfx_utils.c b/stand/liblua/gfx_utils.c new file mode 100644 index 000000000000..301cd9cb8610 --- /dev/null +++ b/stand/liblua/gfx_utils.c @@ -0,0 +1,274 @@ +/*- + * Copyright (c) 2024 Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* Copied from a file that likely shoulve have had this at the top */ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2020 Toomas Soome + * Copyright 2020 RackTop Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "lua.h" +#include "lauxlib.h" +#include "lutils.h" +#include <gfx_fb.h> +#include <pnglite.h> + +/* + * put image using terminal coordinates. + */ +static int +lua_term_putimage(lua_State *L) +{ + const char *name; + png_t png; + uint32_t x1, y1, x2, y2, f; + int nargs, ret = 0, error; + + nargs = lua_gettop(L); + if (nargs != 6) { + lua_pushboolean(L, 0); + return 1; + } + + name = luaL_checkstring(L, 1); + x1 = luaL_checknumber(L, 2); + y1 = luaL_checknumber(L, 3); + x2 = luaL_checknumber(L, 4); + y2 = luaL_checknumber(L, 5); + f = luaL_checknumber(L, 6); + + x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; + y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; + if (x2 != 0) { + x2 = gfx_state.tg_origin.tp_col + + x2 * gfx_state.tg_font.vf_width; + } + if (y2 != 0) { + y2 = gfx_state.tg_origin.tp_row + + y2 * gfx_state.tg_font.vf_height; + } + + if ((error = png_open(&png, name)) != PNG_NO_ERROR) { + if (f & FL_PUTIMAGE_DEBUG) + printf("%s\n", png_error_string(error)); + } else { + if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) + ret = 1; + (void) png_close(&png); + } + lua_pushboolean(L, ret); + return 1; +} + +static int +lua_fb_putimage(lua_State *L) +{ + const char *name; + png_t png; + uint32_t x1, y1, x2, y2, f; + int nargs, ret = 0, error; + + nargs = lua_gettop(L); + if (nargs != 6) { + lua_pushboolean(L, 0); + return 1; + } + + name = luaL_checkstring(L, 1); + x1 = luaL_checknumber(L, 2); + y1 = luaL_checknumber(L, 3); + x2 = luaL_checknumber(L, 4); + y2 = luaL_checknumber(L, 5); + f = luaL_checknumber(L, 6); + + if ((error = png_open(&png, name)) != PNG_NO_ERROR) { + if (f & FL_PUTIMAGE_DEBUG) + printf("%s\n", png_error_string(error)); + } else { + if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) + ret = 1; + (void) png_close(&png); + } + lua_pushboolean(L, ret); + return 1; +} + +static int +lua_fb_setpixel(lua_State *L) +{ + uint32_t x, y; + int nargs; + + nargs = lua_gettop(L); + if (nargs != 2) { + lua_pushnil(L); + return 1; + } + + x = luaL_checknumber(L, 1); + y = luaL_checknumber(L, 2); + gfx_fb_setpixel(x, y); + return 0; +} + +static int +lua_fb_line(lua_State *L) +{ + uint32_t x0, y0, x1, y1, wd; + int nargs; + + nargs = lua_gettop(L); + if (nargs != 5) { + lua_pushnil(L); + return 1; + } + + x0 = luaL_checknumber(L, 1); + y0 = luaL_checknumber(L, 2); + x1 = luaL_checknumber(L, 3); + y1 = luaL_checknumber(L, 4); + wd = luaL_checknumber(L, 5); + gfx_fb_line(x0, y0, x1, y1, wd); + return 0; +} + +static int +lua_fb_bezier(lua_State *L) +{ + uint32_t x0, y0, x1, y1, x2, y2, width; + int nargs; + + nargs = lua_gettop(L); + if (nargs != 7) { + lua_pushnil(L); + return 1; + } + + x0 = luaL_checknumber(L, 1); + y0 = luaL_checknumber(L, 2); + x1 = luaL_checknumber(L, 3); + y1 = luaL_checknumber(L, 4); + x2 = luaL_checknumber(L, 5); + y2 = luaL_checknumber(L, 6); + width = luaL_checknumber(L, 7); + gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); + return 0; +} + +static int +lua_fb_drawrect(lua_State *L) +{ + uint32_t x0, y0, x1, y1, fill; + int nargs; + + nargs = lua_gettop(L); + if (nargs != 5) { + lua_pushnil(L); + return 1; + } + + x0 = luaL_checknumber(L, 1); + y0 = luaL_checknumber(L, 2); + x1 = luaL_checknumber(L, 3); + y1 = luaL_checknumber(L, 4); + fill = luaL_checknumber(L, 5); + gfx_fb_drawrect(x0, y0, x1, y1, fill); + return 0; +} + +static int +lua_term_drawrect(lua_State *L) +{ + uint32_t x0, y0, x1, y1; + int nargs; + + nargs = lua_gettop(L); + if (nargs != 4) { + lua_pushnil(L); + return 1; + } + + x0 = luaL_checknumber(L, 1); + y0 = luaL_checknumber(L, 2); + x1 = luaL_checknumber(L, 3); + y1 = luaL_checknumber(L, 4); + gfx_term_drawrect(x0, y0, x1, y1); + return 0; +} + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg gfxlib[] = { + REG_SIMPLE(fb_bezier), + REG_SIMPLE(fb_drawrect), + REG_SIMPLE(fb_line), + REG_SIMPLE(fb_putimage), + REG_SIMPLE(fb_setpixel), + REG_SIMPLE(term_drawrect), + REG_SIMPLE(term_putimage), + { NULL, NULL }, +}; + +int +luaopen_gfx(lua_State *L) +{ + luaL_newlib(L, gfxlib); + return 1; +} + +void +gfx_interp_ref(void) +{ +} + +static void +gfx_init_md(lua_State *L) +{ + luaL_requiref(L, "gfx", luaopen_gfx, 1); + lua_pop(L, 1); /* Remove lib */ + + /* + * Add in the compatibility references in the loader table. Doing it with + * a pseudo-embedded script is easier than the raw calls. + */ + if (luaL_dostring(L, + "loader.fb_bezier = gfx.fb_bezier\n" + "loader.fb_drawrect = gfx.fb_drawrect\n" + "loader.fb_line = gfx.fb_line\n" + "loader.fb_putimage = gfx.fb_putimage\n" + "loader.fb_setpixel = gfx.fb_setpixel\n" + "loader.term_drawrect = gfx.term_drawrect\n" + "loader.term_putimage = gfx.term_putimage") != 0) { + lua_pop(L, 1); + const char *errstr = lua_tostring(L, -1); + errstr = errstr == NULL ? "unknown" : errstr; + printf("Error adding compat loader bindings: %s.\n", errstr); + } +} + +LUA_COMPILE_SET(gfx_init_md); diff --git a/stand/liblua/lerrno.c b/stand/liblua/lerrno.c index defa3c73baad..744154e43dbd 100644 --- a/stand/liblua/lerrno.c +++ b/stand/liblua/lerrno.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define _WANT_KERNEL_ERRNO 1 #include <errno.h> diff --git a/stand/liblua/lerrno.h b/stand/liblua/lerrno.h index a6ad428facee..4ca4a843c4df 100644 --- a/stand/liblua/lerrno.h +++ b/stand/liblua/lerrno.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #pragma once diff --git a/stand/liblua/locale.h b/stand/liblua/locale.h index b6420935d83f..95ff0d5c7bf4 100644 --- a/stand/liblua/locale.h +++ b/stand/liblua/locale.h @@ -21,6 +21,4 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ diff --git a/stand/liblua/lpager.c b/stand/liblua/lpager.c index 910931e11d58..fb1be4802d21 100644 --- a/stand/liblua/lpager.c +++ b/stand/liblua/lpager.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <lua.h> #include "lauxlib.h" diff --git a/stand/liblua/lstd.c b/stand/liblua/lstd.c index 12675842f65d..60d55d7fbf92 100644 --- a/stand/liblua/lstd.c +++ b/stand/liblua/lstd.c @@ -25,9 +25,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "lstd.h" #include "math.h" diff --git a/stand/liblua/lstd.h b/stand/liblua/lstd.h index 6f9eec2b40b9..2b601f129566 100644 --- a/stand/liblua/lstd.h +++ b/stand/liblua/lstd.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef LSTD_H @@ -31,10 +29,19 @@ #include <stand.h> #include <sys/types.h> +#include <sys/stdarg.h> #include <sys/stdint.h> #include <limits.h> #include <string.h> -#include <machine/stdarg.h> + +/* + * Mini stdio FILE and DIR routines. These are the minimal routines needed by + * the lfs module and lua's base code. We define them minimally here so we don't + * have to modify lua on every import. Further, since they aren't completely + * standard, we #define them to other names so they don't conflict with other + * tooling that makes assumptions about these routines that might not be, in + * fact, correct. + */ typedef struct FILE { @@ -48,6 +55,18 @@ typedef struct DIR int fd; } DIR; +#define fopen lua_loader_fopen +#define freopen lua_loader_freopen +#define fread lua_loader_fread +#define fwrite lua_loader_fwrite +#define fclose lua_loader_fclose +#define ferror lua_loader_ferror +#define feof lua_loader_feof +#define getc lua_loader_getc +#define opendir lua_loader_opendir +#define fdopendir lua_loader_fdopendir +#define closedir lua_loader_closedir + FILE *fopen(const char *filename, const char *mode); FILE *freopen( const char *filename, const char *mode, FILE *stream); size_t fread(void *ptr, size_t size, size_t count, FILE *stream); diff --git a/stand/liblua/luaconf.h b/stand/liblua/luaconf.h index 8a0ad782e5e1..d5c222ce30be 100644 --- a/stand/liblua/luaconf.h +++ b/stand/liblua/luaconf.h @@ -1,6 +1,5 @@ -/* $FreeBSD$ */ /* -** $Id: luaconf.h,v 1.259 2016/12/22 13:08:50 roberto Exp $ +** $Id: luaconf.h $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -218,7 +217,7 @@ #define LUA_LDIR LUA_ROOT "share/" #define LUA_CDIR LUA_ROOT "lib/" -#ifndef LUA_PATH_DEFAULT +#if !defined(LUA_PATH_DEFAULT) #define LUA_PATH_DEFAULT \ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ @@ -433,6 +432,7 @@ #define lua_str2number(s,p) strtof((s), (p)) + #elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ #define LUA_NUMBER long double @@ -783,3 +783,4 @@ #endif + diff --git a/stand/liblua/luaconf.local.h b/stand/liblua/luaconf.local.h new file mode 100644 index 000000000000..7da3d6bddc6e --- /dev/null +++ b/stand/liblua/luaconf.local.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023, Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once +/* + * We need to always define this. For the boot loader, we use it. For flua + * we don't, but it needs to be defined to keep some ifdefs happy. + */ +#define LUA_FLOAT_INT64 4 + +/* set the paths we want */ +#undef LUA_ROOT +#undef LUA_LDIR +#undef LUA_CDIR +#define LUA_ROOT LUA_PATH "/" LUA_VDIR "/" +#define LUA_LDIR LUA_ROOT "share/" +#define LUA_CDIR LUA_ROOT "lib/" + +/* Simplify this, since it's always an int */ +#undef lua_numbertointeger +#define lua_numbertointeger(n,p) \ + (*(p) = (LUA_INTEGER)(n), 1) + +/* Define our number type by brute force, but first undo the default defines */ +#undef panic +#undef LUA_NUMBER +#undef l_floatatt +#undef LUAI_UACNUMBER +#undef LUA_NUMBER_FRMLEN +#undef LUA_NUMBER_FMT +#undef l_mathop +#undef lua_str2number +#undef lua_getlocaledecpoint + +#undef LUA_FLOAT_TYPE +#define LUA_FLOAT_TYPE LUA_FLOAT_INT64 + +#include "lstd.h" + +#include <machine/_inttypes.h> + +#define panic lua_panic +/* Hack to use int64 as the LUA_NUMBER from ZFS code, kinda */ + +#define LUA_NUMBER int64_t + +#define l_floatatt(n) (LUA_FLOAT_INT_HACK_##n) +#define LUA_FLOAT_INT_HACK_MANT_DIG 32 +#define LUA_FLOAT_INT_HACK_MAX_10_EXP 32 + +#define LUAI_UACNUMBER int64_t + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%" PRId64 + +#define l_mathop(x) (lstd_ ## x) + +#define lua_str2number(s,p) strtoll((s), (p), 0) + +#define lua_getlocaledecpoint() '.' + +/* Better buffer size */ +#undef LUAL_BUFFERSIZE +#define LUAL_BUFFERSIZE 128 + +/* Maxalign can't reference double */ +#undef LUAI_MAXALIGN +#define LUAI_MAXALIGN lua_Number n; void *s; lua_Integer i; long l + +#define LUA_AVOID_FLOAT diff --git a/stand/liblua/lutils.c b/stand/liblua/lutils.c index 9243edd07e8f..874dc8bf7d5d 100644 --- a/stand/liblua/lutils.c +++ b/stand/liblua/lutils.c @@ -25,9 +25,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include "lua.h" @@ -35,8 +32,6 @@ __FBSDID("$FreeBSD$"); #include "lstd.h" #include "lutils.h" #include "bootstrap.h" -#include <gfx_fb.h> -#include <pnglite.h> /* * Like loader.perform, except args are passed already parsed @@ -64,6 +59,41 @@ lua_command(lua_State *L) } static int +lua_has_command(lua_State *L) +{ + const char *cmd; + + cmd = luaL_checkstring(L, 1); + if (interp_has_builtin_cmd(cmd)) { + lua_pushboolean(L, 1); + return 1; + } + + lua_pushnil(L); + lua_pushstring(L, "Builtin command not found"); + return 2; +} + +static int +lua_has_feature(lua_State *L) +{ + const char *feature; + char *msg; + + feature = luaL_checkstring(L, 1); + + if (feature_name_is_enabled(feature)) { + lua_pushboolean(L, 1); + return 1; + } + + lua_pushnil(L); + lua_pushstring(L, "Feature not enabled"); + return 2; +} + + +static int lua_perform(lua_State *L) { int argc; @@ -80,6 +110,13 @@ lua_perform(lua_State *L) } static int +lua_exit(lua_State *L) +{ + exit(luaL_checkinteger(L, 1)); + return 0; +} + +static int lua_command_error(lua_State *L) { @@ -348,210 +385,22 @@ lua_writefile(lua_State *L) return 1; } -/* - * put image using terminal coordinates. - */ -static int -lua_term_putimage(lua_State *L) -{ - const char *name; - png_t png; - uint32_t x1, y1, x2, y2, f; - int nargs, ret = 0, error; - - nargs = lua_gettop(L); - if (nargs != 6) { - lua_pushboolean(L, 0); - return 1; - } - - name = luaL_checkstring(L, 1); - x1 = luaL_checknumber(L, 2); - y1 = luaL_checknumber(L, 3); - x2 = luaL_checknumber(L, 4); - y2 = luaL_checknumber(L, 5); - f = luaL_checknumber(L, 6); - - x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; - y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; - if (x2 != 0) { - x2 = gfx_state.tg_origin.tp_col + - x2 * gfx_state.tg_font.vf_width; - } - if (y2 != 0) { - y2 = gfx_state.tg_origin.tp_row + - y2 * gfx_state.tg_font.vf_height; - } - - if ((error = png_open(&png, name)) != PNG_NO_ERROR) { - if (f & FL_PUTIMAGE_DEBUG) - printf("%s\n", png_error_string(error)); - } else { - if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) - ret = 1; - (void) png_close(&png); - } - lua_pushboolean(L, ret); - return 1; -} - -static int -lua_fb_putimage(lua_State *L) -{ - const char *name; - png_t png; - uint32_t x1, y1, x2, y2, f; - int nargs, ret = 0, error; - - nargs = lua_gettop(L); - if (nargs != 6) { - lua_pushboolean(L, 0); - return 1; - } - - name = luaL_checkstring(L, 1); - x1 = luaL_checknumber(L, 2); - y1 = luaL_checknumber(L, 3); - x2 = luaL_checknumber(L, 4); - y2 = luaL_checknumber(L, 5); - f = luaL_checknumber(L, 6); - - if ((error = png_open(&png, name)) != PNG_NO_ERROR) { - if (f & FL_PUTIMAGE_DEBUG) - printf("%s\n", png_error_string(error)); - } else { - if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) - ret = 1; - (void) png_close(&png); - } - lua_pushboolean(L, ret); - return 1; -} - -static int -lua_fb_setpixel(lua_State *L) -{ - uint32_t x, y; - int nargs; - - nargs = lua_gettop(L); - if (nargs != 2) { - lua_pushnil(L); - return 1; - } - - x = luaL_checknumber(L, 1); - y = luaL_checknumber(L, 2); - gfx_fb_setpixel(x, y); - return 0; -} - -static int -lua_fb_line(lua_State *L) -{ - uint32_t x0, y0, x1, y1, wd; - int nargs; - - nargs = lua_gettop(L); - if (nargs != 5) { - lua_pushnil(L); - return 1; - } - - x0 = luaL_checknumber(L, 1); - y0 = luaL_checknumber(L, 2); - x1 = luaL_checknumber(L, 3); - y1 = luaL_checknumber(L, 4); - wd = luaL_checknumber(L, 5); - gfx_fb_line(x0, y0, x1, y1, wd); - return 0; -} - -static int -lua_fb_bezier(lua_State *L) -{ - uint32_t x0, y0, x1, y1, x2, y2, width; - int nargs; - - nargs = lua_gettop(L); - if (nargs != 7) { - lua_pushnil(L); - return 1; - } - - x0 = luaL_checknumber(L, 1); - y0 = luaL_checknumber(L, 2); - x1 = luaL_checknumber(L, 3); - y1 = luaL_checknumber(L, 4); - x2 = luaL_checknumber(L, 5); - y2 = luaL_checknumber(L, 6); - width = luaL_checknumber(L, 7); - gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); - return 0; -} - -static int -lua_fb_drawrect(lua_State *L) -{ - uint32_t x0, y0, x1, y1, fill; - int nargs; - - nargs = lua_gettop(L); - if (nargs != 5) { - lua_pushnil(L); - return 1; - } - - x0 = luaL_checknumber(L, 1); - y0 = luaL_checknumber(L, 2); - x1 = luaL_checknumber(L, 3); - y1 = luaL_checknumber(L, 4); - fill = luaL_checknumber(L, 5); - gfx_fb_drawrect(x0, y0, x1, y1, fill); - return 0; -} - -static int -lua_term_drawrect(lua_State *L) -{ - uint32_t x0, y0, x1, y1; - int nargs; - - nargs = lua_gettop(L); - if (nargs != 4) { - lua_pushnil(L); - return 1; - } - - x0 = luaL_checknumber(L, 1); - y0 = luaL_checknumber(L, 2); - x1 = luaL_checknumber(L, 3); - y1 = luaL_checknumber(L, 4); - gfx_term_drawrect(x0, y0, x1, y1); - return 0; -} - #define REG_SIMPLE(n) { #n, lua_ ## n } static const struct luaL_Reg loaderlib[] = { - REG_SIMPLE(delay), - REG_SIMPLE(command_error), REG_SIMPLE(command), + REG_SIMPLE(command_error), + REG_SIMPLE(delay), + REG_SIMPLE(exit), + REG_SIMPLE(getenv), + REG_SIMPLE(has_command), + REG_SIMPLE(has_feature), REG_SIMPLE(interpret), REG_SIMPLE(parse), - REG_SIMPLE(getenv), REG_SIMPLE(perform), - /* Also registered as the global 'printc' */ - REG_SIMPLE(printc), + REG_SIMPLE(printc), /* Also registered as the global 'printc' */ REG_SIMPLE(setenv), REG_SIMPLE(time), REG_SIMPLE(unsetenv), - REG_SIMPLE(fb_bezier), - REG_SIMPLE(fb_drawrect), - REG_SIMPLE(fb_line), - REG_SIMPLE(fb_putimage), - REG_SIMPLE(fb_setpixel), - REG_SIMPLE(term_drawrect), - REG_SIMPLE(term_putimage), { NULL, NULL }, }; @@ -567,6 +416,33 @@ static const struct luaL_Reg iolib[] = { }; #undef REG_SIMPLE +static void +lua_add_feature(void *cookie, const char *name, const char *desc, bool enabled) +{ + lua_State *L = cookie; + + /* + * The feature table consists solely of features that are enabled, and + * their associated descriptions for debugging purposes. + */ + lua_pushstring(L, desc); + lua_setfield(L, -2, name); +} + +static void +lua_add_features(lua_State *L) +{ + + lua_newtable(L); + feature_iter(&lua_add_feature, L); + + /* + * We should still have just the table on the stack after we're done + * iterating. + */ + lua_setfield(L, -2, "features"); +} + int luaopen_loader(lua_State *L) { @@ -578,6 +454,19 @@ luaopen_loader(lua_State *L) lua_setfield(L, -2, "machine_arch"); lua_pushstring(L, LUA_PATH); lua_setfield(L, -2, "lua_path"); + lua_pushinteger(L, bootprog_rev); + lua_setfield(L, -2, "version"); + lua_pushinteger(L, CMD_OK); + lua_setfield(L, -2, "CMD_OK"); + lua_pushinteger(L, CMD_WARN); + lua_setfield(L, -2, "CMD_WARN"); + lua_pushinteger(L, CMD_ERROR); + lua_setfield(L, -2, "CMD_ERROR"); + lua_pushinteger(L, CMD_CRIT); + lua_setfield(L, -2, "CMD_CRIT"); + lua_pushinteger(L, CMD_FATAL); + lua_setfield(L, -2, "CMD_FATAL"); + lua_add_features(L); /* Set global printc to loader.printc */ lua_register(L, "printc", lua_printc); return 1; diff --git a/stand/liblua/lutils.h b/stand/liblua/lutils.h index d7d968b705bb..7fff8d3ae83d 100644 --- a/stand/liblua/lutils.h +++ b/stand/liblua/lutils.h @@ -22,12 +22,21 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <lua.h> +int luaopen_gfx(lua_State *); int luaopen_loader(lua_State *); int luaopen_io(lua_State *); int luaopen_pager(lua_State *); + +#include <sys/linker_set.h> + +typedef void lua_init_md_t(lua_State *); +#define _LUA_COMPILE_SET Xlua_compile_set +#define LUA_COMPILE_SET(func) \ + DATA_SET(_LUA_COMPILE_SET, func) +#define LUA_FOREACH_SET(s) \ + SET_FOREACH((s), _LUA_COMPILE_SET) +SET_DECLARE(_LUA_COMPILE_SET, lua_init_md_t); diff --git a/stand/liblua/math.h b/stand/liblua/math.h index c29466f1af49..852c95ff54ee 100644 --- a/stand/liblua/math.h +++ b/stand/liblua/math.h @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/liblua32/Makefile b/stand/liblua32/Makefile index 4e09f1b05178..292fff71a956 100644 --- a/stand/liblua32/Makefile +++ b/stand/liblua32/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - DO32=1 .include "${.CURDIR}/../liblua/Makefile" diff --git a/stand/libofw/Makefile b/stand/libofw/Makefile index 2d3e30e1ace9..3d4c70dcfc10 100644 --- a/stand/libofw/Makefile +++ b/stand/libofw/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> LIB= ofw @@ -7,10 +5,6 @@ LIB= ofw SRCS= devicename.c ofw_console.c ofw_copy.c ofw_disk.c \ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ ofw_time.c openfirm.c -.PATH: ${ZFSSRC} -SRCS+= devicename_stubs.c -CFLAGS+= -I${ZFSSRC} -I${SYSDIR}/cddl/boot/zfs -CFLAGS+= -I${SYSDIR}/cddl/contrib/opensolaris/uts/common # Pick up the bootstrap header for some interface items CFLAGS+= -I${LDRSRC} diff --git a/stand/libofw/devicename.c b/stand/libofw/devicename.c index 11c0a1719ff3..f6419632c6bc 100644 --- a/stand/libofw/devicename.c +++ b/stand/libofw/devicename.c @@ -24,18 +24,12 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" #include "libofw.h" -#include "libzfs.h" - -static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **); -/* +/* * Point (dev) at an allocated device specifier for the device matching the * path in (devspec). If it contains an explicit device specification, * use that. If not, use the default device. @@ -43,104 +37,76 @@ static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **); int ofw_getdev(void **vdev, const char *devspec, const char **path) { - struct ofw_devdesc **dev = (struct ofw_devdesc **)vdev; - int rv; + struct devdesc **dev = (struct devdesc **)vdev; + int rv; - /* - * If it looks like this is just a path and no - * device, go with the current device. - */ - if ((devspec == NULL) || - ((strchr(devspec, '@') == NULL) && - (strchr(devspec, ':') == NULL))) { + /* + * If it looks like this is just a path and no device, go with the + * current device. + */ + if (devspec == NULL || strpbrk(devspec, ":@") == NULL) { + rv = devparse(dev, getenv("currdev"), NULL); + if (rv == 0 && path != NULL) + *path = devspec; + return (rv); + } - if (((rv = ofw_parsedev(dev, getenv("currdev"), NULL)) == 0) && - (path != NULL)) - *path = devspec; - return(rv); - } - - /* - * Try to parse the device name off the beginning of the devspec - */ - return(ofw_parsedev(dev, devspec, path)); + /* + * Try to parse the device name off the beginning of the devspec + */ + return (devparse(dev, devspec, path)); } /* - * Point (dev) at an allocated device specifier matching the string version - * at the beginning of (devspec). Return a pointer to the remaining - * text in (path). + * Search the OFW (path) for a node that's of (want_type). */ -static int -ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path) +phandle_t +ofw_path_to_handle(const char *ofwpath, const char *want_type, const char **path) { - struct ofw_devdesc *idev; - struct devsw *dv; - phandle_t handle; - const char *p; - const char *s; - char *ep; - char name[256]; - char type[64]; - int err; - int len; - int i; + const char *p, *s; + char name[256]; + char type[64]; + phandle_t handle; + int len; - for (p = s = devspec; *s != '\0'; p = s) { - if ((s = strchr(p + 1, '/')) == NULL) - s = strchr(p, '\0'); - len = s - devspec; - bcopy(devspec, name, len); - name[len] = '\0'; - if ((handle = OF_finddevice(name)) == -1) { - bcopy(name, type, len); - type[len] = '\0'; - } else if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1) - continue; - for (i = 0; (dv = devsw[i]) != NULL; i++) { - if (strncmp(dv->dv_name, type, strlen(dv->dv_name)) == 0) - goto found; + for (p = s = ofwpath; *s != '\0'; p = s) { + if ((s = strchr(p + 1, '/')) == NULL) + s = strchr(p, '\0'); + len = s - ofwpath; + if (len >= sizeof(name)) + return ((phandle_t)-1); + bcopy(ofwpath, name, len); + name[len] = '\0'; + if ((handle = OF_finddevice(name)) == -1) + continue; + if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1) + continue; + if (strcmp(want_type, type) == 0) { + *path = s; + return (handle); + } } - } - return(ENOENT); - -found: - if (path != NULL) - *path = s; - idev = malloc(sizeof(struct ofw_devdesc)); - if (idev == NULL) { - printf("ofw_parsedev: malloc failed\n"); - return ENOMEM; - } - strcpy(idev->d_path, name); - idev->dd.d_dev = dv; - if (dv->dv_type == DEVT_ZFS) { - p = devspec + strlen(dv->dv_name); - err = zfs_parsedev((struct zfs_devdesc *)idev, p, path); - if (err != 0) { - free(idev); - return (err); - } - } - - if (dev == NULL) { - free(idev); - } else { - *dev = idev; - } - return(0); + return ((phandle_t)-1); } int -ofw_setcurrdev(struct env_var *ev, int flags, const void *value) +ofw_common_parsedev(struct devdesc **dev, const char *devspec, const char **path, + const char *ofwtype) { - struct ofw_devdesc *ncurr; - int rv; - - if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0) - return (rv); - - free(ncurr); + const char *rem_path; + struct ofw_devdesc *idev; - return (mount_currdev(ev, flags, value)); + if (ofw_path_to_handle(devspec, ofwtype, &rem_path) == -1) + return (ENOENT); + idev = malloc(sizeof(struct ofw_devdesc)); + if (idev == NULL) { + printf("ofw_parsedev: malloc failed\n"); + return (ENOMEM); + }; + strlcpy(idev->d_path, devspec, min(rem_path - devspec + 1, + sizeof(idev->d_path))); + *dev = &idev->dd; + if (path != NULL) + *path = rem_path; + return (0); } diff --git a/stand/libofw/libofw.h b/stand/libofw/libofw.h index 0483c9dbf754..0f477ef66c93 100644 --- a/stand/libofw/libofw.h +++ b/stand/libofw/libofw.h @@ -21,13 +21,13 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ #include "openfirm.h" #include <readin.h> +#define DEVT_OFDISK 1001 + struct ofw_devdesc { struct devdesc dd; union { @@ -43,9 +43,9 @@ struct ofw_devdesc { }; extern int ofw_getdev(void **vdev, const char *devspec, const char **path); -extern ev_sethook_t ofw_setcurrdev; extern struct devsw ofwdisk; +extern struct devsw ofw_netdev; extern struct netif_driver ofwnet; int ofwn_getunit(const char *); @@ -59,13 +59,13 @@ extern int ofw_autoload(void); void ofw_memmap(int); +phandle_t ofw_path_to_handle(const char *ofwpath, const char *want_type, const char **path); +int ofw_common_parsedev(struct devdesc **dev, const char *devspec, const char **path, + const char *ofwtype); + struct preloaded_file; struct file_format; -/* MD code implementing MI interfaces */ -vm_offset_t md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb); -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); - extern void reboot(void); struct ofw_reg diff --git a/stand/libofw/ofw_console.c b/stand/libofw/ofw_console.c index a129997c5df2..6925641eb606 100644 --- a/stand/libofw/ofw_console.c +++ b/stand/libofw/ofw_console.c @@ -26,9 +26,6 @@ * the rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include "bootstrap.h" @@ -44,14 +41,13 @@ static ihandle_t stdin; static ihandle_t stdout; struct console ofwconsole = { - "ofw", - "Open Firmware console", - 0, - ofw_cons_probe, - ofw_cons_init, - ofw_cons_putchar, - ofw_cons_getchar, - ofw_cons_poll, + .c_name = "ofw", + .c_desc = "Open Firmware console", + .c_probe = ofw_cons_probe, + .c_init = ofw_cons_init, + .c_out = ofw_cons_putchar, + .c_in = ofw_cons_getchar, + .c_ready = ofw_cons_poll, }; static void @@ -66,7 +62,7 @@ ofw_cons_probe(struct console *cp) static int ofw_cons_init(int arg) { - return 0; + return (0); } void @@ -86,7 +82,7 @@ ofw_cons_putchar(int c) static int saved_char = -1; int -ofw_cons_getchar() +ofw_cons_getchar(void) { unsigned char ch = '\0'; int l; @@ -94,7 +90,7 @@ ofw_cons_getchar() if (saved_char != -1) { l = saved_char; saved_char = -1; - return l; + return (l); } /* At least since version 4.0.0, QEMU became bug-compatible @@ -108,17 +104,17 @@ ofw_cons_getchar() } int -ofw_cons_poll() +ofw_cons_poll(void) { unsigned char ch; if (saved_char != -1) - return 1; + return (1); if (OF_read(stdin, &ch, 1) > 0) { saved_char = ch; - return 1; + return (1); } - return 0; + return (0); } diff --git a/stand/libofw/ofw_copy.c b/stand/libofw/ofw_copy.c index 1d46ba29d9ca..17a46fe4e480 100644 --- a/stand/libofw/ofw_copy.c +++ b/stand/libofw/ofw_copy.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * MD primitives supporting placement of module data * @@ -122,14 +119,14 @@ ofw_copyin(const void *src, vm_offset_t dest, const size_t len) } bcopy(src, (void *)dest, len); - return(len); + return (len); } ssize_t ofw_copyout(const vm_offset_t src, void *dest, const size_t len) { bcopy((void *)src, dest, len); - return(len); + return (len); } ssize_t @@ -146,7 +143,7 @@ ofw_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) buf = malloc(chunk); if (buf == NULL) { printf("ofw_readin: buf malloc failed\n"); - return(0); + return (0); } if (ofw_mapmem(dest, len)) { @@ -169,5 +166,5 @@ ofw_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) } free(buf); - return(len - resid); + return (len - resid); } diff --git a/stand/libofw/ofw_disk.c b/stand/libofw/ofw_disk.c index 2c3bd568a268..d4bce64d9be5 100644 --- a/stand/libofw/ofw_disk.c +++ b/stand/libofw/ofw_disk.c @@ -23,23 +23,19 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Disk I/O routines using Open Firmware */ #include <sys/param.h> +#include <sys/stdarg.h> #include <netinet/in.h> -#include <machine/stdarg.h> - #include <stand.h> #include <sys/disk.h> -#include "bootstrap.h" +#include "disk.h" #include "libofw.h" static int ofwd_init(void); @@ -49,16 +45,23 @@ static int ofwd_open(struct open_file *f, ...); static int ofwd_close(struct open_file *f); static int ofwd_ioctl(struct open_file *f, u_long cmd, void *data); static int ofwd_print(int verbose); +static char * ofwd_fmtdev(struct devdesc *); +static int ofwd_parsedev(struct devdesc **, const char *, const char **); +static bool ofwd_match(struct devsw *, const char *); struct devsw ofwdisk = { - "block", - DEVT_DISK, - ofwd_init, - ofwd_strategy, - ofwd_open, - ofwd_close, - ofwd_ioctl, - ofwd_print + .dv_name = "block", + .dv_type = DEVT_OFDISK, + .dv_init = ofwd_init, + .dv_strategy = ofwd_strategy, + .dv_open = ofwd_open, + .dv_close = ofwd_close, + .dv_ioctl = ofwd_ioctl, + .dv_print = ofwd_print, + .dv_cleanup = nullsys, + .dv_match = ofwd_match, + .dv_fmtdev = ofwd_fmtdev, + .dv_parsedev = ofwd_parsedev, }; /* @@ -169,7 +172,7 @@ ofwd_ioctl(struct open_file *f, u_long cmd, void *data) case DIOCGMEDIASIZE: block_size = OF_block_size(dev->d_handle); n = OF_blocks(dev->d_handle); - *(uint64_t *)data = (uint64_t)(n * block_size); + *(uint64_t *)data = ((uint64_t)n * block_size); break; default: return (ENOTTY); @@ -180,5 +183,52 @@ ofwd_ioctl(struct open_file *f, u_long cmd, void *data) static int ofwd_print(int verbose __unused) { + uintmax_t block_size, n; + int ret; + char line[80]; + + /* + * We don't have a list of devices since we don't parse the whole OFW + * tree to find them. Instead, if we have an open device print info + * about it. Otherwise say we can't. Makes lsdev nicer. + */ + if ((ret = pager_output("block devices:\n")) != 0) + return (ret); + if (kdp != NULL) { + block_size = OF_block_size(kdp->d_handle); + n = OF_blocks(kdp->d_handle); + snprintf(line, sizeof(line), + " %s: OFW block device (%ju X %ju): %ju bytes\n", + kdp->d_path, n, block_size, n * block_size); + if ((ret = pager_output(line)) != 0) + return (ret); + } else { + if ((ret = pager_output(" none are open, so no info\n")) != 0) + return (ret); + } + return (0); } + + +static bool +ofwd_match(struct devsw *devsw, const char *devspec) +{ + const char *path; + + return (ofw_path_to_handle(devspec, devsw->dv_name, &path) != -1); +} + +static char * +ofwd_fmtdev(struct devdesc *idev) +{ + struct ofw_devdesc *dev = (struct ofw_devdesc *)idev; + + return (dev->d_path); +} + +static int +ofwd_parsedev(struct devdesc **dev, const char *devspec, const char **path) +{ + return (ofw_common_parsedev(dev, devspec, path, ofwdisk.dv_name)); +} diff --git a/stand/libofw/ofw_memory.c b/stand/libofw/ofw_memory.c index 2b7cd87ac765..67a4527e07b4 100644 --- a/stand/libofw/ofw_memory.c +++ b/stand/libofw/ofw_memory.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/types.h> diff --git a/stand/libofw/ofw_module.c b/stand/libofw/ofw_module.c index d39a34344556..4c1fe9cd279d 100644 --- a/stand/libofw/ofw_module.c +++ b/stand/libofw/ofw_module.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * ofw-specific module functionality. * @@ -45,5 +42,5 @@ int ofw_autoload(void) { /* XXX Call some machdep autoload routine? */ - return(0); + return (0); } diff --git a/stand/libofw/ofw_net.c b/stand/libofw/ofw_net.c index 4f393cebc2fa..3418216a9836 100644 --- a/stand/libofw/ofw_net.c +++ b/stand/libofw/ofw_net.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> @@ -41,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <net.h> #include <netif.h> +#include "libofw.h" #include "openfirm.h" static int ofwn_probe(struct netif *, void *); @@ -53,22 +51,26 @@ static void ofwn_end(struct netif *); extern struct netif_stats ofwn_stats[]; struct netif_dif ofwn_ifs[] = { - /* dif_unit dif_nsel dif_stats dif_private */ - { 0, 1, &ofwn_stats[0], 0, }, + { + .dif_unit=0, + .dif_nsel=1, + .dif_stats=&ofwn_stats[0], + .dif_private=0, + }, }; struct netif_stats ofwn_stats[nitems(ofwn_ifs)]; struct netif_driver ofwnet = { - "net", /* netif_bname */ - ofwn_match, /* netif_match */ - ofwn_probe, /* netif_probe */ - ofwn_init, /* netif_init */ - ofwn_get, /* netif_get */ - ofwn_put, /* netif_put */ - ofwn_end, /* netif_end */ - ofwn_ifs, /* netif_ifs */ - nitems(ofwn_ifs) /* netif_nifs */ + .netif_bname="net", + .netif_match=ofwn_match, + .netif_probe=ofwn_probe, + .netif_init=ofwn_init, + .netif_get=ofwn_get, + .netif_put=ofwn_put, + .netif_end=ofwn_end, + .netif_ifs=ofwn_ifs, + .netif_nifs=nitems(ofwn_ifs) }; static ihandle_t netinstance; @@ -78,13 +80,13 @@ static void *dmabuf; static int ofwn_match(struct netif *nif, void *machdep_hint) { - return 1; + return (1); } static int ofwn_probe(struct netif *nif, void *machdep_hint) { - return 0; + return (0); } static ssize_t @@ -121,7 +123,7 @@ ofwn_put(struct iodesc *desc, void *pkt, size_t len) printf("netif_put: OF_write returned %d\n", rv); #endif - return rv; + return (rv); } static ssize_t @@ -189,8 +191,6 @@ ofwn_get(struct iodesc *desc, void **pkt, time_t timeout) return (length); } -extern char *strchr(); - static void ofwn_init(struct iodesc *desc, void *machdep_hint) { @@ -256,12 +256,70 @@ ofwn_getunit(const char *path) for (i = 0; i < nofwninfo; i++) { printf(">>> test =\t%s\n", ofwninfo[i].ofwn_path); if (strcmp(path, ofwninfo[i].ofwn_path) == 0) - return i; + return (i); if (strcmp(newpath, ofwninfo[i].ofwn_path) == 0) - return i; + return (i); } - return -1; + return (-1); } #endif + +/* + * To properly match network devices, we have to subclass the netdev device. + * It has a different devdesc than a normal network device (which is fine: + * it's a struct superset) and different matching criteria (since it has to + * look at the path, find a handle and see if that handle is a network node + * or not). + */ + +static int ofwnd_init(void); +static int ofwnd_parsedev(struct devdesc **, const char *, const char **); +static bool ofwnd_match(struct devsw *, const char *); +static char *ofwnd_fmtdev(struct devdesc *); + +struct devsw ofw_netdev = { + .dv_name = "network", + .dv_type = DEVT_NET, + .dv_init = ofwnd_init, + .dv_match = ofwnd_match, + .dv_fmtdev = ofwnd_fmtdev, + .dv_parsedev = ofwnd_parsedev, +}; + +static int ofwnd_init(void) +{ + netdev.dv_init(); + ofw_netdev.dv_strategy = netdev.dv_strategy; + ofw_netdev.dv_open = netdev.dv_open; + ofw_netdev.dv_close = netdev.dv_close; + ofw_netdev.dv_ioctl = netdev.dv_ioctl; + ofw_netdev.dv_print = netdev.dv_print; + ofw_netdev.dv_fmtdev = netdev.dv_fmtdev; + /* parsedev is unique to ofwnd */ + /* match is unique to ofwnd */ + return (0); +} + +static int +ofwnd_parsedev(struct devdesc **dev, const char *devspec, const char **path) +{ + return (ofw_common_parsedev(dev, devspec, path, ofw_netdev.dv_name)); +} + +static bool +ofwnd_match(struct devsw *devsw, const char *devspec) +{ + const char *path; + + return (ofw_path_to_handle(devspec, devsw->dv_name, &path) != -1); +} + +static char * +ofwnd_fmtdev(struct devdesc *idev) +{ + struct ofw_devdesc *dev = (struct ofw_devdesc *)idev; + + return (dev->d_path); +} diff --git a/stand/libofw/ofw_reboot.c b/stand/libofw/ofw_reboot.c index bbb420ac1767..3f705d57d0d2 100644 --- a/stand/libofw/ofw_reboot.c +++ b/stand/libofw/ofw_reboot.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "openfirm.h" diff --git a/stand/libofw/ofw_time.c b/stand/libofw/ofw_time.c index d5ca271564de..48372428ae29 100644 --- a/stand/libofw/ofw_time.c +++ b/stand/libofw/ofw_time.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "openfirm.h" @@ -38,7 +35,7 @@ time(time_t *tloc) secs = OF_milliseconds() / 1000; if (tloc) *tloc = secs; - return secs; + return (secs); } time_t @@ -46,7 +43,7 @@ getsecs(void) { time_t n = 0; time(&n); - return n; + return (n); } void diff --git a/stand/libofw/openfirm.c b/stand/libofw/openfirm.c index b2b89581ae70..1df65784e47a 100644 --- a/stand/libofw/openfirm.c +++ b/stand/libofw/openfirm.c @@ -55,12 +55,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/endian.h> - -#include <machine/stdarg.h> +#include <sys/stdarg.h> #include <stand.h> @@ -137,7 +133,7 @@ OF_test(char *name) /* Return firmware millisecond count. */ int -OF_milliseconds() +OF_milliseconds(void) { static struct { cell_t name; @@ -695,7 +691,7 @@ OF_boot(char *bootspec) /* Suspend and drop back to the Open Firmware interface. */ void -OF_enter() +OF_enter(void) { static struct { cell_t name; @@ -710,7 +706,7 @@ OF_enter() /* Shut down and drop back to the Open Firmware interface. */ void -OF_exit() +OF_exit(void) { static struct { cell_t name; @@ -725,7 +721,7 @@ OF_exit() } void -OF_quiesce() +OF_quiesce(void) { static struct { cell_t name; @@ -772,6 +768,7 @@ OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) if (size > 0) OF_release(virt, size); #endif - entry(0, 0, openfirmware, arg, len); + ((int (*)(u_long, u_long, u_long, void *, u_long))entry) + (0, 0, (u_long)openfirmware, arg, len); } #endif diff --git a/stand/libofw/openfirm.h b/stand/libofw/openfirm.h index 0981dbf093eb..35d10c320b57 100644 --- a/stand/libofw/openfirm.h +++ b/stand/libofw/openfirm.h @@ -53,8 +53,6 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _OPENFIRM_H_ #define _OPENFIRM_H_ @@ -62,7 +60,6 @@ * Prototypes for Open Firmware Interface Routines */ -#include <sys/cdefs.h> #include <sys/types.h> typedef uint32_t ihandle_t; diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index 6f2eaf3d959e..f5a1acea843e 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -1,4 +1,3 @@ -# $FreeBSD$ # Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $ # # Notes: @@ -14,8 +13,8 @@ LIB?= sa # standalone components and stuff we have modified locally SRCS+= gzguts.h zutil.h __main.c abort.c assert.c bcd.c environment.c \ - getopt.c gets.c globals.c \ - hexdump.c pager.c panic.c printf.c strdup.c strerror.c \ + features.c getopt.c gets.c globals.c \ + hexdump.c nvstore.c pager.c panic.c printf.c strdup.c strerror.c \ random.c sbrk.c tslog.c twiddle.c zalloc.c zalloc_malloc.c # private (pruned) versions of libc string functions @@ -89,47 +88,26 @@ SRCS+= _setjmp.S # NOTE: to actually test this functionality after libbz2 upgrade compile # loader(8) with LOADER_BZIP2_SUPPORT defined .PATH: ${SRCTOP}/contrib/bzip2 -CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS - -SRCS+=bzlib.c crctable.c decompress.c huffman.c randtable.c +.for i in bzlib.c crctable.c decompress.c huffman.c randtable.c +CFLAGS.${i}+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS +SRCS+=${i} +.endfor # decompression functionality from zlib +# https://github.com/madler/zlib/issues/633 documents why we suppress deprecated +# prototype warnings. .PATH: ${SRCTOP}/sys/contrib/zlib -CFLAGS+=-DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib -SRCS+= adler32.c crc32.c -SRCS+= infback.c inffast.c inflate.c inftrees.c zutil.c +ZLIB_CFLAGS=-DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib ${NO_WDEPRECATED_NON_PROTOTYPE} +.for i in adler32.c crc32.c infback.c inffast.c inflate.c inftrees.c zutil.c +CFLAGS.${i}+=${ZLIB_CFLAGS} +SRCS+= ${i} +.endfor # lz4 decompression functionality .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 SRCS+= lz4.c CFLAGS.lz4.c+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 -# Create a subset of includes that are safe, as well as adjusting those that aren't -# The lists may drive people nuts, but they are explicitly opt-in -FAKE_DIRS=xlocale arpa -SAFE_INCS=a.out.h assert.h elf.h limits.h nlist.h setjmp.h stddef.h stdbool.h string.h strings.h time.h unistd.h uuid.h -STAND_H_INC=ctype.h fcntl.h signal.h stdio.h stdlib.h -OTHER_INC=stdarg.h errno.h stdint.h - -beforedepend: - mkdir -p ${FAKE_DIRS}; \ - for i in ${SAFE_INCS}; do \ - ln -sf ${SRCTOP}/include/$$i $$i; \ - done; \ - ln -sf ${SYSDIR}/${MACHINE}/include/stdarg.h stdarg.h; \ - ln -sf ${SYSDIR}/sys/errno.h errno.h; \ - ln -sf ${SYSDIR}/sys/stdint.h stdint.h; \ - ln -sf ${SRCTOP}/include/arpa/inet.h arpa/inet.h; \ - ln -sf ${SRCTOP}/include/arpa/tftp.h arpa/tftp.h; \ - for i in _time.h _strings.h _string.h; do \ - [ -f xlocale/$$i ] || :> xlocale/$$i; \ - done; \ - for i in ${STAND_H_INC}; do \ - ln -sf ${SASRC}/stand.h $$i; \ - done -CLEANDIRS+=${FAKE_DIRS} -CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC} - # io routines SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c mount.c \ fstat.c close.c lseek.c open.c read.c write.c readdir.c preload.c @@ -167,21 +145,36 @@ SRCS+= time.c .PATH: ${SRCTOP}/sys/ufs/ffs SRCS+=ffs_subr.c ffs_tables.c -CFLAGS.dosfs.c+= -I${LDRSRC} -CFLAGS.tftp.c+= -I${LDRSRC} -CFLAGS.ufs.c+= -I${LDRSRC} -CFLAGS.bzipfs.c+= -I${SRCTOP}/contrib/bzip2 +# +# i386 has a constrained space for its /boot/loader, so compile out the +# extensive messages diagnosing bad superblocks. i386 doesn't support UEFI +# booting, so doing it always makes sense natively there. When we compile +# for 32-bit on amd64, LIBSA_CPUARCH is also i386 and we use libsa32 only +# for the BIOS /boot/loader which has the same constraints. +# +.if ${LIBSA_CPUARCH} == "i386" +CFLAGS.ffs_subr.c+= -DSTANDALONE_SMALL +.endif + +CFLAGS.gzipfs.c+= ${ZLIB_CFLAGS} +CFLAGS.pkgfs.c+= ${ZLIB_CFLAGS} +CFLAGS.bzipfs.c+= -I${SRCTOP}/contrib/bzip2 -DBZ_NO_STDIO -DBZ_NO_COMPRESS # explicit_bzero and calculate_crc32c .PATH: ${SYSDIR}/libkern SRCS+= explicit_bzero.c crc32_libkern.c +# Bits from GELI reused for some random seeding cases +.PATH: ${SYSDIR}/geom/eli +SRCS+= g_eli_hmac.c pkcs5v2.c + # Maybe GELI .if ${MK_LOADER_GELI} == "yes" .include "${SASRC}/geli/Makefile.inc" .endif .if ${MK_LOADER_VERIEXEC} == "yes" && ${MK_BEARSSL} == "yes" +# XXX Note that these pollutes CFLAGS in a way that's not easy to fix .include "${SRCTOP}/lib/libbearssl/Makefile.libsa.inc" .include "${SRCTOP}/lib/libsecureboot/Makefile.libsa.inc" .endif @@ -191,8 +184,44 @@ SRCS+= explicit_bzero.c crc32_libkern.c .include "${SASRC}/zfs/Makefile.inc" .endif +# Crypto hashing functions +# sha256 and sha512 from sys/crypto +.PATH: ${SYSDIR}/crypto/sha2 +SRCS+= sha256c.c sha512c.c + +# md5 from the kernel +.PATH: ${SYSDIR}/kern +SRCS+= md5c.c + .if ${DO32:U0} == 0 MAN=libsa.3 .endif +# Create a subset of includes that are safe, as well as adjusting those that aren't +# The lists may drive people nuts, but they are explicitly opt-in +FAKE_DIRS=xlocale arpa ssp +SAFE_INCS=a.out.h assert.h elf.h limits.h nlist.h setjmp.h stddef.h stdbool.h string.h strings.h time.h uuid.h +STAND_H_INC=ctype.h fcntl.h signal.h stdio.h stdlib.h unistd.h +OTHER_INC=stdarg.h errno.h stdint.h + +beforedepend: + mkdir -p ${FAKE_DIRS}; \ + for i in ${SAFE_INCS}; do \ + ln -sf ${SRCTOP}/include/$$i $$i; \ + done; \ + ln -sf ${SYSDIR}/sys/errno.h errno.h; \ + ln -sf ${SYSDIR}/sys/stdarg.h stdarg.h; \ + ln -sf ${SYSDIR}/sys/stdint.h stdint.h; \ + ln -sf ${SRCTOP}/include/arpa/inet.h arpa/inet.h; \ + ln -sf ${SRCTOP}/include/arpa/tftp.h arpa/tftp.h; \ + ln -sf ${SRCTOP}/include/ssp/ssp.h ssp/ssp.h; \ + for i in _time.h _strings.h _string.h; do \ + [ -f xlocale/$$i ] || :> xlocale/$$i; \ + done; \ + for i in ${STAND_H_INC}; do \ + ln -sf ${SASRC}/stand.h $$i; \ + done +CLEANDIRS+=${FAKE_DIRS} +CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC} + .include <bsd.lib.mk> diff --git a/stand/libsa/Makefile.depend b/stand/libsa/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/libsa/Makefile.depend +++ b/stand/libsa/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/libsa/__main.c b/stand/libsa/__main.c index e38f33865c05..2c057104476c 100644 --- a/stand/libsa/__main.c +++ b/stand/libsa/__main.c @@ -30,9 +30,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> void __main(void); diff --git a/stand/libsa/abort.c b/stand/libsa/abort.c index d8f66ca0ba23..b521806fd888 100644 --- a/stand/libsa/abort.c +++ b/stand/libsa/abort.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> void diff --git a/stand/libsa/amd64/_setjmp.S b/stand/libsa/amd64/_setjmp.S index 53ea6e9b5d52..62683be11946 100644 --- a/stand/libsa/amd64/_setjmp.S +++ b/stand/libsa/amd64/_setjmp.S @@ -30,12 +30,7 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) - .asciz "@(#)_setjmp.s 5.1 (Berkeley) 4/23/90" -#endif /* LIBC_SCCS and not lint */ #include <machine/asm.h> -__FBSDID("$FreeBSD$"); - /* * C library -- _setjmp, _longjmp * @@ -90,3 +85,5 @@ ENTRY(_longjmp) 1: movq %rcx,0(%rsp) ret END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/libsa/arp.c b/stand/libsa/arp.c index 7d49559b4e04..eff8b9f332a3 100644 --- a/stand/libsa/arp.c +++ b/stand/libsa/arp.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> @@ -178,7 +173,7 @@ arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) if (n == -1 || n < sizeof(struct ether_arp)) { #ifdef ARP_DEBUG if (debug) - printf("bad len=%d\n", n); + printf("bad len=%zd\n", n); #endif free(ptr); return (-1); diff --git a/stand/libsa/assert.c b/stand/libsa/assert.c index 74b9fb4bacbf..8aaf0e507a4d 100644 --- a/stand/libsa/assert.c +++ b/stand/libsa/assert.c @@ -24,11 +24,7 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <assert.h> - #include "stand.h" void diff --git a/stand/libsa/bcd.c b/stand/libsa/bcd.c index 7bd67c91620a..2f55bf9eda3c 100644 --- a/stand/libsa/bcd.c +++ b/stand/libsa/bcd.c @@ -3,9 +3,6 @@ * Cannot be copyrighted. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> u_char const bcd2bin_data[] = { diff --git a/stand/libsa/bootp.c b/stand/libsa/bootp.c index f092db3de968..ac37553c6d34 100644 --- a/stand/libsa/bootp.c +++ b/stand/libsa/bootp.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: bootp.c,v 1.4 93/09/11 03:13:51 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stddef.h> #include <sys/types.h> #include <sys/limits.h> @@ -47,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include <string.h> -#define BOOTP_DEBUGxx #define SUPPORT_DHCP #define DHCP_ENV_NOVENDOR 1 /* do not parse vendor options */ @@ -135,10 +129,7 @@ bootp(int sock) } wbuf; struct bootp *rbootp; -#ifdef BOOTP_DEBUG - if (debug) - printf("bootp: socket=%d\n", sock); -#endif + DEBUG_PRINTF(1, ("bootp: socket=%d\n", sock)); if (!bot) bot = getsecs(); @@ -146,10 +137,7 @@ bootp(int sock) printf("bootp: bad socket. %d\n", sock); return; } -#ifdef BOOTP_DEBUG - if (debug) - printf("bootp: d=%lx\n", (long)d); -#endif + DEBUG_PRINTF(1, ("bootp: socktodesc=%lx\n", (long)d)); bp = &wbuf.wbootp; bzero(bp, sizeof(*bp)); @@ -230,31 +218,20 @@ bootp(int sock) netmask = htonl(IN_CLASSB_NET); else netmask = htonl(IN_CLASSC_NET); -#ifdef BOOTP_DEBUG - if (debug) - printf("'native netmask' is %s\n", intoa(netmask)); -#endif + DEBUG_PRINTF(1, ("'native netmask' is %s\n", intoa(netmask))); } -#ifdef BOOTP_DEBUG - if (debug) - printf("mask: %s\n", intoa(netmask)); -#endif + DEBUG_PRINTF(1,("rootip: %s\n", inet_ntoa(rootip))); + DEBUG_PRINTF(1,("mask: %s\n", intoa(netmask))); /* We need a gateway if root is on a different net */ if (!SAMENET(myip, rootip, netmask)) { -#ifdef BOOTP_DEBUG - if (debug) - printf("need gateway for root ip\n"); -#endif + DEBUG_PRINTF(1,("need gateway for root ip\n")); } /* Toss gateway if on a different net */ if (!SAMENET(myip, gateip, netmask)) { -#ifdef BOOTP_DEBUG - if (debug) - printf("gateway ip (%s) bad\n", inet_ntoa(gateip)); -#endif + DEBUG_PRINTF(1,("gateway ip (%s) bad\n", inet_ntoa(gateip))); gateip.s_addr = 0; } @@ -269,18 +246,11 @@ bootpsend(struct iodesc *d, void *pkt, size_t len) { struct bootp *bp; -#ifdef BOOTP_DEBUG - if (debug) - printf("bootpsend: d=%lx called.\n", (long)d); -#endif - + DEBUG_PRINTF(1,("bootpsend: d=%lx called.\n", (long)d)); bp = pkt; bp->bp_secs = htons((u_short)(getsecs() - bot)); -#ifdef BOOTP_DEBUG - if (debug) - printf("bootpsend: calling sendudp\n"); -#endif + DEBUG_PRINTF(1,("bootpsend: calling sendudp\n")); return (sendudp(d, pkt, len)); } @@ -293,34 +263,22 @@ bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, struct bootp *bp; void *ptr; -#ifdef BOOTP_DEBUG - if (debug) - printf("bootp_recvoffer: called\n"); -#endif + DEBUG_PRINTF(1,("bootp_recvoffer: called\n")); ptr = NULL; n = readudp(d, &ptr, (void **)&bp, tleft); if (n == -1 || n < sizeof(struct bootp) - BOOTP_VENDSIZE) goto bad; -#ifdef BOOTP_DEBUG - if (debug) - printf("bootprecv: checked. bp = %p, n = %zd\n", bp, n); -#endif + DEBUG_PRINTF(1,("bootprecv: checked. bp = %p, n = %zd\n", bp, n)); + if (bp->bp_xid != htonl(d->xid)) { -#ifdef BOOTP_DEBUG - if (debug) { - printf("bootprecv: expected xid 0x%lx, got 0x%x\n", - d->xid, ntohl(bp->bp_xid)); - } -#endif + DEBUG_PRINTF(1,("bootprecv: expected xid 0x%lx, got 0x%x\n", + d->xid, ntohl(bp->bp_xid))); goto bad; } -#ifdef BOOTP_DEBUG - if (debug) - printf("bootprecv: got one!\n"); -#endif + DEBUG_PRINTF(1,("bootprecv: got one!\n")); /* Suck out vendor info */ if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) { @@ -364,10 +322,7 @@ vend_rfc1048(u_char *cp, u_int len) u_char tag; const char *val; -#ifdef BOOTP_DEBUG - if (debug) - printf("vend_rfc1048 bootp info. len=%d\n", len); -#endif + DEBUG_PRINTF(1,("vend_rfc1048 bootp info. len=%d\n", len)); ep = cp + len; /* Step over magic cookie */ @@ -448,10 +403,8 @@ vend_cmu(u_char *cp) { struct cmu_vend *vp; -#ifdef BOOTP_DEBUG - if (debug) - printf("vend_cmu bootp info.\n"); -#endif + DEBUG_PRINTF(1,("vend_cmu bootp info.\n")); + vp = (struct cmu_vend *)cp; if (vp->v_smask.s_addr != 0) { @@ -670,12 +623,14 @@ setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts) /* if not found we end up on the default entry */ /* - * Copy data into the buffer. libstand does not have snprintf so we - * need to be careful with sprintf(). With strings, the source is - * always <256 char so shorter than the buffer so we are safe; with - * other arguments, the longest string is inet_ntoa which is 16 bytes - * so we make sure to have always enough room in the string before - * trying an sprint. + * Copy data into the buffer. While the code uses snprintf, it's also + * careful never to insert strings that would be truncated. inet_ntoa is + * tricky to know the size, so it assumes we can always insert it + * because we reserve 16 bytes at the end of the string for its worst + * case. Other cases are covered because they will write fewer than + * these reserved bytes at the end. Source strings can't overflow (as + * noted below) because buf is 256 bytes and all strings are limited by + * the protocol to be 256 bytes or smaller. */ vp = buf; *vp = '\0'; @@ -695,14 +650,14 @@ setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts) if (vp != buf) *vp++ = FLD_SEP; bcopy(cp, &in_ip.s_addr, sizeof(in_ip.s_addr)); - sprintf(vp, "%s", inet_ntoa(in_ip)); + snprintf(vp, endv - vp, "%s", inet_ntoa(in_ip)); vp += strlen(vp); } break; case __BYTES: /* opaque byte string */ for (; size > 0 && vp < endv; size -= 1, cp += 1) { - sprintf(vp, "%02x", *cp); + snprintf(vp, endv - vp, "%02x", *cp); vp += strlen(vp); } break; @@ -725,7 +680,7 @@ setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts) v = cp[0]; if (vp != buf) *vp++ = FLD_SEP; - sprintf(vp, "%u", v); + snprintf(vp, endv - vp, "%u", v); vp += strlen(vp); } break; @@ -750,21 +705,22 @@ setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts) vp = s; /* prepare for next round */ } buf[0] = '\0'; /* option already done */ + break; } if (tp - tags < sizeof(tags) - 5) { /* add tag to the list */ if (tp != tags) *tp++ = FLD_SEP; - sprintf(tp, "%d", tag); + snprintf(tp, sizeof(tags) - (tp - tags), "%d", tag); tp += strlen(tp); } if (buf[0]) { char env[128]; /* the string name */ if (op->tag == 0) - sprintf(env, op->desc, opts[0].desc, tag); + snprintf(env, sizeof(env), op->desc, opts[0].desc, tag); else - sprintf(env, "%s%s", opts[0].desc, op->desc); + snprintf(env, sizeof(env), "%s%s", opts[0].desc, op->desc); /* * Do not replace existing values in the environment, so that * locally-obtained values can override server-provided values. @@ -774,7 +730,7 @@ setenv_(u_char *cp, u_char *ep, struct dhcp_opt *opts) } if (tp != tags) { char env[128]; /* the string name */ - sprintf(env, "%stags", opts[0].desc); + snprintf(env, sizeof(env), "%stags", opts[0].desc); setenv(env, tags, 1); } } diff --git a/stand/libsa/bootp.h b/stand/libsa/bootp.h index 8939955d861b..57601e025bf5 100644 --- a/stand/libsa/bootp.h +++ b/stand/libsa/bootp.h @@ -18,8 +18,6 @@ * University. Carnegie Mellon makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. - * - * $FreeBSD$ */ #ifndef _BOOTP_H_ diff --git a/stand/libsa/bootparam.c b/stand/libsa/bootparam.c index 30e109e75742..c195a06cc5b3 100644 --- a/stand/libsa/bootparam.c +++ b/stand/libsa/bootparam.c @@ -30,9 +30,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * RPC/bootparams */ diff --git a/stand/libsa/bootparam.h b/stand/libsa/bootparam.h index 9c9f50ea434d..6f0c773a0759 100644 --- a/stand/libsa/bootparam.h +++ b/stand/libsa/bootparam.h @@ -1,5 +1,4 @@ /* $NetBSD: bootparam.h,v 1.3 1998/01/05 19:19:41 perry Exp $ */ -/* $FreeBSD$ */ int bp_whoami(int sock); int bp_getfile(int sock, char *key, struct in_addr *addrp, char *path); diff --git a/stand/libsa/bzipfs.c b/stand/libsa/bzipfs.c index 1cd71f7913a0..ff7ec16e7dc6 100644 --- a/stand/libsa/bzipfs.c +++ b/stand/libsa/bzipfs.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #ifndef REGRESSION #include "stand.h" #else @@ -70,14 +67,15 @@ static int bzf_stat(struct open_file *f, struct stat *sb); #ifndef REGRESSION struct fs_ops bzipfs_fsops = { - "bzip", - bzf_open, - bzf_close, - bzf_read, - null_write, - bzf_seek, - bzf_stat, - null_readdir + .fs_name = "bzip", + .fs_flags = 0, + .fo_open = bzf_open, + .fo_close = bzf_close, + .fo_read = bzf_read, + .fo_write = null_write, + .fo_seek = bzf_seek, + .fo_stat = bzf_stat, + .fo_readdir = null_readdir, }; #endif @@ -368,7 +366,7 @@ bz_internal_error(int errorcode) #ifdef REGRESSION /* Small test case, open and decompress test.bz2 */ -int main() +int main(void) { struct open_file f; char buf[1024]; diff --git a/stand/libsa/cd9660.c b/stand/libsa/cd9660.c index 57e4916c0fb5..d1da39aa479a 100644 --- a/stand/libsa/cd9660.c +++ b/stand/libsa/cd9660.c @@ -31,9 +31,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Stand-alone ISO9660 file reading package. * @@ -84,6 +81,7 @@ static ISO_SUSP_HEADER *susp_lookup_record(struct open_file *f, struct fs_ops cd9660_fsops = { .fs_name = "cd9660", + .fs_flags = 0, .fo_open = cd9660_open, .fo_close = cd9660_close, .fo_read = cd9660_read, diff --git a/stand/libsa/cd9660read.c b/stand/libsa/cd9660read.c index 3f4e667f6942..6062eb061506 100644 --- a/stand/libsa/cd9660read.c +++ b/stand/libsa/cd9660read.c @@ -32,9 +32,6 @@ /* Originally derived from libsa/cd9660.c: */ /* $NetBSD: cd9660.c,v 1.5 1997/06/26 19:11:33 drochner Exp $ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <fs/cd9660/iso.h> #include <fs/cd9660/cd9660_rrip.h> diff --git a/stand/libsa/close.c b/stand/libsa/close.c index a177eb85eb3a..0aa6fd9d6ede 100644 --- a/stand/libsa/close.c +++ b/stand/libsa/close.c @@ -31,8 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)close.c 8.1 (Berkeley) 6/11/93 - * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. @@ -60,9 +58,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" int diff --git a/stand/libsa/closeall.c b/stand/libsa/closeall.c index 92c6955cf5da..3aecd5651541 100644 --- a/stand/libsa/closeall.c +++ b/stand/libsa/closeall.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Toomas Soome <tsoome@me.com> * @@ -26,9 +26,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" void diff --git a/stand/libsa/crc32_libkern.c b/stand/libsa/crc32_libkern.c index d2bd738d4c20..bf9a20f82a47 100644 --- a/stand/libsa/crc32_libkern.c +++ b/stand/libsa/crc32_libkern.c @@ -1,3 +1,2 @@ -/* $FreeBSD$ */ #include "../../sys/libkern/gsb_crc32.c" diff --git a/stand/libsa/dev.c b/stand/libsa/dev.c index 1d1dd075580e..1edc843d508c 100644 --- a/stand/libsa/dev.c +++ b/stand/libsa/dev.c @@ -27,13 +27,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dev.c 8.1 (Berkeley) 6/11/93 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/reboot.h> @@ -56,3 +51,127 @@ noioctl(struct open_file *f __unused, u_long cmd __unused, void *data __unused) { return (EINVAL); } + +char * +devformat(struct devdesc *d) +{ + static char name[DEV_DEVLEN]; + + if (d->d_dev->dv_fmtdev != NULL) + return (d->d_dev->dv_fmtdev(d)); + snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit); + return (name); +} + +/* NB: devspec points to the remainder of the device name after dv_name */ +static int +default_parsedev(struct devdesc **dev, const char *devspec, + const char **path) +{ + struct devdesc *idev; + int unit, err; + char *cp; + + idev = malloc(sizeof(struct devdesc)); + if (idev == NULL) + return (ENOMEM); + + unit = 0; + cp = (char *)devspec; /* strtol interface, alas */ + + if (*devspec != '\0' && *devspec != ':') { + errno = 0; + unit = strtol(devspec, &cp, 0); + if (errno != 0 || cp == devspec) { + err = EUNIT; + goto fail; + } + } + if (*cp != '\0' && *cp != ':') { + err = EINVAL; + goto fail; + } + + idev->d_unit = unit; + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + *dev = idev; + return (0); +fail: + free(idev); + return (err); +} + +/* NB: devspec points to the whole device spec, and possible trailing path */ +int +devparse(struct devdesc **dev, const char *devspec, const char **path) +{ + struct devdesc *idev; + struct devsw *dv; + int i, err; + const char *np; + + /* minimum length check */ + if (strlen(devspec) < 2) + return (EINVAL); + + /* look for a device that matches */ + for (i = 0; devsw[i] != NULL; i++) { + dv = devsw[i]; + if (dv->dv_match != NULL) { + if (dv->dv_match(dv, devspec) != 0) + break; + } else { + if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name))) + break; + } + } + if (devsw[i] == NULL) + return (ENOENT); + idev = NULL; + err = 0; + if (dv->dv_parsedev) { + err = dv->dv_parsedev(&idev, devspec, path); + } else { + np = devspec + strlen(dv->dv_name); + err = default_parsedev(&idev, np, path); + } + if (err != 0) + return (err); + + idev->d_dev = dv; + if (dev != NULL) + *dev = idev; + else + free(idev); + return (0); +} + +int +devinit(void) +{ + int err = 0; + + /* + * March through the device switch probing for things. + */ + for (int i = 0; devsw[i] != NULL; i++) { + if (devsw[i]->dv_init != NULL) { + if ((devsw[i]->dv_init)() != 0) { + err++; + } + } + } + return (err); +} + +void +dev_cleanup(void) +{ + int i; + + /* Call cleanup routines */ + for (i = 0; devsw[i] != NULL; ++i) + if (devsw[i]->dv_cleanup != NULL) + (devsw[i]->dv_cleanup)(); +} diff --git a/stand/libsa/dosfs.c b/stand/libsa/dosfs.c index 452a79ae12dc..38610d917007 100644 --- a/stand/libsa/dosfs.c +++ b/stand/libsa/dosfs.c @@ -1,6 +1,7 @@ /* * Copyright (c) 1996, 1998 Robert Nordier * All rights reserved. + * Copyright 2024 MNX Cloud, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,20 +26,17 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Readonly filesystem for Microsoft FAT12/FAT16/FAT32 filesystems, * also supports VFAT. */ #include <sys/types.h> +#include <sys/disk.h> #include <string.h> #include <stddef.h> #include "stand.h" -#include "disk.h" #include "dosfs.h" @@ -63,6 +61,7 @@ static int dos_unmount(const char *dev, void *data); struct fs_ops dosfs_fsops = { .fs_name = "dosfs", + .fs_flags = 0, .fo_open = dos_open, .fo_close = dos_close, .fo_read = dos_read, @@ -74,10 +73,6 @@ struct fs_ops dosfs_fsops = { .fo_unmount = dos_unmount }; -#define SECSIZ 512 /* sector size */ -#define SSHIFT 9 /* SECSIZ shift */ -#define DEPSEC 16 /* directory entries per sector */ -#define DSHIFT 4 /* DEPSEC shift */ #define LOCLUS 2 /* lowest cluster number */ #define FATBLKSZ 0x20000 /* size of block in the FAT cache buffer */ @@ -95,14 +90,43 @@ typedef struct { u_char heads[2]; /* drive heads */ u_char hidsec[4]; /* hidden sectors */ u_char lsecs[4]; /* huge sectors */ - u_char lspf[4]; /* huge sectors per FAT */ - u_char xflg[2]; /* flags */ - u_char vers[2]; /* filesystem version */ - u_char rdcl[4]; /* root directory start cluster */ - u_char infs[2]; /* filesystem info sector */ - u_char bkbs[2]; /* backup boot sector */ + union { + struct { + u_char drvnum; /* Int 13 drive number */ + u_char rsvd1; /* Reserved */ + u_char bootsig; /* Boot signature (0x29) */ + u_char volid[4]; /* Volume serial number */ + u_char vollab[11]; /* Volume label */ + u_char fstype[8]; /* Informational */ + } f12_f16; + struct { + u_char lspf[4]; /* huge sectors per FAT */ + u_char xflg[2]; /* flags */ + u_char vers[2]; /* filesystem version */ + u_char rdcl[4]; /* root directory cluster */ + u_char infs[2]; /* filesystem info sector */ + u_char bkbs[2]; /* backup boot sector */ + u_char reserved[12]; /* Reserved */ + u_char drvnum; /* Int 13 drive number */ + u_char rsvd1; /* Reserved */ + u_char bootsig; /* Boot signature (0x29) */ + u_char volid[4]; /* Volume serial number */ + u_char vollab[11]; /* Volume label */ + u_char fstype[8]; /* Informational */ + } f32; + } fstype; } DOS_BPB; +typedef struct { + u_char fsi_leadsig[4]; /* Value 0x41615252 */ + u_char fsi_reserved1[480]; + u_char fsi_structsig[4]; /* Value 0x61417272 */ + u_char fsi_free_count[4]; /* Last known free cluster count */ + u_char fsi_next_free[4]; /* First free cluster */ + u_char fsi_reserved2[12]; + u_char fsi_trailsig[4]; /* Value 0xAA550000 */ +} DOS_FSINFO; + /* Initial portion of DOS boot sector */ typedef struct { u_char jmp[3]; /* usually 80x86 'jmp' opcode */ @@ -120,16 +144,18 @@ static DOS_DE dot[2] = { }; /* The usual conversion macros to avoid multiplication and division */ -#define bytsec(n) ((n) >> SSHIFT) -#define secbyt(s) ((s) << SSHIFT) -#define entsec(e) ((e) >> DSHIFT) -#define bytblk(fs, n) ((n) >> (fs)->bshift) -#define blkbyt(fs, b) ((b) << (fs)->bshift) -#define secblk(fs, s) ((s) >> ((fs)->bshift - SSHIFT)) -#define blksec(fs, b) ((b) << ((fs)->bshift - SSHIFT)) +#define bytsec(fs, n) ((n) >> (fs)->sshift) +#define secbyt(fs, s) ((s) << (fs)->sshift) +#define depsec(fs) (1 << (fs)->dshift) +#define entsec(fs, e) ((e) >> (fs)->dshift) +#define bytblk(fs, n) ((n) >> (fs)->bshift) +#define blkbyt(fs, b) ((b) << (fs)->bshift) +#define secblk(fs, s) ((s) >> ((fs)->bshift - (fs)->sshift)) +#define blksec(fs, b) ((b) << ((fs)->bshift - (fs)->sshift)) /* Convert cluster number to offset within filesystem */ -#define blkoff(fs, b) (secbyt((fs)->lsndta) + blkbyt(fs, (b) - LOCLUS)) +#define blkoff(fs, b) (secbyt(fs, (fs)->lsndta) + \ + blkbyt(fs, (b) - LOCLUS)) /* Convert cluster number to logical sector number */ #define blklsn(fs, b) ((fs)->lsndta + blksec(fs, (b) - LOCLUS)) @@ -143,8 +169,8 @@ static DOS_DE dot[2] = { #define okclus(fs, c) ((c) >= LOCLUS && (c) <= (fs)->xclus) /* Get start cluster from directory entry */ -#define stclus(sz, de) ((sz) != 32 ? cv2((de)->clus) : \ - ((u_int)cv2((de)->dex.h_clus) << 16) | \ +#define stclus(sz, de) ((sz) != 32 ? (u_int)cv2((de)->clus) : \ + ((u_int)cv2((de)->dex.h_clus) << 16) | \ cv2((de)->clus)) static int parsebs(DOS_FS *, DOS_BS *); @@ -156,18 +182,18 @@ static off_t fsize(DOS_FS *, DOS_DE *); static int fatcnt(DOS_FS *, u_int); static int fatget(DOS_FS *, u_int *); static int fatend(u_int, u_int); -static int ioread(DOS_FS *, u_int, void *, size_t); -static int ioget(struct open_file *, daddr_t, void *, size_t); +static int ioread(DOS_FS *, uint64_t, void *, size_t); +static int ioget(DOS_FS *, daddr_t, void *, size_t); static int -dos_read_fatblk(DOS_FS *fs, struct open_file *fd, u_int blknum) +dos_read_fatblk(DOS_FS *fs, u_int blknum) { int err; size_t io_size; daddr_t offset_in_fat, max_offset_in_fat; offset_in_fat = ((daddr_t)blknum) * FATBLKSZ; - max_offset_in_fat = secbyt(fs->spf); + max_offset_in_fat = secbyt(fs, (daddr_t)fs->spf); io_size = FATBLKSZ; if (offset_in_fat > max_offset_in_fat) offset_in_fat = max_offset_in_fat; @@ -175,7 +201,7 @@ dos_read_fatblk(DOS_FS *fs, struct open_file *fd, u_int blknum) io_size = ((size_t)(max_offset_in_fat - offset_in_fat)); if (io_size != 0) { - err = ioget(fd, fs->lsnfat + bytsec(offset_in_fat), + err = ioget(fs, fs->lsnfat + bytsec(fs, offset_in_fat), fs->fatbuf, io_size); if (err != 0) { fs->fatbuf_blknum = ((u_int)(-1)); @@ -196,23 +222,34 @@ static int dos_mount_impl(DOS_FS *fs, struct open_file *fd) { int err; + unsigned secsz; u_char *buf; fs->fd = fd; - if ((buf = malloc(secbyt(1))) == NULL) + err = ioctl(fd->f_id, DIOCGSECTORSIZE, &secsz); + if (err != 0) { + return (err); + } + + buf = malloc(secsz); + if (buf == NULL) return (errno); - if ((err = ioget(fs->fd, 0, buf, secbyt(1))) || + + if ((err = ioget(fs, 0, buf, secsz)) || (err = parsebs(fs, (DOS_BS *)buf))) { free(buf); return (err); } - free(buf); + fs->secbuf = buf; - if ((fs->fatbuf = malloc(FATBLKSZ)) == NULL) + if ((fs->fatbuf = malloc(FATBLKSZ)) == NULL) { + free(buf); return (errno); - err = dos_read_fatblk(fs, fd, 0); + } + err = dos_read_fatblk(fs, 0); if (err != 0) { + free(buf); free(fs->fatbuf); return (err); } @@ -295,6 +332,7 @@ dos_unmount_impl(DOS_FS *fs) { if (fs->links) return (EBUSY); + free(fs->secbuf); free(fs->fatbuf); free(fs); return (0); @@ -308,13 +346,13 @@ dos_open(const char *path, struct open_file *fd) { DOS_DE *de; DOS_FILE *f; - DOS_FS *fs; + DOS_FS *fs = NULL; dos_mnt_t *mnt; const char *dev; u_int size, clus; int err; - dev = disk_fmtdev(fd->f_devdata); + dev = devformat((struct devdesc *)fd->f_devdata); STAILQ_FOREACH(mnt, &mnt_list, dos_link) { if (strcmp(dev, mnt->dos_dev) == 0) break; @@ -322,7 +360,7 @@ dos_open(const char *path, struct open_file *fd) if (mnt == NULL) { /* Allocate mount structure, associate with open */ - if ((fs = malloc(sizeof(DOS_FS))) == NULL) + if ((fs = calloc(1, sizeof(DOS_FS))) == NULL) return (errno); if ((err = dos_mount_impl(fs, fd))) { free(fs); @@ -368,7 +406,9 @@ static int dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid) { off_t size; - u_int nb, off, clus, c, cnt, n; + uint64_t off; + size_t nb; + u_int clus, c, cnt, n; DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; int err = 0; @@ -379,7 +419,7 @@ dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid) * 4-5 sec. */ twiddle(4); - nb = (u_int)nbyte; + nb = nbyte; if ((size = fsize(f->fs, &f->de)) == -1) return (EINVAL); if (nb > (n = size - f->offset)) @@ -406,8 +446,12 @@ dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid) } if (!clus || (n = f->fs->bsize - off) > cnt) n = cnt; - if ((err = ioread(f->fs, (c ? blkoff(f->fs, c) : - secbyt(f->fs->lsndir)) + off, buf, n))) + if (c != 0) + off += blkoff(f->fs, (uint64_t)c); + else + off += secbyt(f->fs, f->fs->lsndir); + err = ioread(f->fs, off, buf, n); + if (err != 0) goto out; f->offset += n; f->c = c; @@ -585,36 +629,54 @@ dos_readdir(struct open_file *fd, struct dirent *d) static int parsebs(DOS_FS *fs, DOS_BS *bs) { - u_int sc; + u_int sc, RootDirSectors; - if ((bs->jmp[0] != 0x69 && - bs->jmp[0] != 0xe9 && - (bs->jmp[0] != 0xeb || bs->jmp[2] != 0x90)) || - bs->bpb.media < 0xf0) + if (bs->bpb.media < 0xf0) return (EINVAL); - if (cv2(bs->bpb.secsiz) != SECSIZ) + + /* Check supported sector sizes */ + switch (cv2(bs->bpb.secsiz)) { + case 512: + case 1024: + case 2048: + case 4096: + fs->sshift = ffs(cv2(bs->bpb.secsiz)) - 1; + break; + + default: return (EINVAL); + } + if (!(fs->spc = bs->bpb.spc) || fs->spc & (fs->spc - 1)) return (EINVAL); - fs->bsize = secbyt(fs->spc); + fs->bsize = secbyt(fs, fs->spc); fs->bshift = ffs(fs->bsize) - 1; - if ((fs->spf = cv2(bs->bpb.spf))) { + fs->dshift = ffs(secbyt(fs, 1) / sizeof (DOS_DE)) - 1; + fs->dirents = cv2(bs->bpb.dirents); + fs->spf = cv2(bs->bpb.spf); + fs->lsnfat = cv2(bs->bpb.ressec); + + if (fs->spf != 0) { if (bs->bpb.fats != 2) return (EINVAL); - if (!(fs->dirents = cv2(bs->bpb.dirents))) + if (fs->dirents == 0) return (EINVAL); } else { - if (!(fs->spf = cv4(bs->bpb.lspf))) + fs->spf = cv4(bs->bpb.fstype.f32.lspf); + if (fs->spf == 0) return (EINVAL); - if (!bs->bpb.fats || bs->bpb.fats > 16) + if (bs->bpb.fats == 0 || bs->bpb.fats > 16) return (EINVAL); - if ((fs->rdcl = cv4(bs->bpb.rdcl)) < LOCLUS) + fs->rdcl = cv4(bs->bpb.fstype.f32.rdcl); + if (fs->rdcl < LOCLUS) return (EINVAL); } - if (!(fs->lsnfat = cv2(bs->bpb.ressec))) - return (EINVAL); + + RootDirSectors = ((fs->dirents * sizeof (DOS_DE)) + + (secbyt(fs, 1) - 1)) / secbyt(fs, 1); + fs->lsndir = fs->lsnfat + fs->spf * bs->bpb.fats; - fs->lsndta = fs->lsndir + entsec(fs->dirents); + fs->lsndta = fs->lsndir + RootDirSectors; if (!(sc = cv2(bs->bpb.secs)) && !(sc = cv4(bs->bpb.lsecs))) return (EINVAL); if (fs->lsndta > sc) @@ -622,7 +684,7 @@ parsebs(DOS_FS *fs, DOS_BS *bs) if ((fs->xclus = secblk(fs, sc - fs->lsndta) + 1) < LOCLUS) return (EINVAL); fs->fatsz = fs->dirents ? fs->xclus < 0xff6 ? 12 : 16 : 32; - sc = (secbyt(fs->spf) << 1) / (fs->fatsz >> 2) - 1; + sc = (secbyt(fs, fs->spf) << 1) / (fs->fatsz >> 2) - 1; if (fs->xclus > sc) fs->xclus = sc; return (0); @@ -669,7 +731,7 @@ namede(DOS_FS *fs, const char *path, DOS_DE **dep) static int lookup(DOS_FS *fs, u_int clus, const char *name, DOS_DE **dep) { - static DOS_DIR dir[DEPSEC]; + DOS_DIR *dir; u_char lfn[261]; u_char sfn[13]; u_int nsec, lsec, xdn, chk, sec, ent, x; @@ -683,9 +745,10 @@ lookup(DOS_FS *fs, u_int clus, const char *name, DOS_DE **dep) } if (!clus && fs->fatsz == 32) clus = fs->rdcl; - nsec = !clus ? entsec(fs->dirents) : fs->spc; + nsec = !clus ? entsec(fs, fs->dirents) : fs->spc; lsec = 0; xdn = chk = 0; + dir = (DOS_DIR *)fs->secbuf; for (;;) { if (!clus && !lsec) lsec = fs->lsndir; @@ -694,9 +757,10 @@ lookup(DOS_FS *fs, u_int clus, const char *name, DOS_DE **dep) else return (EINVAL); for (sec = 0; sec < nsec; sec++) { - if ((err = ioget(fs->fd, lsec + sec, dir, secbyt(1)))) + if ((err = ioget(fs, lsec + sec, dir, + secbyt(fs, 1)))) return (err); - for (ent = 0; ent < DEPSEC; ent++) { + for (ent = 0; ent < depsec(fs); ent++) { if (!*dir[ent].de.name) return (ENOENT); if (*dir[ent].de.name != 0xe5) { @@ -819,7 +883,7 @@ fsize(DOS_FS *fs, DOS_DE *de) int n; if (!(size = cv4(de->size)) && de->attr & FA_DIR) { - if (!(c = cv2(de->clus))) { + if (!(c = stclus(fs->fatsz, de))) { size = fs->dirents * sizeof(DOS_DE); } else { if ((n = fatcnt(fs, c)) == -1) @@ -863,14 +927,14 @@ fatget(DOS_FS *fs, u_int *c) /* ensure that current 128K FAT block is cached */ offset = fatoff(fs->fatsz, val_in); nbyte = fs->fatsz != 32 ? 2 : 4; - if (offset + nbyte > secbyt(fs->spf)) + if (offset + nbyte > secbyt(fs, fs->spf)) return (EINVAL); blknum = offset / FATBLKSZ; offset %= FATBLKSZ; if (offset + nbyte > FATBLKSZ) return (EINVAL); if (blknum != fs->fatbuf_blknum) { - err = dos_read_fatblk(fs, fs->fd, blknum); + err = dos_read_fatblk(fs, blknum); if (err != 0) return (err); } @@ -912,55 +976,58 @@ fatend(u_int sz, u_int c) * Offset-based I/O primitive */ static int -ioread(DOS_FS *fs, u_int offset, void *buf, size_t nbyte) +ioread(DOS_FS *fs, uint64_t offset, void *buf, size_t nbyte) { char *s; - u_int off, n; + size_t n, secsiz; int err; - u_char local_buf[SECSIZ]; + uint64_t off; + secsiz = secbyt(fs, 1); s = buf; - if ((off = offset & (SECSIZ - 1))) { + if ((off = offset & (secsiz - 1))) { offset -= off; - if ((n = SECSIZ - off) > nbyte) + if ((n = secsiz - off) > nbyte) n = nbyte; - err = ioget(fs->fd, bytsec(offset), local_buf, - sizeof(local_buf)); + err = ioget(fs, bytsec(fs, offset), fs->secbuf, secsiz); if (err != 0) return (err); - memcpy(s, local_buf + off, n); - offset += SECSIZ; + memcpy(s, fs->secbuf + off, n); + offset += secsiz; s += n; nbyte -= n; } - n = nbyte & (SECSIZ - 1); + n = nbyte & (secsiz - 1); if (nbyte -= n) { - if ((err = ioget(fs->fd, bytsec(offset), s, nbyte))) + if ((err = ioget(fs, bytsec(fs, offset), s, nbyte))) return (err); offset += nbyte; s += nbyte; } if (n != 0) { - err = ioget(fs->fd, bytsec(offset), local_buf, - sizeof(local_buf)); + err = ioget(fs, bytsec(fs, offset), fs->secbuf, secsiz); if (err != 0) return (err); - memcpy(s, local_buf, n); + memcpy(s, fs->secbuf, n); } return (0); } /* - * Sector-based I/O primitive + * Sector-based I/O primitive. Note, since strategy functions are operating + * in terms of 512B sectors, we need to do necessary conversion here. */ static int -ioget(struct open_file *fd, daddr_t lsec, void *buf, size_t size) +ioget(DOS_FS *fs, daddr_t lsec, void *buf, size_t size) { size_t rsize; int rv; + struct open_file *fd = fs->fd; /* Make sure we get full read or error. */ rsize = 0; + /* convert native sector number to 512B sector number. */ + lsec = secbyt(fs, lsec) >> 9; rv = (fd->f_dev->dv_strategy)(fd->f_devdata, F_READ, lsec, size, buf, &rsize); if ((rv == 0) && (size != rsize)) diff --git a/stand/libsa/dosfs.h b/stand/libsa/dosfs.h index 30bb43534492..9d844001a057 100644 --- a/stand/libsa/dosfs.h +++ b/stand/libsa/dosfs.h @@ -23,8 +23,6 @@ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef DOSIO_H @@ -96,12 +94,15 @@ typedef union { typedef struct { struct open_file *fd; /* file descriptor */ + u_char *secbuf; /* sector cache */ u_char *fatbuf; /* FAT cache buffer */ u_int fatbuf_blknum; /* number of 128K block in FAT cache buffer */ u_int links; /* active links to structure */ + u_int sshift; /* sector shift */ u_int spc; /* sectors per cluster */ u_int bsize; /* cluster size in bytes */ u_int bshift; /* cluster conversion shift */ + u_int dshift; /* directory entries shift */ u_int dirents; /* root directory entries */ u_int spf; /* sectors per fat */ u_int rdcl; /* root directory start cluster */ diff --git a/stand/libsa/environment.c b/stand/libsa/environment.c index 53b6a75cc020..d139249a8e84 100644 --- a/stand/libsa/environment.c +++ b/stand/libsa/environment.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Manage an environment-like space in which string variables may be stored. * Provide support for some method-like operations for setting/retrieving @@ -69,6 +66,17 @@ env_setenv(const char *name, int flags, const void *value, if ((ev = env_getenv(name)) != NULL) { /* + * If the new value doesn't have NOKENV set, we'll drop the flag + * if it's set on the entry so that the override propagates + * correctly. We do this *before* sending it to the hook in + * case the hook declines to operate on it (e.g., because the + * value matches what was already set) -- we would still want + * the explicitly set value to propagate. + */ + if (!(flags & EV_NOKENV)) + ev->ev_flags &= ~EV_NOKENV; + + /* * If there's a set hook, let it do the work * (unless we are working for one already). */ @@ -80,7 +88,6 @@ env_setenv(const char *name, int flags, const void *value, free(ev->ev_value); ev->ev_value = NULL; ev->ev_flags &= ~EV_DYNAMIC; - } else { /* @@ -126,12 +133,13 @@ env_setenv(const char *name, int flags, const void *value, /* If we have a new value, use it */ if (flags & EV_VOLATILE) { ev->ev_value = strdup(value); - ev->ev_flags |= EV_DYNAMIC; + flags |= EV_DYNAMIC; } else { ev->ev_value = (char *)value; - ev->ev_flags |= flags & EV_DYNAMIC; } + ev->ev_flags |= flags & (EV_DYNAMIC | EV_NOKENV); + return (0); } diff --git a/stand/libsa/ether.c b/stand/libsa/ether.c index 3616777e7955..08ef131e9e0e 100644 --- a/stand/libsa/ether.c +++ b/stand/libsa/ether.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/socket.h> #include <string.h> diff --git a/stand/libsa/ext2fs.c b/stand/libsa/ext2fs.c index b81654552af3..f7096282f156 100644 --- a/stand/libsa/ext2fs.c +++ b/stand/libsa/ext2fs.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -108,14 +105,15 @@ static int dtmap[] = { DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_UNKNOWN : dtmap[x] struct fs_ops ext2fs_fsops = { - "ext2fs", - ext2fs_open, - ext2fs_close, - ext2fs_read, - null_write, - ext2fs_seek, - ext2fs_stat, - ext2fs_readdir + .fs_name = "ext2fs", + .fs_flags = 0, + .fo_open = ext2fs_open, + .fo_close = ext2fs_close, + .fo_read = ext2fs_read, + .fo_write = null_write, + .fo_seek = ext2fs_seek, + .fo_stat = ext2fs_stat, + .fo_readdir = ext2fs_readdir, }; #define EXT2_SBSIZE 1024 @@ -796,10 +794,11 @@ ext2fs_close(struct open_file *f) struct file *fp = (struct file *)f->f_fsdata; int level; - f->f_fsdata = (void *)0; - if (fp == (struct file *)0) + if (fp == NULL) return (0); + f->f_fsdata = NULL; + for (level = 0; level < EXT2_NIADDR; level++) { if (fp->f_blk[level]) free(fp->f_blk[level]); @@ -891,16 +890,17 @@ ext2fs_readdir(struct open_file *f, struct dirent *d) /* * assume that a directory entry will not be split across blocks */ -again: - if (fp->f_seekp >= fp->f_di.di_size) - return (ENOENT); - error = buf_read_file(f, &buf, &buf_size); - if (error) - return (error); - ed = (struct ext2dirent *)buf; - fp->f_seekp += ed->d_reclen; - if (ed->d_ino == (ino_t)0) - goto again; + + do { + if (fp->f_seekp >= fp->f_di.di_size) + return (ENOENT); + error = buf_read_file(f, &buf, &buf_size); + if (error) + return (error); + ed = (struct ext2dirent *)buf; + fp->f_seekp += ed->d_reclen; + } while (ed->d_ino == (ino_t)0); + d->d_type = EXTFTODT(ed->d_type); strncpy(d->d_name, ed->d_name, ed->d_namlen); d->d_name[ed->d_namlen] = '\0'; diff --git a/stand/libsa/features.c b/stand/libsa/features.c new file mode 100644 index 000000000000..23dce2b13b60 --- /dev/null +++ b/stand/libsa/features.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2023 Kyle Evans <kevans@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + * + */ + +#include <sys/param.h> + +#include "stand.h" + +static uint32_t loader_features; + +#define FEATURE_ENTRY(name, desc) { FEATURE_##name, #name, desc } +static const struct feature_entry { + uint32_t value; + const char *name; + const char *desc; +} feature_map[] = { + FEATURE_ENTRY(EARLY_ACPI, "Loader probes ACPI in early startup"), +}; + +void +feature_enable(uint32_t mask) +{ + + loader_features |= mask; +} + +bool +feature_name_is_enabled(const char *name) +{ + const struct feature_entry *entry; + + for (size_t i = 0; i < nitems(feature_map); i++) { + entry = &feature_map[i]; + + if (strcmp(entry->name, name) == 0) + return ((loader_features & entry->value) != 0); + } + + return (false); +} + +void +feature_iter(feature_iter_fn *iter_fn, void *cookie) +{ + const struct feature_entry *entry; + + for (size_t i = 0; i < nitems(feature_map); i++) { + entry = &feature_map[i]; + + (*iter_fn)(cookie, entry->name, entry->desc, + (loader_features & entry->value) != 0); + } +} diff --git a/stand/libsa/fstat.c b/stand/libsa/fstat.c index 47893416e0bf..5b6664622100 100644 --- a/stand/libsa/fstat.c +++ b/stand/libsa/fstat.c @@ -27,13 +27,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)stat.c 8.1 (Berkeley) 6/11/93 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" int diff --git a/stand/libsa/geli/Makefile.inc b/stand/libsa/geli/Makefile.inc index 734bcf6be5e6..8300359a465a 100644 --- a/stand/libsa/geli/Makefile.inc +++ b/stand/libsa/geli/Makefile.inc @@ -1,21 +1,9 @@ -# $FreeBSD$ # Extra stuff for GELI .PATH: ${SASRC}/geli -CFLAGS+= -I${LDRSRC} - # Our password input method -SRCS+= pwgets.c - -# sha256 and sha512 from sys/crypto -.PATH: ${SYSDIR}/crypto/sha2 -CFLAGS+= -DWEAK_REFS -SRCS+= sha256c.c sha512c.c - -# md5 from libmd -.PATH: ${SRCTOP}/lib/libmd -SRCS+= md5c.c +SRCS+= pwgets.c # AES implementation from sys/crypto .PATH: ${SYSDIR}/crypto/rijndael @@ -27,15 +15,14 @@ SRCS+= ${i} # local GELI Implementation .PATH: ${SYSDIR}/geom/eli -SRCS+= \ - geliboot.c \ +.for i in gelidev.c geli_metadata.c +CFLAGS.${i}+= -I${LDRSRC} +SRCS+= ${i} +.endfor +SRCS+= geliboot.c \ geliboot_crypto.c \ - gelidev.c \ - geli_metadata.c \ - g_eli_hmac.c \ g_eli_key.c \ g_eli_key_cache.c \ - pkcs5v2.c \ # aes .PATH: ${SYSDIR}/opencrypto diff --git a/stand/libsa/geli/geli_metadata.c b/stand/libsa/geli/geli_metadata.c index ba46058f688f..22439ff938be 100644 --- a/stand/libsa/geli/geli_metadata.c +++ b/stand/libsa/geli/geli_metadata.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Ian Lepore <ian@FreeBSD.org> * @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stand.h> diff --git a/stand/libsa/geli/geliboot.c b/stand/libsa/geli/geliboot.c index f7069e3887ee..04c53e73b29a 100644 --- a/stand/libsa/geli/geliboot.c +++ b/stand/libsa/geli/geliboot.c @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stand.h> diff --git a/stand/libsa/geli/geliboot.h b/stand/libsa/geli/geliboot.h index 0c2ef817e97d..82258fb440b2 100644 --- a/stand/libsa/geli/geliboot.h +++ b/stand/libsa/geli/geliboot.h @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <crypto/intake.h> diff --git a/stand/libsa/geli/geliboot_crypto.c b/stand/libsa/geli/geliboot_crypto.c index 90c9be30cf03..6cb47d5572c3 100644 --- a/stand/libsa/geli/geliboot_crypto.c +++ b/stand/libsa/geli/geliboot_crypto.c @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stdio.h> diff --git a/stand/libsa/geli/geliboot_internal.h b/stand/libsa/geli/geliboot_internal.h index 2af74466179f..50157f24c7f5 100644 --- a/stand/libsa/geli/geliboot_internal.h +++ b/stand/libsa/geli/geliboot_internal.h @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _GELIBOOT_INTERNAL_H_ @@ -40,8 +38,6 @@ #include <geom/eli/g_eli.h> #include <geom/eli/pkcs5v2.h> -#include <bootstrap.h> - /* Pull in the md5, sha256, and sha512 implementations */ #include <sys/md5.h> #include <crypto/sha2/sha256.h> diff --git a/stand/libsa/geli/gelidev.c b/stand/libsa/geli/gelidev.c index d312d7b17e0e..091916ca9d0f 100644 --- a/stand/libsa/geli/gelidev.c +++ b/stand/libsa/geli/gelidev.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Ian Lepore <ian@FreeBSD.org> * @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <stand.h> @@ -62,6 +60,8 @@ static struct devsw geli_devsw = { .dv_ioctl = geli_dev_ioctl, .dv_print = geli_dev_print, .dv_cleanup = geli_dev_cleanup, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; /* @@ -300,12 +300,16 @@ geli_probe_and_attach(struct open_file *f) hdesc = (struct disk_devdesc *)(f->f_devdata); + /* We only work on DEVT_DISKs */ + if (hdesc->dd.d_dev->dv_type != DEVT_DISK) + return; /* Get the last block number for the host provider. */ - hdesc->dd.d_dev->dv_ioctl(f, DIOCGMEDIASIZE, &hmediasize); + if (hdesc->dd.d_dev->dv_ioctl(f, DIOCGMEDIASIZE, &hmediasize) != 0) + return; hlastblk = (hmediasize / DEV_BSIZE) - 1; /* Taste the host provider. If it's not geli-encrypted just return. */ - gdev = geli_taste(diskdev_read, hdesc, hlastblk, disk_fmtdev(hdesc)); + gdev = geli_taste(diskdev_read, hdesc, hlastblk, devformat(&hdesc->dd)); if (gdev == NULL) return; diff --git a/stand/libsa/geli/pwgets.c b/stand/libsa/geli/pwgets.c index 450255f1ee36..5259334a3a7a 100644 --- a/stand/libsa/geli/pwgets.c +++ b/stand/libsa/geli/pwgets.c @@ -27,13 +27,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)gets.c 8.1 (Berkeley) 6/11/93 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" /* gets() with constrained input length, for passwords */ diff --git a/stand/libsa/getopt.c b/stand/libsa/getopt.c index ead2ee56267c..4c36d262d87c 100644 --- a/stand/libsa/getopt.c +++ b/stand/libsa/getopt.c @@ -27,13 +27,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; -#endif /* LIBC_SCCS and not lint */ - #include "stand.h" #include <string.h> diff --git a/stand/libsa/gets.c b/stand/libsa/gets.c index 206a6d25fcea..922c2ab2a945 100644 --- a/stand/libsa/gets.c +++ b/stand/libsa/gets.c @@ -27,13 +27,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)gets.c 8.1 (Berkeley) 6/11/93 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" /* gets() with constrained input length */ diff --git a/stand/libsa/globals.c b/stand/libsa/globals.c index 8fb56cf23e6b..6bd3a4243d73 100644 --- a/stand/libsa/globals.c +++ b/stand/libsa/globals.c @@ -7,9 +7,6 @@ * must be included extraneously. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -20,6 +17,7 @@ __FBSDID("$FreeBSD$"); u_char bcea[6] = BA; /* broadcast ethernet address */ char rootpath[FNAME_SIZE] = "/"; /* root mount path */ +int rootport; /* port for rootpath server */ char bootfile[FNAME_SIZE]; /* bootp says to boot this */ char hostname[FNAME_SIZE]; /* our hostname */ int hostnamelen; diff --git a/stand/libsa/gpt.c b/stand/libsa/gpt.c index 46e67a9c9a2d..0ba3f0ee1985 100644 --- a/stand/libsa/gpt.c +++ b/stand/libsa/gpt.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/gpt.h> @@ -79,7 +76,7 @@ gptupdate(const char *which, struct dsk *dskp, struct gpt_hdr *hdr, hdr->hdr_crc_table = crc32(0, Z_NULL, 0); hdr->hdr_crc_table = crc32(hdr->hdr_crc_table, (const Bytef *)table, hdr->hdr_entries * hdr->hdr_entsz); - hdr->hdr_crc_self = crc32(0, Z_NULL, 0);; + hdr->hdr_crc_self = crc32(0, Z_NULL, 0); hdr->hdr_crc_self = crc32(hdr->hdr_crc_self, (const Bytef *)hdr, hdr->hdr_size); bzero(secbuf, DEV_BSIZE); diff --git a/stand/libsa/gpt.h b/stand/libsa/gpt.h index 6710aa45ca71..7b8d0adb0321 100644 --- a/stand/libsa/gpt.h +++ b/stand/libsa/gpt.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _GPT_H_ diff --git a/stand/libsa/gzipfs.c b/stand/libsa/gzipfs.c index 8154b0f95a9a..6b22f750f3ef 100644 --- a/stand/libsa/gzipfs.c +++ b/stand/libsa/gzipfs.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" #include <sys/stat.h> @@ -52,14 +49,15 @@ static off_t zf_seek(struct open_file *f, off_t offset, int where); static int zf_stat(struct open_file *f, struct stat *sb); struct fs_ops gzipfs_fsops = { - "zip", - zf_open, - zf_close, - zf_read, - null_write, - zf_seek, - zf_stat, - null_readdir + .fs_name = "zip", + .fs_flags = 0, + .fo_open = zf_open, + .fo_close = zf_close, + .fo_read = zf_read, + .fo_write = null_write, + .fo_seek = zf_seek, + .fo_stat = zf_stat, + .fo_readdir = null_readdir, }; static int diff --git a/stand/libsa/hexdump.c b/stand/libsa/hexdump.c index 50cce47b8f30..cce6e323c2cb 100644 --- a/stand/libsa/hexdump.c +++ b/stand/libsa/hexdump.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <string.h> #include <stand.h> @@ -64,7 +61,7 @@ hexdump(caddr_t region, size_t len) for (x = 0; x < 16; x++) { if ((line + x) < (region + len)) { c = *(uint8_t *)(line + x); - if ((c < ' ') || (c > '~')) /* !isprint(c) */ + if (!isprint(c)) c = '.'; emit("%c", c); } else { diff --git a/stand/libsa/i386/_setjmp.S b/stand/libsa/i386/_setjmp.S index 95b0ea8037f5..a1bd8d55834b 100644 --- a/stand/libsa/i386/_setjmp.S +++ b/stand/libsa/i386/_setjmp.S @@ -32,7 +32,6 @@ #if defined(LIBC_RCS) && !defined(lint) .text - .asciz "$FreeBSD$" #endif /* LIBC_RCS and not lint */ /* @@ -75,3 +74,5 @@ ENTRY(_longjmp) 1: movl %ecx,0(%esp) ret END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/libsa/in_cksum.c b/stand/libsa/in_cksum.c index 2f8c448fc0eb..15b2adb6080c 100644 --- a/stand/libsa/in_cksum.c +++ b/stand/libsa/in_cksum.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: in_cksum.c,v 1.1 92/09/11 01:15:55 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <machine/endian.h> @@ -61,7 +56,7 @@ in_cksum(void *p, int len) sum += v + *cp++; len--; } - if (((long)cp & 1) == 0) { + if (((uintptr_t)cp & 1) == 0) { while ((len -= 2) >= 0) { sum += *(u_short *)cp; cp += 2; diff --git a/stand/libsa/inet_ntoa.c b/stand/libsa/inet_ntoa.c index 45c79f26151d..9edc91930942 100644 --- a/stand/libsa/inet_ntoa.c +++ b/stand/libsa/inet_ntoa.c @@ -27,13 +27,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> diff --git a/stand/libsa/ioctl.c b/stand/libsa/ioctl.c index 7363236ada0e..cc592a454812 100644 --- a/stand/libsa/ioctl.c +++ b/stand/libsa/ioctl.c @@ -31,8 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)ioctl.c 8.1 (Berkeley) 6/11/93 - * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. @@ -60,13 +58,10 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" int -ioctl(int fd, u_long cmd, char *arg) +ioctl(int fd, u_long cmd, void *arg) { struct open_file *f; @@ -75,12 +70,12 @@ ioctl(int fd, u_long cmd, char *arg) errno = EBADF; return (-1); } - if (f->f_flags & F_RAW) { + if (f->f_dev == NULL) + errno = EIO; + else errno = (f->f_dev->dv_ioctl)(f, cmd, arg); - if (errno) - return (-1); - return (0); - } - errno = EIO; - return (-1); + + if (errno != 0) + return (-1); + return (0); } diff --git a/stand/libsa/iodesc.h b/stand/libsa/iodesc.h index 199fbcf74e98..4d15a87d1fc0 100644 --- a/stand/libsa/iodesc.h +++ b/stand/libsa/iodesc.h @@ -32,8 +32,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef __SYS_LIBNETBOOT_IODESC_H diff --git a/stand/libsa/ip.c b/stand/libsa/ip.c index f9e373bb1157..e9e4f519681d 100644 --- a/stand/libsa/ip.c +++ b/stand/libsa/ip.c @@ -37,14 +37,12 @@ * once we will implement the support for tcp. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/socket.h> #include <sys/queue.h> #include <string.h> +#include <stdbool.h> #include <net/if.h> #include <netinet/in.h> @@ -92,17 +90,10 @@ sendip(struct iodesc *d, void *pkt, size_t len, uint8_t proto) struct ip *ip; u_char *ea; -#ifdef NET_DEBUG - if (debug) { - printf("sendip: proto: %x d=%p called.\n", proto, (void *)d); - if (d) { - printf("saddr: %s:%d", - inet_ntoa(d->myip), ntohs(d->myport)); - printf(" daddr: %s:%d\n", - inet_ntoa(d->destip), ntohs(d->destport)); - } - } -#endif + DEBUG_PRINTF(1, ("sendip: proto: %x d=%p called.\n", proto, (void *)d)); + DEBUG_PRINTF(1, ("saddr: %s:%d daddr: %s:%d\n", + inet_ntoa(d->myip), ntohs(d->myport), + inet_ntoa(d->destip), ntohs(d->destport))); ip = (struct ip *)pkt - 1; len += sizeof(*ip); @@ -146,137 +137,123 @@ ip_reasm_free(struct ip_reasm *ipr) free(ipr); } -static int +static bool ip_reasm_add(struct ip_reasm *ipr, void *pkt, struct ip *ip) { - struct ip_queue *ipq, *prev, *p; + struct ip_queue *ipq, *p; + uint16_t off_q, off_ip; - if ((ipq = calloc(1, sizeof (*ipq))) == NULL) - return (1); + if ((ipq = calloc(1, sizeof(*ipq))) == NULL) + return (false); ipq->ipq_pkt = pkt; ipq->ipq_hdr = ip; - prev = NULL; STAILQ_FOREACH(p, &ipr->ip_queue, ipq_next) { - if ((ntohs(p->ipq_hdr->ip_off) & IP_OFFMASK) < - (ntohs(ip->ip_off) & IP_OFFMASK)) { - prev = p; - continue; + off_q = ntohs(p->ipq_hdr->ip_off) & IP_OFFMASK; + off_ip = ntohs(ip->ip_off) & IP_OFFMASK; + + if (off_q == off_ip) { /* duplicate */ + free(pkt); + free(ipq); + return (true); } - if (prev == NULL) + + if (off_ip < off_q) { + /* + * Everything in queue has larger offset, + * drop out of loop and insert to HEAD. + */ break; + } + + /* + * p in queue is smaller than ip, check if we need to put + * ip after p or after p->next. + */ + struct ip_queue *next = STAILQ_NEXT(p, ipq_next); + if (next == NULL) { + /* insert after p */ + STAILQ_INSERT_AFTER(&ipr->ip_queue, p, ipq, ipq_next); + return (true); + } - STAILQ_INSERT_AFTER(&ipr->ip_queue, prev, ipq, ipq_next); - return (0); + off_q = ntohs(next->ipq_hdr->ip_off) & IP_OFFMASK; + if (off_ip < off_q) { + /* next fragment offset is larger, insert after p. */ + STAILQ_INSERT_AFTER(&ipr->ip_queue, p, ipq, ipq_next); + return (true); + } + /* next fragment offset is smaller, loop */ } STAILQ_INSERT_HEAD(&ipr->ip_queue, ipq, ipq_next); - return (0); + return (true); } /* * Receive a IP packet and validate it is for us. */ static ssize_t -readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, - uint8_t proto) +readipv4(struct iodesc *d, void **pkt, void **payload, ssize_t n) { - ssize_t n; + struct ip *ip = *payload; size_t hlen; struct ether_header *eh; - struct ip *ip; struct udphdr *uh; - uint16_t etype; /* host order */ - char *ptr; + char *ptr = *pkt; struct ip_reasm *ipr; struct ip_queue *ipq, *last; + bool morefrag, isfrag; + uint16_t fragoffset; -#ifdef NET_DEBUG - if (debug) - printf("readip: called\n"); -#endif - - ip = NULL; - ptr = NULL; - n = readether(d, (void **)&ptr, (void **)&ip, tleft, &etype); - if (n == -1 || n < sizeof(*ip) + sizeof(*uh)) { - free(ptr); - return (-1); - } - - /* Ethernet address checks now in readether() */ - - /* Need to respond to ARP requests. */ - if (etype == ETHERTYPE_ARP) { - struct arphdr *ah = (void *)ip; - if (ah->ar_op == htons(ARPOP_REQUEST)) { - /* Send ARP reply */ - arp_reply(d, ah); - } + if (n < sizeof(*ip)) { free(ptr); errno = EAGAIN; /* Call me again. */ return (-1); } - if (etype != ETHERTYPE_IP) { -#ifdef NET_DEBUG - if (debug) - printf("readip: not IP. ether_type=%x\n", etype); -#endif - free(ptr); - return (-1); - } - - /* Check ip header */ - if (ip->ip_v != IPVERSION || /* half char */ - ip->ip_p != proto) { -#ifdef NET_DEBUG - if (debug) { - printf("readip: IP version or proto. ip_v=%d ip_p=%d\n", - ip->ip_v, ip->ip_p); - } -#endif - free(ptr); - return (-1); - } - hlen = ip->ip_hl << 2; if (hlen < sizeof(*ip) || in_cksum(ip, hlen) != 0) { -#ifdef NET_DEBUG - if (debug) - printf("readip: short hdr or bad cksum.\n"); -#endif + DEBUG_PRINTF(1, ("%s: short hdr or bad cksum.\n", __func__)); free(ptr); + errno = EAGAIN; /* Call me again. */ return (-1); } + if (n < ntohs(ip->ip_len)) { -#ifdef NET_DEBUG - if (debug) - printf("readip: bad length %d < %d.\n", - (int)n, ntohs(ip->ip_len)); -#endif + DEBUG_PRINTF(1, ("readip: bad length %zd < %d.\n", + n, ntohs(ip->ip_len))); free(ptr); + errno = EAGAIN; /* Call me again. */ return (-1); } + + fragoffset = (ntohs(ip->ip_off) & IP_OFFMASK) * 8; + morefrag = (ntohs(ip->ip_off) & IP_MF) == 0 ? false : true; + isfrag = morefrag || fragoffset != 0; + + uh = (struct udphdr *)((uintptr_t)ip + sizeof(*ip)); + if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { -#ifdef NET_DEBUG - if (debug) { - printf("readip: bad saddr %s != ", inet_ntoa(d->myip)); - printf("%s\n", inet_ntoa(ip->ip_dst)); - } -#endif + DEBUG_PRINTF(1, ("%s: not for us: saddr %s (%d) != %s (%d)\n", + __func__, inet_ntoa(d->myip), ntohs(d->myport), + inet_ntoa(ip->ip_dst), ntohs(uh->uh_dport))); free(ptr); + errno = EAGAIN; /* Call me again. */ return (-1); } /* Unfragmented packet. */ - if ((ntohs(ip->ip_off) & IP_MF) == 0 && - (ntohs(ip->ip_off) & IP_OFFMASK) == 0) { - uh = (struct udphdr *)((uintptr_t)ip + sizeof (*ip)); + if (!isfrag) { + DEBUG_PRINTF(1, ("%s: unfragmented saddr %s:%d -> %s:%d\n", + __func__, + inet_ntoa(ip->ip_src), ntohs(uh->uh_sport), + inet_ntoa(ip->ip_dst), ntohs(uh->uh_dport))); /* If there were ip options, make them go away */ if (hlen != sizeof(*ip)) { - bcopy(((u_char *)ip) + hlen, uh, uh->uh_ulen - hlen); + bcopy(((u_char *)ip) + hlen, uh, + ntohs(uh->uh_ulen) - hlen); ip->ip_len = htons(sizeof(*ip)); n -= hlen - sizeof(*ip); } @@ -298,7 +275,7 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, /* Allocate new reassembly entry */ if (ipr == NULL) { - if ((ipr = calloc(1, sizeof (*ipr))) == NULL) { + if ((ipr = calloc(1, sizeof(*ipr))) == NULL) { free(ptr); return (-1); } @@ -310,37 +287,22 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, ipr->ip_ttl = MAXTTL; STAILQ_INIT(&ipr->ip_queue); STAILQ_INSERT_TAIL(&ire_list, ipr, ip_next); + DEBUG_PRINTF(1, ("%s: new reassembly ID=%d %s -> %s\n", + __func__, ntohs(ip->ip_id), inet_ntoa(ip->ip_src), + inet_ntoa(ip->ip_dst))); } - if (ip_reasm_add(ipr, ptr, ip) != 0) { + /* + * NOTE: with ip_reasm_add() ptr will be stored in reassembly + * queue and we can not free it without destroying the queue. + */ + if (!ip_reasm_add(ipr, ptr, ip)) { STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); free(ipr); free(ptr); return (-1); } - if ((ntohs(ip->ip_off) & IP_MF) == 0) { - ipr->ip_total_size = (8 * (ntohs(ip->ip_off) & IP_OFFMASK)); - ipr->ip_total_size += n + sizeof (*ip); - ipr->ip_total_size += sizeof (struct ether_header); - - ipr->ip_pkt = malloc(ipr->ip_total_size + 2); - if (ipr->ip_pkt == NULL) { - STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); - ip_reasm_free(ipr); - return (-1); - } - } - - /* - * If we do not have re-assembly buffer ipr->ip_pkt, we are still - * missing fragments, so just restart the read. - */ - if (ipr->ip_pkt == NULL) { - errno = EAGAIN; - return (-1); - } - /* * Walk the packet list in reassembly queue, if we got all the * fragments, build the packet. @@ -348,35 +310,59 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, n = 0; last = NULL; STAILQ_FOREACH(ipq, &ipr->ip_queue, ipq_next) { - if ((ntohs(ipq->ipq_hdr->ip_off) & IP_OFFMASK) != n / 8) { - STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); - ip_reasm_free(ipr); + fragoffset = (ntohs(ipq->ipq_hdr->ip_off) & IP_OFFMASK) * 8; + if (fragoffset != n) { + DEBUG_PRINTF(1, ("%s: need more fragments %d %s -> ", + __func__, ntohs(ipq->ipq_hdr->ip_id), + inet_ntoa(ipq->ipq_hdr->ip_src))); + DEBUG_PRINTF(1, ("%s offset=%d MF=%d\n", + inet_ntoa(ipq->ipq_hdr->ip_dst), + fragoffset, + (ntohs(ipq->ipq_hdr->ip_off) & IP_MF) != 0)); + errno = EAGAIN; return (-1); } n += ntohs(ipq->ipq_hdr->ip_len) - (ipq->ipq_hdr->ip_hl << 2); last = ipq; } + + /* complete queue has last packet with MF 0 */ if ((ntohs(last->ipq_hdr->ip_off) & IP_MF) != 0) { + DEBUG_PRINTF(1, ("%s: need more fragments %d %s -> ", + __func__, ntohs(last->ipq_hdr->ip_id), + inet_ntoa(last->ipq_hdr->ip_src))); + DEBUG_PRINTF(1, ("%s offset=%d MF=%d\n", + inet_ntoa(last->ipq_hdr->ip_dst), + (ntohs(last->ipq_hdr->ip_off) & IP_OFFMASK) * 8, + (ntohs(last->ipq_hdr->ip_off) & IP_MF) != 0)); errno = EAGAIN; return (-1); } + ipr->ip_total_size = n + sizeof(*ip) + sizeof(struct ether_header); + ipr->ip_pkt = malloc(ipr->ip_total_size + 2); + if (ipr->ip_pkt == NULL) { + STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); + ip_reasm_free(ipr); + return (-1); + } + ipq = STAILQ_FIRST(&ipr->ip_queue); /* Fabricate ethernet header */ eh = (struct ether_header *)((uintptr_t)ipr->ip_pkt + 2); - bcopy((void *)((uintptr_t)ipq->ipq_pkt + 2), eh, sizeof (*eh)); + bcopy((void *)((uintptr_t)ipq->ipq_pkt + 2), eh, sizeof(*eh)); /* Fabricate IP header */ - ipr->ip_hdr = (struct ip *)((uintptr_t)eh + sizeof (*eh)); - bcopy(ipq->ipq_hdr, ipr->ip_hdr, sizeof (*ipr->ip_hdr)); - ipr->ip_hdr->ip_hl = sizeof (*ipr->ip_hdr) >> 2; + ipr->ip_hdr = (struct ip *)((uintptr_t)eh + sizeof(*eh)); + bcopy(ipq->ipq_hdr, ipr->ip_hdr, sizeof(*ipr->ip_hdr)); + ipr->ip_hdr->ip_hl = sizeof(*ipr->ip_hdr) >> 2; ipr->ip_hdr->ip_len = htons(n); ipr->ip_hdr->ip_sum = 0; - ipr->ip_hdr->ip_sum = in_cksum(ipr->ip_hdr, sizeof (*ipr->ip_hdr)); + ipr->ip_hdr->ip_sum = in_cksum(ipr->ip_hdr, sizeof(*ipr->ip_hdr)); n = 0; - ptr = (char *)((uintptr_t)ipr->ip_hdr + sizeof (*ipr->ip_hdr)); + ptr = (char *)((uintptr_t)ipr->ip_hdr + sizeof(*ipr->ip_hdr)); STAILQ_FOREACH(ipq, &ipr->ip_queue, ipq_next) { char *data; size_t len; @@ -398,6 +384,9 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, STAILQ_REMOVE_HEAD(&ire_list, ip_next); ip_reasm_free(ipr); } + DEBUG_PRINTF(1, ("%s: completed fragments ID=%d %s -> %s\n", + __func__, ntohs(ip->ip_id), inet_ntoa(ip->ip_src), + inet_ntoa(ip->ip_dst))); return (n); } @@ -413,15 +402,63 @@ readip(struct iodesc *d, void **pkt, void **payload, time_t tleft, t = getsecs(); while ((getsecs() - t) < tleft) { + ssize_t n; + uint16_t etype; /* host order */ + void *ptr = NULL; + void *data = NULL; + errno = 0; - ret = readipv4(d, pkt, payload, tleft, proto); - if (ret >= 0) - return (ret); - /* Bubble up the error if it wasn't successful */ - if (errno != EAGAIN) - return (-1); + n = readether(d, &ptr, &data, tleft, &etype); + if (n == -1) { + free(ptr); + continue; + } + /* Ethernet address checks are done in readether() */ + + /* Need to respond to ARP requests. */ + if (etype == ETHERTYPE_ARP) { + struct arphdr *ah = data; + + DEBUG_PRINTF(1, ("%s: ARP request\n", __func__)); + + if (ah->ar_op == htons(ARPOP_REQUEST)) { + /* Send ARP reply */ + arp_reply(d, ah); + } + free(ptr); + continue; /* Get next packet */ + } + + if (etype == ETHERTYPE_IP) { + struct ip *ip = data; + + if (ip->ip_v == IPVERSION && /* half char */ + ip->ip_p == proto) { + errno = 0; + ret = readipv4(d, &ptr, &data, n); + if (ret >= 0) { + *pkt = ptr; + *payload = data; + return (ret); + } + + /* + * Bubble up the error if it wasn't successful + */ + if (errno != EAGAIN) + return (-1); + continue; + } + DEBUG_PRINTF(1, ("%s: IP version or proto. " + "ip_v=%d ip_p=%d\n", + __func__, ip->ip_v, ip->ip_p)); + free(ptr); + continue; + } + free(ptr); } /* We've exhausted tleft; timeout */ errno = ETIMEDOUT; + DEBUG_PRINTF(1, ("%s: timeout\n", __func__)); return (-1); } diff --git a/stand/libsa/libsa.3 b/stand/libsa/libsa.3 index f1bfcd7b5be7..0947f97a0a1f 100644 --- a/stand/libsa/libsa.3 +++ b/stand/libsa/libsa.3 @@ -22,9 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd February 22, 2018 +.Dd September 9, 2022 .Dt LIBSA 3 .Os .Sh NAME @@ -499,9 +497,114 @@ Attempts to open and display the file .Fa fname . Returns -1 on error, 0 at EOF, or 1 if the user elects to quit while reading. .El +.Sh FEATURE SUPPORT +A set of functions are provided to communicate support of features from the +loader binary to the interpreter. +These are used to do something sensible if we are still operating with a loader +binary that behaves differently than expected. +.Bl -hang -width 10n +.It Xo +.Ft void +.Fn feature_enable "uint32_t mask" +.Xc +.Pp +Enable the referenced +.Fa mask +feature, which should be one of the +.Li FEATURE_* +macros defined in +.In stand.h . +.It Xo +.Ft bool +.Fn feature_name_is_enabled "const char *name" +.Xc +.Pp +Check if the referenced +.Fa name +feature is enabled. +The +.Fa name +is usually the same name as the +.Li FEATURE_* +macro, but with the FEATURE_ prefix stripped off. +The authoritative source of feature names is the mapping table near the top in +.Pa stand/libsa/features.c . +.It Xo +.Ft void +.Fn "(feature_iter_fn)" "void *cookie" "const char *name" "const char *desc" "bool enabled" +.Xc +.Pp +The +.Fa cookie +argument is passed as-is from the argument of the same name to +.Fn feature_iter . +The +.Fa name +and +.Fa desc +arguments are defined in the mapping table in +.Pa stand/libsa/features.c . +The +.Fa enabled +argument indicates the current status of the feature, though one could +theoretically turn a feature off in later execution. +As such, this should likely not be trusted if it is needed after the iteration +has finished. +.It Xo +.Ft void +.Fn "feature_iter" "feature_iter_fn *iter_fn" "void *cookie" +.Xc +.Pp +Iterate over the current set of features. +.El .Sh MISC .Bl -hang -width 10n .It Xo +.Ft char * +.Fn devformat "struct devdesc *" +.Xc +.Pp +Format the specified device as a string. +.It Xo +.Ft int +.Fn devparse "struct devdesc **dev" "const char *devdesc" "const char **path" +.Xc +.Pp +Parse the +.Dv devdesc +string of the form +.Sq device:[/path/to/file] . +The +.Dv devsw +table is used to match the start of the +.Sq device +string with +.Fa dv_name . +If +.Fa dv_parsedev +is non-NULL, then it will be called to parse the rest of the string and allocate +the +.Dv struct devdesc +for this path. +If NULL, then a default routine will be called that will allocate a simple +.Dv struct devdesc , +parse a unit number and ensure there's no trailing characters. +If +.Dv path +is non-NULL, then a pointer to the remainder of the +.Dv devdesc +string after the device specification is written. +.It Xo +.Ft int +.Fn devinit void +.Xc +.Pp +Calls all the +.Fa dv_init +routines in the +.Dv devsw +array, returning the number of routines that returned an error. +.It Xo .Ft void .Fn twiddle void .Xc @@ -615,7 +718,7 @@ The device driver itself will already have been called for the close; this call should clean up any allocation made by devopen only. .It Xo .Ft void -.Fn abort +.Fn __abort .Xc .Pp Calls @@ -678,6 +781,10 @@ The same as but for .Xr bzip2 1 Ns -compressed files. +.It Va pkgfs_fsops +File access from a tar file typically streamed via TFTP. +The order of files in the tar file must match the order they are +to be consumed as rewind is not practical. .El .Pp The array of @@ -687,6 +794,112 @@ pointers should be terminated with a NULL. Devices are exported by the supporting code via the array .Vt struct devsw *devsw[] which is a NULL terminated array of pointers to device switch structures. +.Sh DRIVER INTERFACE +The driver needs to provide a common set of entry points that are +used by +.Nm libsa +to interface with the device. +.Bd -literal +struct devsw { + const char dv_name[DEV_NAMLEN]; + int dv_type; + int (*dv_init)(void); + int (*dv_strategy)(void *devdata, int rw, daddr_t blk, + size_t size, char *buf, size_t *rsize); + int (*dv_open)(struct open_file *f, ...); + int (*dv_close)(struct open_file *f); + int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data); + int (*dv_print)(int verbose); + void (*dv_cleanup)(void); + char * (*dv_fmtdev)(struct devdesc *); + int (*dv_parsedev)(struct devdesc **dev, const char *devpart, + const char **path); + bool (*dv_match)(struct devsw *dv, const char *devspec); +}; +.Ed +.Bl -tag -width ".Fn dv_strategy" +.It Fn dv_name +The device's name. +.It Fn dv_type +Type of device. +The supported types are: +.Bl -tag -width "DEVT_NONE" +.It DEVT_NONE +.It DEVT_DISK +.It DEVT_NET +.It DEVT_CD +.It DEVT_ZFS +.It DEVT_FD +.El +Each type may have its own associated (struct type_devdesc), +which has the generic (struct devdesc) as its first member. +.It Fn dv_init +Driver initialization routine. +This routine should probe for available units. +Drivers are responsible for maintaining lists of units for later enumeration. +No other driver routines may be called before +.Fn dv_init +returns. +.It Fn dv_open +The driver open routine. +.It Fn dv_close +The driver close routine. +.It Fn dv_ioctl +The driver ioctl routine. +.It Fn dv_print +Prints information about the available devices. +Information should be presented with +.Fn pager_output . +.It Fn dv_cleanup +Cleans up any memory used by the device before the next stage is run. +.It Fn dv_fmtdev +Converts the specified devdesc to the canonical string representation +for that device. +.It Fn dv_parsedev +Parses the device portion of a file path. +The +.Dv devpart +will point to the +.Sq tail +of device name, possibly followed by a colon and a path within the device. +The +.Sq tail +is, by convention, the part of the device specification that follows the +.Fa dv_name +part of the string. +So when +.Fa devparse +is parsing the string +.Dq disk3p5:/xxx , +.Dv devpart +will point to the +.Sq 3 +in that string. +The parsing routine is expected to allocate a new +.Dv struct devdesc +or subclass and return it in +.Dv dev +when successful. +This routine should set +.Dv path +to point to the portion of the string after device specification, or +.Dq /xxx +in the earlier example. +Generally, code needing to parse a path will use +.Fa devparse +instead of calling this routine directly. +.It Fn dv_match +.Dv NULL +to specify that all device paths starting with +.Fa dv_name +match. +Otherwise, this function returns 0 for a match and a non-zero +.Dv errno +to indicate why it didn't match. +This is helpful when you claim the device path after using it to query +properties on systems that have uniform naming for different types of +devices. +.El .Sh HISTORY The .Nm diff --git a/stand/libsa/lseek.c b/stand/libsa/lseek.c index c4ca97b148d6..9a4722b84c33 100644 --- a/stand/libsa/lseek.c +++ b/stand/libsa/lseek.c @@ -31,8 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)lseek.c 8.1 (Berkeley) 6/11/93 - * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. @@ -60,9 +58,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" off_t diff --git a/stand/libsa/mips/_setjmp.S b/stand/libsa/mips/_setjmp.S deleted file mode 100644 index 972fb2cc1ec8..000000000000 --- a/stand/libsa/mips/_setjmp.S +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ralph Campbell. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <machine/asm.h> - -#if 0 -#if defined(LIBC_SCCS) - .text - .asciz "$OpenBSD: _setjmp.S,v 1.6 1996/09/23 21:27:53 imp Exp $" -#endif /* LIBC_SCCS */ -#endif - -/* - * C library -- _setjmp, _longjmp - * - * _longjmp(a,v) - * will generate a "return(v)" from - * the last call to - * _setjmp(a) - * by restoring registers from the stack, - * The previous signal state is NOT restored. - */ - -LEAF(_setjmp) - .set noreorder - REG_LI v0, _JB_MAGIC__SETJMP # sigcontext magic number - REG_S v0, (_JB_MAGIC * SZREG)(a0) # saved in sc_regs[0] - REG_S ra, (_JB_REG_RA * SZREG)(a0) # sc_pc = return address - REG_S s0, (_JB_REG_S0 * SZREG)(a0) - REG_S s1, (_JB_REG_S1 * SZREG)(a0) - REG_S s2, (_JB_REG_S2 * SZREG)(a0) - REG_S s3, (_JB_REG_S3 * SZREG)(a0) - REG_S s4, (_JB_REG_S4 * SZREG)(a0) - REG_S s5, (_JB_REG_S5 * SZREG)(a0) - REG_S s6, (_JB_REG_S6 * SZREG)(a0) - REG_S s7, (_JB_REG_S7 * SZREG)(a0) - REG_S sp, (_JB_REG_SP * SZREG)(a0) - REG_S s8, (_JB_REG_S8 * SZREG)(a0) - j ra - move v0, zero -END(_setjmp) - -LEAF(_longjmp) -#ifdef ABICALLS - subu sp, sp, 32 - .cprestore 16 -#endif - .set noreorder - REG_L v0, (_JB_MAGIC * SZREG)(a0) # get magic number - REG_L ra, (_JB_REG_RA * SZREG)(a0) - bne v0, _JB_MAGIC__SETJMP, botch # jump if error - - addu sp, sp, 32 # does not matter, sanity - REG_L s0, (_JB_REG_S0 * SZREG)(a0) - REG_L s1, (_JB_REG_S1 * SZREG)(a0) - REG_L s2, (_JB_REG_S2 * SZREG)(a0) - REG_L s3, (_JB_REG_S3 * SZREG)(a0) - REG_L s4, (_JB_REG_S4 * SZREG)(a0) - REG_L s5, (_JB_REG_S5 * SZREG)(a0) - REG_L s6, (_JB_REG_S6 * SZREG)(a0) - REG_L s7, (_JB_REG_S7 * SZREG)(a0) - REG_L sp, (_JB_REG_SP * SZREG)(a0) - REG_L s8, (_JB_REG_S8 * SZREG)(a0) - - j ra - move v0, a1 -botch: - jal _C_LABEL(longjmperror) - nop - jal _C_LABEL(abort) - nop -END(_longjmp) diff --git a/stand/libsa/mount.c b/stand/libsa/mount.c index c9abe6b945fe..c866dc9c7055 100644 --- a/stand/libsa/mount.c +++ b/stand/libsa/mount.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/queue.h> @@ -110,7 +107,10 @@ mount(const char *dev, const char *path, int flags __unused, void *data) fs = file_system[i]; if (fs->fo_mount == NULL) continue; - + DEBUG_PRINTF(1,("%s: fs=%s path=%s\n", + __func__, fs->fs_name, path)); + if (is_tftp()) + break; if (fs->fo_mount(dev, path, &data) != 0) continue; diff --git a/stand/libsa/net.c b/stand/libsa/net.c index e04a370e466e..76b31c50d1e7 100644 --- a/stand/libsa/net.c +++ b/stand/libsa/net.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/socket.h> diff --git a/stand/libsa/net.h b/stand/libsa/net.h index 77a11c8dcab6..945b6b9ea45f 100644 --- a/stand/libsa/net.h +++ b/stand/libsa/net.h @@ -32,8 +32,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _STAND_NET_H @@ -77,6 +75,7 @@ enum net_proto { extern u_char bcea[6]; extern char rootpath[FNAME_SIZE]; +extern int rootport; extern char bootfile[FNAME_SIZE]; extern char hostname[FNAME_SIZE]; extern int hostnamelen; diff --git a/stand/libsa/netif.c b/stand/libsa/netif.c index 4e91e11a9413..4b40af9aed32 100644 --- a/stand/libsa/netif.c +++ b/stand/libsa/netif.c @@ -31,12 +31,8 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/types.h> -#include <sys/cdefs.h> #include <string.h> #include <netinet/in.h> @@ -91,7 +87,7 @@ netif_match(struct netif *nif, void *machdep_hint) { struct netif_driver *drv = nif->nif_driver; -#if NETIF_DEBUG +#ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_match (%d)\n", drv->netif_bname, nif->nif_unit, nif->nif_sel); diff --git a/stand/libsa/netif.h b/stand/libsa/netif.h index 44165ab0d88a..74b41c75666c 100644 --- a/stand/libsa/netif.h +++ b/stand/libsa/netif.h @@ -1,6 +1,5 @@ /* $NetBSD: netif.h,v 1.4 1995/09/14 23:45:30 pk Exp $ */ -/* $FreeBSD$ */ #ifndef __SYS_LIBNETBOOT_NETIF_H #define __SYS_LIBNETBOOT_NETIF_H diff --git a/stand/libsa/nfs.c b/stand/libsa/nfs.c index 5757395caba2..f3e9060c9881 100644 --- a/stand/libsa/nfs.c +++ b/stand/libsa/nfs.c @@ -28,9 +28,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/time.h> #include <sys/socket.h> @@ -133,14 +130,15 @@ static int nfs_readdir(struct open_file *f, struct dirent *d); struct nfs_iodesc nfs_root_node; struct fs_ops nfs_fsops = { - "nfs", - nfs_open, - nfs_close, - nfs_read, - null_write, - nfs_seek, - nfs_stat, - nfs_readdir + .fs_name = "nfs", + .fs_flags = 0, + .fo_open = nfs_open, + .fo_close = nfs_close, + .fo_read = nfs_read, + .fo_write = null_write, + .fo_seek = nfs_seek, + .fo_stat = nfs_stat, + .fo_readdir = nfs_readdir, }; static int nfs_read_size = NFSREAD_MIN_SIZE; diff --git a/stand/libsa/nfsv2.h b/stand/libsa/nfsv2.h index 09b2428b8012..bcae55b06b1d 100644 --- a/stand/libsa/nfsv2.h +++ b/stand/libsa/nfsv2.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* $NetBSD: nfsv2.h,v 1.2 1996/02/26 23:05:23 gwr Exp $ */ /* @@ -31,8 +30,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)nfsv2.h 8.1 (Berkeley) 6/10/93 */ /* diff --git a/stand/libsa/nullfs.c b/stand/libsa/nullfs.c index cc77f9500786..1ac759995448 100644 --- a/stand/libsa/nullfs.c +++ b/stand/libsa/nullfs.c @@ -30,8 +30,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)open.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University @@ -60,9 +58,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" /* diff --git a/stand/libsa/nvstore.c b/stand/libsa/nvstore.c new file mode 100644 index 000000000000..f6be3b1ca47f --- /dev/null +++ b/stand/libsa/nvstore.c @@ -0,0 +1,148 @@ +/*- + * Copyright 2020 Toomas Soome <tsoome@me.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Big Theory Statement. + * + * nvstore is abstraction layer to implement data read/write to different + * types of non-volatile storage. + * + * User interfaces: + * Provide mapping via environment: setenv/unsetenv/putenv. Access via + * environment functions/commands is available once nvstore has + * attached the backend and stored textual data is mapped to environment. + * + * nvstore_init(): attach new backend and create the environment mapping. + * nvstore_fini: detach backend and unmap the related environment. + * + * The disk based storage, such as UFS file or ZFS bootenv label area, is + * only accessible after root file system is set. Root file system change + * will switch the back end storage. + */ + +#include <stdbool.h> +#include <sys/queue.h> +#include "stand.h" +#include "nvstore.h" + +nvstore_list_t stores = STAILQ_HEAD_INITIALIZER(stores); + +void * +nvstore_get_store(const char *name) +{ + nvstore_t *st; + + st = NULL; + + STAILQ_FOREACH(st, &stores, nvs_next) { + if (strcmp(name, st->nvs_name) == 0) + break; + } + + return (st); +} + +int +nvstore_init(const char *name, nvs_callbacks_t *cb, void *data) +{ + nvstore_t *st; + + st = nvstore_get_store(name); + if (st != NULL) + return (EEXIST); + + if ((st = malloc(sizeof (*st))) == NULL) + return (ENOMEM); + + if ((st->nvs_name = strdup(name)) == NULL) { + free(st); + return (ENOMEM); + } + + st->nvs_data = data; + st->nvs_cb = cb; + + STAILQ_INSERT_TAIL(&stores, st, nvs_next); + return (0); +} + +int +nvstore_fini(const char *name) +{ + nvstore_t *st; + + st = nvstore_get_store(name); + if (st == NULL) + return (ENOENT); + + STAILQ_REMOVE(&stores, st, nvstore, nvs_next); + + free(st->nvs_name); + free(st->nvs_data); + free(st); + return (0); +} + +int +nvstore_print(void *ptr) +{ + nvstore_t *st = ptr; + + return (st->nvs_cb->nvs_iterate(st->nvs_data, st->nvs_cb->nvs_print)); +} + +int +nvstore_get_var(void *ptr, const char *name, void **data) +{ + nvstore_t *st = ptr; + + return (st->nvs_cb->nvs_getter(st->nvs_data, name, data)); +} + +int +nvstore_set_var(void *ptr, int type, const char *name, + void *data, size_t size) +{ + nvstore_t *st = ptr; + + return (st->nvs_cb->nvs_setter(st->nvs_data, type, name, data, size)); +} + +int +nvstore_set_var_from_string(void *ptr, const char *type, const char *name, + const char *data) +{ + nvstore_t *st = ptr; + + return (st->nvs_cb->nvs_setter_str(st->nvs_data, type, name, data)); +} + +int +nvstore_unset_var(void *ptr, const char *name) +{ + nvstore_t *st = ptr; + + return (st->nvs_cb->nvs_unset(st->nvs_data, name)); +} diff --git a/stand/libsa/zfs/devicename_stubs.c b/stand/libsa/nvstore.h index 41bf907e0cf1..a03a73249194 100644 --- a/stand/libsa/zfs/devicename_stubs.c +++ b/stand/libsa/nvstore.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org> - * All rights reserved. + * Copyright 2020 Toomas Soome <tsoome@me.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,24 +23,17 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); +/* Private part of nvstore API, for internal use only */ -#include <stand.h> -#include "libzfs.h" +#pragma once -__attribute__((weak)) -int -zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) -{ - return (EINVAL); -} +typedef struct nvstore { + char *nvs_name; + void *nvs_data; + nvs_callbacks_t *nvs_cb; + STAILQ_ENTRY(nvstore) nvs_next; +} nvstore_t; -__attribute__((weak)) -char * -zfs_fmtdev(void *vdev) -{ - static char buf[128]; +typedef STAILQ_HEAD(store_list, nvstore) nvstore_list_t; - return (buf); -} +extern nvstore_list_t stores; diff --git a/stand/libsa/open.c b/stand/libsa/open.c index c62e48f0e1d8..91848aca7dbe 100644 --- a/stand/libsa/open.c +++ b/stand/libsa/open.c @@ -31,8 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)open.c 8.1 (Berkeley) 6/11/93 - * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. @@ -60,9 +58,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" struct fs_ops *exclusive_file_system; @@ -143,6 +138,8 @@ open(const char *fname, int mode) struct fs_ops *fs; struct open_file *f; int fd, i, error, besterror; + bool is_dir; + size_t n; const char *file; TSENTER(); @@ -159,31 +156,42 @@ open(const char *fname, int mode) f->f_devdata = NULL; file = NULL; + if (exclusive_file_system == NULL || + (exclusive_file_system->fs_flags & FS_OPS_NO_DEVOPEN) == 0) { + error = devopen(f, fname, &file); + if (error || + (((f->f_flags & F_NODEV) == 0) && f->f_dev == NULL)) + goto err; + + /* see if we opened a raw device; otherwise, 'file' is the file name. */ + if (file == NULL || *file == '\0') { + f->f_flags |= F_RAW; + f->f_rabuf = NULL; + TSEXIT(); + return (fd); + } + } else + file = fname; + if (exclusive_file_system != NULL) { + /* loader is forcing the filesystem to be used */ fs = exclusive_file_system; - error = (fs->fo_open)(fname, f); + error = (fs->fo_open)(file, f); if (error == 0) goto ok; goto err; } - error = devopen(f, fname, &file); - if (error || - (((f->f_flags & F_NODEV) == 0) && f->f_dev == NULL)) - goto err; - - /* see if we opened a raw device; otherwise, 'file' is the file name. */ - if (file == NULL || *file == '\0') { - f->f_flags |= F_RAW; - f->f_rabuf = NULL; - TSEXIT(); - return (fd); - } - /* pass file name to the different filesystem open routines */ besterror = ENOENT; + n = strlen(file); + is_dir = (n > 0 && file[n - 1] == '/'); for (i = 0; file_system[i] != NULL; i++) { fs = file_system[i]; + if (is_dir && is_tftp()) { + error = EOPNOTSUPP; + goto err; + } error = (fs->fo_open)(file, f); if (error == 0) goto ok; diff --git a/stand/libsa/pager.c b/stand/libsa/pager.c index a966b0bd7992..40d6a4397c69 100644 --- a/stand/libsa/pager.c +++ b/stand/libsa/pager.c @@ -27,9 +27,6 @@ * Simple paged-output and paged-viewing functions */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" #include <string.h> diff --git a/stand/libsa/panic.c b/stand/libsa/panic.c index bc6e7e2aca5a..a555743f0414 100644 --- a/stand/libsa/panic.c +++ b/stand/libsa/panic.c @@ -33,11 +33,8 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> -#include <machine/stdarg.h> +#include <sys/stdarg.h> /* * Boot loaders and other standalone programs that wish to have a diff --git a/stand/libsa/pkgfs.c b/stand/libsa/pkgfs.c index ffa16309ee6a..6eb3badf7068 100644 --- a/stand/libsa/pkgfs.c +++ b/stand/libsa/pkgfs.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" #include <sys/stat.h> @@ -34,12 +31,6 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <zlib.h> -#ifdef PKGFS_DEBUG -#define DBG(x) printf x -#else -#define DBG(x) -#endif - static int pkg_open(const char *, struct open_file *); static int pkg_close(struct open_file *); static int pkg_read(struct open_file *, void *, size_t, size_t *); @@ -49,14 +40,15 @@ static int pkg_readdir(struct open_file *, struct dirent *); static off_t pkg_atol(const char *, unsigned); struct fs_ops pkgfs_fsops = { - "pkg", - pkg_open, - pkg_close, - pkg_read, - null_write, - pkg_seek, - pkg_stat, - pkg_readdir + .fs_name = "pkg", + .fs_flags = FS_OPS_NO_DEVOPEN, + .fo_open = pkg_open, + .fo_close = pkg_close, + .fo_read = pkg_read, + .fo_write = null_write, + .fo_seek = pkg_seek, + .fo_stat = pkg_stat, + .fo_readdir = pkg_readdir, }; #define PKG_BUFSIZE 512 @@ -175,6 +167,9 @@ pkgfs_init(const char *pkgname, struct fs_ops *proto) exclusive_file_system = NULL; + DEBUG_PRINTF(0, ("%s(%s: '%s') -> %d (error=%d)\n", __func__, + proto->fs_name, pkgname, fd, errno)); + if (fd == -1) return (errno); @@ -242,7 +237,7 @@ pkg_open_follow(const char *fn, struct open_file *f, int lnks) if (strcmp(fn, tf->tf_hdr.ut_name) == 0) { f->f_fsdata = tf; tf->tf_fp = 0; /* Reset the file pointer. */ - DBG(("%s: found %s type %c\n", __func__, + DEBUG_PRINTF(1, ("%s: found %s type %c\n", __func__, fn, tf->tf_hdr.ut_typeflag[0])); if (tf->tf_hdr.ut_typeflag[0] == '2') { /* we have a symlink @@ -278,6 +273,7 @@ pkg_close(struct open_file *f) /* * Free up the cache if we read all of the file. */ + DEBUG_PRINTF(1, ("%s(%s)\n", __func__, tf->tf_hdr.ut_name)); if (tf->tf_fp == tf->tf_size && tf->tf_cachesz > 0) { free(tf->tf_cache); tf->tf_cachesz = 0; @@ -300,6 +296,8 @@ pkg_read(struct open_file *f, void *buf, size_t size, size_t *res) return (EBADF); } + DEBUG_PRINTF(4, ("%s(%s,%zd)\n", __func__, tf->tf_hdr.ut_name, size)); + if (tf->tf_cachesz == 0) cache_data(tf, 1); @@ -337,6 +335,8 @@ pkg_read(struct open_file *f, void *buf, size_t size, size_t *res) tf->tf_fp = fp; if (res != NULL) *res = size; + DEBUG_PRINTF(4, ("%s(%s) res=%zd\n", __func__, tf->tf_hdr.ut_name, + (ssize_t)(tf->tf_size - tf->tf_fp))); return ((sz == -1) ? errno : 0); } @@ -380,7 +380,7 @@ pkg_seek(struct open_file *f, off_t ofs, int whence) return (tf->tf_fp); } } - DBG(("%s: negative file seek (%jd)\n", __func__, + DEBUG_PRINTF(3, ("%s: negative file seek (%jd)\n", __func__, (intmax_t)delta)); errno = ESPIPE; return (-1); @@ -514,26 +514,28 @@ cache_data(struct tarfile *tf, int force) size_t sz; if (tf == NULL) { - DBG(("%s: no file to cache data for?\n", __func__)); + DEBUG_PRINTF(5, ("%s: no file to cache data for?\n", + __func__)); errno = EINVAL; return (-1); } pkg = tf->tf_pkg; if (pkg == NULL) { - DBG(("%s: no package associated with file?\n", __func__)); + DEBUG_PRINTF(5, ("%s: no package associated with file?\n", + __func__)); errno = EINVAL; return (-1); } if (tf->tf_cachesz > 0) { - DBG(("%s: data already cached\n", __func__)); + DEBUG_PRINTF(5, ("%s: data already cached\n", __func__)); errno = EINVAL; return (-1); } if (tf->tf_ofs != pkg->pkg_ofs) { - DBG(("%s: caching after force read of file %s?\n", + DEBUG_PRINTF(5, ("%s: caching after force read of file %s?\n", __func__, tf->tf_hdr.ut_name)); errno = EINVAL; return (-1); @@ -551,7 +553,8 @@ cache_data(struct tarfile *tf, int force) tf->tf_cache = malloc(sz); if (tf->tf_cache == NULL) { - DBG(("%s: could not allocate %d bytes\n", __func__, (int)sz)); + DEBUG_PRINTF(5, ("%s: could not allocate %d bytes\n", + __func__, (int)sz)); errno = ENOMEM; return (-1); } @@ -735,7 +738,7 @@ new_package(int fd, struct package **pp) } /* - * Done parsing the ZIP header. Spkgt the inflation engine. + * Done parsing the ZIP header. Start the inflation engine. */ error = inflateInit2(&pkg->pkg_zs, -15); if (error != Z_OK) diff --git a/stand/libsa/powerpc/_setjmp.S b/stand/libsa/powerpc/_setjmp.S index 485050f003a1..a47920380a23 100644 --- a/stand/libsa/powerpc/_setjmp.S +++ b/stand/libsa/powerpc/_setjmp.S @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* from: NetBSD: setjmp.S,v 1.1 1998/01/27 15:13:12 sakamoto Exp $ */ /* from: OpenBSD: setjmp.S,v 1.2 1996/12/28 06:22:18 rahnds Exp */ /* kernel version of this file, does not have signal goop */ @@ -115,3 +114,5 @@ ASENTRY_NOPROF(_longjmp) mr 3, 4 blr ASEND(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/libsa/powerpc/syncicache.c b/stand/libsa/powerpc/syncicache.c index 434dcec63416..1f99007dcdae 100644 --- a/stand/libsa/powerpc/syncicache.c +++ b/stand/libsa/powerpc/syncicache.c @@ -31,11 +31,6 @@ * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $ */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - #include <sys/param.h> #if defined(_KERNEL) || defined(_STANDALONE) #include <sys/time.h> @@ -59,7 +54,7 @@ int cacheline_size = 0; static void getcachelinesize(void); static void -getcachelinesize() +getcachelinesize(void) { static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE }; int clen; diff --git a/stand/libsa/preload.c b/stand/libsa/preload.c index 3d41101dc861..499075c0efac 100644 --- a/stand/libsa/preload.c +++ b/stand/libsa/preload.c @@ -24,9 +24,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include "stand.h" diff --git a/stand/libsa/printf.c b/stand/libsa/printf.c index 4de547b644dd..053b54d31eff 100644 --- a/stand/libsa/printf.c +++ b/stand/libsa/printf.c @@ -30,30 +30,20 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Standaloneified version of the FreeBSD kernel printf family. */ #include <sys/types.h> +#include <sys/stdarg.h> #include <sys/stddef.h> #include <sys/stdint.h> #include <limits.h> #include <string.h> #include "stand.h" -/* - * Note that stdarg.h and the ANSI style va_start macro is used for both - * ANSI and traditional C compilers. - */ -#include <machine/stdarg.h> - #define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1) typedef void (kvprintf_fn_t)(int, void *); diff --git a/stand/libsa/random.c b/stand/libsa/random.c index e4eee6e43c8e..d17d636e1597 100644 --- a/stand/libsa/random.c +++ b/stand/libsa/random.c @@ -25,13 +25,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)random.c 8.1 (Berkeley) 6/10/93 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> static long randseed = 1; diff --git a/stand/libsa/rarp.c b/stand/libsa/rarp.c index a81994e51b5c..20bbd56de6e6 100644 --- a/stand/libsa/rarp.c +++ b/stand/libsa/rarp.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/socket.h> #include <net/if.h> @@ -83,7 +78,7 @@ rarp_getipaddress(int sock) } #ifdef RARP_DEBUG if (debug) - printf("rarp: d=%x\n", (u_int)d); + printf("rarp: d=%lx\n", (long)d); #endif bzero((char*)&wbuf.data, sizeof(wbuf.data)); @@ -161,7 +156,7 @@ rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, if (n == -1 || n < sizeof(struct ether_arp)) { #ifdef RARP_DEBUG if (debug) - printf("bad len=%d\n", n); + printf("bad len=%zd\n", n); #endif free(ptr); return (-1); diff --git a/stand/libsa/read.c b/stand/libsa/read.c index d079944bf5d0..e610f8a0779c 100644 --- a/stand/libsa/read.c +++ b/stand/libsa/read.c @@ -31,8 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)read.c 8.1 (Berkeley) 6/11/93 - * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. @@ -60,9 +58,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include "stand.h" diff --git a/stand/libsa/readdir.c b/stand/libsa/readdir.c index 7757647e11e8..558ff99b265c 100644 --- a/stand/libsa/readdir.c +++ b/stand/libsa/readdir.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include "stand.h" diff --git a/stand/libsa/rpc.c b/stand/libsa/rpc.c index 0f011e13a309..6b11282a10be 100644 --- a/stand/libsa/rpc.c +++ b/stand/libsa/rpc.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: rpc.c,v 1.12 93/09/28 08:31:56 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * RPC functions used by NFS and bootparams. * Note that bootparams requires the ability to find out the diff --git a/stand/libsa/rpc.h b/stand/libsa/rpc.h index 5efe83210142..a13f983ad575 100644 --- a/stand/libsa/rpc.h +++ b/stand/libsa/rpc.h @@ -31,8 +31,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* XXX defines we can't easily get from system includes */ diff --git a/stand/libsa/rpcv2.h b/stand/libsa/rpcv2.h index 4f1f016333a0..4973b3918110 100644 --- a/stand/libsa/rpcv2.h +++ b/stand/libsa/rpcv2.h @@ -30,10 +30,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)rpcv2.h 8.1 (Berkeley) 6/10/93 - * - * $FreeBSD$ */ /* diff --git a/stand/libsa/saioctl.h b/stand/libsa/saioctl.h index 5124f86187c9..2ad35443e367 100644 --- a/stand/libsa/saioctl.h +++ b/stand/libsa/saioctl.h @@ -27,10 +27,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)saioctl.h 8.1 (Berkeley) 6/11/93 - * - * $FreeBSD$ */ /* ioctl's -- for disks just now */ diff --git a/stand/libsa/sbrk.c b/stand/libsa/sbrk.c index 2f169ea60f66..7d9446bff866 100644 --- a/stand/libsa/sbrk.c +++ b/stand/libsa/sbrk.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Minimal sbrk() emulation required for malloc support. */ diff --git a/stand/libsa/smbios.c b/stand/libsa/smbios.c index 5582a2f3ce90..32cd198a9537 100644 --- a/stand/libsa/smbios.c +++ b/stand/libsa/smbios.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/endian.h> @@ -38,33 +35,112 @@ __FBSDID("$FreeBSD$"); * * System Management BIOS Reference Specification, v2.6 Final * http://www.dmtf.org/standards/published_documents/DSP0134_2.6.0.pdf + * + * System Management BIOS (SMBIOS) Reference Specification, 3.6.0 + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf */ /* - * 2.1.1 SMBIOS Structure Table Entry Point + * The first quoted paragraph below can also be found in section 2.1.1 SMBIOS + * Structure Table Entry Point of System Management BIOS Reference + * Specification, v2.6 Final + * + * (From System Management BIOS (SMBIOS) Reference Specification, 3.6.0) + * 5.2.1 SMBIOS 2.1 (32-bit) Entry Point + * + * "On non-UEFI systems, the 32-bit SMBIOS Entry Point structure, can be + * located by application software by searching for the anchor-string on + * paragraph (16-byte) boundaries within the physical memory address + * range 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate + * anchor string that is used by some existing DMI browsers. + * + * On UEFI-based systems, the SMBIOS Entry Point structure can be located by + * looking in the EFI Configuration Table for the SMBIOS GUID + * (SMBIOS_TABLE_GUID, {EB9D2D31-2D88-11D3-9A16-0090273FC14D}) and using the + * associated pointer. See section 4.6 of the UEFI Specification for details. + * See section 2.3 of the UEFI Specification for how to report the containing + * memory type. + * + * NOTE While the SMBIOS Major and Minor Versions (offsets 06h and 07h) + * currently duplicate the information that is present in the SMBIOS BCD + * Revision (offset 1Eh), they provide a path for future growth in this + * specification. The BCD Revision, for example, provides only a single digit + * for each of the major and minor version numbers." + * + * 5.2.2 SMBIOS 860 3.0 (64-bit) Entry Point * - * "On non-EFI systems, the SMBIOS Entry Point structure, described below, can - * be located by application software by searching for the anchor-string on - * paragraph (16-byte) boundaries within the physical memory address range - * 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate anchor - * string that is used by some existing DMI browsers." + * "On non-UEFI systems, the 64-bit SMBIOS Entry Point structure can be located + * by application software by searching for the anchor-string on paragraph + * (16-byte) boundaries within the physical memory address range 000F0000h to + * 000FFFFFh. + * + * On UEFI-based systems, the SMBIOS Entry Point structure can be located by + * looking in the EFI Configuration Table for the SMBIOS 3.x GUID + * (SMBIOS3_TABLE_GUID, {F2FD1544-9794-4A2C-992E-E5BBCF20E394}) and using the + * associated pointer. See section 4.6 of the UEFI Specification for details. + * See section 2.3 of the UEFI Specification for how to report the containing + * memory type." */ #define SMBIOS_START 0xf0000 #define SMBIOS_LENGTH 0x10000 #define SMBIOS_STEP 0x10 #define SMBIOS_SIG "_SM_" +#define SMBIOS3_SIG "_SM3_" #define SMBIOS_DMI_SIG "_DMI_" +#define SMBIOS_EOT_TYPE 0x7f + +/* + * 5.1 General + *... + * NOTE The Entry Point Structure and all SMBIOS structures assume a + * little-endian ordering convention... + * ... + * + * We use memcpy to avoid unaligned access to memory. To normal memory, this is + * fine, but the memory we are using might be mmap'd /dev/mem which under Linux + * on aarch64 doesn't allow unaligned access. leXdec and friends can't be used + * because those can optimize to an unaligned load (which often is fine, but not + * for mmap'd /dev/mem which has special memory attributes). + */ +static inline uint8_t +SMBIOS_GET8(const caddr_t base, int off) +{ + return (base[off]); +} -#define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off))) -#define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off))) -#define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off))) +static inline uint16_t +SMBIOS_GET16(const caddr_t base, int off) +{ + uint16_t v; + + memcpy(&v, base + off, sizeof(v)); + return (le16toh(v)); +} + +static inline uint32_t +SMBIOS_GET32(const caddr_t base, int off) +{ + uint32_t v; + + memcpy(&v, base + off, sizeof(v)); + return (le32toh(v)); +} + +static inline uint64_t +SMBIOS_GET64(const caddr_t base, int off) +{ + uint64_t v; + + memcpy(&v, base + off, sizeof(v)); + return (le64toh(v)); +} #define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01) #define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base)) struct smbios_attr { - int probed; - caddr_t addr; + int is_64bit_ep; + caddr_t addr; size_t length; size_t count; int major; @@ -96,15 +172,47 @@ static caddr_t smbios_sigsearch(const caddr_t addr, const uint32_t len) { caddr_t cp; + caddr_t v2_p = NULL; /* Search on 16-byte boundaries. */ - for (cp = addr; cp < addr + len; cp += SMBIOS_STEP) - if (strncmp(cp, SMBIOS_SIG, 4) == 0 && + for (cp = addr; cp < addr + len; cp += SMBIOS_STEP) { + /* v3.0, 64-bit Entry point */ + if (strncmp(cp, SMBIOS3_SIG, sizeof(SMBIOS3_SIG) - 1) == 0 && + /* + * The specification only guarantees the presence of the + * Structure Table Maximum Size and Address Entry fields at + * offsets 0x0c and 0x10 if the Entry Point Revision is not + * 0. + */ + SMBIOS_GET8(cp, 0x0a) != 0 && + smbios_checksum(cp, SMBIOS_GET8(cp, 0x06)) == 0) { +#ifdef __ILP32__ + uint64_t end_addr; + + end_addr = SMBIOS_GET64(cp, 0x10) + /* Start address. */ + SMBIOS_GET32(cp, 0x0c); /* Maximum size. */ + /* Is the table (or part of it) located above 4G? */ + if (end_addr >= (uint64_t)1 << 32) + /* Can't access it with 32-bit addressing. */ + continue; +#endif + smbios.is_64bit_ep = 1; + return (cp); + } + + /* v2.1, 32-bit Entry point */ + if (strncmp(cp, SMBIOS_SIG, sizeof(SMBIOS_SIG) - 1) == 0 && smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 && strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5) == 0 && - smbios_checksum(cp + 0x10, 0x0f) == 0) - return (cp); - return (NULL); + smbios_checksum(cp + 0x10, 0x0f) == 0) { + /* + * Note that we saw this entry point, but don't return + * it right now as we favor the 64-bit one if present. + */ + v2_p = cp; + } + } + return (v2_p); } static const char* @@ -139,10 +247,10 @@ smbios_setenv(const char *name, caddr_t addr, const int offset) #define UUID_TYPE uint32_t #define UUID_STEP sizeof(UUID_TYPE) #define UUID_ALL_BITS (UUID_SIZE / UUID_STEP) -#define UUID_GET(base, off) (*(UUID_TYPE *)((base) + (off))) +#define UUID_GET(base, off) SMBIOS_GET32(base, off) static void -smbios_setuuid(const char *name, const caddr_t addr, const int ver) +smbios_setuuid(const char *name, const caddr_t addr, const int ver __unused) { char uuid[37]; int byteorder, i, ones, zeros; @@ -298,6 +406,8 @@ smbios_parse_table(const caddr_t addr) { caddr_t cp; int proc, size, osize, type; + uint8_t bios_minor, bios_major; + char buf[16]; type = SMBIOS_GET8(addr, 0); /* 3.1.2 Structure Header Format */ switch(type) { @@ -305,6 +415,13 @@ smbios_parse_table(const caddr_t addr) smbios_setenv("smbios.bios.vendor", addr, 0x04); smbios_setenv("smbios.bios.version", addr, 0x05); smbios_setenv("smbios.bios.reldate", addr, 0x08); + bios_major = SMBIOS_GET8(addr, 0x14); + bios_minor = SMBIOS_GET8(addr, 0x15); + if (bios_minor != 0xFF && bios_major != 0xFF) { + snprintf(buf, sizeof(buf), "%u.%u", + bios_major, bios_minor); + setenv("smbios.bios.revision", buf, 1); + } break; case 1: /* 3.3.2 System Information (Type 1) */ @@ -344,6 +461,7 @@ smbios_parse_table(const caddr_t addr) break; case 4: /* 3.3.5 Processor Information (Type 4) */ + smbios_setenv("smbios.processor.version", addr, 0x10); /* * Offset 18h: Processor Status * @@ -401,6 +519,9 @@ smbios_parse_table(const caddr_t addr) (size & 0x7fff) : (size << 10); break; + case SMBIOS_EOT_TYPE: /* 3.3.42 End-of-Table (Type 127) */ + return (NULL); + default: /* skip other types */ break; } @@ -418,18 +539,26 @@ smbios_find_struct(int type) { caddr_t dmi; size_t i; + caddr_t ep; if (smbios.addr == NULL) return (NULL); + ep = smbios.addr + smbios.length; for (dmi = smbios.addr, i = 0; - dmi < smbios.addr + smbios.length && i < smbios.count; i++) { - if (SMBIOS_GET8(dmi, 0) == type) - return dmi; + dmi < ep && i < smbios.count; i++) { + const uint8_t seen_type = SMBIOS_GET8(dmi, 0); + + if (seen_type == type) + return (dmi); + if (seen_type == SMBIOS_EOT_TYPE) + /* End of table. */ + break; /* Find structure terminator. */ dmi = SMBIOS_GETSTR(dmi); - while (SMBIOS_GET16(dmi, 0) != 0) + while (SMBIOS_GET16(dmi, 0) != 0 && dmi < ep) dmi++; + /* Skip it. */ dmi += 2; } @@ -441,31 +570,56 @@ smbios_probe(const caddr_t addr) { caddr_t saddr, info; uintptr_t paddr; - - if (smbios.probed) - return; - smbios.probed = 1; + int maj_off; + int min_off; /* Search signatures and validate checksums. */ - saddr = smbios_sigsearch(addr ? addr : PTOV(SMBIOS_START), - SMBIOS_LENGTH); + saddr = addr != NULL ? smbios_sigsearch(addr, 1) : + smbios_sigsearch(PTOV(SMBIOS_START), SMBIOS_LENGTH); if (saddr == NULL) return; - smbios.length = SMBIOS_GET16(saddr, 0x16); /* Structure Table Length */ - paddr = SMBIOS_GET32(saddr, 0x18); /* Structure Table Address */ - smbios.count = SMBIOS_GET16(saddr, 0x1c); /* No of SMBIOS Structures */ - smbios.ver = SMBIOS_GET8(saddr, 0x1e); /* SMBIOS BCD Revision */ - - if (smbios.ver != 0) { - smbios.major = smbios.ver >> 4; - smbios.minor = smbios.ver & 0x0f; - if (smbios.major > 9 || smbios.minor > 9) - smbios.ver = 0; + if (smbios.is_64bit_ep) { + /* Structure Table Length */ + smbios.length = SMBIOS_GET32(saddr, 0x0c); + /* Structure Table Address */ + paddr = SMBIOS_GET64(saddr, 0x10); + /* Not present in V3, set it to the maximum value (no limit). */ + smbios.count = -1; + /* + * No BCD revision in V3, we'll determine the version thanks to + * the major and minor fields below. + */ + smbios.ver = 0; + maj_off = 0x07; + min_off = 0x08; + } else { + /* Structure Table Length */ + smbios.length = SMBIOS_GET16(saddr, 0x16); + /* Structure Table Address */ + paddr = SMBIOS_GET32(saddr, 0x18); + /* No. of SMBIOS Structures */ + smbios.count = SMBIOS_GET16(saddr, 0x1c); + /* SMBIOS BCD Revision */ + smbios.ver = SMBIOS_GET8(saddr, 0x1e); + if (smbios.ver != 0) { + smbios.major = smbios.ver >> 4; + smbios.minor = smbios.ver & 0x0f; + if (smbios.major > 9 || smbios.minor > 9) + smbios.ver = 0; + } + maj_off = 0x06; + min_off = 0x07; } + + if (smbios.ver == 0) { - smbios.major = SMBIOS_GET8(saddr, 0x06);/* SMBIOS Major Version */ - smbios.minor = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Minor Version */ + /* + * v3 table, or v2 with BCD revision being 0 or bad. Use the + * major and minor version fields. + */ + smbios.major = SMBIOS_GET8(saddr, maj_off); + smbios.minor = SMBIOS_GET8(saddr, min_off); } smbios.ver = (smbios.major << 8) | smbios.minor; smbios.addr = PTOV(paddr); @@ -482,7 +636,7 @@ smbios_probe(const caddr_t addr) } } -void +caddr_t smbios_detect(const caddr_t addr) { char buf[16]; @@ -491,12 +645,14 @@ smbios_detect(const caddr_t addr) smbios_probe(addr); if (smbios.addr == NULL) - return; + return (NULL); - for (dmi = smbios.addr, i = 0; - dmi < smbios.addr + smbios.length && i < smbios.count; i++) + for (dmi = smbios.addr, i = 0; dmi != NULL && + dmi < smbios.addr + smbios.length && i < smbios.count; i++) dmi = smbios_parse_table(dmi); + setenv("smbios.entry_point_type", smbios.is_64bit_ep ? + "v3 (64-bit)" : "v2.1 (32-bit)", 1); sprintf(buf, "%d.%d", smbios.major, smbios.minor); setenv("smbios.version", buf, 1); if (smbios.enabled_memory > 0 || smbios.old_enabled_memory > 0) { @@ -512,6 +668,8 @@ smbios_detect(const caddr_t addr) sprintf(buf, "%u", smbios.populated_sockets); setenv("smbios.socket.populated", buf, 1); } + + return (smbios.addr); } static int @@ -524,8 +682,21 @@ int smbios_match(const char* bios_vendor, const char* maker, const char* product) { - /* XXXRP currently, only called from non-EFI. */ - smbios_probe(NULL); + static bool probed = false; + + /* + * This routine is called only from non-EFI loaders on determining the + * amount of usable memory. In particular, it is so before malloc() can + * be used, so before smbios_detect() can be called (as it uses + * setenv()). Consequently, since smbios_probe() is not exported, we + * ensure it has been called beforehand to fetch into the static + * 'smbios' structure the metadata that is to be matched. + */ + if (!probed) { + probed = true; + smbios_probe(NULL); + } + return (smbios_match_str(bios_vendor, smbios.bios_vendor) && smbios_match_str(maker, smbios.maker) && smbios_match_str(product, smbios.product)); diff --git a/stand/libsa/smbios.h b/stand/libsa/smbios.h index 03fc07e29362..f3fd394ec7fc 100644 --- a/stand/libsa/smbios.h +++ b/stand/libsa/smbios.h @@ -22,13 +22,11 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _SMBIOS_H_ #define _SMBIOS_H_ -void smbios_detect(const caddr_t); +caddr_t smbios_detect(const caddr_t); int smbios_match(const char *, const char *, const char *); #endif /* _SMBIOS_H_ */ diff --git a/stand/libsa/splitfs.c b/stand/libsa/splitfs.c index af28704bc465..eb4b3a1feb11 100644 --- a/stand/libsa/splitfs.c +++ b/stand/libsa/splitfs.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" #define NTRIES (3) @@ -52,14 +49,15 @@ static off_t splitfs_seek(struct open_file *f, off_t offset, int where); static int splitfs_stat(struct open_file *f, struct stat *sb); struct fs_ops splitfs_fsops = { - "split", - splitfs_open, - splitfs_close, - splitfs_read, - null_write, - splitfs_seek, - splitfs_stat, - null_readdir + .fs_name = "split", + .fs_flags = 0, + .fo_open = splitfs_open, + .fo_close = splitfs_close, + .fo_read = splitfs_read, + .fo_write = null_write, + .fo_seek = splitfs_seek, + .fo_stat = splitfs_stat, + .fo_readdir = null_readdir, }; static void diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index 097d8ba28d0b..aaba0aa7fb39 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $ */ @@ -54,15 +52,12 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)stand.h 8.1 (Berkeley) 6/11/93 */ #ifndef STAND_H #define STAND_H #include <sys/types.h> -#include <sys/cdefs.h> #include <sys/stat.h> #include <sys/dirent.h> #include <sys/queue.h> @@ -87,11 +82,20 @@ #define EOFFSET (ELAST+8) /* relative seek not supported */ #define ESALAST (ELAST+8) /* */ -/* Partial signal emulation for sig_atomic_t */ -#include <machine/signal.h> +/* + * LUA needs sig_atomic_t. This is defined to be long or int on all our + * platforms. On all but powerpc, these are all the same thing as long. 64-bit + * powerpc defines this as int, but long can also be accessed atomically. It's + * also OK because we don't have signal handlers in the boot loader. + */ +typedef long sig_atomic_t; + +__BEGIN_DECLS struct open_file; +#define FS_OPS_NO_DEVOPEN 1 + /* * This structure is used to define file system operations in a file system * independent way. @@ -102,6 +106,7 @@ struct open_file; */ struct fs_ops { const char *fs_name; + int fs_flags; int (*fo_open)(const char *path, struct open_file *f); int (*fo_close)(struct open_file *f); int (*fo_read)(struct open_file *f, void *buf, @@ -139,9 +144,12 @@ extern struct fs_ops efihttp_fsops; /* * Device switch */ +#define DEV_NAMLEN 8 /* Length of name of device class */ +#define DEV_DEVLEN 128 /* Length of longest device instance name */ +struct devdesc; struct devsw { - const char dv_name[8]; - int dv_type; /* opaque type constant, arch-dependant */ + const char dv_name[DEV_NAMLEN]; + int dv_type; /* opaque type constant */ #define DEVT_NONE 0 #define DEVT_DISK 1 #define DEVT_NET 2 @@ -156,6 +164,9 @@ struct devsw { int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data); int (*dv_print)(int verbose); /* print device information */ void (*dv_cleanup)(void); + char * (*dv_fmtdev)(struct devdesc *); + int (*dv_parsedev)(struct devdesc **, const char *, const char **); + bool (*dv_match)(struct devsw *, const char *); }; /* @@ -166,9 +177,14 @@ extern struct devsw netdev; extern int errno; /* - * Generic device specifier; architecture-dependent - * versions may be larger, but should be allowed to - * overlap. + * Generic device specifier; architecture-dependent versions may be larger, but + * should be allowed to overlap. The larger device specifiers store more data + * than can fit in the generic one that's gleaned after parsing the device + * string, or used in some cases to indicate wildcards that match a variety of + * situations based on what's on the drive itself rather than what the progammer + * might know in advance. Information about open files is stored in d_opendata, + * though what's passed into the open routine may differ from what's present + * after the open on some configurations. */ struct devdesc { struct devsw *d_dev; @@ -176,6 +192,11 @@ struct devdesc { void *d_opendata; }; +char *devformat(struct devdesc *d); +int devparse(struct devdesc **, const char *, const char **); +int devinit(void); +void dev_cleanup(void); + struct open_file { int f_flags; /* see F_* below */ struct devsw *f_dev; /* pointer to device operations */ @@ -257,6 +278,11 @@ static __inline int ispunct(int c) (c >= '[' && c <= '`') || (c >= '{' && c <= '~'); } +static __inline int isprint(int c) +{ + return (c >= ' ') && (c <= '~'); +} + static __inline int toupper(int c) { return islower(c) ? c - 'a' + 'A' : c; @@ -300,6 +326,7 @@ extern int close(int); extern void closeall(void); extern ssize_t read(int, void *, size_t); extern ssize_t write(int, const void *, size_t); +extern int ioctl(int, u_long, void *); extern struct dirent *readdirfd(int); extern void preload(int); @@ -325,6 +352,7 @@ extern int pager_file(const char *fname); #define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */ #define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */ #define EV_NOHOOK (1<<2) /* don't call hook when setting */ +#define EV_NOKENV (1<<3) /* don't add to kenv (loader-only) */ struct env_var; typedef char *(ev_format_t)(struct env_var *ev); @@ -480,9 +508,56 @@ extern void *reallocf(void *, size_t); */ caddr_t ptov(uintptr_t); +/* dev_net.c */ +bool is_tftp(void); + +/* features.c */ +typedef void (feature_iter_fn)(void *, const char *, const char *, bool); + +extern void feature_enable(uint32_t); +extern bool feature_name_is_enabled(const char *); +extern void feature_iter(feature_iter_fn *, void *); + +/* + * Note that these should also be added to the mapping table in features.c, + * which the interpreter may query to provide details from. The name with + * FEATURE_ removed is assumed to be the name we'll provide in the loader + * features table, just to simplify reasoning about these. + */ +#define FEATURE_EARLY_ACPI 0x0001 + /* hexdump.c */ void hexdump(caddr_t region, size_t len); +/* nvstore.c */ +typedef int (nvstore_getter_cb_t)(void *, const char *, void **); +typedef int (nvstore_setter_cb_t)(void *, int, const char *, + const void *, size_t); +typedef int (nvstore_setter_str_cb_t)(void *, const char *, const char *, + const char *); +typedef int (nvstore_unset_cb_t)(void *, const char *); +typedef int (nvstore_print_cb_t)(void *, void *); +typedef int (nvstore_iterate_cb_t)(void *, int (*)(void *, void *)); + +typedef struct nvs_callbacks { + nvstore_getter_cb_t *nvs_getter; + nvstore_setter_cb_t *nvs_setter; + nvstore_setter_str_cb_t *nvs_setter_str; + nvstore_unset_cb_t *nvs_unset; + nvstore_print_cb_t *nvs_print; + nvstore_iterate_cb_t *nvs_iterate; +} nvs_callbacks_t; + +int nvstore_init(const char *, nvs_callbacks_t *, void *); +int nvstore_fini(const char *); +void *nvstore_get_store(const char *); +int nvstore_print(void *); +int nvstore_get_var(void *, const char *, void **); +int nvstore_set_var(void *, int, const char *, void *, size_t); +int nvstore_set_var_from_string(void *, const char *, const char *, + const char *); +int nvstore_unset_var(void *, const char *); + /* tslog.c */ #define TSRAW(a, b, c) tslog(a, b, c) #define TSENTER() TSRAW("ENTER", __func__, NULL) @@ -493,4 +568,19 @@ void tslog(const char *, const char *, const char *); void tslog_setbuf(void * buf, size_t len); void tslog_getbuf(void ** buf, size_t * len); +__END_DECLS + +/* define _DEBUG_LEVEL n or _DEBUG_LEVEL_VAR before include */ +#ifndef DEBUG_PRINTF +# if defined(_DEBUG_LEVEL) || defined(_DEBUG_LEVEL_VAR) +# ifndef _DEBUG_LEVEL_VAR +# define _DEBUG_LEVEL_VAR _debug +static int _debug = _DEBUG_LEVEL; +# endif +# define DEBUG_PRINTF(n, args) if (_DEBUG_LEVEL_VAR >= n) printf args +# else +# define DEBUG_PRINTF(n, args) +# endif +#endif + #endif /* STAND_H */ diff --git a/stand/libsa/stat.c b/stand/libsa/stat.c index f3b198955ab8..6d519a6e6f16 100644 --- a/stand/libsa/stat.c +++ b/stand/libsa/stat.c @@ -27,13 +27,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)stat.c 8.1 (Berkeley) 6/11/93 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" int diff --git a/stand/libsa/strcasecmp.c b/stand/libsa/strcasecmp.c index 12ec81b022c4..2dddac8e207e 100644 --- a/stand/libsa/strcasecmp.c +++ b/stand/libsa/strcasecmp.c @@ -27,16 +27,8 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/cdefs.h> -#include <string.h> #include "stand.h" - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ +#include <string.h> int strcasecmp(const char *s1, const char *s2) diff --git a/stand/libsa/strdup.c b/stand/libsa/strdup.c index ad7200c69850..739b161c1f01 100644 --- a/stand/libsa/strdup.c +++ b/stand/libsa/strdup.c @@ -27,13 +27,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include "stand.h" #include <stddef.h> #include <string.h> diff --git a/stand/libsa/strerror.c b/stand/libsa/strerror.c index e08ca0a7f175..219f652dec06 100644 --- a/stand/libsa/strerror.c +++ b/stand/libsa/strerror.c @@ -29,9 +29,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include "stand.h" static struct diff --git a/stand/libsa/tftp.c b/stand/libsa/tftp.c index c520a9e3b3b1..656c402683bb 100644 --- a/stand/libsa/tftp.c +++ b/stand/libsa/tftp.c @@ -31,9 +31,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Simple TFTP implementation for libsa. * Assumes: @@ -53,9 +50,12 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <arpa/tftp.h> +#ifdef LOADER_VERIEXEC +#include <verify_file.h> +#endif + #include <string.h> -#include <bootstrap.h> #include "stand.h" #include "net.h" #include "netif.h" @@ -77,6 +77,7 @@ static int tftp_preload(struct open_file *); struct fs_ops tftp_fsops = { .fs_name = "tftp", + .fs_flags = 0, .fo_open = tftp_open, .fo_close = tftp_close, .fo_read = tftp_read, @@ -88,7 +89,6 @@ struct fs_ops tftp_fsops = { }; static int tftpport = 2000; -static int is_open = 0; /* * The legacy TFTP_BLKSIZE value was SEGSIZE(512). @@ -102,13 +102,17 @@ static int is_open = 0; * Jumbo frames in the future. */ #define TFTP_MAX_BLKSIZE 9008 -#define TFTP_TRIES 2 +#define TFTP_TRIES 3 struct tftp_handle { struct iodesc *iodesc; + struct iodesc io; + int id; + ino_t ino; + int port; int currblock; /* contents of lastdata */ - int islastblock:1; /* flag */ - int tries:4; /* number of read attempts */ + unsigned int islastblock:1; /* flag */ + unsigned int tries:4; /* number of read attempts */ int validsize; int off; char *path; /* saved for re-requests */ @@ -181,6 +185,9 @@ tftp_sendack(struct tftp_handle *h, u_short block) wbuf.t.th_block = htons(block); wtail += 2; + DEBUG_PRINTF(5,("%s: myport=%hu xid=%lu, block=%hu\n", + __func__, h->iodesc->myport, h->iodesc->xid, block)); + sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } @@ -194,6 +201,7 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *ptr = NULL; ssize_t len; int tftp_error; + unsigned short block; errno = 0; extra = recv_extra; @@ -207,19 +215,22 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, } extra->rtype = ntohs(t->th_opcode); - switch (ntohs(t->th_opcode)) { + block = ntohs(t->th_block); + DEBUG_PRINTF(6,("%s: myport=%hu xid=%lu, block=%hu, opcode=%hu\n", + __func__, d->myport, d->xid, block, extra->rtype)); + switch (extra->rtype) { case DATA: { int got; - if (htons(t->th_block) < (u_short)d->xid) { + if (block < (u_short)d->xid) { /* * Apparently our ACK was missed, re-send. */ - tftp_sendack(h, htons(t->th_block)); + tftp_sendack(h, block); free(ptr); return (-1); } - if (htons(t->th_block) != (u_short)d->xid) { + if (block != (u_short)d->xid) { /* * Packet from the future, drop this. */ @@ -245,9 +256,7 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, printf("illegal tftp error %d\n", tftp_error); errno = EIO; } else { -#ifdef TFTP_DEBUG - printf("tftp-error %d\n", tftp_error); -#endif + DEBUG_PRINTF(0, ("tftp-error %d\n", tftp_error)); errno = tftperrors[tftp_error]; } free(ptr); @@ -288,9 +297,7 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, return (0); } default: -#ifdef TFTP_DEBUG - printf("tftp type %d not handled\n", ntohs(t->th_opcode)); -#endif + DEBUG_PRINTF(0, ("tftp type %hu not handled\n", extra->rtype)); free(ptr); return (-1); } @@ -347,7 +354,7 @@ tftp_makereq(struct tftp_handle *h) bcopy("0", wtail, 2); wtail += 2; - h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff)); + h->iodesc->myport = htons(h->port + (getsecs() & 0x3ff)); h->iodesc->destport = htons(IPPORT_TFTP); h->iodesc->xid = 1; /* expected block */ @@ -355,11 +362,15 @@ tftp_makereq(struct tftp_handle *h) h->islastblock = 0; h->validsize = 0; + DEBUG_PRINTF(5,("%s: %s: id=%d port=%d myport=%hu xid=1\n", + __func__, h->path, h->id, h->port, ntohs(h->iodesc->myport))); pkt = NULL; recv_extra.tftp_handle = h; res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t, &recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { + DEBUG_PRINTF(3,("%s: %s: id=%d errno=%d\n", + __func__, h->path, h->id, errno)); free(pkt); return (errno); } @@ -414,12 +425,18 @@ tftp_getnextblock(struct tftp_handle *h) h->iodesc->xid = h->currblock + 1; /* expected block */ + DEBUG_PRINTF(5,("%s: %s: id=%d port=%d myport=%hu xid=%lu\n", + __func__, h->path, h->id, h->port, + ntohs(h->iodesc->myport), h->iodesc->xid)); + pkt = NULL; recv_extra.tftp_handle = h; res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t, &recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { /* 0 is OK! */ + DEBUG_PRINTF(3,("%s: %s: id=%d errno=%d\n", + __func__, h->path, h->id, errno)); free(pkt); return (errno); } @@ -432,21 +449,32 @@ tftp_getnextblock(struct tftp_handle *h) if (res < h->tftp_blksize) h->islastblock = 1; /* EOF */ - if (h->islastblock == 1) { + DEBUG_PRINTF(5,("%s: %s: id=%d res=%d blksz=%d last=%d\n", + __func__, h->path, h->id, res, h->tftp_blksize, h->islastblock)); + + if (h->islastblock) { /* Send an ACK for the last block */ - wbuf.t.th_block = htons((u_short)h->currblock); - sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); + tftp_sendack(h, h->currblock); } return (0); } +/* + * If doing verification we need to handle multiple + * files at the same time. + */ +#define TOPEN_MAX 8 +static struct tftp_handle *handles[TOPEN_MAX]; + static int tftp_open(const char *path, struct open_file *f) { struct devdesc *dev; struct tftp_handle *tftpfile; struct iodesc *io; + static int lx = 0; + int i, x; int res; size_t pathsize; const char *extraslash; @@ -454,24 +482,39 @@ tftp_open(const char *path, struct open_file *f) if (netproto != NET_TFTP) return (EINVAL); - if (f->f_dev->dv_type != DEVT_NET) + if (f->f_dev == NULL || f->f_dev->dv_type != DEVT_NET) return (EINVAL); - if (is_open) + tftpfile = NULL; + for (x = lx + 1, i = 0; i < TOPEN_MAX; i++, x++) { + x %= TOPEN_MAX; + if (handles[x] == NULL) { + handles[x] = tftpfile = calloc(1, sizeof(*tftpfile)); + if (tftpfile == NULL) + return (ENOMEM); + /* id allows us to clear the slot on close */ + tftpfile->id = lx = x; + /* port ensures a different session with server */ + tftpfile->port = (tftpport + (x * tftpport)) & 0xffff; + DEBUG_PRINTF(1, ("%s(%s) id=%d port=%d\n", + __func__, path, tftpfile->id, tftpfile->port)); + break; + } + } + if (tftpfile == NULL) { + DEBUG_PRINTF(1, ("%s: EBUSY\n", __func__)); return (EBUSY); - - tftpfile = calloc(1, sizeof(*tftpfile)); - if (!tftpfile) - return (ENOMEM); - + } tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE; dev = f->f_devdata; - tftpfile->iodesc = io = socktodesc(*(int *)(dev->d_opendata)); + io = socktodesc(*(int *)(dev->d_opendata)); if (io == NULL) { free(tftpfile); return (EINVAL); } + memcpy(&tftpfile->io, io, sizeof(tftpfile->io)); + io = tftpfile->iodesc = &tftpfile->io; io->destip = rootip; tftpfile->off = 0; pathsize = (strlen(rootpath) + 1 + strlen(path) + 1) * sizeof(char); @@ -484,8 +527,11 @@ tftp_open(const char *path, struct open_file *f) extraslash = ""; else extraslash = "/"; - res = snprintf(tftpfile->path, pathsize, "%s%s%s", - rootpath, extraslash, path); + if (rootpath[0] == '/' && rootpath[1] == '\0' && path[0] == '/') + res = strlcpy(tftpfile->path, path, pathsize); + else + res = snprintf(tftpfile->path, pathsize, "%s%s%s", + rootpath, extraslash, path); if (res < 0 || res > pathsize) { free(tftpfile->path); free(tftpfile); @@ -495,13 +541,13 @@ tftp_open(const char *path, struct open_file *f) res = tftp_makereq(tftpfile); if (res) { + handles[tftpfile->id] = NULL; free(tftpfile->path); free(tftpfile->pkt); free(tftpfile); return (res); } f->f_fsdata = tftpfile; - is_open = 1; return (0); } @@ -551,9 +597,7 @@ tftp_read(struct open_file *f, void *addr, size_t size, rc = tftp_getnextblock(tftpfile); if (rc) { /* no answer */ -#ifdef TFTP_DEBUG - printf("tftp: read error\n"); -#endif + DEBUG_PRINTF(0, ("tftp: read error\n")); if (tftpfile->tries > TFTP_TRIES) { return (rc); } else { @@ -572,10 +616,8 @@ tftp_read(struct open_file *f, void *addr, size_t size, inbuffer = tftpfile->validsize - offinblock; if (inbuffer < 0) { -#ifdef TFTP_DEBUG - printf("tftp: invalid offset %d\n", - tftpfile->off); -#endif + DEBUG_PRINTF(0, ("tftp: invalid offset %d\n", + tftpfile->off)); return (EINVAL); } count = (size < inbuffer ? size : inbuffer); @@ -590,15 +632,15 @@ tftp_read(struct open_file *f, void *addr, size_t size, if ((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ } else { -#ifdef TFTP_DEBUG - printf("tftp: block %d not found\n", needblock); -#endif + DEBUG_PRINTF(0, ("tftp: block %d not found\n", needblock)); return (EINVAL); } } out: + DEBUG_PRINTF(4, ("%s(%s) res=%ld\n", __func__, tftpfile->path, + (tftpfile->tftp_tsize - tftpfile->off))); if (resid != NULL) *resid = res; return (rc); @@ -614,15 +656,18 @@ tftp_close(struct open_file *f) tftp_senderr(tftpfile, 0, "No error: file closed"); if (tftpfile) { + DEBUG_PRINTF(1, ("%s(%d): %s\n", __func__, + tftpfile->id, tftpfile->path)); + handles[tftpfile->id] = NULL; free(tftpfile->path); free(tftpfile->pkt); free(tftpfile->tftp_cache); free(tftpfile); } - is_open = 0; return (0); } + static int tftp_stat(struct open_file *f, struct stat *sb) { @@ -634,6 +679,29 @@ tftp_stat(struct open_file *f, struct stat *sb) sb->st_uid = 0; sb->st_gid = 0; sb->st_size = tftpfile->tftp_tsize; + sb->st_mtime = 0; +#ifdef LOADER_VERIEXEC + /* libsecureboot needs st_dev and st_ino at minimum; + * we need to fake something that will be close enough to + * unique. + */ + sb->st_dev = (dev_t)tftpfile->iodesc->destip.s_addr; + /* we don't want to compute this more than once */ + if (tftpfile->ino == 0) { + union { + unsigned char digest[SHA_DIGEST_LENGTH]; + ino_t ino; + } u; + + hash_string(tftpfile->path, 0, u.digest, sizeof(u.digest)); + + tftpfile->ino = u.ino & 0x7fffffff; + DEBUG_PRINTF(2,("%s(%s) dev=%lu ino=%lu\n", __func__, + tftpfile->path, (unsigned long)sb->st_dev, + (unsigned long)tftpfile->ino)); + } + sb->st_ino = tftpfile->ino; +#endif return (0); } @@ -831,9 +899,7 @@ tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) return (-1); } -#ifdef TFTP_DEBUG - printf("tftp_blksize: %u\n", h->tftp_blksize); - printf("tftp_tsize: %lu\n", h->tftp_tsize); -#endif + DEBUG_PRINTF(2, ("tftp_blksize: %u\n", h->tftp_blksize)); + DEBUG_PRINTF(2, ("tftp_tsize: %lu\n", h->tftp_tsize)); return (0); } diff --git a/stand/libsa/tftp.h b/stand/libsa/tftp.h index c56fb81aafaa..2354f048ac9a 100644 --- a/stand/libsa/tftp.h +++ b/stand/libsa/tftp.h @@ -29,8 +29,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ diff --git a/stand/libsa/time.c b/stand/libsa/time.c index c34cbfc92af1..7f33b137bd07 100644 --- a/stand/libsa/time.c +++ b/stand/libsa/time.c @@ -27,9 +27,6 @@ * The parts of kern_tc.c and other timekeeping bits of the kernel. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/time.h> volatile time_t time_second = 1; diff --git a/stand/libsa/tslog.c b/stand/libsa/tslog.c index a2791f9dc9c4..7a92ee6c23f3 100644 --- a/stand/libsa/tslog.c +++ b/stand/libsa/tslog.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #if defined(__amd64__) || defined(__i386__) diff --git a/stand/libsa/twiddle.c b/stand/libsa/twiddle.c index 60022e4c8167..9ecfbeac3389 100644 --- a/stand/libsa/twiddle.c +++ b/stand/libsa/twiddle.c @@ -30,13 +30,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include "stand.h" diff --git a/stand/libsa/udp.c b/stand/libsa/udp.c index e531627e0577..a0a662a19976 100644 --- a/stand/libsa/udp.c +++ b/stand/libsa/udp.c @@ -31,13 +31,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/socket.h> diff --git a/stand/libsa/ufs.c b/stand/libsa/ufs.c index 12703a3e18aa..868e8d47dbbd 100644 --- a/stand/libsa/ufs.c +++ b/stand/libsa/ufs.c @@ -67,9 +67,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Stand-alone file reading package. */ @@ -81,7 +78,6 @@ __FBSDID("$FreeBSD$"); #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> #include "stand.h" -#include "disk.h" #include "string.h" static int ufs_open(const char *path, struct open_file *f); @@ -97,6 +93,7 @@ static int ufs_unmount(const char *dev, void *data); struct fs_ops ufs_fsops = { .fs_name = "ufs", + .fs_flags = 0, .fo_open = ufs_open, .fo_close = ufs_close, .fo_read = ufs_read, @@ -114,10 +111,7 @@ struct fs_ops ufs_fsops = { struct file { off_t f_seekp; /* seek pointer */ struct fs *f_fs; /* pointer to super-block */ - union dinode { - struct ufs1_dinode di1; - struct ufs2_dinode di2; - } f_di; /* copy of on-disk inode */ + union dinode f_dp; /* copy of on-disk inode */ int f_nindir[UFS_NIADDR]; /* number of blocks mapped by indirect block at level i */ @@ -133,7 +127,7 @@ struct file { }; #define DIP(fp, field) \ ((fp)->f_fs->fs_magic == FS_UFS1_MAGIC ? \ - (fp)->f_di.di1.field : (fp)->f_di.di2.field) + (fp)->f_dp.dp1.field : (fp)->f_dp.dp2.field) typedef struct ufs_mnt { char *um_dev; @@ -152,7 +146,10 @@ static int search_directory(char *, struct open_file *, ino_t *); static int ufs_use_sa_read(void *, off_t, void **, int); /* from ffs_subr.c */ -int ffs_sbget(void *, struct fs **, off_t, char *, +int ffs_sbget(void *devfd, struct fs **fsp, off_t sblock, int flags, + char *filltype, + int (*readfunc)(void *devfd, off_t loc, void **bufp, int size)); +int ffs_sbsearch(void *, struct fs **, int, char *, int (*)(void *, off_t, void **, int)); /* @@ -186,10 +183,10 @@ read_inode(ino_t inumber, struct open_file *f) } if (fp->f_fs->fs_magic == FS_UFS1_MAGIC) - fp->f_di.di1 = ((struct ufs1_dinode *)buf) + fp->f_dp.dp1 = ((struct ufs1_dinode *)buf) [ino_to_fsbo(fs, inumber)]; else - fp->f_di.di2 = ((struct ufs2_dinode *)buf) + fp->f_dp.dp2 = ((struct ufs2_dinode *)buf) [ino_to_fsbo(fs, inumber)]; /* @@ -407,7 +404,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p) block_size = sblksize(fs, DIP(fp, di_size), file_block); if (file_block != fp->f_buf_blkno) { - if (fp->f_buf == (char *)0) + if (fp->f_buf == NULL) fp->f_buf = malloc(fs->fs_bsize); rc = block_map(f, file_block, &disk_block); @@ -520,7 +517,7 @@ ufs_open(const char *upath, struct open_file *f) return (errno); f->f_fsdata = (void *)fp; - dev = disk_fmtdev(f->f_devdata); + dev = devformat((struct devdesc *)f->f_devdata); /* Is this device mounted? */ STAILQ_FOREACH(mnt, &mnt_list, um_link) { if (strcmp(dev, mnt->um_dev) == 0) @@ -530,8 +527,8 @@ ufs_open(const char *upath, struct open_file *f) if (mnt == NULL) { /* read super block */ twiddle(1); - if ((rc = ffs_sbget(f, &fs, STDSB_NOHASHFAIL, "stand", - ufs_use_sa_read)) != 0) { + if ((rc = ffs_sbget(f, &fs, UFS_STDSB, UFS_NOHASHFAIL, "stand", + ufs_use_sa_read)) != 0) { goto out; } } else { @@ -739,7 +736,7 @@ ufs_close(struct open_file *f) } free(fp->f_buf); - dev = disk_fmtdev(f->f_devdata); + dev = devformat((struct devdesc *)f->f_devdata); STAILQ_FOREACH(mnt, &mnt_list, um_link) { if (strcmp(dev, mnt->um_dev) == 0) break; @@ -886,16 +883,23 @@ ufs_readdir(struct open_file *f, struct dirent *d) /* * assume that a directory entry will not be split across blocks */ -again: - if (fp->f_seekp >= DIP(fp, di_size)) - return (ENOENT); - error = buf_read_file(f, &buf, &buf_size); - if (error) - return (error); - dp = (struct direct *)buf; - fp->f_seekp += dp->d_reclen; - if (dp->d_ino == (ino_t)0) - goto again; + + do { + if (fp->f_seekp >= DIP(fp, di_size)) + return (ENOENT); + error = buf_read_file(f, &buf, &buf_size); + if (error) + return (error); + dp = (struct direct *)buf; + /* + * Check for corrupt directory entry and bail out rather + * than spin forever hoping that the user has other options. + */ + if (dp->d_reclen == 0) + return (0); + fp->f_seekp += dp->d_reclen; + } while (dp->d_ino == (ino_t)0); + d->d_type = dp->d_type; strcpy(d->d_name, dp->d_name); return (0); diff --git a/stand/libsa/ufsread.c b/stand/libsa/ufsread.c index bd9ad2c57103..86ac8fbbbab7 100644 --- a/stand/libsa/ufsread.c +++ b/stand/libsa/ufsread.c @@ -43,9 +43,6 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> @@ -111,6 +108,13 @@ fsfind(const char *name, ufs_ino_t * ino) *ino = d.d_ino; return d.d_type; } + /* + * Check for corrupt directory entry and bail out + * rather than spin forever hoping that the user + * has other options. + */ + if (d.d_reclen == 0) + return 0; s += d.d_reclen; } if (n != -1 && ls) diff --git a/stand/libsa/uuid_from_string.c b/stand/libsa/uuid_from_string.c index b28e204b2739..bdb43f30a2cb 100644 --- a/stand/libsa/uuid_from_string.c +++ b/stand/libsa/uuid_from_string.c @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/libsa/uuid_to_string.c b/stand/libsa/uuid_to_string.c index 68d3d73515dd..cb9254fadaee 100644 --- a/stand/libsa/uuid_to_string.c +++ b/stand/libsa/uuid_to_string.c @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ diff --git a/stand/libsa/write.c b/stand/libsa/write.c index db82d7eaf4f6..06b9bfc63ac2 100644 --- a/stand/libsa/write.c +++ b/stand/libsa/write.c @@ -31,8 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)write.c 8.1 (Berkeley) 6/11/93 - * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. @@ -60,9 +58,6 @@ * rights to redistribute these changes. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include "stand.h" diff --git a/stand/libsa/x86/hypervisor.c b/stand/libsa/x86/hypervisor.c index 8061a6386630..dc153c23c40a 100644 --- a/stand/libsa/x86/hypervisor.c +++ b/stand/libsa/x86/hypervisor.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> diff --git a/stand/libsa/xlocale_private.h b/stand/libsa/xlocale_private.h index 074aca692550..7a125e2dda11 100644 --- a/stand/libsa/xlocale_private.h +++ b/stand/libsa/xlocale_private.h @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef STAND_XLOCALE_PRIVATE_H diff --git a/stand/libsa/zalloc.c b/stand/libsa/zalloc.c index 851cdfbd563d..98738cf1f357 100644 --- a/stand/libsa/zalloc.c +++ b/stand/libsa/zalloc.c @@ -27,9 +27,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> /* diff --git a/stand/libsa/zalloc_defs.h b/stand/libsa/zalloc_defs.h index 66f943549340..74ead9f997a2 100644 --- a/stand/libsa/zalloc_defs.h +++ b/stand/libsa/zalloc_defs.h @@ -25,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/libsa/zalloc_malloc.c b/stand/libsa/zalloc_malloc.c index 215e07d34a84..ad7984a60046 100644 --- a/stand/libsa/zalloc_malloc.c +++ b/stand/libsa/zalloc_malloc.c @@ -27,9 +27,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk */ diff --git a/stand/libsa/zalloc_mem.h b/stand/libsa/zalloc_mem.h index 5a6854105974..6c79b538757a 100644 --- a/stand/libsa/zalloc_mem.h +++ b/stand/libsa/zalloc_mem.h @@ -25,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/libsa/zalloc_protos.h b/stand/libsa/zalloc_protos.h index d129a64f2993..71f29c5fd3fe 100644 --- a/stand/libsa/zalloc_protos.h +++ b/stand/libsa/zalloc_protos.h @@ -25,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _ZALLOC_PROTOS_H diff --git a/stand/libsa/zfs/Makefile.inc b/stand/libsa/zfs/Makefile.inc index 2a06db0d2f5d..2e9d5679f71f 100644 --- a/stand/libsa/zfs/Makefile.inc +++ b/stand/libsa/zfs/Makefile.inc @@ -1,96 +1,84 @@ -# $FreeBSD$ - .PATH: ${ZFSSRC} .PATH: ${SYSDIR}/crypto/skein .PATH: ${ZFSOSSRC}/spl +.PATH: ${OZFS}/module/zstd .PATH: ${OZFS}/module/zstd/lib/common .PATH: ${OZFS}/module/zstd/lib/compress .PATH: ${OZFS}/module/zstd/lib/decompress -ZFSSRC= zfs.c nvlist.c skein.c skein_block.c list.c -ZFSSRC+= zstd_shim.c -ZFSSRC+= entropy_common.c error_private.c -ZFSSRC+= fse_compress.c fse_decompress.c hist.c -ZFSSRC+= huf_compress.c huf_decompress.c pool.c xxhash.c -ZFSSRC+= zstd_common.c zstd_compress.c zstd_compress_literals.c -ZFSSRC+= zstd_compress_sequences.c zstd_compress_superblock.c -ZFSSRC+= zstd_ddict.c zstd_decompress.c zstd_decompress_block.c -ZFSSRC+= zstd_double_fast.c zstd_fast.c zstd_lazy.c zstd_ldm.c -ZFSSRC+= zstd_opt.c +.PATH: ${OZFS}/module/icp/asm-aarch64/blake3 +.PATH: ${OZFS}/module/icp/algs/blake3 +ZFS_SRC= zfs.c nvlist.c skein.c skein_block.c list.c +ZFS_SRC+= zfs_zstd.c +ZFS_SRC+= blake3.c blake3_generic.c blake3_impl.c +ZSTD_SRC+= entropy_common.c error_private.c +ZSTD_SRC+= fse_decompress.c hist.c +ZSTD_SRC+= huf_decompress.c pool.c xxhash.c +ZSTD_SRC+= zstd_common.c +ZSTD_SRC+= zstd_ddict.c zstd_decompress.c zstd_decompress_block.c +ZSTD_SRC+= zstd_double_fast.c zstd_fast.c zstd_lazy.c zstd_ldm.c -CFLAGS+= -DHAS_ZSTD_ZFS -SRCS+= ${ZFSSRC} +SRCS+= ${ZFS_SRC} ${ZSTD_SRC} ${ZFS_SRC_AS} -CFLAGS+= -I${LDRSRC} -CFLAGS+= -I${SYSDIR}/cddl/boot/zfs -CFLAGS+= -I${SYSDIR}/crypto/skein +# +# Any file that needs the FreeBSD overrides that are in +# include/os/freebssd/spl/XXX needs to have these added to +# CFLAGS_EARLY.file.c. In general, we try to build out of the OpenZFS tree +# unaltered. There's a problem, though, that since we're building for a +# standalone environment that's neither userland nor kernel, we sometimes need +# special code and that's handled by the 'nested' includes where we either setup +# something just-so before we include the include/XXX file, or if we need to +# tweak something defined in that file. +# -ZFS_EARLY= -I${ZFSOSINC} \ +ZFS_EARLY= -I${ZFSSRC}/spl \ + -I${ZFSOSINC} \ -I${ZFSOSINC}/spl \ -I${ZFSOSINC}/zfs -.for i in ${ZFSSRC} -CFLAGS.$i+= -include ${ZFSOSINC}/spl/sys/ccompile.h +# +# For all files, though, we prepend the sys/ccompile.h file to the build which +# has a bunch of defines that are present in OpenSolaris / Illumos, but missing +# from FreeBSD. +# +.for i in ${ZFS_SRC} ${ZSTD_SRC} +CFLAGS.$i+= -include ${ZFSOSINC}/spl/sys/ccompile.h -Wformat -Wall -I${OZFS}/include \ + -DNEED_SOLARIS_BOOLEAN .endfor +CFLAGS_EARLY.blake3.c+= ${ZFS_EARLY} -DOMIT_SIMD +CFLAGS_EARLY.blake3_generic.c+= ${ZFS_EARLY} -DOMIT_SIMD +CFLAGS_EARLY.blake3_impl.c+= ${ZFS_EARLY} -DOMIT_SIMD CFLAGS_EARLY.list.c+= ${ZFS_EARLY} -CFLAGS_EARLY.zstd_shim.c+= ${ZFS_EARLY} +CFLAGS_EARLY.zfs_zstd.c+= ${ZFS_EARLY} +CFLAGS_EARLY.nvlist.c+= ${ZFS_EARLY} +CFLAGS_EARLY.zfs.c += ${ZFS_EARLY} -# Can't use the early flags because there's two conflicting definitions of boolean_t in -# the zfs code that need to be unified. -CFLAGS.nvlist.c+= -I${ZFSOSINC}/spl -CFLAGS.zfs.c+= -I${ZFSOSINC}/spl \ +# +# zfs.c is special: we need to define HAS_ZSTD_ZFS to get zfssubr.c to initialize zstd +# properly. We need to have the cddl boot compat directory in the include path for zfssubr.c +# to be found, and we need a couple of other include paths for skein and lz4. Finally we +# temporarily need LDRSRC to pick up part.h until libsa has a way to look into partitions +# or enumerate them... +# +CFLAGS.zfs.c+= -DHAS_ZSTD_ZFS \ + -I${SYSDIR}/cddl/boot/zfs \ + -I${LDRSRC} \ + -I${SYSDIR}/crypto/skein \ -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 -CFLAGS.entropy_common.c= -U__BMI__ -CFLAGS.entropy_common.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.error_private.c= -U__BMI__ -CFLAGS.error_private.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.fse_compress.c= -U__BMI__ -CFLAGS.fse_compress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.fse_decompress.c= -U__BMI__ -CFLAGS.fse_decompress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.hist.c= -U__BMI__ -CFLAGS.hist.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.huf_compress.c= -U__BMI__ -CFLAGS.huf_compress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.huf_decompress.c= -U__BMI__ -CFLAGS.huf_decompress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.pool.c= -U__BMI__ -CFLAGS.pool.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.xxhash.c= -U__BMI__ -CFLAGS.xxhash.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_common.c= -U__BMI__ -CFLAGS.zstd_common.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_compress.c= -U__BMI__ -CFLAGS.zstd_compress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_compress_literals.c= -U__BMI__ -CFLAGS.zstd_compress_literals.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_compress_sequences.c= -U__BMI__ -CFLAGS.zstd_compress_sequences.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_compress_superblock.c= -U__BMI__ -CFLAGS.zstd_compress_superblock.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_double_fast.c= -U__BMI__ -CFLAGS.zstd_double_fast.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_fast.c= -U__BMI__ -CFLAGS.zstd_fast.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_lazy.c= -U__BMI__ -CFLAGS.zstd_lazy.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_ldm.c= -U__BMI__ -CFLAGS.zstd_ldm.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_opt.c= -U__BMI__ -CFLAGS.zstd_opt.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_ddict.c= -U__BMI__ -CFLAGS.zstd_ddict.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_decompress.c= -U__BMI__ -CFLAGS.zstd_decompress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_decompress_block.c= -U__BMI__ -CFLAGS.zstd_decompress_block.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL} -CFLAGS.zstd_shim.c+= -DIN_BASE -DIN_LIBSA -I${OZFS}/include + +# +# ZSTD coding style has some issues, so suppress clang's warnings. Also, zstd's +# use of BMI instrucitons is broken in this environment, so avoid them. +# +.for i in ${ZSTD_SRC} +CFLAGS.$i+= -U__BMI__ ${NO_WBITWISE_INSTEAD_OF_LOGICAL} +.endfor + +CFLAGS.zfs_zstd.c+= -DIN_BASE -DIN_LIBSA + +CFLAGS.blake3_impl.c+= -I${OZFS}/module/icp/algs/blake3 -I${OZFS}/module/icp/include -DIN_LIBSA # Do not unroll skein loops, reduce code size CFLAGS.skein_block.c+= -DSKEIN_LOOP=111 -CFLAGS+= -I${SYSDIR}/contrib/openzfs/include -CFLAGS+= -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs -CFLAGS.zfs.c+= -I${SYSDIR}/cddl/contrib/opensolaris/common/lz4 - -CFLAGS+= -Wformat -Wall +CWARNFLAGS.zfs.c+= ${NO_WDANGLING_POINTER} diff --git a/stand/libsa/zfs/libzfs.h b/stand/libsa/zfs/libzfs.h index e8676c0d53b8..35af864e7e0b 100644 --- a/stand/libsa/zfs/libzfs.h +++ b/stand/libsa/zfs/libzfs.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef _BOOT_LIBZFS_H_ @@ -48,10 +46,8 @@ struct zfs_devdesc { uint64_t root_guid; }; -int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, - const char **path); -char *zfs_fmtdev(void *vdev); -int zfs_probe_dev(const char *devname, uint64_t *pool_guid); +char *zfs_fmtdev(struct devdesc *); +int zfs_probe_dev(const char *devname, uint64_t *pool_guid, bool part_too); int zfs_list(const char *name); int zfs_get_bootonce(void *, const char *, char *, size_t); int zfs_get_bootenv(void *, nvlist_t **); diff --git a/stand/libsa/zfs/nvlist.c b/stand/libsa/zfs/nvlist.c index e5e0abecb274..6cb496a57b26 100644 --- a/stand/libsa/zfs/nvlist.c +++ b/stand/libsa/zfs/nvlist.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/endian.h> #include <sys/stdint.h> diff --git a/stand/libsa/zfs/spl/sys/blake3.h b/stand/libsa/zfs/spl/sys/blake3.h new file mode 100644 index 000000000000..aa2d3b7e55cc --- /dev/null +++ b/stand/libsa/zfs/spl/sys/blake3.h @@ -0,0 +1,17 @@ +/* + * Copyright 2022, Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +/* + * Gross and ugly hack to cope with upstream's sys/blake3.h not being standalone + * safe. + */ +#define _KERNEL + +#include_next <sys/blake3.h> + +#undef _KERNEL diff --git a/stand/libsa/zfs/spl/sys/zfs_context.h b/stand/libsa/zfs/spl/sys/zfs_context.h new file mode 100644 index 000000000000..9f12955dd05f --- /dev/null +++ b/stand/libsa/zfs/spl/sys/zfs_context.h @@ -0,0 +1,32 @@ +/* + * Copyright 2022, Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +/* TODO: openzfs/include/sys/uio_impl.h must not be included in stand */ +#ifndef _SYS_UIO_IMPL_H +#define _SYS_UIO_IMPL_H +#endif + +/* + * sys/atomic.h must be included after sys/sysmacros.h. The latter includes + * machine/atomic.h, which interferes. Sadly, upstream includes them in the + * wrong order, so we include it here to fix that. + */ +#include <sys/sysmacros.h> + +#include_next <sys/zfs_context.h> + +#define SYSCTL_HANDLER_ARGS void + +/* + * Not sure why I need these, but including the canonical stand.h fails because + * the normal string.h doesn't like all the other shenanigans in this environment. + */ +void *memcpy(void *dst, const void *src, size_t len); +void *memset(void *dest, int c, size_t len); +void *memmem(const void *big, size_t big_len, const void *little, + size_t little_len); diff --git a/stand/libsa/zfs/zfs.c b/stand/libsa/zfs/zfs.c index 633ef3b18784..70a102f6425d 100644 --- a/stand/libsa/zfs/zfs.c +++ b/stand/libsa/zfs/zfs.c @@ -22,13 +22,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Stand-alone file reading package. */ @@ -66,6 +61,9 @@ static void zfs_bootenv_initial(const char *envname, spa_t *spa, static void zfs_checkpoints_initial(spa_t *spa, const char *name, const char *dsname); +static int zfs_parsedev(struct devdesc **idev, const char *devspec, + const char **path); + struct devsw zfs_dev; struct fs_ops zfs_fsops = { @@ -108,7 +106,8 @@ struct zfs_be_entry { static int zfs_open(const char *upath, struct open_file *f) { - struct zfsmount *mount = (struct zfsmount *)f->f_devdata; + struct devdesc *dev = f->f_devdata; + struct zfsmount *mount = dev->d_opendata; struct file *fp; int rc; @@ -149,7 +148,8 @@ zfs_close(struct open_file *f) static int zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */) { - const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; + struct devdesc *dev = f->f_devdata; + const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa; struct file *fp = (struct file *)f->f_fsdata; struct stat sb; size_t n; @@ -213,7 +213,8 @@ zfs_seek(struct open_file *f, off_t offset, int where) static int zfs_stat(struct open_file *f, struct stat *sb) { - const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; + struct devdesc *dev = f->f_devdata; + const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa; struct file *fp = (struct file *)f->f_fsdata; return (zfs_dnode_stat(spa, &fp->f_dnode, sb)); @@ -222,7 +223,8 @@ zfs_stat(struct open_file *f, struct stat *sb) static int zfs_readdir(struct open_file *f, struct dirent *d) { - const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; + struct devdesc *dev = f->f_devdata; + const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa; struct file *fp = (struct file *)f->f_fsdata; mzap_ent_phys_t mze; struct stat sb; @@ -366,59 +368,77 @@ zfs_readdir(struct open_file *f, struct dirent *d) } } +static spa_t * +spa_find_by_dev(struct zfs_devdesc *dev) +{ + + if (dev->dd.d_dev->dv_type != DEVT_ZFS) + return (NULL); + + if (dev->pool_guid == 0) + return (STAILQ_FIRST(&zfs_pools)); + + return (spa_find_by_guid(dev->pool_guid)); +} + /* * if path is NULL, create mount structure, but do not add it to list. */ static int zfs_mount(const char *dev, const char *path, void **data) { - struct zfs_devdesc *zfsdev; + struct zfs_devdesc *zfsdev = NULL; spa_t *spa; - struct zfsmount *mnt; + struct zfsmount *mnt = NULL; int rv; errno = 0; - zfsdev = malloc(sizeof(*zfsdev)); - if (zfsdev == NULL) - return (errno); - - rv = zfs_parsedev(zfsdev, dev + 3, NULL); + rv = zfs_parsedev((struct devdesc **)&zfsdev, dev, NULL); if (rv != 0) { - free(zfsdev); return (rv); } spa = spa_find_by_dev(zfsdev); - if (spa == NULL) - return (ENXIO); + if (spa == NULL) { + rv = ENXIO; + goto err; + } mnt = calloc(1, sizeof(*mnt)); - if (mnt != NULL && path != NULL) + if (mnt == NULL) { + rv = ENOMEM; + goto err; + } + + if (mnt->path != NULL) { mnt->path = strdup(path); - rv = errno; + if (mnt->path == NULL) { + rv = ENOMEM; + goto err; + } + } - if (mnt != NULL) - rv = zfs_mount_impl(spa, zfsdev->root_guid, mnt); - free(zfsdev); + rv = zfs_mount_impl(spa, zfsdev->root_guid, mnt); - if (rv == 0 && mnt != NULL && mnt->objset.os_type != DMU_OST_ZFS) { + if (rv == 0 && mnt->objset.os_type != DMU_OST_ZFS) { printf("Unexpected object set type %ju\n", (uintmax_t)mnt->objset.os_type); rv = EIO; } - +err: if (rv != 0) { if (mnt != NULL) free(mnt->path); free(mnt); + free(zfsdev); return (rv); } - if (mnt != NULL) { - *data = mnt; - if (path != NULL) - STAILQ_INSERT_TAIL(&zfsmount, mnt, next); - } + *data = mnt; + if (path != NULL) + STAILQ_INSERT_TAIL(&zfsmount, mnt, next); + + free(zfsdev); return (rv); } @@ -773,35 +793,12 @@ zfs_probe_partition(void *arg, const char *partname, int zfs_get_bootenv(void *vdev, nvlist_t **benvp) { - struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; - nvlist_t *benv = NULL; - vdev_t *vd; spa_t *spa; - if (dev->dd.d_dev->dv_type != DEVT_ZFS) - return (ENOTSUP); - - if ((spa = spa_find_by_dev(dev)) == NULL) + if ((spa = spa_find_by_dev((struct zfs_devdesc *)vdev)) == NULL) return (ENXIO); - if (spa->spa_bootenv == NULL) { - STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, - v_childlink) { - benv = vdev_read_bootenv(vd); - - if (benv != NULL) - break; - } - spa->spa_bootenv = benv; - } else { - benv = spa->spa_bootenv; - } - - if (benv == NULL) - return (ENOENT); - - *benvp = benv; - return (0); + return (zfs_get_bootenv_spa(spa, benvp)); } /* @@ -810,22 +807,12 @@ zfs_get_bootenv(void *vdev, nvlist_t **benvp) int zfs_set_bootenv(void *vdev, nvlist_t *benv) { - struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; - vdev_t *vd; - if (dev->dd.d_dev->dv_type != DEVT_ZFS) - return (ENOTSUP); - - if ((spa = spa_find_by_dev(dev)) == NULL) + if ((spa = spa_find_by_dev((struct zfs_devdesc *)vdev)) == NULL) return (ENXIO); - STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, v_childlink) { - vdev_write_bootenv(vd, benv); - } - - spa->spa_bootenv = benv; - return (0); + return (zfs_set_bootenv_spa(spa, benv)); } /* @@ -835,27 +822,12 @@ zfs_set_bootenv(void *vdev, nvlist_t *benv) int zfs_get_bootonce(void *vdev, const char *key, char *buf, size_t size) { - nvlist_t *benv; - char *result = NULL; - int result_size, rv; - - if ((rv = zfs_get_bootenv(vdev, &benv)) != 0) - return (rv); + spa_t *spa; - if ((rv = nvlist_find(benv, key, DATA_TYPE_STRING, NULL, - &result, &result_size)) == 0) { - if (result_size == 0) { - /* ignore empty string */ - rv = ENOENT; - } else { - size = MIN((size_t)result_size + 1, size); - strlcpy(buf, result, size); - } - (void) nvlist_remove(benv, key, DATA_TYPE_STRING); - (void) zfs_set_bootenv(vdev, benv); - } + if ((spa = spa_find_by_dev((struct zfs_devdesc *)vdev)) == NULL) + return (ENXIO); - return (rv); + return (zfs_get_bootonce_spa(spa, key, buf, size)); } /* @@ -1292,8 +1264,12 @@ zfs_nvstore_unset_impl(void *vdev, const char *name, bool unset_env) rv = zfs_set_bootenv(vdev, spa->spa_bootenv); } - if (unset_env) - env_discard(env_getenv(name)); + if (unset_env) { + struct env_var *ev = env_getenv(name); + + if (ev != NULL) + env_discard(ev); + } return (rv); } @@ -1490,7 +1466,7 @@ zfs_attach_nvstore(void *vdev) } int -zfs_probe_dev(const char *devname, uint64_t *pool_guid) +zfs_probe_dev(const char *devname, uint64_t *pool_guid, bool parts_too) { struct ptable *table; struct zfs_probe_args pa; @@ -1506,6 +1482,8 @@ zfs_probe_dev(const char *devname, uint64_t *pool_guid) ret = zfs_probe(pa.fd, pool_guid); if (ret == 0) return (0); + if (!parts_too) + return (ENXIO); /* Probe each partition */ ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz); @@ -1583,11 +1561,10 @@ zfs_dev_open(struct open_file *f, ...) rv = 0; /* This device is not set as currdev, mount us private copy. */ if (mount == NULL) - rv = zfs_mount(zfs_fmtdev(dev), NULL, (void **)&mount); + rv = zfs_mount(devformat(&dev->dd), NULL, (void **)&mount); if (rv == 0) { - f->f_devdata = mount; - free(dev); + dev->dd.d_opendata = mount; } return (rv); } @@ -1595,25 +1572,18 @@ zfs_dev_open(struct open_file *f, ...) static int zfs_dev_close(struct open_file *f) { + struct devdesc *dev; struct zfsmount *mnt, *mount; - mnt = f->f_devdata; + dev = f->f_devdata; + mnt = dev->d_opendata; STAILQ_FOREACH(mount, &zfsmount, next) { if (mnt->spa->spa_guid == mount->spa->spa_guid) break; } - /* - * devclose() will free f->f_devdata, but since we do have - * pointer to zfsmount structure in f->f_devdata, and - * zfs_unmount() will also free the zfsmount structure, - * we will get double free. To prevent double free, - * we must set f_devdata to NULL there. - */ - if (mount != NULL) - f->f_devdata = NULL; - + /* XXX */ return (0); } @@ -1633,11 +1603,13 @@ struct devsw zfs_dev = { .dv_close = zfs_dev_close, .dv_ioctl = noioctl, .dv_print = zfs_dev_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, + .dv_fmtdev = zfs_fmtdev, + .dv_parsedev = zfs_parsedev, }; -int -zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) +static int +zfs_parsedev(struct devdesc **idev, const char *devspec, const char **path) { static char rootname[ZFS_MAXNAMELEN]; static char poolname[ZFS_MAXNAMELEN]; @@ -1646,8 +1618,9 @@ zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) const char *np; const char *sep; int rv; + struct zfs_devdesc *dev; - np = devspec; + np = devspec + 3; /* Skip the leading 'zfs' */ if (*np != ':') return (EINVAL); np++; @@ -1670,18 +1643,24 @@ zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) spa = spa_find_by_name(poolname); if (!spa) return (ENXIO); + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return (ENOMEM); dev->pool_guid = spa->spa_guid; rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid); - if (rv != 0) + if (rv != 0) { + free(dev); return (rv); + } if (path != NULL) *path = (*end == '\0') ? end : end + 1; dev->dd.d_dev = &zfs_dev; + *idev = &dev->dd; return (0); } char * -zfs_fmtdev(void *vdev) +zfs_fmtdev(struct devdesc *vdev) { static char rootname[ZFS_MAXNAMELEN]; static char buf[2 * ZFS_MAXNAMELEN + 8]; @@ -1689,7 +1668,7 @@ zfs_fmtdev(void *vdev) spa_t *spa; buf[0] = '\0'; - if (dev->dd.d_dev->dv_type != DEVT_ZFS) + if (vdev->d_dev->dv_type != DEVT_ZFS) return (buf); /* Do we have any pools? */ diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c index 865294dafed4..f15d9b016068 100644 --- a/stand/libsa/zfs/zfsimpl.c +++ b/stand/libsa/zfs/zfsimpl.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Stand-alone ZFS file reader. */ @@ -110,36 +107,27 @@ typedef struct indirect_vsd { } indirect_vsd_t; /* - * List of all vdevs, chained through v_alllink. - */ -static vdev_list_t zfs_vdevs; - -/* - * List of ZFS features supported for read + * List of supported read-incompatible ZFS features. Do not add here features + * marked as ZFEATURE_FLAG_READONLY_COMPAT, they are irrelevant for read-only! */ static const char *features_for_read[] = { - "org.illumos:lz4_compress", - "com.delphix:hole_birth", - "com.delphix:extensible_dataset", + "com.datto:bookmark_v2", + "com.datto:encryption", + "com.delphix:bookmark_written", + "com.delphix:device_removal", "com.delphix:embedded_data", - "org.open-zfs:large_blocks", + "com.delphix:extensible_dataset", + "com.delphix:head_errlog", + "com.delphix:hole_birth", + "com.joyent:multi_vdev_crash_dump", + "com.klarasystems:vdev_zaps_v2", + "org.freebsd:zstd_compress", + "org.illumos:lz4_compress", "org.illumos:sha512", "org.illumos:skein", + "org.open-zfs:large_blocks", + "org.openzfs:blake3", "org.zfsonlinux:large_dnode", - "com.joyent:multi_vdev_crash_dump", - "com.delphix:spacemap_histogram", - "com.delphix:zpool_checkpoint", - "com.delphix:spacemap_v2", - "com.datto:encryption", - "com.datto:bookmark_v2", - "org.zfsonlinux:allocation_classes", - "com.datto:resilver_defer", - "com.delphix:device_removal", - "com.delphix:obsolete_counts", - "com.intel:allocation_classes", - "org.freebsd:zstd_compress", - "com.delphix:bookmark_written", - "com.delphix:head_errlog", NULL }; @@ -174,7 +162,6 @@ vdev_indirect_mapping_entry_phys_t * static void zfs_init(void) { - STAILQ_INIT(&zfs_vdevs); STAILQ_INIT(&zfs_pools); dnode_cache_buf = malloc(SPA_MAXBLOCKSIZE); @@ -446,7 +433,7 @@ vdev_indirect_mapping_entry(vdev_indirect_mapping_t *vim, uint64_t index) * * It's possible that the given offset will not be in the mapping table * (i.e. no mapping entries contain this offset), in which case, the - * return value value depends on the "next_if_missing" parameter. + * return value depends on the "next_if_missing" parameter. * * If the offset is not found in the table and "next_if_missing" is * B_FALSE, then NULL will always be returned. The behavior is intended @@ -846,16 +833,27 @@ vdev_replacing_read(vdev_t *vdev, const blkptr_t *bp, void *buf, return (kid->v_read(kid, bp, buf, offset, bytes)); } +/* + * List of vdevs that were fully initialized from their own label, but later a + * newer label was found that obsoleted the stale label, freeing its + * configuration tree. We keep those vdevs around, since a new configuration + * may include them. + */ +static vdev_list_t orphans = STAILQ_HEAD_INITIALIZER(orphans); + static vdev_t * -vdev_find(uint64_t guid) +vdev_find(vdev_list_t *list, uint64_t guid) { - vdev_t *vdev; + vdev_t *vdev, *safe; - STAILQ_FOREACH(vdev, &zfs_vdevs, v_alllink) + STAILQ_FOREACH_SAFE(vdev, list, v_childlink, safe) { if (vdev->v_guid == guid) return (vdev); + if ((vdev = vdev_find(&vdev->v_children, guid)) != NULL) + return (vdev); + } - return (0); + return (NULL); } static vdev_t * @@ -864,6 +862,11 @@ vdev_create(uint64_t guid, vdev_read_t *_read) vdev_t *vdev; vdev_indirect_config_t *vic; + if ((vdev = vdev_find(&orphans, guid))) { + STAILQ_REMOVE(&orphans, vdev, vdev, v_childlink); + return (vdev); + } + vdev = calloc(1, sizeof(vdev_t)); if (vdev != NULL) { STAILQ_INIT(&vdev->v_children); @@ -878,7 +881,6 @@ vdev_create(uint64_t guid, vdev_read_t *_read) if (_read != NULL) { vic = &vdev->vdev_indirect_config; vic->vic_prev_indirect_vdev = UINT64_MAX; - STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink); } } @@ -1042,22 +1044,19 @@ vdev_init(uint64_t guid, const nvlist_t *nvlist, vdev_t **vdevp) * STAILQ_INSERT_AFTER. */ static vdev_t * -vdev_find_previous(vdev_t *top_vdev, vdev_t *vdev) +vdev_find_previous(vdev_t *top_vdev, uint64_t id) { vdev_t *v, *previous; - if (STAILQ_EMPTY(&top_vdev->v_children)) - return (NULL); - previous = NULL; STAILQ_FOREACH(v, &top_vdev->v_children, v_childlink) { - if (v->v_id > vdev->v_id) + if (v->v_id > id) return (previous); - if (v->v_id == vdev->v_id) + if (v->v_id == id) return (v); - if (v->v_id < vdev->v_id) + if (v->v_id < id) previous = v; } return (previous); @@ -1079,7 +1078,7 @@ vdev_child_count(vdev_t *vdev) /* * Insert vdev into top_vdev children list. List is ordered by v_id. */ -static void +static vdev_t * vdev_insert(vdev_t *top_vdev, vdev_t *vdev) { vdev_t *previous; @@ -1092,7 +1091,7 @@ vdev_insert(vdev_t *top_vdev, vdev_t *vdev) * so we can use either STAILQ_INSERT_HEAD or STAILQ_INSERT_AFTER * as STAILQ does not have insert before. */ - previous = vdev_find_previous(top_vdev, vdev); + previous = vdev_find_previous(top_vdev, vdev->v_id); if (previous == NULL) { STAILQ_INSERT_HEAD(&top_vdev->v_children, vdev, v_childlink); @@ -1101,7 +1100,8 @@ vdev_insert(vdev_t *top_vdev, vdev_t *vdev) * This vdev was configured from label config, * do not insert duplicate. */ - return; + free(vdev); + return (previous); } else { STAILQ_INSERT_AFTER(&top_vdev->v_children, previous, vdev, v_childlink); @@ -1110,24 +1110,28 @@ vdev_insert(vdev_t *top_vdev, vdev_t *vdev) count = vdev_child_count(top_vdev); if (top_vdev->v_nchildren < count) top_vdev->v_nchildren = count; + return (vdev); } static int -vdev_from_nvlist(spa_t *spa, uint64_t top_guid, const nvlist_t *nvlist) +vdev_from_nvlist(spa_t *spa, uint64_t top_guid, uint64_t label_guid, + uint64_t txg, const nvlist_t *nvlist) { vdev_t *top_vdev, *vdev; nvlist_t **kids = NULL; int rc, nkids; /* Get top vdev. */ - top_vdev = vdev_find(top_guid); + top_vdev = vdev_find(&spa->spa_root_vdev->v_children, top_guid); if (top_vdev == NULL) { rc = vdev_init(top_guid, nvlist, &top_vdev); if (rc != 0) return (rc); top_vdev->v_spa = spa; top_vdev->v_top = top_vdev; - vdev_insert(spa->spa_root_vdev, top_vdev); + top_vdev->v_label = label_guid; + top_vdev->v_txg = txg; + (void )vdev_insert(spa->spa_root_vdev, top_vdev); } /* Add children if there are any. */ @@ -1148,7 +1152,7 @@ vdev_from_nvlist(spa_t *spa, uint64_t top_guid, const nvlist_t *nvlist) vdev->v_spa = spa; vdev->v_top = top_vdev; - vdev_insert(top_vdev, vdev); + vdev = vdev_insert(top_vdev, vdev); } } else { /* @@ -1167,28 +1171,6 @@ done: return (rc); } -static int -vdev_init_from_label(spa_t *spa, const nvlist_t *nvlist) -{ - uint64_t pool_guid, top_guid; - nvlist_t *vdevs; - int rc; - - if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, - NULL, &pool_guid, NULL) || - nvlist_find(nvlist, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64, - NULL, &top_guid, NULL) || - nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST, - NULL, &vdevs, NULL)) { - printf("ZFS: can't find vdev details\n"); - return (ENOENT); - } - - rc = vdev_from_nvlist(spa, top_guid, vdevs); - nvlist_destroy(vdevs); - return (rc); -} - static void vdev_set_state(vdev_t *vdev) { @@ -1235,14 +1217,14 @@ vdev_set_state(vdev_t *vdev) } static int -vdev_update_from_nvlist(uint64_t top_guid, const nvlist_t *nvlist) +vdev_update_from_nvlist(vdev_t *root, uint64_t top_guid, const nvlist_t *nvlist) { vdev_t *vdev; nvlist_t **kids = NULL; int rc, nkids; /* Update top vdev. */ - vdev = vdev_find(top_guid); + vdev = vdev_find(&root->v_children, top_guid); if (vdev != NULL) vdev_set_initial_state(vdev, nvlist); @@ -1258,7 +1240,7 @@ vdev_update_from_nvlist(uint64_t top_guid, const nvlist_t *nvlist) if (rc != 0) break; - vdev = vdev_find(guid); + vdev = vdev_find(&root->v_children, guid); if (vdev != NULL) vdev_set_initial_state(vdev, kids[i]); } @@ -1274,6 +1256,19 @@ vdev_update_from_nvlist(uint64_t top_guid, const nvlist_t *nvlist) return (rc); } +static void +vdev_free(struct vdev *vdev) +{ + struct vdev *kid, *safe; + + STAILQ_FOREACH_SAFE(kid, &vdev->v_children, v_childlink, safe) + vdev_free(kid); + if (vdev->v_phys_read != NULL) + STAILQ_INSERT_HEAD(&orphans, vdev, v_childlink); + else + free(vdev); +} + static int vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist) { @@ -1317,14 +1312,16 @@ vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist) NULL, &guid, NULL); if (rc != 0) break; - vdev = vdev_find(guid); + vdev = vdev_find(&spa->spa_root_vdev->v_children, guid); /* * Top level vdev is missing, create it. + * XXXGL: how can this happen? */ if (vdev == NULL) - rc = vdev_from_nvlist(spa, guid, kids[i]); + rc = vdev_from_nvlist(spa, guid, 0, 0, kids[i]); else - rc = vdev_update_from_nvlist(guid, kids[i]); + rc = vdev_update_from_nvlist(spa->spa_root_vdev, guid, + kids[i]); if (rc != 0) break; } @@ -1342,6 +1339,53 @@ vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist) return (rc); } +static bool +nvlist_find_child_guid(const nvlist_t *nvlist, uint64_t guid) +{ + nvlist_t **kids = NULL; + int nkids, i; + bool rv = false; + + if (nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY, + &nkids, &kids, NULL) != 0) + nkids = 0; + + for (i = 0; i < nkids; i++) { + uint64_t kid_guid; + + if (nvlist_find(kids[i], ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, + NULL, &kid_guid, NULL) != 0) + break; + if (kid_guid == guid) + rv = true; + else + rv = nvlist_find_child_guid(kids[i], guid); + if (rv) + break; + } + + for (i = 0; i < nkids; i++) + nvlist_destroy(kids[i]); + free(kids); + + return (rv); +} + +static bool +nvlist_find_vdev_guid(const nvlist_t *nvlist, uint64_t guid) +{ + nvlist_t *vdevs; + bool rv; + + if (nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST, NULL, + &vdevs, NULL) != 0) + return (false); + rv = nvlist_find_child_guid(vdevs, guid); + nvlist_destroy(vdevs); + + return (rv); +} + static spa_t * spa_find_by_guid(uint64_t guid) { @@ -1367,19 +1411,6 @@ spa_find_by_name(const char *name) } static spa_t * -spa_find_by_dev(struct zfs_devdesc *dev) -{ - - if (dev->dd.d_dev->dv_type != DEVT_ZFS) - return (NULL); - - if (dev->pool_guid == 0) - return (STAILQ_FIRST(&zfs_pools)); - - return (spa_find_by_guid(dev->pool_guid)); -} - -static spa_t * spa_create(uint64_t guid, const char *name) { spa_t *spa; @@ -1399,7 +1430,7 @@ spa_create(uint64_t guid, const char *name) free(spa); return (NULL); } - spa->spa_root_vdev->v_name = strdup("root"); + spa->spa_root_vdev->v_name = spa->spa_name; STAILQ_INSERT_TAIL(&zfs_pools, spa, spa_link); return (spa); @@ -1701,14 +1732,14 @@ static int vdev_write_bootenv_impl(vdev_t *vdev, vdev_boot_envblock_t *be) { vdev_t *kid; - int rv = 0, rc; + int rv = 0, err; STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { if (kid->v_state != VDEV_STATE_HEALTHY) continue; - rc = vdev_write_bootenv_impl(kid, be); - if (rv == 0) - rv = rc; + err = vdev_write_bootenv_impl(kid, be); + if (err != 0) + rv = err; } /* @@ -1718,12 +1749,12 @@ vdev_write_bootenv_impl(vdev_t *vdev, vdev_boot_envblock_t *be) return (rv); for (int l = 0; l < VDEV_LABELS; l++) { - rc = vdev_label_write(vdev, l, be, + err = vdev_label_write(vdev, l, be, offsetof(vdev_label_t, vl_be)); - if (rc != 0) { + if (err != 0) { printf("failed to write bootenv to %s label %d: %d\n", - vdev->v_name ? vdev->v_name : "unknown", l, rc); - rv = rc; + vdev->v_name ? vdev->v_name : "unknown", l, err); + rv = err; } } return (rv); @@ -2023,11 +2054,10 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, { vdev_t vtmp; spa_t *spa; - vdev_t *vdev; - nvlist_t *nvl; + vdev_t *vdev, *top; + nvlist_t *nvl, *vdevs; uint64_t val; - uint64_t guid, vdev_children; - uint64_t pool_txg, pool_guid; + uint64_t guid, pool_guid, top_guid, txg; const char *pool_name; int rc, namelen; @@ -2083,13 +2113,18 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, } if (nvlist_find(nvl, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64, - NULL, &pool_txg, NULL) != 0 || + NULL, &txg, NULL) != 0 || + txg == 0 || + nvlist_find(nvl, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64, + NULL, &top_guid, NULL) != 0 || nvlist_find(nvl, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, NULL, &pool_guid, NULL) != 0 || nvlist_find(nvl, ZPOOL_CONFIG_POOL_NAME, DATA_TYPE_STRING, - NULL, &pool_name, &namelen) != 0) { + NULL, &pool_name, &namelen) != 0 || + nvlist_find(nvl, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, + NULL, &guid, NULL) != 0) { /* - * Cache and spare devices end up here - just ignore + * Cache, spare and replaced devices end up here - just ignore * them. */ nvlist_destroy(nvl); @@ -2103,8 +2138,6 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, if (spa == NULL) { char *name; - nvlist_find(nvl, ZPOOL_CONFIG_VDEV_CHILDREN, - DATA_TYPE_UINT64, NULL, &vdev_children, NULL); name = malloc(namelen + 1); if (name == NULL) { nvlist_destroy(nvl); @@ -2118,10 +2151,47 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, nvlist_destroy(nvl); return (ENOMEM); } - spa->spa_root_vdev->v_nchildren = vdev_children; } - if (pool_txg > spa->spa_txg) - spa->spa_txg = pool_txg; + + /* + * Check if configuration is already known. If configuration is known + * and txg numbers don't match, we got 2x2 scenarios here. First, is + * the label being read right now _newer_ than the one read before. + * Second, is the vdev that provided the stale label _present_ in the + * newer configuration. If neither is true, we completely ignore the + * label. + */ + STAILQ_FOREACH(top, &spa->spa_root_vdev->v_children, v_childlink) + if (top->v_guid == top_guid) { + bool newer, present; + + if (top->v_txg == txg) + break; + newer = (top->v_txg < txg); + present = newer ? + nvlist_find_vdev_guid(nvl, top->v_label) : + (vdev_find(&top->v_children, guid) != NULL); + printf("ZFS: pool %s vdev %s %s stale label from " + "0x%jx@0x%jx, %s 0x%jx@0x%jx\n", + spa->spa_name, top->v_name, + present ? "using" : "ignoring", + newer ? top->v_label : guid, + newer ? top->v_txg : txg, + present ? "referred by" : "using", + newer ? guid : top->v_label, + newer ? txg : top->v_txg); + if (newer) { + STAILQ_REMOVE(&spa->spa_root_vdev->v_children, + top, vdev, v_childlink); + vdev_free(top); + break; + } else if (present) { + break; + } else { + nvlist_destroy(nvl); + return (EIO); + } + } /* * Get the vdev tree and create our in-core copy of it. @@ -2129,19 +2199,22 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, * be some kind of alias (overlapping slices, dangerously dedicated * disks etc). */ - if (nvlist_find(nvl, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, - NULL, &guid, NULL) != 0) { - nvlist_destroy(nvl); - return (EIO); - } - vdev = vdev_find(guid); + vdev = vdev_find(&spa->spa_root_vdev->v_children, guid); /* Has this vdev already been inited? */ if (vdev && vdev->v_phys_read) { nvlist_destroy(nvl); return (EIO); } - rc = vdev_init_from_label(spa, nvl); + if (nvlist_find(nvl, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST, NULL, + &vdevs, NULL)) { + printf("ZFS: can't find vdev details\n"); + nvlist_destroy(nvl); + return (ENOENT); + } + + rc = vdev_from_nvlist(spa, top_guid, guid, txg, vdevs); + nvlist_destroy(vdevs); nvlist_destroy(nvl); if (rc != 0) return (rc); @@ -2150,7 +2223,7 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, * We should already have created an incomplete vdev for this * vdev. Find it and initialise it with our read proc. */ - vdev = vdev_find(guid); + vdev = vdev_find(&spa->spa_root_vdev->v_children, guid); if (vdev != NULL) { vdev->v_phys_read = _read; vdev->v_phys_write = _write; @@ -3067,11 +3140,12 @@ zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) char name[256]; char component[256]; uint64_t dir_obj, parent_obj, child_dir_zapobj; - dnode_phys_t child_dir_zap, dataset, dir, parent; + dnode_phys_t child_dir_zap, snapnames_zap, dataset, dir, parent; dsl_dir_phys_t *dd; dsl_dataset_phys_t *ds; char *p; int len; + boolean_t issnap = B_FALSE; p = &name[sizeof(name) - 1]; *p = '\0'; @@ -3082,6 +3156,8 @@ zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) } ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; dir_obj = ds->ds_dir_obj; + if (ds->ds_snapnames_zapobj == 0) + issnap = B_TRUE; for (;;) { if (objset_get_dnode(spa, spa->spa_mos, dir_obj, &dir) != 0) @@ -3097,6 +3173,34 @@ zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) &parent) != 0) return (EIO); dd = (dsl_dir_phys_t *)&parent.dn_bonus; + if (issnap == B_TRUE) { + /* + * The dataset we are looking up is a snapshot + * the dir_obj is the parent already, we don't want + * the grandparent just yet. Reset to the parent. + */ + dd = (dsl_dir_phys_t *)&dir.dn_bonus; + /* Lookup the dataset to get the snapname ZAP */ + if (objset_get_dnode(spa, spa->spa_mos, + dd->dd_head_dataset_obj, &dataset)) + return (EIO); + ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; + if (objset_get_dnode(spa, spa->spa_mos, + ds->ds_snapnames_zapobj, &snapnames_zap) != 0) + return (EIO); + /* Get the name of the snapshot */ + if (zap_rlookup(spa, &snapnames_zap, component, + objnum) != 0) + return (EIO); + len = strlen(component); + p -= len; + memcpy(p, component, len); + --p; + *p = '@'; + issnap = B_FALSE; + continue; + } + child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) @@ -3126,9 +3230,11 @@ zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum) { char element[256]; uint64_t dir_obj, child_dir_zapobj; - dnode_phys_t child_dir_zap, dir; + dnode_phys_t child_dir_zap, snapnames_zap, dir, dataset; dsl_dir_phys_t *dd; + dsl_dataset_phys_t *ds; const char *p, *q; + boolean_t issnap = B_FALSE; if (objset_get_dnode(spa, spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir)) @@ -3159,6 +3265,25 @@ zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum) p += strlen(p); } + if (issnap == B_TRUE) { + if (objset_get_dnode(spa, spa->spa_mos, + dd->dd_head_dataset_obj, &dataset)) + return (EIO); + ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; + if (objset_get_dnode(spa, spa->spa_mos, + ds->ds_snapnames_zapobj, &snapnames_zap) != 0) + return (EIO); + /* Actual loop condition #2. */ + if (zap_lookup(spa, &snapnames_zap, element, + sizeof (dir_obj), 1, &dir_obj) != 0) + return (ENOENT); + *objnum = dir_obj; + return (0); + } else if ((q = strchr(element, '@')) != NULL) { + issnap = B_TRUE; + element[q - element] = '\0'; + p = q + 1; + } child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) @@ -3509,8 +3634,10 @@ zfs_spa_init(spa_t *spa) return (EIO); } rc = load_nvlist(spa, config_object, &nvlist); - if (rc != 0) + if (rc != 0) { + printf("ZFS: failed to load pool %s nvlist\n", spa->spa_name); return (rc); + } rc = zap_lookup(spa, &dir, DMU_POOL_ZPOOL_CHECKPOINT, sizeof(uint64_t), sizeof(checkpoint) / sizeof(uint64_t), @@ -3813,3 +3940,82 @@ done: free(entry); return (rc); } + +/* + * Return either a cached copy of the bootenv, or read each of the vdev children + * looking for the bootenv. Cache what's found and return the results. Returns 0 + * when benvp is filled in, and some errno when not. + */ +static int +zfs_get_bootenv_spa(spa_t *spa, nvlist_t **benvp) +{ + vdev_t *vd; + nvlist_t *benv = NULL; + + if (spa->spa_bootenv == NULL) { + STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, + v_childlink) { + benv = vdev_read_bootenv(vd); + + if (benv != NULL) + break; + } + spa->spa_bootenv = benv; + } + benv = spa->spa_bootenv; + + if (benv == NULL) + return (ENOENT); + + *benvp = benv; + return (0); +} + +/* + * Store nvlist to pool label bootenv area. Also updates cached pointer in spa. + */ +static int +zfs_set_bootenv_spa(spa_t *spa, nvlist_t *benv) +{ + vdev_t *vd; + + STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, v_childlink) { + vdev_write_bootenv(vd, benv); + } + + spa->spa_bootenv = benv; + return (0); +} + +/* + * Get bootonce value by key. The bootonce <key, value> pair is removed from the + * bootenv nvlist and the remaining nvlist is committed back to disk. This process + * the bootonce flag since we've reached the point in the boot that we've 'used' + * the BE. For chained boot scenarios, we may reach this point multiple times (but + * only remove it and return 0 the first time). + */ +static int +zfs_get_bootonce_spa(spa_t *spa, const char *key, char *buf, size_t size) +{ + nvlist_t *benv; + char *result = NULL; + int result_size, rv; + + if ((rv = zfs_get_bootenv_spa(spa, &benv)) != 0) + return (rv); + + if ((rv = nvlist_find(benv, key, DATA_TYPE_STRING, NULL, + &result, &result_size)) == 0) { + if (result_size == 0) { + /* ignore empty string */ + rv = ENOENT; + } else if (buf != NULL) { + size = MIN((size_t)result_size + 1, size); + strlcpy(buf, result, size); + } + (void)nvlist_remove(benv, key, DATA_TYPE_STRING); + (void)zfs_set_bootenv_spa(spa, benv); + } + + return (rv); +} diff --git a/stand/libsa/zfs/zstd_shim.c b/stand/libsa/zfs/zstd_shim.c deleted file mode 100644 index b1ba4babcf36..000000000000 --- a/stand/libsa/zfs/zstd_shim.c +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2020 M. Warner Losh <imp@FreeBSD.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Small amount of shim code needed to get zfs_zstd.c to compile. These items - * here should all be defined in the SPL or as part of libsa somewhere, but - * aren't for reasons that haven't been tracked down yet. Ideally, they would - * all go away and we'd compile zfs_zstd.c directly. Based on an original by - * Matt Macey, but only the #include remains untouched from that. - */ - -#define ZFS_MODULE_PARAM_ARGS void -typedef int boolean_t; /* This one may be tough to get rid of */ - -/* TODO: openzfs/include/sys/uio_impl.h must not be included */ -#ifndef _SYS_UIO_IMPL_H -#define _SYS_UIO_IMPL_H -#endif - -#include <contrib/openzfs/module/zstd/zfs_zstd.c> diff --git a/stand/libsa32/Makefile b/stand/libsa32/Makefile index eba6c00bd891..7dea1efd0051 100644 --- a/stand/libsa32/Makefile +++ b/stand/libsa32/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - DO32=1 .include <bsd.init.mk> diff --git a/stand/libsa32/Makefile.depend b/stand/libsa32/Makefile.depend index 73bc18c8c0fc..11aba52f82cf 100644 --- a/stand/libsa32/Makefile.depend +++ b/stand/libsa32/Makefile.depend @@ -1,8 +1,6 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - stand/libsa \ .include <dirdeps.mk> diff --git a/stand/loader.mk b/stand/loader.mk index aa88122cb7a1..4073e523e552 100644 --- a/stand/loader.mk +++ b/stand/loader.mk @@ -1,11 +1,10 @@ -# $FreeBSD$ - .PATH: ${LDRSRC} ${BOOTSRC}/libsa CFLAGS+=-I${LDRSRC} SRCS+= boot.c commands.c console.c devopen.c interp.c SRCS+= interp_backslash.c interp_parse.c ls.c misc.c +SRCS+= modinfo.c SRCS+= module.c nvstore.c pnglite.c tslog.c CFLAGS.module.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite @@ -30,6 +29,33 @@ SRCS+= load_elf64.c reloc_elf64.c SRCS+= metadata.c .endif +# +# LOADER_*_SUPPORT variables are used to subset the boot loader in the various +# configurations each platform supports. These are typically used to omit broken +# options, or to size optimize for space constrained instances. These are set in +# loader Makefiles (which include loader.mk) to control which subset of features +# are enabled. These cannot generally be set in src.conf since that would affect +# all loaders, but also not all loaders are setup for overrides like that and +# not all combinations of the following have been tested or even work. Sometimes +# non-default values won't work due to buggy support for that component being +# optional. +# +# LOADER_BZIP2_SUPPORT Add support for bzip2 compressed files +# LOADER_CD9660_SUPPORT Add support for iso9660 filesystems +# LOADER_DISK_SUPPORT Adds support for disks and mounting filesystems on it +# LOADER_EXT2FS_SUPPORT Add support for ext2 Linux filesystems +# LOADER_GPT_SUPPORT Add support for GPT partitions +# LOADER_GZIP_SUPPORT Add support for gzip compressed files +# LOADER_INSTALL_SUPPORT Add support for booting off of installl ISOs +# LOADER_MBR_SUPPORT Add support for MBR partitions +# LOADER_MSDOS_SUPPORT Add support for FAT filesystems +# LOADER_NET_SUPPORT Adds networking support (useless w/o net drivers sometimes) +# LOADER_NFS_SUPPORT Add NFS support +# LOADER_TFTP_SUPPORT Add TFTP support +# LOADER_UFS_SUPPORT Add support for UFS filesystems +# LOADER_ZFS_SUPPORT Add support for ZFS filesystems +# + .if ${LOADER_DISK_SUPPORT:Uyes} == "yes" CFLAGS.part.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib SRCS+= disk.c part.c vdisk.c @@ -75,8 +101,6 @@ SRCS+= interp_simple.c .error Unknown interpreter ${LOADER_INTERP} .endif -.include "${BOOTSRC}/veriexec.mk" - .if defined(BOOT_PROMPT_123) CFLAGS+= -DBOOT_PROMPT_123 .endif @@ -161,12 +185,19 @@ vers.c: ${LDRSRC}/newvers.sh ${VERSION_FILE} CFLAGS+= -DELF_VERBOSE .endif -.if !empty(HELP_FILES) +# Each loader variant defines their own help filename. Optional or +# build-specific commands are included by augmenting HELP_FILES. +.if !defined(HELP_FILENAME) +.error Define HELP_FILENAME before including loader.mk +.endif + HELP_FILES+= ${LDRSRC}/help.common -CLEANFILES+= loader.help -FILES+= loader.help +CFLAGS+= -DHELP_FILENAME=\"${HELP_FILENAME}\" +.if ${INSTALL_LOADER_HELP_FILE:Uyes} == "yes" +CLEANFILES+= ${HELP_FILENAME} +FILES+= ${HELP_FILENAME} +.endif -loader.help: ${HELP_FILES} +${HELP_FILENAME}: ${HELP_FILES} cat ${HELP_FILES} | awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.endif diff --git a/stand/lua.mk b/stand/lua.mk index 711d95e48ba0..6c7c832ba3a0 100644 --- a/stand/lua.mk +++ b/stand/lua.mk @@ -1,6 +1,4 @@ -# $FreeBSD$ # Common flags to build lua related files CFLAGS+= -I${LUASRC} -I${LDRSRC} -I${LIBLUASRC} -CFLAGS+= -DLUA_FLOAT_TYPE=LUA_FLOAT_INT64 diff --git a/stand/lua/Makefile b/stand/lua/Makefile index fe6fd6f63c8e..d319261e18b2 100644 --- a/stand/lua/Makefile +++ b/stand/lua/Makefile @@ -1,13 +1,14 @@ -# $FreeBSD$ - .include <bsd.init.mk> -MAN= cli.lua.8 \ +MAN= loader.conf.lua.5 \ + cli.lua.8 \ color.lua.8 \ config.lua.8 \ core.lua.8 \ drawer.lua.8 \ + gfx.lua.8 \ hook.lua.8 \ + loader.lua.8 \ menu.lua.8 \ password.lua.8 \ screen.lua.8 @@ -23,6 +24,7 @@ FILES= cli.lua \ gfx-beastie.lua \ gfx-beastiebw.lua \ gfx-fbsdbw.lua \ + gfx-install.lua \ gfx-orb.lua \ gfx-orbbw.lua \ menu.lua \ diff --git a/stand/lua/Makefile.depend b/stand/lua/Makefile.depend new file mode 100644 index 000000000000..11aba52f82cf --- /dev/null +++ b/stand/lua/Makefile.depend @@ -0,0 +1,10 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/lua/cli.lua b/stand/lua/cli.lua index 12f6b57642db..6832da0a31a5 100644 --- a/stand/lua/cli.lua +++ b/stand/lua/cli.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,8 +24,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local config = require("config") local core = require("core") diff --git a/stand/lua/cli.lua.8 b/stand/lua/cli.lua.8 index 2d6df3fd4e6b..aee1d3d53579 100644 --- a/stand/lua/cli.lua.8 +++ b/stand/lua/cli.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd July 24, 2021 +.Dd March 29, 2025 .Dt CLI.LUA 8 .Os .Sh NAME .Nm cli.lua -.Nd FreeBSD Lua CLI module +.Nd bootloader command line interpreter module .Sh DESCRIPTION .Nm contains the main functionality required to add new CLI commands, which can be diff --git a/stand/lua/color.lua b/stand/lua/color.lua index 4dc16cacb97e..bdb29e6de670 100644 --- a/stand/lua/color.lua +++ b/stand/lua/color.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- All rights reserved. @@ -25,8 +25,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local core = require("core") local hook = require("hook") diff --git a/stand/lua/color.lua.8 b/stand/lua/color.lua.8 index d32f702c0daa..9a3b9b1b9385 100644 --- a/stand/lua/color.lua.8 +++ b/stand/lua/color.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd August 19, 2018 +.Dd March 29, 2025 .Dt COLOR.LUA 8 .Os .Sh NAME .Nm color.lua -.Nd FreeBSD color module +.Nd bootloader color module .Sh DESCRIPTION .Nm contains functionality for working with colors. diff --git a/stand/lua/config.lua b/stand/lua/config.lua index 9ef7c0796f46..26f65ecc17b6 100644 --- a/stand/lua/config.lua +++ b/stand/lua/config.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> @@ -26,8 +26,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local hook = require("hook") @@ -45,6 +43,7 @@ local MSG_FAILSETENV = "Failed to '%s' with value: %s" local MSG_FAILOPENCFG = "Failed to open config: '%s'" local MSG_FAILREADCFG = "Failed to read config: '%s'" local MSG_FAILPARSECFG = "Failed to parse config: '%s'" +local MSG_FAILEXECLUA = "Failed to execute lua conf '%s': '%s'" local MSG_FAILPARSEVAR = "Failed to parse variable '%s': %s" local MSG_FAILEXBEF = "Failed to execute '%s' before loading '%s'" local MSG_FAILEXAF = "Failed to execute '%s' after loading '%s'" @@ -62,8 +61,11 @@ local MSG_FAILSYN_EOLESC = "Stray escape at end of line" local MSG_FAILSYN_EOLVAR = "Unescaped $ at end of line" local MSG_FAILSYN_BADVAR = "Malformed variable expression at position '%d'" -local MODULEEXPR = '([-%w_]+)' -local QVALEXPR = '"(.*)"' +-- MODULEEXPR should more or less allow the exact same set of characters as the +-- env_var entries in the pattern table. This is perhaps a good target for a +-- little refactoring. +local MODULEEXPR = '([%w%d-_.]+)' +local QVALEXPR = '"([^"]*)"' local QVALREPL = QVALEXPR:gsub('%%', '%%%%') local WORDEXPR = "([-%w%d][-%w%d_.]*)" local WORDREPL = WORDEXPR:gsub('%%', '%%%%') @@ -244,65 +246,82 @@ end -- local pattern_table = { { + luaexempt = true, str = "(#.*)", process = function(_, _) end, groups = 1, }, -- module_load="value" { - str = MODULEEXPR .. "_load%s*=%s*$VALUE", + name = MODULEEXPR .. "_load%s*", + val = "%s*$VALUE", process = function(k, v) if modules[k] == nil then modules[k] = {} end modules[k].load = v:upper() + setEnv(k .. "_load", v:upper()) end, }, -- module_name="value" { - str = MODULEEXPR .. "_name%s*=%s*$VALUE", + name = MODULEEXPR .. "_name%s*", + val = "%s*$VALUE", process = function(k, v) setKey(k, "name", v) + setEnv(k .. "_name", v) end, }, -- module_type="value" { - str = MODULEEXPR .. "_type%s*=%s*$VALUE", + name = MODULEEXPR .. "_type%s*", + val = "%s*$VALUE", process = function(k, v) setKey(k, "type", v) + setEnv(k .. "_type", v) end, }, -- module_flags="value" { - str = MODULEEXPR .. "_flags%s*=%s*$VALUE", + name = MODULEEXPR .. "_flags%s*", + val = "%s*$VALUE", process = function(k, v) setKey(k, "flags", v) + setEnv(k .. "_flags", v) end, }, -- module_before="value" { - str = MODULEEXPR .. "_before%s*=%s*$VALUE", + name = MODULEEXPR .. "_before%s*", + val = "%s*$VALUE", process = function(k, v) setKey(k, "before", v) + setEnv(k .. "_before", v) end, }, -- module_after="value" { - str = MODULEEXPR .. "_after%s*=%s*$VALUE", + name = MODULEEXPR .. "_after%s*", + val = "%s*$VALUE", process = function(k, v) setKey(k, "after", v) + setEnv(k .. "_after", v) end, }, -- module_error="value" { - str = MODULEEXPR .. "_error%s*=%s*$VALUE", + name = MODULEEXPR .. "_error%s*", + val = "%s*$VALUE", process = function(k, v) setKey(k, "error", v) + setEnv(k .. "_error", v) end, }, -- exec="command" { - str = "exec%s*=%s*" .. QVALEXPR, + luaexempt = true, + name = "exec%s*", + val = "%s*" .. QVALEXPR, process = function(k, _) if cli_execute_unparsed(k) ~= 0 then print(MSG_FAILEXEC:format(k)) @@ -312,7 +331,8 @@ local pattern_table = { }, -- env_var="value" or env_var=[word|num] { - str = "([%w][%w%d-_.]*)%s*=%s*$VALUE", + name = "([%w][%w%d-_.]*)%s*", + val = "%s*$VALUE", process = function(k, v) local pv, msg = processEnvVar(v) if not pv then @@ -321,6 +341,8 @@ local pattern_table = { end if setEnv(k, pv) ~= 0 then print(MSG_FAILSETENV:format(k, v)) + else + return pv end end, }, @@ -479,6 +501,18 @@ local function checkNextboot() loader.setenv("nextboot_enable", "NO") end +local function processEnv(k, v) + for _, val in ipairs(pattern_table) do + if not val.luaexempt and val.name then + local matched = k:match(val.name) + + if matched then + return val.process(matched, v) + end + end + end +end + -- Module exports config.verbose = false @@ -504,7 +538,47 @@ function config.processFile(name, silent) return silent end - return config.parse(text) + if name:match(".lua$") then + local cfg_env = setmetatable({}, { + indices = {}, + __index = function(env, key) + if getmetatable(env).indices[key] then + return rawget(env, key) + end + + return loader.getenv(key) + end, + __newindex = function(env, key, val) + getmetatable(env).indices[key] = true + rawset(env, key, val) + end, + }) + + -- Give local modules a chance to populate the config + -- environment. + hook.runAll("config.buildenv", cfg_env) + local res, err = pcall(load(text, name, "t", cfg_env)) + if res then + for k, v in pairs(cfg_env) do + local t = type(v) + if t ~= "function" and t ~= "table" then + if t ~= "string" then + v = tostring(v) + end + local pval = processEnv(k, v) + if pval then + setEnv(k, pval) + end + end + end + else + print(MSG_FAILEXECLUA:format(name, err)) + end + + return res + else + return config.parse(text) + end end -- silent runs will not return false if we fail to open the file @@ -515,6 +589,9 @@ function config.parse(text) for line in text:gmatch("([^\n]+)") do if line:match("^%s*$") == nil then for _, val in ipairs(pattern_table) do + if val.str == nil then + val.str = val.name .. "=" .. val.val + end local pattern = '^%s*' .. val.str .. '%s*(.*)'; local cgroups = val.groups or 2 local k, v, c = checkPattern(line, pattern) @@ -553,8 +630,7 @@ function config.readConf(file, loaded_files) return end - -- We'll process loader_conf_dirs at the top-level readConf - local load_conf_dirs = next(loaded_files) == nil + local top_level = next(loaded_files) == nil -- Are we the top-level readConf? print("Loading " .. file) -- The final value of loader_conf_files is not important, so just @@ -579,14 +655,40 @@ function config.readConf(file, loaded_files) end end - if load_conf_dirs then + if top_level then local loader_conf_dirs = getEnv("loader_conf_dirs") + + -- If product_vars is set, it must be a list of environment variable names + -- to walk through to guess product information. The order matters as + -- reading a config files override the previously defined values. + -- + -- If product information can be guessed, for each product information + -- found, also read config files found in /boot/loader.conf.d/PRODUCT/. + local product_vars = getEnv("product_vars") + if product_vars then + local product_conf_dirs = "" + for var in product_vars:gmatch("%S+") do + local product = getEnv(var) + if product then + product_conf_dirs = product_conf_dirs .. " /boot/loader.conf.d/" .. product + end + end + + if loader_conf_dirs then + loader_conf_dirs = loader_conf_dirs .. product_conf_dirs + else + loader_conf_dirs = product_conf_dirs + end + end + + -- Process "loader_conf_dirs" extra-directories if loader_conf_dirs ~= nil then for name in loader_conf_dirs:gmatch("[%w%p]+") do if lfs.attributes(name, "mode") ~= "directory" then print(MSG_FAILDIR:format(name)) goto nextdir end + for cfile in lfs.dir(name) do if cfile:match(".conf$") then local fpath = name .. "/" .. cfile @@ -598,6 +700,15 @@ function config.readConf(file, loaded_files) ::nextdir:: end end + + -- Always allow overriding with local config files, e.g., + -- /boot/loader.conf.local. + local local_loader_conf_files = getEnv("local_loader_conf_files") + if local_loader_conf_files then + for name in local_loader_conf_files:gmatch("[%w%p]+") do + config.readConf(name, loaded_files) + end + end end end @@ -798,6 +909,7 @@ function config.getModuleInfo() } end +hook.registerType("config.buildenv") hook.registerType("config.loaded") hook.registerType("config.reloaded") hook.registerType("kernel.loaded") diff --git a/stand/lua/config.lua.8 b/stand/lua/config.lua.8 index 4fc51c90045f..7e8863203446 100644 --- a/stand/lua/config.lua.8 +++ b/stand/lua/config.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd December 17, 2020 +.Dd March 29, 2025 .Dt CONFIG.LUA 8 .Os .Sh NAME .Nm config.lua -.Nd FreeBSD config module +.Nd bootloader configuration module .Sh DESCRIPTION .Nm contains configuration and module loading functionality. @@ -66,9 +64,13 @@ as a configuration file .Po e.g., as .Pa loader.conf .Pc -and then processing files listed in +and then process files listed in the .Ev loader_conf_files -variable +variable. Additionnaly, the top-level call to readConf will process files listed in the +.Ev loader_conf_dirs +and +.Ev local_loader_conf_files +variables .Po see .Xr loader.conf 5 .Pc . @@ -217,11 +219,19 @@ as well as a representation of The following hooks are defined in .Nm : .Bl -tag -width "config.reloaded" -offset indent +.It Fn config.buildenv env .It Fn config.loaded .It Fn config.reloaded .It Fn kernel.loaded .It Fn modules.loaded .El +.Pp +Note that the +.Fn config.buildenv +hook is only invoked when an environment needs to be built to execute a lua +configuration file that has been specified in +.Ev loader_conf_files . +It will be invoked for each configuration file encountered. .Sh SEE ALSO .Xr loader.conf 5 , .Xr loader 8 , diff --git a/stand/lua/core.lua b/stand/lua/core.lua index 27e3c14de9ff..f42be6fbebb7 100644 --- a/stand/lua/core.lua +++ b/stand/lua/core.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> @@ -26,14 +26,13 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local config = require("config") local hook = require("hook") local core = {} +local default_acpi = false local default_safe_mode = false local default_single_user = false local default_verbose = false @@ -48,20 +47,14 @@ local function composeLoaderCmd(cmd_name, argstr) end local function recordDefaults() - -- On i386, hint.acpi.0.rsdp will be set before we're loaded. On !i386, - -- it will generally be set upon execution of the kernel. Because of - -- this, we can't (or don't really want to) detect/disable ACPI on !i386 - -- reliably. Just set it enabled if we detect it and leave well enough - -- alone if we don't. - local boot_acpi = core.isSystem386() and core.getACPIPresent(false) local boot_single = loader.getenv("boot_single") or "no" local boot_verbose = loader.getenv("boot_verbose") or "no" + + default_acpi = core.getACPI() default_single_user = boot_single:lower() ~= "no" default_verbose = boot_verbose:lower() ~= "no" - if boot_acpi then - core.setACPI(true) - end + core.setACPI(default_acpi) core.setSingleUser(default_single_user) core.setVerbose(default_verbose) end @@ -139,18 +132,26 @@ function core.setSingleUser(single_user) core.su = single_user end -function core.getACPIPresent(checking_system_defaults) - local c = loader.getenv("hint.acpi.0.rsdp") +function core.hasACPI() + -- We can't trust acpi.rsdp to be set if the loader binary doesn't do + -- ACPI detection early enough. UEFI loader historically didn't, so + -- we'll fallback to assuming ACPI is enabled if this binary does not + -- declare that it probes for ACPI early enough + if loader.getenv("acpi.rsdp") ~= nil then + return true + end - if c ~= nil then - if checking_system_defaults then - return true - end - -- Otherwise, respect disabled if it's set - c = loader.getenv("hint.acpi.0.disabled") - return c == nil or tonumber(c) ~= 1 + return not core.hasFeature("EARLY_ACPI") +end + +function core.getACPI() + if not core.hasACPI() then + return false end - return false + + -- Otherwise, respect disabled if it's set + local c = loader.getenv("hint.acpi.0.disabled") + return c == nil or tonumber(c) ~= 1 end function core.setACPI(acpi) @@ -159,13 +160,11 @@ function core.setACPI(acpi) end if acpi then - loader.setenv("acpi_load", "YES") + config.enableModule("acpi") loader.setenv("hint.acpi.0.disabled", "0") - loader.unsetenv("loader.acpi_disabled_by_user") else - loader.unsetenv("acpi_load") + config.disableModule("acpi") loader.setenv("hint.acpi.0.disabled", "1") - loader.setenv("loader.acpi_disabled_by_user", "1") end core.acpi = acpi end @@ -178,18 +177,16 @@ function core.setSafeMode(safe_mode) loader.setenv("kern.smp.disabled", "1") loader.setenv("hw.ata.ata_dma", "0") loader.setenv("hw.ata.atapi_dma", "0") - loader.setenv("hw.ata.wc", "0") - loader.setenv("hw.eisa_slots", "0") loader.setenv("kern.eventtimer.periodic", "1") loader.setenv("kern.geom.part.check_integrity", "0") + loader.setenv("boot_safe", "YES") else loader.unsetenv("kern.smp.disabled") loader.unsetenv("hw.ata.ata_dma") loader.unsetenv("hw.ata.atapi_dma") - loader.unsetenv("hw.ata.wc") - loader.unsetenv("hw.eisa_slots") loader.unsetenv("kern.eventtimer.periodic") loader.unsetenv("kern.geom.part.check_integrity") + loader.unsetenv("boot_safe") end core.sm = safe_mode end @@ -206,17 +203,18 @@ function core.kernelList() return core.cached_kernels end - local k = loader.getenv("kernel") + local default_kernel = loader.getenv("kernel") local v = loader.getenv("kernels") local autodetect = loader.getenv("kernels_autodetect") or "" local kernels = {} local unique = {} local i = 0 - if k ~= nil then + + if default_kernel then i = i + 1 - kernels[i] = k - unique[k] = true + kernels[i] = default_kernel + unique[default_kernel] = true end if v ~= nil then @@ -244,6 +242,8 @@ function core.kernelList() return core.cached_kernels end + local present = {} + -- Automatically detect other bootable kernel directories using a -- heuristic. Any directory in /boot that contains an ordinary file -- named "kernel" is considered eligible. @@ -272,8 +272,25 @@ function core.kernelList() unique[file] = true end + present[file] = true + ::continue:: end + + -- If we found more than one kernel, prune the "kernel" specified kernel + -- off of the list if it wasn't found during traversal. If we didn't + -- actually find any kernels, we just assume that they know what they're + -- doing and leave it alone. + if default_kernel and not present[default_kernel] and #kernels > 1 then + for n = 1, #kernels do + if n == #kernels then + kernels[n] = nil + else + kernels[n] = kernels[n + 1] + end + end + end + core.cached_kernels = kernels return core.cached_kernels end @@ -354,13 +371,14 @@ end function core.loadEntropy() if core.isUEFIBoot() then if (loader.getenv("entropy_efi_seed") or "no"):lower() == "yes" then - loader.perform("efi-seed-entropy") + local seedsize = loader.getenv("entropy_efi_seed_size") or "2048" + loader.perform("efi-seed-entropy " .. seedsize) end end end function core.setDefaults() - core.setACPI(core.getACPIPresent(true)) + core.setACPI(default_acpi) core.setSafeMode(default_safe_mode) core.setSingleUser(default_single_user) core.setVerbose(default_verbose) @@ -384,6 +402,15 @@ function core.boot(argstr) loader.perform(composeLoaderCmd("boot", argstr)) end +function core.hasFeature(name) + if not loader.has_feature then + -- Loader too old, no feature support + return nil, "No feature support in loaded loader" + end + + return loader.has_feature(name) +end + function core.isSingleUserBoot() local single_user = loader.getenv("boot_single") return single_user ~= nil and single_user:lower() == "yes" @@ -443,10 +470,6 @@ function core.isSerialBoot() return false end -function core.isSystem386() - return loader.machine_arch == "i386" -end - -- Is the menu skipped in the environment in which we've booted? function core.isMenuSkipped() return string.lower(loader.getenv("beastie_disable") or "") == "yes" @@ -522,6 +545,36 @@ function core.nextConsoleChoice() end end +-- The graphical-enabled loaders have unicode drawing character support. The +-- text-only ones do not. We check the old and new bindings for term_drawrect as +-- a proxy for unicode support, which will work on older boot loaders as well +-- as be future proof for when we remove the old binding. This also abstracts +-- out the test to one spot in case we start to export this notion more directly. +function core.hasUnicode() + return gfx.term_drawrect ~= nil or loader.term_drawrect ~= nil +end + +-- Sanity check the boot loader revision +-- Loaders with version 3.0 have everything that we need without backwards +-- compatible hacks. Warn users that still have old versions to upgrade so +-- that we can remove the backwards compatible hacks in the future since +-- they have been there a long time. +local loader_major = 3 + +function core.loaderTooOld() + return loader.version == nil or loader.version < loader_major * 1000 +end + +if core.loaderTooOld() then + print("**********************************************************************") + print("**********************************************************************") + print("***** *****") + print("***** BOOT LOADER IS TOO OLD. PLEASE UPGRADE. *****") + print("***** *****") + print("**********************************************************************") + print("**********************************************************************") +end + recordDefaults() hook.register("config.reloaded", core.clearCachedKernels) return core diff --git a/stand/lua/core.lua.8 b/stand/lua/core.lua.8 index eb9ac5336d8e..de43d3e2b220 100644 --- a/stand/lua/core.lua.8 +++ b/stand/lua/core.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd March 21, 2018 +.Dd March 29, 2025 .Dt CORE.LUA 8 .Os .Sh NAME .Nm core.lua -.Nd FreeBSD core module +.Nd bootloader core module .Sh DESCRIPTION .Nm contains core functionality that does not have a more fitting module. @@ -92,7 +90,7 @@ constants. .Ss Exported functions The following functions are exported from .Nm : -.Bl -tag -width core.getACPIPresent -offset indent +.Bl -tag -width core.setSingleUser -offset indent .It Fn core.setVerbose verbose Sets or unsets .Ev boot_verbose . @@ -105,15 +103,14 @@ Sets or unsets If .Fa singleUser is omitted, toggle the current single user setting. -.It Fn core.getACPIPresent checkingSystemDefaults -Check whether ACPI is present. -This will only be accurate for i386-compatible loaders, including non-UEFI -loaders on amd64 systems. -If -.Fa checkingSystemDefaults -is true, ignore the current value of -.Ev hint.acpi.0.disabled . -Otherwise, return true only if ACPI is both present and not disabled. +.It Fn core.getACPI +Return true if ACPI is both present and not explicitly disabled by +.Ev hints.acpi.0.disabled . +.It Fn core.hasACPI +Checks whether ACPI support is present. +This requires the loader to probe the system and set +.Ev acpi.rsdp +early before starting the interpreter. .It Fn core.setACPI acpi Sets or unsets .Ev acpi_load , @@ -129,8 +126,6 @@ Sets or unsets .Ev kern.smp.disabled , .Ev hw.ata.ata_dma , .Ev hw.ata.atapi_dma , -.Ev hw.ata.wc , -.Ev hw.eisa_slots , .Ev kern.eventtimer.periodic , and .Ev kern.geom.part.check_integrity . @@ -147,6 +142,13 @@ due to a boot environment change or a potential change in either .Ic kernel or .Ic kernels . +.It Fn core.hasFeature featureName +Checks whether the named +.Fa featureName +is enabled in the current loader. +This is specifically used for detecting capabilities of the loaded loader +binary, so that one can reasonably implement backwards compatibility shims if +needed. .It Fn core.kernelList Returns a table of kernels to display on the boot menu. This will combine @@ -204,9 +206,6 @@ This checks .Ev boot_serial , and .Ev boot_multicons . -.It Fn core.isSystem386 -Returns true if this bootloader was compiled as an i386 binary. -This generally applies to i386 loaders as well as non-UEFI loaders on amd64. .It Fn core.deepCopyTable tbl Recursively deep copies .Fa tbl @@ -219,6 +218,10 @@ If there are no elements, this returns nil and nil. If there is one element, this returns the front element and an empty table. This will not operate on truly associative tables; numeric indices are required. +.It Fn core.loaderTooOld +Returns true if the loader is too old. +Specifically, this means, is the loader old enough to require one or more +workarounds in the current lua base modules. .El .Sh SEE ALSO .Xr loader.conf 5 , diff --git a/stand/lua/drawer.lua b/stand/lua/drawer.lua index 6f6e2fe1b3e8..1c03ed93f00a 100644 --- a/stand/lua/drawer.lua +++ b/stand/lua/drawer.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> @@ -26,8 +26,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local color = require("color") local config = require("config") @@ -49,6 +47,19 @@ local frame_size local default_shift local shift +-- Make this code compatible with older loader binaries. We moved the term_* +-- functions from loader to the gfx. if we're running on an older loader that +-- has these functions, create aliases for them in gfx. The loader binary might +-- be so old as to not have them, but in that case, we want to copy the nil +-- values. The new loader will provide loader.* versions of all the gfx.* +-- functions for backwards compatibility, so we only define the functions we use +-- here. +if gfx == nil then + gfx = {} + gfx.term_drawrect = loader.term_drawrect + gfx.term_putimage = loader.term_putimage +end + local function menuEntryName(drawing_menu, entry) local name_handler = menu_name_handlers[entry.entry_type] @@ -90,6 +101,39 @@ local function processFile(gfxname) return true end +-- Backwards compatibility shims for previous FreeBSD versions, please document +-- new additions +local function adapt_fb_shim(def) + -- In FreeBSD 14.x+, we have improved framebuffer support in the loader + -- and some graphics may have images that we can actually draw on the + -- screen. Those graphics may come with shifts that are distinct from + -- the ASCII version, so we move both ascii and image versions into + -- their own tables. + if not def.ascii then + def.ascii = { + image = def.graphic, + requires_color = def.requires_color, + shift = def.shift, + } + end + if def.image then + assert(not def.fb, + "Unrecognized graphic definition format") + + -- Legacy images may have adapted a shift from the ASCII + -- version, or perhaps we just didn't care enough to adjust it. + -- Steal the shift. + def.fb = { + image = def.image, + width = def.image_rl, + shift = def.shift, + } + end + + def.adapted = true + return def +end + local function getBranddef(brand) if brand == nil then return nil @@ -112,6 +156,8 @@ local function getBranddef(brand) end branddef = branddefs[brand] + elseif not branddef.adapted then + adapt_fb_shim(branddef) end return branddef @@ -139,6 +185,8 @@ local function getLogodef(logo) end logodef = logodefs[logo] + elseif not logodef.adapted then + adapt_fb_shim(logodef) end return logodef @@ -155,6 +203,10 @@ local function drawmenu(menudef) local x = menu_position.x local y = menu_position.y + if string.lower(loader.getenv("loader_menu") or "") == "none" then + return + end + x = x + shift.x y = y + shift.y @@ -202,6 +254,13 @@ local function defaultframe() return "double" end +local function gfxenabled() + return (loader.getenv("loader_gfx") or "yes"):lower() ~= "no" +end +local function gfxcapable() + return core.isFramebufferConsole() and gfx.term_putimage +end + local function drawframe() local x = menu_position.x - 3 local y = menu_position.y - 1 @@ -227,8 +286,8 @@ local function drawframe() x = x + shift.x y = y + shift.y - if core.isFramebufferConsole() and loader.term_drawrect ~= nil then - loader.term_drawrect(x, y, x + w, y + h) + if gfxenabled() and gfxcapable() then + gfx.term_drawrect(x, y, x + w, y + h) return true end @@ -265,6 +324,10 @@ local function drawbox() local menu_header_align = loader.getenv("loader_menu_title_align") local menu_header_x + if string.lower(loader.getenv("loader_menu") or "") == "none" then + return + end + x = x + shift.x y = y + shift.y @@ -304,22 +367,23 @@ local function drawbrand() branddef = getBranddef(drawer.default_brand) end - local graphic = branddef.graphic + local graphic = branddef.ascii.image x = x + shift.x y = y + shift.y - if branddef.shift ~= nil then - x = x + branddef.shift.x - y = y + branddef.shift.y - end - if core.isFramebufferConsole() and - loader.term_putimage ~= nil and - branddef.image ~= nil then - if loader.term_putimage(branddef.image, 1, 1, 0, 7, 0) - then + local gfx_requested = branddef.fb and gfxenabled() + if gfx_requested and gfxcapable() then + if branddef.fb.shift then + x = x + (branddef.fb.shift.x or 0) + y = y + (branddef.fb.shift.y or 0) + end + if gfx.term_putimage(branddef.fb.image, x, y, 0, 7, 0) then return true end + elseif branddef.ascii.shift then + x = x + (branddef.ascii.shift.x or 0) + y = y + (branddef.ascii.shift.y or 0) end draw(x, y, graphic) end @@ -335,8 +399,8 @@ local function drawlogo() local logodef = getLogodef(logo) - if logodef == nil or logodef.graphic == nil or - (not colored and logodef.requires_color) then + if logodef == nil or logodef.ascii == nil or + (not colored and logodef.ascii.requires_color) then -- Choose a sensible default if colored then logodef = getLogodef(drawer.default_color_logodef) @@ -350,7 +414,10 @@ local function drawlogo() end end - if logodef ~= nil and logodef.graphic == none then + -- This is a special little hack for the "none" logo to re-align the + -- menu and the brand to avoid having a lot of extraneous whitespace on + -- the right side. + if logodef and logodef.ascii.image == none then shift = logodef.shift else shift = default_shift @@ -359,25 +426,23 @@ local function drawlogo() x = x + shift.x y = y + shift.y - if logodef ~= nil and logodef.shift ~= nil then - x = x + logodef.shift.x - y = y + logodef.shift.y - end - - if core.isFramebufferConsole() and - loader.term_putimage ~= nil and - logodef.image ~= nil then - local y1 = 15 + local gfx_requested = logodef.fb and gfxenabled() + if gfx_requested and gfxcapable() then + local y1 = logodef.fb.width or 15 - if logodef.image_rl ~= nil then - y1 = logodef.image_rl + if logodef.fb.shift then + x = x + (logodef.fb.shift.x or 0) + y = y + (logodef.fb.shift.y or 0) end - if loader.term_putimage(logodef.image, x, y, 0, y + y1, 0) - then + if gfx.term_putimage(logodef.fb.image, x, y, 0, y + y1, 0) then return true end + elseif logodef.ascii.shift then + x = x + (logodef.ascii.shift.x or 0) + y = y + (logodef.ascii.shift.y or 0) end - draw(x, y, logodef.graphic) + + draw(x, y, logodef.ascii.image) end local function drawitem(func) @@ -434,11 +499,15 @@ branddefs = { -- Indexed by valid values for loader_brand in loader.conf(5). Valid -- keys are: graphic (table depicting graphic) ["fbsd"] = { - graphic = fbsd_brand, - image = "/boot/images/freebsd-brand-rev.png", + ascii = { + image = fbsd_brand, + }, + fb = { + image = "/boot/images/freebsd-brand-rev.png", + }, }, ["none"] = { - graphic = none, + ascii = { image = none }, }, } @@ -447,21 +516,27 @@ logodefs = { -- are: requires_color (boolean), graphic (table depicting graphic), and -- shift (table containing x and y). ["tribute"] = { - graphic = fbsd_brand, + ascii = { + image = fbsd_brand, + }, }, ["tributebw"] = { - graphic = fbsd_brand, + ascii = { + image = fbsd_brand, + }, }, ["none"] = { - graphic = none, + ascii = { + image = none, + }, shift = {x = 17, y = 0}, }, } brand_position = {x = 2, y = 1} -logo_position = {x = 46, y = 4} +logo_position = {x = 40, y = 10} menu_position = {x = 5, y = 10} -frame_size = {w = 42, h = 13} +frame_size = {w = 39, h = 14} default_shift = {x = 0, y = 0} shift = default_shift @@ -473,14 +548,12 @@ drawer.default_bw_logodef = 'orbbw' -- drawer module in case it's a filesystem issue. drawer.default_fallback_logodef = 'none' --- These should go away after FreeBSD 13; only available for backwards --- compatibility with old logo- files. function drawer.addBrand(name, def) - branddefs[name] = def + branddefs[name] = adapt_fb_shim(def) end function drawer.addLogo(name, def) - logodefs[name] = def + logodefs[name] = adapt_fb_shim(def) end drawer.frame_styles = { @@ -495,23 +568,45 @@ drawer.frame_styles = { top_right = "+", bottom_right = "+", }, - ["single"] = { +} + +if core.hasUnicode() then + -- unicode based framing characters + drawer.frame_styles["single"] = { horizontal = "\xE2\x94\x80", vertical = "\xE2\x94\x82", top_left = "\xE2\x94\x8C", bottom_left = "\xE2\x94\x94", top_right = "\xE2\x94\x90", bottom_right = "\xE2\x94\x98", - }, - ["double"] = { + } + drawer.frame_styles["double"] = { horizontal = "\xE2\x95\x90", vertical = "\xE2\x95\x91", top_left = "\xE2\x95\x94", bottom_left = "\xE2\x95\x9A", top_right = "\xE2\x95\x97", bottom_right = "\xE2\x95\x9D", - }, -} + } +else + -- non-unicode cons25-style framing characters + drawer.frame_styles["single"] = { + horizontal = "\xC4", + vertical = "\xB3", + top_left = "\xDA", + bottom_left = "\xC0", + top_right = "\xBF", + bottom_right = "\xD9", + } + drawer.frame_styles["double"] = { + horizontal = "\xCD", + vertical = "\xBA", + top_left = "\xC9", + bottom_left = "\xC8", + top_right = "\xBB", + bottom_right = "\xBC", + } +end function drawer.drawscreen(menudef) -- drawlogo() must go first. diff --git a/stand/lua/drawer.lua.8 b/stand/lua/drawer.lua.8 index 4a76895bdddb..91738f4b2434 100644 --- a/stand/lua/drawer.lua.8 +++ b/stand/lua/drawer.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd August 19, 2018 +.Dd March 29, 2025 .Dt DRAWER.LUA 8 .Os .Sh NAME .Nm drawer.lua -.Nd FreeBSD menu/screen drawer module +.Nd bootloader menu/screen drawer module .Sh DESCRIPTION .Nm contains functionality for drawing and manipulating the menu, logo, and brand diff --git a/stand/lua/gfx-beastie.lua b/stand/lua/gfx-beastie.lua index f88f8c8dd306..f91e70667dac 100644 --- a/stand/lua/gfx-beastie.lua +++ b/stand/lua/gfx-beastie.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,8 +24,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- return { logo = { @@ -51,5 +49,6 @@ return { " `--{__________)\027[m", }, requires_color = true, + shift = {x = 2, y = -5}, } } diff --git a/stand/lua/gfx-beastiebw.lua b/stand/lua/gfx-beastiebw.lua index 5895b2436542..84e3dc6997df 100644 --- a/stand/lua/gfx-beastiebw.lua +++ b/stand/lua/gfx-beastiebw.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,8 +24,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- return { logo = { @@ -50,5 +48,6 @@ return { " ,' ,-----' |", " `--{__________)", }, + shift = {x = 2, y = -5}, } } diff --git a/stand/lua/gfx-fbsdbw.lua b/stand/lua/gfx-fbsdbw.lua index c219934b4ad6..df3b6c856eef 100644 --- a/stand/lua/gfx-fbsdbw.lua +++ b/stand/lua/gfx-fbsdbw.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,8 +24,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- return { logo = { @@ -44,6 +42,6 @@ return { " | | | |", " |____/|_____/|_____/", }, - shift = {x = 5, y = 4}, + shift = {x = 7, y = -1}, } } diff --git a/stand/lua/gfx-install.lua b/stand/lua/gfx-install.lua new file mode 100644 index 000000000000..d4cd34e32e1e --- /dev/null +++ b/stand/lua/gfx-install.lua @@ -0,0 +1,24 @@ +-- +-- Copyright (c) 2025 Joseph Mingrone <jrm@FreeBSD.org> +-- +-- SPDX-License-Identifier: BSD-2-Clause +-- + +return { + brand = { + ascii = { + image = { + " _____ ____ ____ ____ ___ _ _ _", + "| ___| __ ___ ___| __ ) ___|| _ \\ |_ _|_ __ ___| |_ __ _| | | ___ _ __", + "| |_ | '__/ _ \\/ _ \\ _ \\___ \\| | | | | || '_ \\/ __| __/ _` | | |/ _ \\ '__|", + "| _|| | | __/ __/ |_) |__) | |_| | | || | | \\__ \\ || (_| | | | __/ |", + "|_| |_| \\___|\\___|____/____/|____/ |___|_| |_|___/\\__\\__,_|_|_|\\___|_|", + }, + requires_color = false, + }, + fb = { + image = "/boot/images/freebsd-install-brand-rev.png", + width = 80, + }, + } +} diff --git a/stand/lua/gfx-orb.lua b/stand/lua/gfx-orb.lua index 2702618948d6..6845d6fa07bb 100644 --- a/stand/lua/gfx-orb.lua +++ b/stand/lua/gfx-orb.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,12 +24,11 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- return { logo = { - graphic = { + ascii = { + image = { " \027[31m``` \027[31;1m`\027[31m", " s` `.....---...\027[31;1m....--.``` -/\027[31m", " +o .--` \027[31;1m/y:` +.\027[31m", @@ -45,10 +44,14 @@ return { " `:` \027[31;1m`:`", " \027[31;1m.-- `--.", " .---.....----.\027[m", + }, + requires_color = true, + shift = {x = 5, y = -1}, + }, + fb = { + image = "/boot/images/freebsd-logo-rev.png", + width = 15, + shift = {x = 2, y = -2}, }, - requires_color = true, - shift = {x = 2, y = 3}, - image = "/boot/images/freebsd-logo-rev.png", - image_rl = 15 } } diff --git a/stand/lua/gfx-orbbw.lua b/stand/lua/gfx-orbbw.lua index 7cc8b1919b03..135ff806b67c 100644 --- a/stand/lua/gfx-orbbw.lua +++ b/stand/lua/gfx-orbbw.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,28 +24,28 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- return { logo = { - graphic = { - " ``` `", - " s` `.....---.......--.``` -/", - " +o .--` /y:` +.", - " yo`:. :o `+-", - " y/ -/` -o/", - " .- ::/sy+:.", - " / `-- /", - " `: :`", - " `: :`", - " / /", - " .- -.", - " -- -.", - " `:` `:`", - " .-- `--.", - " .---.....----.", + ascii = { + image = { + " ``` `", + " s` `.....---.......--.``` -/", + " +o .--` /y:` +.", + " yo`:. :o `+-", + " y/ -/` -o/", + " .- ::/sy+:.", + " / `-- /", + " `: :`", + " `: :`", + " / /", + " .- -.", + " -- -.", + " `:` `:`", + " .-- `--.", + " .---.....----.", + }, + shift = {x = 2, y = -1}, }, - shift = {x = 2, y = 4}, } } diff --git a/stand/lua/gfx.lua.8 b/stand/lua/gfx.lua.8 new file mode 100644 index 000000000000..75f258026804 --- /dev/null +++ b/stand/lua/gfx.lua.8 @@ -0,0 +1,106 @@ +.\" +.\" Copyright (c) 2024 Netflix, Inc. +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.Dd March 29, 2025 +.Dt GFX.LUA 8 +.Os +.Sh NAME +.Nm gfx.lua +.Nd bootloader graphics module +.Sh DESCRIPTION +The built-in graphics related Lua bindings for the +.Fx +boot loaders using the Lua interpreter are available via the +.Ic gfx +table. +.Ss Exported Functions +The following functions are exported in the +.Nm loader +table. +.Bl -tag -width term_putimage +.It Fn fb_bezier x0 y0 x1 y1 x2 y2 width +Draw a bezier curve through the points +.Pq Va x0 , Va y0 , +.Pq Va x1 , Va y1 , +and +.Pq Va x2 , Va y2 +of width +.Va width . +The units are in pixels and have an origin of +.Pq 0 , 0 . +.It Fn fb_drawrect x0 y0 x1 y1 fill +Fill in a rectangle with the pixel +.Va fill +with the corners +.Pq Va x0 , Va y0 +and +.Pq Va x1 , Va y1 . +The units are in pixels and have an origin of +.Pq 0 , 0 . +.It Fn fb_line x0 y0 x1 y1 width +Draw a line from +.Pq Va x0 , Va y0 +to +.Pq Va x1 , Va y1 +with a width of +.Va width . +The units are in pixels and have an origin of +.Pq 0 , 0 . +.It Fn fb_putimage name x0 y0 x1 y1 f +Load the PNG file +.Va name +and place it in the rectangle +with the corners +.Pq Va x0 , Va y0 +and +.Pq Va x1 , Va y1 +and fill with pixel +.Va f . +The units are in pixels and have an origin of +.Pq 0 , 0 . +.It Fn fb_set_pixel x y +Sets the pixel at +.Pq Va x , Va y . +The units are in pixels and have an origin of +.Pq 0 , 0 . +.It Fn term_drawrect x0 y0 x1 y1 +Draw the outline of a rectangle with the text coordinate corners of +.Pq Va x0 , Va y0 +and +.Pq Va x1 , Va y1 . +The units are in character cells and have an origin of +.Pq 1 , 1 . +.It Fn term_putimage name x0 y0 x1 y1 f +Load the PNG file +.Va name +and place it in the rectangle +with the text coordinate corners +.Pq Va x0 , Va y0 +and +.Pq Va x1 , Va y1 +and fill with pixel +.Va f . +The units are in character cells and have an origin of +.Pq 1 , 1 . +.El +.Pp +This table is optional and should only be used if it is non-nil and if +.Fn core.isFramebufferConsole +is true. +.Ss Compatibility +All the interfaces described above are also available via the +.Ic loader +table through at last FreeBSD 15.0. +.Sh SEE ALSO +.Xr loader.conf 5 , +.Xr core.lua 8 , +.Xr loader 8 , +.Xr loader.lua 8 +.Sh AUTHORS +The +.Nm +man page was written by +.An Warner Losh Aq Mt imp@FreeBSD.org . + diff --git a/stand/lua/hook.lua b/stand/lua/hook.lua index 9c7e4deeb7e4..796189eeef18 100644 --- a/stand/lua/hook.lua +++ b/stand/lua/hook.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> -- @@ -24,8 +24,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local hook = {} @@ -60,7 +58,7 @@ end -- Takes a hooktype and runs all functions associated with that specific hook -- type in the order that they were registered in. This ordering should likely -- not be relied upon. -function hook.runAll(hooktype) +function hook.runAll(hooktype, data) local selected_hooks = registered_hooks[hooktype] if selected_hooks == nil then -- This message, and the print() above, should only be seen by @@ -74,7 +72,7 @@ function hook.runAll(hooktype) end if #selected_hooks > 0 then for _, func in ipairs(selected_hooks) do - func() + func(data) end end return #selected_hooks diff --git a/stand/lua/hook.lua.8 b/stand/lua/hook.lua.8 index 1bc9ca96b509..91d5f76b6e1c 100644 --- a/stand/lua/hook.lua.8 +++ b/stand/lua/hook.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd June 9, 2018 +.Dd March 29, 2025 .Dt HOOK.LUA 8 .Os .Sh NAME .Nm hook.lua -.Nd FreeBSD hook module +.Nd bootloader hook module .Sh DESCRIPTION .Nm contains functionality for defining hook types and attaching hooks. @@ -39,6 +37,8 @@ Hooks are functions used to attach custom behaviors at pre-defined points in loader execution. These pre-defined points are what we refer to as .Dq hook types . +Hooks may also take an optional data parameter, which may or may not be +populated by the caller. .Pp Before using the functionality provided by .Nm , diff --git a/stand/lua/loader.conf.lua.5 b/stand/lua/loader.conf.lua.5 new file mode 100644 index 000000000000..509944ab6598 --- /dev/null +++ b/stand/lua/loader.conf.lua.5 @@ -0,0 +1,75 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2020 Kyle Evans <kevans@FreeBSD.org> +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 10, 2023 +.Dt LOADER.CONF.LUA 5 +.Os +.Sh NAME +.Nm loader.conf.lua +.Nd system bootstrap Lua configuration information +.Sh DESCRIPTION +When the lua-based +.Xr loader 8 +encounters a filename in +.Va loader_conf_files +that has a +.Dq .lua +suffix, it will be loaded and executed by the lua interpreter in a limited +environment. +.Pp +The limited environment does not contain the ability to reference or load other +lua modules. +Existing loader environment variables may be referenced as if they were already +defined global variables. +.Pp +A lua configuration file may set any global variable, which will subsequently +be processed and added to the environment after execution of the configuration +file has completed. +Other than the +.Ar exec +setting, all variables described in +.Xr loader.conf 5 +operate the same in the +.Nm +environment. +Note that the settings describing module options can only be set in the +environment; there is currently no way for a +.Pa loader.conf.lua +to fetch them. +At this time, global table and function values are ignored. +.Pp +The +.Fn config.buildenv +hook will be run with an empty environment provided to it that may be populated +by a custom +.Pa local.lua . +.Sh SEE ALSO +.Xr loader.conf 5 +.Sh AUTHORS +The mechanism for loading +.Nm +files was originally written by +.An Kyle Evans Aq Mt kevans@FreeBSD.org . diff --git a/stand/lua/loader.lua b/stand/lua/loader.lua index 0008cae93641..0874239db587 100644 --- a/stand/lua/loader.lua +++ b/stand/lua/loader.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> @@ -26,8 +26,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- -- The cli module should be included first here. Some of the functions that it -- defines are necessary for the Lua-based loader to operate in general. @@ -56,4 +54,6 @@ if not core.isMenuSkipped() then else -- Load kernel/modules before we go config.loadelf() + -- Load platform entropy if possible + core.loadEntropy() end diff --git a/stand/lua/loader.lua.8 b/stand/lua/loader.lua.8 new file mode 100644 index 000000000000..ffee46526c9f --- /dev/null +++ b/stand/lua/loader.lua.8 @@ -0,0 +1,196 @@ +.\" +.\" Copyright (c) 2024 Netflix, Inc. +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.Dd March 29, 2025 +.Dt LOADER.LUA 8 +.Os +.Sh NAME +.Nm loader.lua +.Nd bootloader Lua binding module +.Sh DESCRIPTION +The built-in Lua bindings for the +.Fx +boot loaders using the Lua interpreter +are available via the +.Ic loader +table. +.Pp +The +.Ic loader +table is always available in Lua scripts. +There is no need to require it like other loader-specific modules. +.Ss Exported Variables +The following variables are provided by the Lua interpreter in the +.Nm loader +table: +.Bl -tag -width machine_arch +.It Ic machine +The target's +.Va hw.machine +.Xr sysctl 8 +value. +.It Ic machine_arch +The target's +.Va hw.machine_arch +.Xr sysctl 8 +value. +Some boot loaders are 32-bit applications that then load a 64-bit +kernel. +In these cases, +.Ic machine_arch +represents the 32-bit architecture, not the 64-bit architecture. +.It Ic lua_path +The current lua loading path. +.It Ic version +The version of the boot program. +.El +.Ss Exported Functions +The following functions are exported in the +.Nm loader +table. +.Bl -tag -width term_putimage +.It Fn delay usec +Delay for +.Va usec +microseconds. +.It Fn command_error +Returns the error string from the last command to fail. +.It Fn command argc argv +Like +.Fn perform +but the arguments are already parsed onto the stack. +.It Fn exit status +Exit the boot loader back to the firmware with a status of +.Va status . +The interpretation of this value is firmware specific. +.It Fn interpret str +Execute the loader builtin command +.Va str +as if it were typed by the user. +This will first try to execute +.Va str +as Lua. +If that fails, it will attempt to execute it as a cli command, +including those defined by the +.Xr cli.lua 8 +mechanism. +If that fails, it will attempt to execute it as a builtin command +and return the same values as +.Fn perform . +.It Fn parse str +Parses the command +.Va str +into its words and return those words on the stack. +.It Fn getenv name +Obtains the value of the environment variable +.Va name . +.It Fn has_command cmd +returns +.Va true +if +.Va commmand +is present in the interpreter as a builtin. +Otherwise it returns +.Va nil +and an error string. +It does not check the +.Dq cli +table to see if a user defined command has been created. +.It Fn has_feature feature +returns +.Va true +if the +.Va feature +is enabled. +Otherwise it returns +.Va nil +and an error string. +.It Fn perform str +Execute the loader builtin command +.Va str . +Returns the result of the command, one of the following values: +.Bl -tag -width loader -offset indent +.It loader.CMD_OK +The command completed successfully. +.It loader.CMD_WARN +The command was successful, but the user stopped its output +prematurely. +.It loader.CMD_ERROR +The command did not complete successfully. +Use +.Va command_error +to retrieve the error. +.It loader.CMD_CRIT +The command returned a critical error that was already printed. +.It loader.CMD_FATAL +The command determined continuation was not possible +and the loader panicked. +In practice, though, +.Fn panic +does not return. +.El +.It Fn printc str +Outputs the string using the loader's +.Fn putchar +function. +This function is also available globally as +.Fn printc . +.It Fn setenv name value +Insert or reset the environment variable +.Va name +into the loader's environment list. +If no environment variable with this name exists, one is created. +If one exists, its value is replaced. +.It Fn time +Returns the loader's notion of time, in seconds since 1970. +The value of loader's notion varies somewhat between different loading +environments. +.It Fn unsetenv name +Removes the environment variable +.Va name +from the loader's environment list. +.El +.Ss Compatibility +The functions +.Fn fb_bezier , +.Fn fb_drawrect , +.Fn fb_line , +.Fn fb_putimage , +.Fn fb_set_pixel , +.Fn term_drawrect , +and +.Fn term_putimage +have moved to the +.Ic gfx +table. +They remain in the +.Ic loader +table for a transition period and are documented in +.Xr gfx.lua 8 . +.Ss Default File +In addition, the Lua interpreters start with the file +.Pa /boot/lua/loader.lua +when they start to boot the system. +The default one will fixup the screen, load the configuration files, check for a +password, and then load the menu or load the kernel file and then return. +If autoboot is enabled, the loaded files will boot. +.Sh SEE ALSO +.Xr loader.conf 5 , +.Xr core.lua 8 , +.Xr gfx.lua 8 , +.Xr loader 8 , +.Xr sysctl 8 +.Sh AUTHORS +The +.Nm +man page was written by +.An Warner Losh Aq Mt imp@FreeBSD.org . +.Sh BUGS +.Fn command +and +.Fn perform +should return a tuple when there's +.Va CMD_ERROR +or worse. diff --git a/stand/lua/menu.lua b/stand/lua/menu.lua index f1a4f07a8d73..fb0645eb46ba 100644 --- a/stand/lua/menu.lua +++ b/stand/lua/menu.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> @@ -26,8 +26,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local cli = require("cli") local core = require("core") @@ -58,6 +56,13 @@ local function bootenvSet(env) loader.setenv("vfs.root.mountfrom", env) loader.setenv("currdev", env .. ":") config.reload() + if loader.getenv("kernelname") ~= nil then + loader.perform("unload") + end +end + +local function multiUserPrompt() + return loader.getenv("loader_menu_multi_user_prompt") or "Multi user" end -- Module exports @@ -117,7 +122,7 @@ menu.boot_environments = { if is_default then name_color = color.escapefg(color.GREEN) else - name_color = color.escapefg(color.BLUE) + name_color = color.escapefg(color.CYAN) end bootenv_name = bootenv_name .. name_color .. choice .. color.resetfg() @@ -171,7 +176,7 @@ menu.boot_options = { -- acpi { entry_type = core.MENU_ENTRY, - visible = core.isSystem386, + visible = core.hasACPI, name = function() return OnOff(color.highlight("A") .. "CPI :", core.acpi) @@ -250,24 +255,40 @@ menu.welcome = { }, { entry_type = core.MENU_SEPARATOR, - name = "Options:", + name = "Kernel:", }, menu_entries.kernel_options, + { + entry_type = core.MENU_SEPARATOR, + }, + { + entry_type = core.MENU_SEPARATOR, + name = "Options:", + }, menu_entries.boot_options, menu_entries.zpool_checkpoints, menu_entries.boot_envs, menu_entries.chainload, menu_entries.vendor, + { + entry_type = core.MENU_SEPARATOR, + }, + menu_entries.loader_needs_upgrade, } end, all_entries = { multi_user = { entry_type = core.MENU_ENTRY, - name = color.highlight("B") .. "oot Multi user " .. - color.highlight("[Enter]"), + name = function() + return color.highlight("B") .. "oot " .. + multiUserPrompt() .. " " .. + color.highlight("[Enter]") + end, -- Not a standard menu entry function! - alternate_name = color.highlight("B") .. - "oot Multi user", + alternate_name = function() + return color.highlight("B") .. "oot " .. + multiUserPrompt() + end, func = function() core.setSingleUser(false) core.boot() @@ -318,22 +339,19 @@ menu.welcome = { items = core.kernelList, name = function(idx, choice, all_choices) if #all_choices == 0 then - return "Kernel: " + return "" end - local is_default = (idx == 1) - local kernel_name = "" + local kernel_name local name_color - if is_default then + if idx == 1 then name_color = color.escapefg(color.GREEN) - kernel_name = "default/" else - name_color = color.escapefg(color.BLUE) + name_color = color.escapefg(color.CYAN) end - kernel_name = kernel_name .. name_color .. - choice .. color.resetfg() - return color.highlight("K") .. "ernel: " .. - kernel_name .. " (" .. idx .. " of " .. + kernel_name = name_color .. choice .. + color.resetfg() + return kernel_name .. " (" .. idx .. " of " .. #all_choices .. ")" end, func = function(_, choice, _) @@ -401,6 +419,15 @@ menu.welcome = { end, alias = {"l", "L"}, }, + loader_needs_upgrade = { + entry_type = core.MENU_SEPARATOR, + name = function() + return color.highlight("Loader needs to be updated") + end, + visible = function() + return core.loaderTooOld() + end + }, vendor = { entry_type = core.MENU_ENTRY, visible = function() @@ -507,12 +534,14 @@ function menu.run() drawn_menu = nil screen.defcursor() + -- We explicitly want the newline print adds print("Exiting menu!") end function menu.autoboot(delay) local x = loader.getenv("loader_menu_timeout_x") or 4 - local y = loader.getenv("loader_menu_timeout_y") or 23 + local y = loader.getenv("loader_menu_timeout_y") or 24 + local autoboot_show = loader.getenv("loader_autoboot_show") or "yes" local endtime = loader.time() + delay local time local last @@ -520,19 +549,24 @@ function menu.autoboot(delay) time = endtime - loader.time() if last == nil or last ~= time then last = time - screen.setcursor(x, y) - print("Autoboot in " .. time .. - " seconds. [Space] to pause ") - screen.defcursor() + if autoboot_show == "yes" then + screen.setcursor(x, y) + printc("Autoboot in " .. time .. + " seconds. [Space] to pause ") + screen.defcursor() + end end if io.ischar() then local ch = io.getchar() if ch == core.KEY_ENTER then break else - -- erase autoboot msg - screen.setcursor(0, y) - print(string.rep(" ", 80)) + -- Erase autoboot msg. While real VT100s + -- wouldn't scroll when receiving a char with + -- the cursor at (79, 24), bad emulators do. + -- Avoid the issue by stopping at 79. + screen.setcursor(1, y) + printc(string.rep(" ", 79)) screen.defcursor() return ch end diff --git a/stand/lua/menu.lua.8 b/stand/lua/menu.lua.8 index 38655414258f..e2e32efdf3b4 100644 --- a/stand/lua/menu.lua.8 +++ b/stand/lua/menu.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd March 31, 2021 +.Dd March 29, 2025 .Dt MENU.LUA 8 .Os .Sh NAME .Nm menu.lua -.Nd FreeBSD dynamic menu boot module +.Nd bootloader dynamic menu module .Sh DESCRIPTION .Nm contains the main functionality required to build a dynamic menu system. @@ -283,6 +281,7 @@ stock_options[#stock_options + 1] = { end, alias= {"l", "L"} } +.Ed .Sh SEE ALSO .Xr loader.conf 5 , .Xr core.lua 8 , diff --git a/stand/lua/password.lua b/stand/lua/password.lua index 8edd4edd7ec3..3d3060f5cab3 100644 --- a/stand/lua/password.lua +++ b/stand/lua/password.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> @@ -26,8 +26,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local core = require("core") local screen = require("screen") @@ -135,6 +133,7 @@ function password.check() local pwd = loader.getenv("password") if pwd ~= nil then core.autoboot() + loader.setenv("autoboot_delay", "NO") -- The autoboot sequence was interrupted, so we'll need to -- prompt for a password. Put the screen back into a known -- good state, otherwise we're drawing back a couple lines diff --git a/stand/lua/password.lua.8 b/stand/lua/password.lua.8 index db235aadec8d..34623c001206 100644 --- a/stand/lua/password.lua.8 +++ b/stand/lua/password.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd August 19, 2018 +.Dd March 29, 2025 .Dt PASSWORD.LUA 8 .Os .Sh NAME .Nm password.lua -.Nd FreeBSD password module +.Nd bootloader password module .Sh DESCRIPTION .Nm contains functionality for prompting for and checking passwords. diff --git a/stand/lua/screen.lua b/stand/lua/screen.lua index baa58fb23dca..89d5416815fd 100644 --- a/stand/lua/screen.lua +++ b/stand/lua/screen.lua @@ -1,5 +1,5 @@ -- --- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> -- All rights reserved. @@ -25,8 +25,6 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- --- $FreeBSD$ --- local color = require("color") local core = require("core") @@ -34,7 +32,7 @@ local core = require("core") local screen = {} -- Module exports -screen.default_x = 0 +screen.default_x = 1 screen.default_y = 25 function screen.clear() diff --git a/stand/lua/screen.lua.8 b/stand/lua/screen.lua.8 index d272f3ca8028..a41ce6faf08b 100644 --- a/stand/lua/screen.lua.8 +++ b/stand/lua/screen.lua.8 @@ -1,5 +1,5 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org> .\" @@ -24,14 +24,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd August 19, 2018 +.Dd March 29, 2025 .Dt SCREEN.LUA 8 .Os .Sh NAME .Nm screen.lua -.Nd FreeBSD screen manipulation module +.Nd bootloader screen manipulation module .Sh DESCRIPTION .Nm contains functionality for manipulating the screen. diff --git a/stand/man/Makefile b/stand/man/Makefile index 27370624ff62..1075c2e831c7 100644 --- a/stand/man/Makefile +++ b/stand/man/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> M.${MK_EFI}+= boot1.efi.8 diff --git a/stand/man/Makefile.depend b/stand/man/Makefile.depend index f80275d86ab1..11aba52f82cf 100644 --- a/stand/man/Makefile.depend +++ b/stand/man/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/man/boot1.efi.8 b/stand/man/boot1.efi.8 index efd3c2c93d5e..b6135f8e0e12 100644 --- a/stand/man/boot1.efi.8 +++ b/stand/man/boot1.efi.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd April 6, 2021 .Dt BOOT1.EFI 8 .Os diff --git a/stand/man/loader.8 b/stand/man/loader.8 index 7e652a536b21..4fc3bbb7cff0 100644 --- a/stand/man/loader.8 +++ b/stand/man/loader.8 @@ -23,8 +23,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd September 29, 2021 .Dt LOADER 8 .Os diff --git a/stand/man/loader.efi.8 b/stand/man/loader.efi.8 index ca7480d5eba6..c488ac257804 100644 --- a/stand/man/loader.efi.8 +++ b/stand/man/loader.efi.8 @@ -1,8 +1,13 @@ .\" -.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" SPDX-License-Identifier: BSD-2-Clause .\" -.\" Copyright (c) 2019 Netflix, Inc +.\" Copyright (c) 2019-2022 Netflix, Inc .\" Copyright (c) 2022 Mateusz Piotrowski <0mp@FreeBSD.org> +.\" Copyright 2022 The FreeBSD Foundation +.\" +.\" Part of this documentation was written by +.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship +.\" from the FreeBSD Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -25,9 +30,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd March 18, 2022 +.Dd September 3, 2024 .Dt LOADER.EFI 8 .Os .Sh NAME @@ -41,7 +44,287 @@ loads the kernel. .Xr boot1.efi 8 is used to load .Nm -when it is placed within the system. +when it is placed within a UFS or ZFS file system. +Alternatively, +.Nm +is used directly when configured with +.Xr efibootmgr 8 , +or when placed directly as the default boot program as described in +.Xr uefi 8 . +When a system is built using +.Xr bsdinstall 8 , +.Nm +will be used directly. +.Ss Console Considerations +The EFI BIOS provides a generic console. +In +.Nm +this is selected by specifying +.Dq efi +using the +.Dv console +variable. +.Nm +examines the +.Dv 8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut +UEFI environment variable to guess what the +.Dq efi +console points to. +.Nm +will output its prompts and menus to all the places specified by ConOut. +However, the +.Fx +kernel has a limitation when more than one console is present. +The kernel outputs to all configured consoles. +Only the primary console will get the log messages from the +.Xr rc 8 +system, and prompts for things like +.Xr geli 8 +passwords. +If +.Nm +finds a video device first, then +.Nm +tells the kernel to use the video console as primary. +Likewise, if a serial device is first in the +.Dv ConOut +list, the serial port will be the primary console. +.Pp +If there is no +.Dv ConOut +variable, both serial and video are attempted. +.Nm +uses the +.Dq efi +console for the video (which may or may not work) and +.Dq comconsole +for the serial on +.Dv COM1 +at the default baud rate. +The kernel will use a dual console, with the video console +primary if a UEFI graphics device is detected, or the serial console +as primary if not. +.Pp +On x86 platforms, if you wish to redirect the loader's output to a serial port +when the EFI BIOS doesn't support it, or to a serial port that isn't the one the +EFI BIOS redirects its output to, set +.Dv console +to +.Dq comconsole . +The default port is +.Dv COM1 +with an I/O address of 0x3f8. +.Dv comconsole_port +is used to set this to a different port address. +.Dv comconsole_speed +is used to set the of the serial port (the default is 9600). +If you have +.Dv console +set to +.Dq efi,comconsole +you will get output on both the EFI console and the serial port. +If this causes a doubling of characters, set +.Dv console +to +.Dq efi , +since your EFI BIOS is redirecting to the serial port already. +.Pp +If your EFI BIOS redirects the serial port, you may need to tell the kernel +which address to use. +EFI uses ACPI's UID to identify the serial port, but +.Nm +does not have an ACPI parser, so it cannot convert that to an I/O port. +The +.Fx +kernel initializes its consoles before it can decode ACPI resources. +The +.Fx +kernel will look at the +.Dv hw.uart.console +variable to set its serial console. +Its format should be described in +.Xr uart 4 +but is not. +Set it to +.Dq io:0x3f8,br:115200 +with the proper port address. +PCI or memory mapped ports are beyond the scope of this man page. +.Pp +The serial ports are assigned as follows on IBM PC compatible systems: +.Bl -column -offset indent ".Sy Windows Name" ".Sy I/O Port Address" ".Sy Typical FreeBSD device" +.It Sy Windows Name Ta Sy I/O Port Address Ta Sy Typical FreeBSD device +.It COM1 Ta 0x3f8 Ta Pa /dev/uart0 +.It COM2 Ta 0x2f8 Ta Pa /dev/uart1 +.It COM3 Ta 0x3e8 Ta Pa /dev/uart2 +.It COM4 Ta 0x2e8 Ta Pa /dev/uart3 +.El +Though +.Dv COM3 +and +.Dv COM4 +can vary. +.Pp +.Ss Primary Console +The primary console is set using the boot flags. +These command line arguments set corresponding flags for the kernel. +These flags can be controlled by setting loader environment variables +to +.Dq yes +or +.Dq no . +Boot flags may be set on the command line to the boot command. +Inside the kernel, the RB_ flags are used to control behavior, sometimes +in architecturally specific ways and are included to aid in discovery +of any behavior not covered in this document. +.Bl -column -offset indent ".Sy boot flag" ".Sy loader variable" ".Sy Kernel RB_ flag" +.It Sy boot flag Ta Sy loader variable Ta Sy Kernel RB_ flag +.It Fl a Ta Dv boot_askme Ta Va RB_ASKNAME +.It Fl c Ta Dv boot_cdrom Ta Va RB_CDROM +.It Fl d Ta Dv boot_ddb Ta Va RB_KDB +.It Fl r Ta Dv boot_dfltroot Ta Va RB_DFLTROOT +.It Fl D Ta Dv boot_multiple Ta Va RB_MULTIPLE +.It Fl m Ta Dv boot_mute Ta Va RB_MUTE +.It Fl g Ta Dv boot_gdb Ta Va RB_GDB +.It Fl h Ta Dv boot_serial Ta Va RB_SERIAL +.It Fl p Ta Dv boot_pause Ta Va RB_PAUSE +.It Fl P Ta Dv boot_probe Ta Va RB_PROBE +.It Fl s Ta Dv boot_single Ta Va RB_SINGLE +.It Fl v Ta Dv boot_verbose Ta Va RB_VERBOSE +.El +And the following flags determine the primary console: +.Bl -column -offset indent ".Sy Flags" ".Sy Kernel Flags" ".Sy Kernel Consoles" ".Sy Primary Console" +.It Sy Flags Ta Sy Kernel Flags Ta Sy Kernel Consoles Ta Sy Primary Console +.It none Ta 0 Ta Video Ta Video +.It Fl h Ta RB_SERIAL Ta Serial Ta Serial +.It Fl D Ta RB_MULTIPLE Ta Serial, Video Ta Video +.It Fl Dh Ta RB_SERIAL | RB_MULTIPLE Ta Serial, Video Ta Serial +.El +.Pp +.Nm +does not implement the probe +.Fl P +functionality where we use the video console if a keyboard is connected and a +serial console otherwise. +.Ss Additional Environment Variables +.Nm +loads some extra variables early in startup from +.Pa /efi/freebsd/loader.env +from the EFI partition. +Only simple variables can be set here. +It can be useful to specify the root filesystem: +.Bd -literal -offset indent +rootdev=disk0s1a +.Ed +.Ss Staging Slop +The kernel must parse the firmware memory map tables to know what memory +it can use. +Since it must allocate memory to do this, +.Nm +ensures there's extra memory available, called +.Dq slop , +after everything it loads +.Po +the kernel, modules and metadata +.Pc +for the kernel to bootstrap the memory allocator. +.Pp +By default, amd64 reserves 8MB. +The +.Ic staging_slop +command allows for tuning the slop size. +It takes a single argument, the size of the slop in bytes. +.Ss amd64 Nocopy +.Nm +will load the kernel into memory that is 2MB aligned below 4GB. +It cannot load to a fixed address because the UEFI firmware may reserve +arbitrary memory for its use at runtime. +Prior to +.Fx 13.1 , +kernels retained the old BIOS-boot protocol of loading at exactly 2MB. +Such kernels must be copied from their loaded location to 2MB prior +starting them up. +The +.Ic copy_staging +command is used to enable this copying for older kernels. +It takes a single argument +which can be one of +.Bl -tag -width disable +.It Ar disable +Force-disable copying staging area to +.Ad 2M . +.It Ar enable +Force-enable copying staging area to +.Ad 2M . +.It Ar auto +Selects the behaviour based on the kernel's capability of boostraping +from non-2M physical base. +The kernel reports this capability by exporting the symbol +.Va kernphys . +.El +.Pp +Arm64 loaders have operated in the +.Sq nocopy +mode from their inception, so there is no +.Ic copy_staging +command on that platform. +Riscv, 32-bit arm and arm64 have always loaded at any +.Ad 2MB +aligned location, so do not provide +.Ic copy_staging . +.Pp +.Bd -ragged -offset indent +.Sy Note. +BIOS loaders on i386 and amd64 put the staging area starting +at the physical address +.Ad 2M , +then enable paging with identical mapping for the low +.Ad 1G . +The initial port of +.Nm +followed the same scheme for handing control to the kernel, +since it avoided modifications for the loader/kernel hand-off protocol, +and for the kernel page table bootstrap. +.Pp +This approach is incompatible with the UEFI specification, +and as a practical matter, caused troubles on many boards, +because UEFI firmware is free to use any memory for its own needs. +Applications like +.Nm +must only use memory explicitly allocated using boot interfaces. +The original way also potentially destroyed UEFI runtime interfaces data. +.Pp +Eventually, +.Nm +and the kernel were improved to avoid this problem. +.Ed +.Ss amd64 Faults +Because it executes in x86 protected mode, the amd64 version of +.Nm +is susceptible to CPU faults due to programmer mistakes and +memory corruption. +To make debugging such faults easier, amd64 +.Nm +can provide detailed reporting of the CPU state at the time +of the fault. +.Pp +The +.Ic grab_faults +command installs a handler for faults directly in the IDT, +avoiding the use of the UEFI debugging interface +.Fn EFI_DEBUG_SUPPORT_PROTOCOL.RegisterExceptionCallback . +That interface is left available for advanced debuggers in +the UEFI environment. +The +.Ic ungrab_faults +command tries to deinstall the fault handler, returning TSS and IDT +CPU tables to their pre-installation state. +The +.Ic fault +command produces a fault in the +.Nm +environment for testing purposes, by executing the +.Ic ud2 +processor instruction. .Sh FILES .Bl -tag -width "/boot/loader.efi" .It Pa /boot/loader.efi @@ -49,7 +332,7 @@ The location of the UEFI kernel loader within the system. .El .Ss EFI System Partition .Nm -is installed on ESP (EFI System Partition) in one of the following locations: +is installed on the ESP (EFI System Partition) in one of the following locations: .Bl -tag -width "efi/freebsd/loader.efi" .It Pa efi/boot/bootXXX.efi The default location for any EFI loader @@ -68,35 +351,142 @@ EFI loader. The default location for the ESP mount point is documented in .Xr hier 7 . .Sh EXAMPLES -.Ss Updating loader.efi on ESP -The following examples shows how to install a new +.Ss Updating loader.efi on the ESP +The following example shows how to install a new .Nm -on ESP. +on the ESP. +The exact placement is complicated due to the diversity of +installations, setups and situations. +In this section, paths that are all lower case are Unix paths. +Paths that are all upper case are relative to the ESP mount point, +though they may appear as lower case on your system because the +FAT filesystem of the ESP is case insensitive. .Pp -First, find the partition of type +Locate the ESP, which has its own partition type of .Dq efi : .Bd -literal -offset indent -# gpart list | grep -Ew '(Name|efi)' -1. Name: nvd0p1 - type: efi -2. Name: nvd0p2 -3. Name: nvd0p3 -4. Name: nvd0p4 -1. Name: nvd0 +# gpart show nda0 +=> 40 7501476448 nda0 GPT (3.5T) + 40 614400 1 efi (300M) + 614440 7500862048 2 freebsd-zfs (3.5T) .Ed .Pp -The name of ESP on this system is -.Pa nvd0p1 . +The name of the ESP on this system is +.Pa nda0p1 . +By default, this will be mounted on +.Pa /boot/efi . +To check: +.Bd -literal -offset indent +# mount | grep nda0p1 +/dev/nda0p1 on /boot/efi (msdosfs, local) +.Ed +If it's not mounted, you will need to mount it: +.Bd -literal -offset indent +# mount -t msdosfs /dev/nda0p1 /boot/efi +.Ed .Pp -Second, let's mount ESP, copy -.Nm -to the special location reserved for -.Fx -EFI loaders, and unmount once finished: +.Xr efibootmgr 8 +reports what we booted from. +.Bd -literal -offset indent +# efibootmgr -v +Boot to FW : false +BootCurrent: 0001 +Timeout : 2 seconds +BootOrder : 0000, 0001, 0003, 0004, 0005, 0006, 0001, 0008, 000A, 000B, 000C, 000E, 0007 +\&... ++Boot0001* FreeBSD ZPOOL HD(1,GPT,b5d0f86b-265d-1e1b-18aa-0ed55e1e73bd,0x28,0x96000)/File(\eEFI\eFREEBSD\eLOADER.EFI) + nda0p1:/EFI/FREEBSD/LOADER.EFI /boot/efi//EFI/FREEBSD/LOADER.EFI +\&... +.Ed +Often there are several options, depending on the BIOS. +The entry that we booted with is marked with a +.Sq + +at the start of the line, as shown above. +So in this case, this firmware is using +.Pa /EFI/FREEBSD/LOADER.EFI +from the ESP. +Often times it will be the UEFI +.Dq default +loader, which varies by architecture. +.Bl -column -offset indent "Architecture" "Default Path" +.It Sy Architecture Ta Sy Default Path +.It amd64 Ta Pa /EFI/BOOT/BOOTX64.EFI +.It arm Ta Pa /EFI/BOOT/BOOTARM.EFI +.It arm64 Ta Pa /EFI/BOOT/BOOTAA64.EFI +.It i386 Ta Pa /EFI/BOOT/BOOTIA32.EFI +.It riscv Ta Pa /EFI/BOOT/BOOTRISCV64.EFI +.El +However, care must be taken: some multiple-boot environments rely on a special +.Pa bootXXX.efi +to function. +Before updating a +.Pa bootXXX.efi +file, make sure it is the FreeBSD boot loader before updating it: +.Bd -literal -offset indent +# strings /boot/efi/EFI/BOOT/BOOTX64.EFI | grep FreeBSD | grep EFI +FreeBSD/amd64 EFI loader, Revision 3.0 +.Ed +.Pp +.Xr bsdinstall 8 +copies +.Pa loader.efi +to the default name if there wasn't one there before. +Check to see if they are copies before updating (with X64 substituted using the +above table): +.Bd -literal -offset indent +# cmp /boot/efi/EFI/FREEBSD/LOADER.EFI /boot/efi/EFI/BOOT/BOOTX64.EFI +.Ed +Copy the loader: +.Bd -literal -offset indent +# cp /boot/loader.efi /boot/efi/EFI/FREEBSD/LOADER.EFI +.Ed +replacing the all caps part of the example with the proper path. +.Pp +If ESP path was +.Pa /FREEBSD/LOADER.EFI +and LOADER.EFI and BOOTX64.EFI were identical in the cmp step, +copy the loader to the default location: +.Bd -literal -offset indent +# cp /boot/loader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI +.Ed +.Pp +Finally, if you mounted the ESP, you may wish to unmount it. .Bd -literal -offset indent -# mount_msdosfs /dev/nvd0p1 /boot/efi -# cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi # umount /boot/efi +.Ed .Sh SEE ALSO .Xr loader 8 , .Xr uefi 8 +.Sh BUGS +Non-x86 serial console handling is even more confusing and less well documented. +.Pp +Sometimes when the serial port speed isn't set, 9600 is used. +Other times the result is typically 115200 since the speed remains unchanged +from the default. +.Pp +U-Boot implements a subset of the UEFI standard. +Some versions do not support fetching loader variables, so +.Pa efibootmgr +may not work. +In addition, +.Pa efibootmgr +is not supported on armv7 or riscv. +In these instances, the user has to understand what was booted to update +it properly (and in most cases, it will be the FreeBSD path and the UEFI default +so just copy loader.efi there if there are loaders there). +Typically in these embedded situations, there is only one .efi file (loader.efi +or a copy of loader.efi). +The path to this file is typically the default removable path above. +.Pp +Managing booting multiple OSes on UEFI varies greatly, so extra caution when +updating the UEFI default loader. +.Pp +The old, now obsolete, boot1.efi was installed as bootx64.efi in +.Fx 10 +and earlier. +Since it was quite limited in functionality, we created very small +ESPs by default. +A modern loader.efi will not fit. +However, if the old boot1.efi still works, there's no need to update +it since it will chain boot /boot/loader.efi from a copy that +make installworld updates. diff --git a/stand/man/loader_4th.8 b/stand/man/loader_4th.8 index 868e70d180d2..9e87326f893b 100644 --- a/stand/man/loader_4th.8 +++ b/stand/man/loader_4th.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd September 29, 2021 .Dt LOADER_4TH 8 .Os diff --git a/stand/man/loader_lua.8 b/stand/man/loader_lua.8 index 1432000c4b53..0aa467237266 100644 --- a/stand/man/loader_lua.8 +++ b/stand/man/loader_lua.8 @@ -22,8 +22,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" .Dd September 29, 2021 .Dt LOADER_LUA 8 .Os @@ -199,6 +197,7 @@ Loader init .Nm configuration files, as described in .Xr loader.conf 5 . +.El .Sh EXAMPLES Boot in single user mode: .Pp diff --git a/stand/man/loader_simp.8 b/stand/man/loader_simp.8 index d628b0d6d008..cdacd823b1a5 100644 --- a/stand/man/loader_simp.8 +++ b/stand/man/loader_simp.8 @@ -22,9 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd September 29, 2021 +.Dd September 30, 2021 .Dt LOADER_SIMP 8 .Os .Sh NAME @@ -341,6 +339,21 @@ In a running system, the state of console muting can be manipulated by the utility. .It Va boot_pause During the device probe, pause after each line is printed. +.It Va boot_safe +Force userland to boot in +.Dq safe mode , +which may disable or limit the functionality of some services that may not be +desired in safe mode. +This is typically set by selecting +.Dq safe mode +in the loader menu, which also sets some other hints for the kernel. +Applications wishing to respect safe mode should +.Sy only +test for the presence of +.Va boot_safe +in +.Xr kenv 1 , +not for any particular value. .It Va boot_serial Force the use of a serial console even when an internal console is present. @@ -360,7 +373,7 @@ Defines the speed of the serial console (i386 and amd64 only). If the previous boot stage indicated that a serial console is in use then this variable is initialized to the current speed of the console serial port. -Otherwise it is set to 9600 unless this was overridden using the +Otherwise it is set to 115200 unless this was overridden using the .Va BOOT_COMCONSOLE_SPEED variable when .Nm @@ -661,6 +674,7 @@ command line by booting unconditionally in .Pa loader.rc . In order for this to be effective, one should also configure the firmware (BIOS or UEFI) to prevent booting from unauthorized devices. +.El .Sh FILES .Bl -tag -width /boot/loader_simp -compact .It Pa /boot/loader_simp @@ -670,6 +684,7 @@ itself. The script run by .Nm on startup. +.El .Sh EXAMPLES Boot in single user mode: .Pp diff --git a/stand/powerpc/Makefile b/stand/powerpc/Makefile index d0c5830e4042..c6403f324ba7 100644 --- a/stand/powerpc/Makefile +++ b/stand/powerpc/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - NO_OBJ=t .include <bsd.init.mk> diff --git a/stand/powerpc/Makefile.inc b/stand/powerpc/Makefile.inc index 265f86d1ed55..01b5f23410c8 100644 --- a/stand/powerpc/Makefile.inc +++ b/stand/powerpc/Makefile.inc @@ -1,3 +1 @@ -# $FreeBSD$ - .include "../Makefile.inc" diff --git a/stand/powerpc/boot1.chrp/Makefile b/stand/powerpc/boot1.chrp/Makefile index 928f30e7eabb..e67414584bc8 100644 --- a/stand/powerpc/boot1.chrp/Makefile +++ b/stand/powerpc/boot1.chrp/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= boot1.elf @@ -7,7 +5,7 @@ NEWVERSWHAT= "Open Firmware boot block" ${MACHINE_ARCH} INSTALLFLAGS= -b FILES= boot1.hfs -SRCS= boot1.c ashldi3.c syncicache.c +SRCS= boot1.c ashldi3.c syncicache.c memset.c CFLAGS+=-I${LDRSRC} # Load boot1.elf below kernel. diff --git a/stand/powerpc/boot1.chrp/Makefile.hfs b/stand/powerpc/boot1.chrp/Makefile.hfs index c6c2d866f6bf..cd526de8ec7a 100644 --- a/stand/powerpc/boot1.chrp/Makefile.hfs +++ b/stand/powerpc/boot1.chrp/Makefile.hfs @@ -1,4 +1,3 @@ # This file autogenerated by generate-hfs.sh - DO NOT EDIT -# $FreeBSD$ BOOTINFO_OFFSET=0x9c BOOT1_OFFSET=0x1c diff --git a/stand/powerpc/boot1.chrp/boot1.c b/stand/powerpc/boot1.chrp/boot1.c index ed7c55d11d6f..1a546f3473e2 100644 --- a/stand/powerpc/boot1.chrp/boot1.c +++ b/stand/powerpc/boot1.chrp/boot1.c @@ -15,15 +15,14 @@ * purpose. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/dirent.h> #include <sys/endian.h> +#include <sys/stdarg.h> + #include <machine/elf.h> -#include <machine/stdarg.h> #include <machine/md_var.h> + #include <ufs/ffs/fs.h> #include "paths.h" @@ -58,7 +57,7 @@ static void exit(int) __dead2; static void load(const char *); static int dskread(void *, uint64_t, int); -static void usage(void); +static void usage(void) __dead2; static void bcopy(const void *src, void *dst, size_t len); static void bzero(void *b, size_t len); diff --git a/stand/powerpc/boot1.chrp/generate-hfs.sh b/stand/powerpc/boot1.chrp/generate-hfs.sh index ef368d1566b4..dc2b12d8f826 100755 --- a/stand/powerpc/boot1.chrp/generate-hfs.sh +++ b/stand/powerpc/boot1.chrp/generate-hfs.sh @@ -1,7 +1,7 @@ #!/bin/sh # This script generates the dummy HFS filesystem used for the PowerPC boot -# blocks. It uses hfsutils (emulators/hfsutils) to generate a template +# blocks. It uses hfsutils (filesystems/hfsutils) to generate a template # filesystem with the relevant interesting files. These are then found by # grep, and the offsets written to a Makefile snippet. # @@ -10,8 +10,6 @@ # template (e.g. because the boot block or the CHRP script have grown), # you must install it from ports. -# $FreeBSD$ - HFS_SIZE=1600 #Size in 512-byte blocks of the produced image CHRPBOOT_SIZE=2k @@ -50,14 +48,12 @@ BOOTINFO_OFFSET=$(echo 0x$BOOTINFO_OFFSET | awk '{printf("%x\n",$1/512);}') BOOT1_OFFSET=$(echo 0x$BOOT1_OFFSET | awk '{printf("%x\n",$1/512);}') echo '# This file autogenerated by generate-hfs.sh - DO NOT EDIT' > Makefile.hfs -echo '# $FreeBSD$' >> Makefile.hfs echo "BOOTINFO_OFFSET=0x$BOOTINFO_OFFSET" >> Makefile.hfs echo "BOOT1_OFFSET=0x$BOOT1_OFFSET" >> Makefile.hfs bzip2 $OUTPUT_FILE echo 'HFS template boot filesystem created by generate-hfs.sh' > $OUTPUT_FILE.bz2.uu echo 'DO NOT EDIT' >> $OUTPUT_FILE.bz2.uu -echo '$FreeBSD$' >> $OUTPUT_FILE.bz2.uu uuencode $OUTPUT_FILE.bz2 $OUTPUT_FILE.bz2 >> $OUTPUT_FILE.bz2.uu rm $OUTPUT_FILE.bz2 diff --git a/stand/powerpc/boot1.chrp/hfs.tmpl.bz2.uu b/stand/powerpc/boot1.chrp/hfs.tmpl.bz2.uu index 20b7695e6db4..4adb468de6a8 100644 --- a/stand/powerpc/boot1.chrp/hfs.tmpl.bz2.uu +++ b/stand/powerpc/boot1.chrp/hfs.tmpl.bz2.uu @@ -1,6 +1,5 @@ HFS template boot filesystem created by generate-hfs.sh DO NOT EDIT -$FreeBSD$ begin 644 hfs.tmpl.bz2 M0EIH.3%!629365^MV6L``"]__O___M)20>!0O2$>0#MUW$!$``%%$``@``!` M!`!R2<`![@H2"2A2-Z)-HC]4`:`-``T:&@&@#0/TTH<`PC":8A@$`R`&$:9, diff --git a/stand/powerpc/ofw/Makefile b/stand/powerpc/ofw/Makefile index 28eb8ee91fad..552e828b7614 100644 --- a/stand/powerpc/ofw/Makefile +++ b/stand/powerpc/ofw/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_CD9660_SUPPORT?= yes LOADER_EXT2FS_SUPPORT?= no LOADER_MSDOS_SUPPORT?= no @@ -18,9 +16,7 @@ INSTALLFLAGS= -b # Architecture-specific loader code SRCS= conf.c vers.c main.c elf_freebsd.c ppc64_elf_freebsd.c start.c -SRCS+= ucmpdi2.c gfx_fb_stub.c - -CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken +SRCS+= ucmpdi2.c .include "${BOOTSRC}/fdt.mk" .if ${MK_FDT} == "yes" @@ -37,6 +33,7 @@ SRCS+= trampolineLE.S .endif HELP_FILES= ${FDTSRC}/help.fdt +HELP_FILENAME= loader.help.ofw # Always add MI sources .include "${BOOTSRC}/loader.mk" @@ -49,18 +46,14 @@ CFLAGS+= -DRELOC=${RELOC} -g LDFLAGS= -nostdlib -static -.if ${MACHINE_ARCH} == "powerpc64le" -LDFLAGS+= -T ${.CURDIR}/ldscript.powerpcle -.else -LDFLAGS+= -T ${.CURDIR}/ldscript.powerpc -.endif +LDFLAGS+= -L ${.CURDIR} -T ${.CURDIR}/${MACHINE_ARCH}.ldscript # Open Firmware standalone support library LIBOFW= ${BOOTOBJ}/libofw/libofw.a CFLAGS+= -I${BOOTSRC}/libofw -DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} -LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBSAFDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBSAFDT} ${LIBSA} MK_PIE= no diff --git a/stand/i386/libfirewire/Makefile.depend b/stand/powerpc/ofw/Makefile.depend index 18be76b0cb6f..15a1f9c07f7c 100644 --- a/stand/i386/libfirewire/Makefile.depend +++ b/stand/powerpc/ofw/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/stand/powerpc/ofw/cas.c b/stand/powerpc/ofw/cas.c index e95af42762a5..45fd4d8d567f 100644 --- a/stand/powerpc/ofw/cas.c +++ b/stand/powerpc/ofw/cas.c @@ -23,9 +23,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <openfirm.h> #include <stand.h> @@ -43,10 +40,13 @@ __FBSDID("$FreeBSD$"); #define PVR_CPU_P8NVL 0x004c0000 #define PVR_CPU_P8 0x004d0000 #define PVR_CPU_P9 0x004e0000 +#define PVR_CPU_P10 0x00800000 +#define PVR_CPU_P11 0x00820000 #define PVR_CPU_MASK 0xffff0000 #define PVR_ISA_207 0x0f000004 #define PVR_ISA_300 0x0f000005 +#define PVR_ISA_31 0x0f000006 #define PVR_ISA_MASK 0xffffffff /* loader version of kernel's CPU_MAXSIZE */ @@ -125,7 +125,7 @@ struct opt_vec5 { } __packed; static struct ibm_arch_vec { - struct pvr pvr_list[7]; + struct pvr pvr_list[10]; uint8_t num_opts; struct opt_vec_ignore vec1; struct opt_vec_ignore vec2; @@ -138,8 +138,11 @@ static struct ibm_arch_vec { { htobe32(PVR_CPU_MASK), htobe32(PVR_CPU_P8E) }, { htobe32(PVR_CPU_MASK), htobe32(PVR_CPU_P8NVL) }, { htobe32(PVR_CPU_MASK), htobe32(PVR_CPU_P9) }, + { htobe32(PVR_CPU_MASK), htobe32(PVR_CPU_P10) }, + { htobe32(PVR_CPU_MASK), htobe32(PVR_CPU_P11) }, { htobe32(PVR_ISA_MASK), htobe32(PVR_ISA_207) }, { htobe32(PVR_ISA_MASK), htobe32(PVR_ISA_300) }, + { htobe32(PVR_ISA_MASK), htobe32(PVR_ISA_31) }, { 0, 0xffffffffu } /* terminator */ }, 4, /* num_opts (4 actually means 5 option vectors) */ @@ -188,7 +191,7 @@ ppc64_cas(void) { phandle_t pkg; ihandle_t inst; - cell_t err; + cell_t err = 0; uint8_t buf[16], idx, val; int i, len, rc, radix_mmu; const char *var; diff --git a/stand/powerpc/ofw/conf.c b/stand/powerpc/ofw/conf.c index a472faeed97b..c96048b5a09c 100644 --- a/stand/powerpc/ofw/conf.c +++ b/stand/powerpc/ofw/conf.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" #include "libofw.h" @@ -54,7 +51,7 @@ struct devsw *devsw[] = { &ofwdisk, #endif #if defined(LOADER_NET_SUPPORT) - &netdev, + &ofw_netdev, #endif NULL }; diff --git a/stand/powerpc/ofw/elf_freebsd.c b/stand/powerpc/ofw/elf_freebsd.c index 89811e965d6e..4d34fa18c5dd 100644 --- a/stand/powerpc/ofw/elf_freebsd.c +++ b/stand/powerpc/ofw/elf_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/linker.h> @@ -41,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "libofw.h" #include "openfirm.h" +#include "modinfo.h" extern char end[]; extern vm_offset_t reloc; /* From <arch>/conf.c */ @@ -60,7 +58,7 @@ __elfN(ofw_loadfile)(char *filename, uint64_t dest, * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ - if (!strcmp((*result)->f_type, "elf kernel")) + if (!strcmp((*result)->f_type, md_kerntype)) __syncicache((void *) (*result)->f_addr, (*result)->f_size); #endif return (0); diff --git a/stand/powerpc/ofw/main.c b/stand/powerpc/ofw/main.c index 81195d3f2444..093dda27ae04 100644 --- a/stand/powerpc/ofw/main.c +++ b/stand/powerpc/ofw/main.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/endian.h> #include <stand.h> @@ -38,9 +35,21 @@ __FBSDID("$FreeBSD$"); #include <machine/asm.h> #include <machine/psl.h> -struct arch_switch archsw; /* MI/MD interface boundary */ +#ifdef CAS +static int ppc64_autoload(void); +#endif -extern char end[]; +struct arch_switch archsw = { /* MI/MD interface boundary */ + .arch_getdev = ofw_getdev, + .arch_copyin = ofw_copyin, + .arch_copyout = ofw_copyout, + .arch_readin = ofw_readin, +#ifdef CAS + .arch_autoload = ppc64_autoload, +#else + .arch_autoload = ofw_autoload, +#endif +}; uint32_t acells, scells; @@ -168,26 +177,14 @@ main(int (*openfirm)(void *)) */ cons_probe(); - archsw.arch_getdev = ofw_getdev; - archsw.arch_copyin = ofw_copyin; - archsw.arch_copyout = ofw_copyout; - archsw.arch_readin = ofw_readin; #ifdef CAS setenv("cas", "1", 0); - archsw.arch_autoload = ppc64_autoload; -#else - archsw.arch_autoload = ofw_autoload; #endif /* Set up currdev variable to have hooks in place. */ - env_setenv("currdev", EV_VOLATILE, "", ofw_setcurrdev, env_nounset); + env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, env_nounset); - /* - * March through the device switch probing for things. - */ - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); + devinit(); printf("\n%s", bootprog_info); printf("Memory: %lldKB\n", memsize() / 1024); @@ -207,11 +204,11 @@ main(int (*openfirm)(void *)) bargc = 0; parse(&bargc, &bargv, bootargs); if (bargc == 1) - env_setenv("currdev", EV_VOLATILE, bargv[0], ofw_setcurrdev, + env_setenv("currdev", EV_VOLATILE, bargv[0], gen_setcurrdev, env_nounset); else env_setenv("currdev", EV_VOLATILE, bootpath, - ofw_setcurrdev, env_nounset); + gen_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); setenv("LINES", "24", 1); /* optional */ diff --git a/stand/powerpc/ofw/ofwfdt.c b/stand/powerpc/ofw/ofwfdt.c index ff1458ed2edf..eeb5f132a3f2 100644 --- a/stand/powerpc/ofw/ofwfdt.c +++ b/stand/powerpc/ofw/ofwfdt.c @@ -23,9 +23,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <fdt_platform.h> diff --git a/stand/powerpc/ofw/powerpc.ldscript b/stand/powerpc/ofw/powerpc.ldscript new file mode 100644 index 000000000000..aa48f257af1a --- /dev/null +++ b/stand/powerpc/ofw/powerpc.ldscript @@ -0,0 +1,3 @@ +OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", + "elf32-powerpc-freebsd") +INCLUDE "ppc-common.ldscript" diff --git a/stand/powerpc/ofw/powerpc64.ldscript b/stand/powerpc/ofw/powerpc64.ldscript new file mode 100644 index 000000000000..aa48f257af1a --- /dev/null +++ b/stand/powerpc/ofw/powerpc64.ldscript @@ -0,0 +1,3 @@ +OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", + "elf32-powerpc-freebsd") +INCLUDE "ppc-common.ldscript" diff --git a/stand/powerpc/ofw/powerpc64le.ldscript b/stand/powerpc/ofw/powerpc64le.ldscript new file mode 100644 index 000000000000..269d8121db6b --- /dev/null +++ b/stand/powerpc/ofw/powerpc64le.ldscript @@ -0,0 +1,3 @@ +OUTPUT_FORMAT("elf32-powerpcle-freebsd", "elf32-powerpcle-freebsd", + "elf32-powerpcle-freebsd") +INCLUDE "ppc-common.ldscript" diff --git a/stand/powerpc/ofw/powerpcspe.ldscript b/stand/powerpc/ofw/powerpcspe.ldscript new file mode 100644 index 000000000000..aa48f257af1a --- /dev/null +++ b/stand/powerpc/ofw/powerpcspe.ldscript @@ -0,0 +1,3 @@ +OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", + "elf32-powerpc-freebsd") +INCLUDE "ppc-common.ldscript" diff --git a/stand/powerpc/ofw/ldscript.powerpcle b/stand/powerpc/ofw/ppc-common.ldscript index 813459b8c242..e12dee74824a 100644 --- a/stand/powerpc/ofw/ldscript.powerpcle +++ b/stand/powerpc/ofw/ppc-common.ldscript @@ -1,8 +1,4 @@ -/* $FreeBSD$ */ - -OUTPUT_FORMAT("elf32-powerpcle-freebsd", "elf32-powerpcle-freebsd", - "elf32-powerpcle-freebsd") -OUTPUT_ARCH(powerpcle:common) +OUTPUT_ARCH(powerpc:common) ENTRY(_start) SEARCH_DIR(/usr/lib); PROVIDE (__stack = 0); @@ -57,6 +53,7 @@ SECTIONS .sbss2 : { *(.sbss2) } /* Adjust the address for the data segment to the next page up. */ . = ((. + 0x1000) & ~(0x1000 - 1)); + .data.rel.ro : { *(.data.rel.ro*) } .data : { *(.data) diff --git a/stand/powerpc/ofw/ppc64_elf_freebsd.c b/stand/powerpc/ofw/ppc64_elf_freebsd.c index 38c664228c12..bc68d129f353 100644 --- a/stand/powerpc/ofw/ppc64_elf_freebsd.c +++ b/stand/powerpc/ofw/ppc64_elf_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> @@ -41,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "libofw.h" #include "openfirm.h" +#include "modinfo.h" extern char end[]; extern vm_offset_t reloc; /* From <arch>/conf.c */ @@ -59,7 +57,7 @@ ppc64_ofw_elf_loadfile(char *filename, uint64_t dest, * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ - if (!strcmp((*result)->f_type, "elf kernel")) + if (!strcmp((*result)->f_type, md_kerntype)) __syncicache((void *) (*result)->f_addr, (*result)->f_size); return (0); } diff --git a/stand/powerpc/ofw/start.c b/stand/powerpc/ofw/start.c index 5e0744be45a3..227fc3bc7fc7 100644 --- a/stand/powerpc/ofw/start.c +++ b/stand/powerpc/ofw/start.c @@ -30,9 +30,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "libofw.h" diff --git a/stand/powerpc/ofw/trampolineLE.S b/stand/powerpc/ofw/trampolineLE.S index cd940fb3dfee..39f4e9108519 100644 --- a/stand/powerpc/ofw/trampolineLE.S +++ b/stand/powerpc/ofw/trampolineLE.S @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 Brandon Bergren <bdragon@FreeBSD.org> * @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asm.h> diff --git a/stand/powerpc/ofw/version b/stand/powerpc/ofw/version index cb0f6938f966..fd8b01228f46 100644 --- a/stand/powerpc/ofw/version +++ b/stand/powerpc/ofw/version @@ -1,6 +1,2 @@ -$FreeBSD$ - -NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this -file is important. Make sure the current version number is on line 6. - +3.0: Lua scripts API stability 0.1: Initial OFW/PowerPC version. diff --git a/stand/uboot/Makefile b/stand/uboot/Makefile index 052c9615bfc2..becca47944da 100644 --- a/stand/uboot/Makefile +++ b/stand/uboot/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_MSDOS_SUPPORT?= no @@ -11,6 +9,8 @@ LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no LOADER_DISK_SUPPORT?= yes +BINDIR= /boot/uboot + .include <bsd.init.mk> .include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc" @@ -23,7 +23,6 @@ PROG= ubldr .endif NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} -BINDIR= /boot/uboot INSTALLFLAGS= -b WARNS?= 1 @@ -35,21 +34,21 @@ WARNS?= 1 CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized .endif -HELP_FILES= ${.CURDIR}/help.uboot ${BOOTSRC}/fdt/help.fdt +HELP_FILES= ${.CURDIR}/help.uboot ${BOOTSRC}/fdt/help.fdt +HELP_FILENAME= loader.help.uboot # Always add MI sources .include "${BOOTSRC}/loader.mk" -LDSCRIPT= ${.CURDIR}/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH} +LDSCRIPT= ${.CURDIR}/arch/${MACHINE_CPUARCH}/${MACHINE_CPUARCH}.ldscript LDFLAGS= -nostdlib -static -T ${LDSCRIPT} LDFLAGS+= -Wl,-znotext SRCS+= main.c vers.c SRCS+= copy.c devicename.c elf_freebsd.c glue.c -SRCS+= net.c reboot.c time.c gfx_fb_stub.c +SRCS+= net.c reboot.c time.c SRCS+= uboot_console.c uboot_disk.c uboot_fdt.c uboot_module.c -CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken CFLAGS.glue.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib CFLAGS+= -I${BOOTSRC}/common @@ -62,8 +61,6 @@ SRCS+= metadata.c .include "${BOOTSRC}/fdt.mk" -CFLAGS+= -fPIC - # Pick up the bootstrap header for some interface items CFLAGS+= -I${LDRSRC} @@ -80,7 +77,7 @@ OBJS+= ${SRCS:N*.h:R:S/$/.o/g} ubldr ubldr.bin ubldr.pie: ${OBJS} .endif -DPADD= ${LDR_INTERP} ${LIBFDT} ${LIBSA} -LDADD= ${LDR_INTERP} ${LIBFDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBSAFDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBSAFDT} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/i386/zfsboot/Makefile.depend b/stand/uboot/Makefile.depend index 58b2754996b4..4f7d14fe96fe 100644 --- a/stand/i386/zfsboot/Makefile.depend +++ b/stand/uboot/Makefile.depend @@ -2,13 +2,8 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - include \ - include/xlocale \ - lib/libmd \ - stand/i386/btx/btx \ - stand/i386/btx/lib \ - stand/libsa32 \ - stand/zfs32 \ + stand/fdt \ + stand/libsa \ .include <dirdeps.mk> diff --git a/stand/uboot/Makefile.depend.options b/stand/uboot/Makefile.depend.options new file mode 100644 index 000000000000..d70bc7edd168 --- /dev/null +++ b/stand/uboot/Makefile.depend.options @@ -0,0 +1,9 @@ +DIRDEPS_OPTIONS = FORTH LOADER_LUA + +DIRDEPS.FORTH.yes += \ + stand/ficl \ + +DIRDEPS.LOADER_LUA.yes += \ + stand/lua \ + +.include <dirdeps-options.mk> diff --git a/stand/uboot/api_public.h b/stand/uboot/api_public.h index f393de88933b..3e11a0041b5b 100644 --- a/stand/uboot/api_public.h +++ b/stand/uboot/api_public.h @@ -48,8 +48,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD$ - * * This file needs to be kept in sync with U-Boot reference: * http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=blob;f=include/api_public.h */ diff --git a/stand/uboot/arch/arm/Makefile.inc b/stand/uboot/arch/arm/Makefile.inc index 66cb3f1b4dda..115f48672b18 100644 --- a/stand/uboot/arch/arm/Makefile.inc +++ b/stand/uboot/arch/arm/Makefile.inc @@ -4,22 +4,22 @@ UBLDR_LOADADDR?= 0x1000000 SRCS+= start.S conf.c self_reloc.c -ldscript.abs: +abs.ldscript: echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} -ldscript.pie: +pie.ldscript: echo "UBLDR_LOADADDR = 0;" >${.TARGET} -ubldr: ${OBJS} ldscript.abs ${LDSCRIPT} ${DPADD} - ${CC} ${CFLAGS} -T ldscript.abs ${LDFLAGS} \ +ubldr: ${OBJS} abs.ldscript ${LDSCRIPT} ${DPADD} + ${CC} ${CFLAGS} -T abs.ldscript ${LDFLAGS} \ -o ${.TARGET} ${OBJS} ${LDADD} -ubldr.pie: ${OBJS} ldscript.pie ${LDSCRIPT} ${DPADD} - ${CC} ${CFLAGS} -T ldscript.pie ${LDFLAGS} -pie -Wl,-Bsymbolic \ +ubldr.pie: ${OBJS} pie.ldscript ${LDSCRIPT} ${DPADD} + ${CC} ${CFLAGS} -T pie.ldscript ${LDFLAGS} -pie -Wl,-Bsymbolic \ -o ${.TARGET} ${OBJS} ${LDADD} ubldr.bin: ubldr.pie ${OBJCOPY} -S -O binary ubldr.pie ${.TARGET} -CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin +CLEANFILES+= abs.ldscript pie.ldscript ubldr ubldr.pie ubldr.bin diff --git a/stand/uboot/arch/arm/ldscript.arm b/stand/uboot/arch/arm/arm.ldscript index b768e00f39a3..3ab3d165cde2 100644 --- a/stand/uboot/arch/arm/ldscript.arm +++ b/stand/uboot/arch/arm/arm.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_ARCH(arm) ENTRY(_start) diff --git a/stand/uboot/arch/arm/conf.c b/stand/uboot/arch/arm/conf.c index 077541220f92..7d36e6d6629e 100644 --- a/stand/uboot/arch/arm/conf.c +++ b/stand/uboot/arch/arm/conf.c @@ -25,9 +25,6 @@ * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" #include "libuboot.h" diff --git a/stand/uboot/arch/arm/start.S b/stand/uboot/arch/arm/start.S index 781d4829df35..ff076b0bb3a7 100644 --- a/stand/uboot/arch/arm/start.S +++ b/stand/uboot/arch/arm/start.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asm.h> diff --git a/stand/uboot/arch/powerpc/Makefile.inc b/stand/uboot/arch/powerpc/Makefile.inc index 226cfc2f7369..555eef94f1cc 100644 --- a/stand/uboot/arch/powerpc/Makefile.inc +++ b/stand/uboot/arch/powerpc/Makefile.inc @@ -1,4 +1,3 @@ - SRCS+= start.S conf.c ppc64_elf_freebsd.c .PATH: ${SYSDIR}/libkern SRCS+= ucmpdi2.c diff --git a/stand/uboot/arch/powerpc/conf.c b/stand/uboot/arch/powerpc/conf.c index 1ace9b5e53de..963a4ded4dcf 100644 --- a/stand/uboot/arch/powerpc/conf.c +++ b/stand/uboot/arch/powerpc/conf.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" #include "libuboot.h" diff --git a/stand/uboot/arch/powerpc/ldscript.powerpc b/stand/uboot/arch/powerpc/powerpc.ldscript index 923838365793..7f33129a7b59 100644 --- a/stand/uboot/arch/powerpc/ldscript.powerpc +++ b/stand/uboot/arch/powerpc/powerpc.ldscript @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", "elf32-powerpc-freebsd") diff --git a/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c b/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c index 57b2e791fbba..e500b862de2e 100644 --- a/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c +++ b/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> @@ -40,10 +37,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "libuboot.h" - -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); -extern char end[]; -extern vm_offset_t reloc; /* From <arch>/conf.c */ +#include "modinfo.h" int ppc64_uboot_elf_loadfile(char *filename, uint64_t dest, @@ -59,7 +53,7 @@ ppc64_uboot_elf_loadfile(char *filename, uint64_t dest, * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ - if (!strcmp((*result)->f_type, "elf kernel")) + if (!strcmp((*result)->f_type, md_kerntype)) __syncicache((void *) (*result)->f_addr, (*result)->f_size); return (0); } diff --git a/stand/uboot/arch/powerpc/start.S b/stand/uboot/arch/powerpc/start.S index cee56e6ea75b..475c5801a360 100644 --- a/stand/uboot/arch/powerpc/start.S +++ b/stand/uboot/arch/powerpc/start.S @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <machine/asm.h> diff --git a/stand/uboot/copy.c b/stand/uboot/copy.c index 65451d0fbec0..7758e754666b 100644 --- a/stand/uboot/copy.c +++ b/stand/uboot/copy.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com> + * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,8 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <stand.h> @@ -37,7 +35,7 @@ __FBSDID("$FreeBSD$"); #include "libuboot.h" /* - * MD primitives supporting placement of module data + * MD primitives supporting placement of module data */ #ifdef __arm__ @@ -53,20 +51,17 @@ __FBSDID("$FreeBSD$"); extern void _start(void); /* ubldr entry point address. */ +uint64_t loadbase; +bool loadbase_set = false; + /* * This is called for every object loaded (kernel, module, dtb file, etc). The * expected return value is the next address at or after the given addr which is * appropriate for loading the given object described by type and data. On each * call the addr is the next address following the previously loaded object. - * - * The first call is for loading the kernel, and the addr argument will be zero, - * and we search for a big block of ram to load the kernel and modules. - * - * On subsequent calls the addr will be non-zero, and we just round it up so - * that each object begins on a page boundary. */ -uint64_t -uboot_loadaddr(u_int type, void *data, uint64_t addr) +static uint64_t +uboot_loadaddr(void) { struct sys_info *si; uint64_t sblock, eblock, subldr, eubldr; @@ -75,87 +70,89 @@ uboot_loadaddr(u_int type, void *data, uint64_t addr) int i; char *envstr; - if (addr == 0) { - /* - * If the loader_kernaddr environment variable is set, blindly - * honor it. It had better be right. We force interpretation - * of the value in base-16 regardless of any leading 0x prefix, - * because that's the U-Boot convention. - */ - envstr = ub_env_get("loader_kernaddr"); - if (envstr != NULL) - return (strtoul(envstr, NULL, 16)); - - /* - * Find addr/size of largest DRAM block. Carve our own address - * range out of the block, because loading the kernel over the - * top ourself is a poor memory-conservation strategy. Avoid - * memory at beginning of the first block of physical ram, - * since u-boot likes to pass args and data there. Assume that - * u-boot has moved itself to the very top of ram and - * optimistically assume that we won't run into it up there. - */ - if ((si = ub_get_sys_info()) == NULL) - panic("could not retrieve system info"); - - biggest_block = 0; - biggest_size = 0; - subldr = rounddown2((uintptr_t)_start, KERN_ALIGN); - eubldr = roundup2((uint64_t)uboot_heap_end, KERN_ALIGN); - for (i = 0; i < si->mr_no; i++) { - if (si->mr[i].flags != MR_ATTR_DRAM) - continue; - sblock = roundup2((uint64_t)si->mr[i].start, - KERN_ALIGN); - eblock = rounddown2((uint64_t)si->mr[i].start + - si->mr[i].size, KERN_ALIGN); - if (biggest_size == 0) - sblock += KERN_MINADDR; - if (subldr >= sblock && subldr < eblock) { - if (subldr - sblock > eblock - eubldr) { - this_block = sblock; - this_size = subldr - sblock; - } else { - this_block = eubldr; - this_size = eblock - eubldr; - } - } else if (subldr < sblock && eubldr < eblock) { - /* Loader is below or engulfs the sblock */ - this_block = (eubldr < sblock) ? sblock : eubldr; - this_size = eblock - this_block; + /* + * If the loader_kernaddr environment variable is set, blindly + * honor it. It had better be right. We force interpretation + * of the value in base-16 regardless of any leading 0x prefix, + * because that's the U-Boot convention. + */ + envstr = ub_env_get("loader_kernaddr"); + if (envstr != NULL) + return (strtoul(envstr, NULL, 16)); + + /* + * Find addr/size of largest DRAM block. Carve our own address + * range out of the block, because loading the kernel over the + * top ourself is a poor memory-conservation strategy. Avoid + * memory at beginning of the first block of physical ram, + * since u-boot likes to pass args and data there. Assume that + * u-boot has moved itself to the very top of ram and + * optimistically assume that we won't run into it up there. + */ + if ((si = ub_get_sys_info()) == NULL) + panic("could not retrieve system info"); + + biggest_block = 0; + biggest_size = 0; + subldr = rounddown2((uintptr_t)_start, KERN_ALIGN); + eubldr = roundup2((uint64_t)uboot_heap_end, KERN_ALIGN); + for (i = 0; i < si->mr_no; i++) { + if (si->mr[i].flags != MR_ATTR_DRAM) + continue; + sblock = roundup2((uint64_t)si->mr[i].start, + KERN_ALIGN); + eblock = rounddown2((uint64_t)si->mr[i].start + + si->mr[i].size, KERN_ALIGN); + if (biggest_size == 0) + sblock += KERN_MINADDR; + if (subldr >= sblock && subldr < eblock) { + if (subldr - sblock > eblock - eubldr) { + this_block = sblock; + this_size = subldr - sblock; } else { - this_block = 0; - this_size = 0; - } - if (biggest_size < this_size) { - biggest_block = this_block; - biggest_size = this_size; + this_block = eubldr; + this_size = eblock - eubldr; } + } else if (subldr < sblock && eubldr < eblock) { + /* Loader is below or engulfs the sblock */ + this_block = (eubldr < sblock) ? sblock : eubldr; + this_size = eblock - this_block; + } else { + this_block = 0; + this_size = 0; } - if (biggest_size == 0) - panic("Not enough DRAM to load kernel"); + if (biggest_size < this_size) { + biggest_block = this_block; + biggest_size = this_size; + } + } + if (biggest_size == 0) + panic("Not enough DRAM to load kernel"); #if 0 - printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n", - (uintmax_t)biggest_block, - (uintmax_t)biggest_block + biggest_size - 1, - (uintmax_t)biggest_size / 1024 / 1024); + printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n", + (uintmax_t)biggest_block, + (uintmax_t)biggest_block + biggest_size - 1, + (uintmax_t)biggest_size / 1024 / 1024); #endif - return (biggest_block); - } - return roundup2(addr, PAGE_SIZE); + return (biggest_block); } ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len) { - bcopy(src, (void *)dest, len); + if (!loadbase_set) { + loadbase = uboot_loadaddr(); + loadbase_set = true; + } + + bcopy(src, (void *)(dest + loadbase), len); return (len); } ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len) { - bcopy((void *)src, dest, len); + bcopy((void *)(src + loadbase), dest, len); return (len); } diff --git a/stand/uboot/devicename.c b/stand/uboot/devicename.c index b6b0e6e40639..4ee9c7fd72c4 100644 --- a/stand/uboot/devicename.c +++ b/stand/uboot/devicename.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> @@ -115,7 +112,8 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec, #ifdef LOADER_DISK_SUPPORT case DEVT_DISK: - err = disk_parsedev((struct disk_devdesc *)idev, np, path); + free(idev); + err = disk_parsedev((struct devdesc **)&idev, devspec, path); if (err != 0) goto fail; break; @@ -147,6 +145,10 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec, goto fail; } idev->dd.d_dev = dv; + /* + * dev can be NULL, since uboot_getdev calls us directly, rather than via + * dv_parsedev in devparse() which otherwise ensures that it can't be NULL. + */ if (dev == NULL) { free(idev); } else { @@ -160,29 +162,6 @@ fail: } -char * -uboot_fmtdev(void *vdev) -{ - struct uboot_devdesc *dev = (struct uboot_devdesc *)vdev; - static char buf[128]; - - switch(dev->dd.d_dev->dv_type) { - case DEVT_NONE: - strcpy(buf, "(no device)"); - break; - - case DEVT_DISK: -#ifdef LOADER_DISK_SUPPORT - return (disk_fmtdev(vdev)); -#endif - - case DEVT_NET: - sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); - break; - } - return(buf); -} - /* * Set currdev to suit the value being supplied in (value). */ diff --git a/stand/uboot/elf_freebsd.c b/stand/uboot/elf_freebsd.c index 802d6e96dee6..3b1bdc542538 100644 --- a/stand/uboot/elf_freebsd.c +++ b/stand/uboot/elf_freebsd.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/linker.h> @@ -39,8 +36,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "libuboot.h" - -extern vm_offset_t md_load(char *, vm_offset_t *, vm_offset_t *); +#include "modinfo.h" int __elfN(uboot_load)(char *filename, uint64_t dest, @@ -57,7 +53,7 @@ __elfN(uboot_load)(char *filename, uint64_t dest, * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ - if (!strcmp((*result)->f_type, "elf kernel")) + if (!strcmp((*result)->f_type, md_kerntype)) __syncicache((void *) (*result)->f_addr, (*result)->f_size); #endif return (0); diff --git a/stand/uboot/glue.c b/stand/uboot/glue.c index 83c0e3da41a5..8d8e2a57d1fc 100644 --- a/stand/uboot/glue.c +++ b/stand/uboot/glue.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <zlib.h> diff --git a/stand/uboot/glue.h b/stand/uboot/glue.h index 9399549fcc68..e09ca2d81363 100644 --- a/stand/uboot/glue.h +++ b/stand/uboot/glue.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/uboot/help.uboot b/stand/uboot/help.uboot index c1574af92715..fae48d7db373 100644 --- a/stand/uboot/help.uboot +++ b/stand/uboot/help.uboot @@ -1,4 +1,3 @@ -$FreeBSD$ ############################################################################### # Tubenv DShow or import U-Boot environment variables diff --git a/stand/uboot/libuboot.h b/stand/uboot/libuboot.h index 18a12c216d7e..49bfff3ada6f 100644 --- a/stand/uboot/libuboot.h +++ b/stand/uboot/libuboot.h @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <disk.h> @@ -50,7 +48,6 @@ struct uboot_devdesc { #endif int uboot_getdev(void **vdev, const char *devspec, const char **path); -char *uboot_fmtdev(void *vdev); int uboot_setcurrdev(struct env_var *ev, int flags, const void *value); extern int devs_no; @@ -60,7 +57,6 @@ extern struct devsw uboot_storage; extern uintptr_t uboot_heap_start; extern uintptr_t uboot_heap_end; -uint64_t uboot_loadaddr(u_int type, void *data, uint64_t addr); ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len); ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len); ssize_t uboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); diff --git a/stand/uboot/main.c b/stand/uboot/main.c index 85ddf5db1f90..6f53c83543ba 100644 --- a/stand/uboot/main.c +++ b/stand/uboot/main.c @@ -26,8 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <stand.h> @@ -37,22 +35,25 @@ __FBSDID("$FreeBSD$"); #include "glue.h" #include "libuboot.h" -#ifndef nitems -#define nitems(x) (sizeof((x)) / sizeof((x)[0])) -#endif - #ifndef HEAP_SIZE #define HEAP_SIZE (2 * 1024 * 1024) #endif struct uboot_devdesc currdev; -struct arch_switch archsw; /* MI/MD interface boundary */ +struct arch_switch archsw = { /* MI/MD interface boundary */ + .arch_getdev = uboot_getdev, + .arch_copyin = uboot_copyin, + .arch_copyout = uboot_copyout, + .arch_readin = uboot_readin, + .arch_autoload = uboot_autoload, +}; + int devs_no; uintptr_t uboot_heap_start; uintptr_t uboot_heap_end; -struct device_type { +struct device_type { const char *name; int type; } device_types[] = { @@ -67,8 +68,6 @@ struct device_type { extern char end[]; -extern unsigned char _etext[]; -extern unsigned char _edata[]; extern unsigned char __bss_start[]; extern unsigned char __sbss_start[]; extern unsigned char __sbss_end[]; @@ -206,7 +205,7 @@ device_typename(int type) static void get_load_device(int *type, int *unit, int *slice, int *partition) { - struct disk_devdesc dev; + struct disk_devdesc *dev; char *devstr; const char *p; char *endp; @@ -233,14 +232,21 @@ get_load_device(int *type, int *unit, int *slice, int *partition) * parse the remainder of the string as such, and if it works, return * those results. Otherwise we'll fall through to the code that parses * the legacy format. + * + * disk_parsedev now assumes that it points to the start of the device + * name, but since it doesn't know about uboot's usage, just subtract 4 + * since it always adds 4. This is the least-bad solution since it makes + * all the other loader code easier (might be better to create a fake + * 'disk...' string, but that's more work than uboot is worth). */ if (*type & DEV_TYP_STOR) { size_t len = strlen(p); if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 && - disk_parsedev(&dev, p, NULL) == 0) { - *unit = dev.dd.d_unit; - *slice = dev.d_slice; - *partition = dev.d_partition; + disk_parsedev((struct devdesc **)&dev, p - 4, NULL) == 0) { /* Hack */ + *unit = dev->dd.d_unit; + *slice = dev->d_slice; + *partition = dev->d_partition; + free(dev); return; } } @@ -331,10 +337,10 @@ get_load_device(int *type, int *unit, int *slice, int *partition) *unit = -1; *slice = D_SLICEWILD; *partition = D_PARTWILD; -} +} static void -print_disk_probe_info() +print_disk_probe_info(void) { char slice[32]; char partition[32]; @@ -360,7 +366,7 @@ print_disk_probe_info() } static int -probe_disks(int devidx, int load_type, int load_unit, int load_slice, +probe_disks(int devidx, int load_type, int load_unit, int load_slice, int load_partition) { int open_result, unit; @@ -506,7 +512,7 @@ main(int argc, char **argv) if ((load_type == DEV_TYP_NONE || (load_type & DEV_TYP_STOR)) && strcmp(devsw[i]->dv_name, "disk") == 0) { - if (probe_disks(i, load_type, load_unit, load_slice, + if (probe_disks(i, load_type, load_unit, load_slice, load_partition) == 0) break; } @@ -526,7 +532,7 @@ main(int argc, char **argv) return (0xbadef1ce); } - ldev = uboot_fmtdev(&currdev); + ldev = devformat(&currdev.dd); env_setenv("currdev", EV_VOLATILE, ldev, uboot_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, ldev, env_noset, env_nounset); printf("Booting from %s\n", ldev); @@ -538,13 +544,6 @@ do_interact: setenv("usefdt", "1", 1); #endif - archsw.arch_loadaddr = uboot_loadaddr; - archsw.arch_getdev = uboot_getdev; - archsw.arch_copyin = uboot_copyin; - archsw.arch_copyout = uboot_copyout; - archsw.arch_readin = uboot_readin; - archsw.arch_autoload = uboot_autoload; - interact(); /* doesn't return */ return (0); @@ -629,7 +628,7 @@ handle_uboot_env_var(enum ubenv_action action, const char * var) * import the uboot variable ubname into the loader variable ldname, * otherwise the historical behavior is to import to uboot.ubname. */ - if (action == UBENV_IMPORT) { + if (action == UBENV_IMPORT) { len = strcspn(var, "="); if (len == 0) { printf("name cannot start with '=': '%s'\n", var); diff --git a/stand/uboot/net.c b/stand/uboot/net.c index 81b8c5bc9f5b..392dd1ca45c2 100644 --- a/stand/uboot/net.c +++ b/stand/uboot/net.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> @@ -103,7 +100,7 @@ static struct uboot_softc uboot_softc; * to obtain all this info again. */ static void -get_env_net_params() +get_env_net_params(void) { char *envstr; in_addr_t rootaddr, serveraddr; diff --git a/stand/uboot/reboot.c b/stand/uboot/reboot.c index 9f4d277eb6f9..792ade02fdd2 100644 --- a/stand/uboot/reboot.c +++ b/stand/uboot/reboot.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "glue.h" diff --git a/stand/uboot/time.c b/stand/uboot/time.c index a3c73f471a25..64eae3c2e682 100644 --- a/stand/uboot/time.c +++ b/stand/uboot/time.c @@ -25,11 +25,7 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> - #include "glue.h" /* diff --git a/stand/uboot/uboot_console.c b/stand/uboot/uboot_console.c index f49f455c7efa..b850a88c4018 100644 --- a/stand/uboot/uboot_console.c +++ b/stand/uboot/uboot_console.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "bootstrap.h" #include "glue.h" @@ -40,14 +37,13 @@ static int uboot_cons_getchar(void); static int uboot_cons_poll(void); struct console uboot_console = { - "uboot", - "U-Boot console", - 0, - uboot_cons_probe, - uboot_cons_init, - uboot_cons_putchar, - uboot_cons_getchar, - uboot_cons_poll, + .c_name = "uboot", + .c_desc = "U-Boot console", + .c_probe = uboot_cons_probe, + .c_init = uboot_cons_init, + .c_out = uboot_cons_putchar, + .c_in = uboot_cons_getchar, + .c_ready = uboot_cons_poll, }; static void @@ -75,14 +71,14 @@ uboot_cons_putchar(int c) } static int -uboot_cons_getchar() +uboot_cons_getchar(void) { return (ub_getc()); } static int -uboot_cons_poll() +uboot_cons_poll(void) { return (ub_tstc()); diff --git a/stand/uboot/uboot_disk.c b/stand/uboot/uboot_disk.c index 70dcfdcc8863..1f75f0f6da3c 100644 --- a/stand/uboot/uboot_disk.c +++ b/stand/uboot/uboot_disk.c @@ -31,12 +31,10 @@ * Block storage I/O routines for U-Boot */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/disk.h> -#include <machine/stdarg.h> +#include <sys/stdarg.h> + #include <stand.h> #include "api_public.h" @@ -81,15 +79,17 @@ static int stor_print(int); static void stor_cleanup(void); struct devsw uboot_storage = { - "disk", - DEVT_DISK, - stor_init, - stor_strategy, - stor_open, - stor_close, - stor_ioctl, - stor_print, - stor_cleanup + .dv_name = "disk", + .dv_type = DEVT_DISK, + .dv_init = stor_init, + .dv_strategy = stor_strategy, + .dv_open = stor_open, + .dv_close = stor_close, + .dv_ioctl = stor_ioctl, + .dv_print = stor_print, + .dv_cleanup = stor_cleanup, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; static int diff --git a/stand/uboot/uboot_fdt.c b/stand/uboot/uboot_fdt.c index 4b0a85e3aec0..d6f99f8b29cb 100644 --- a/stand/uboot/uboot_fdt.c +++ b/stand/uboot/uboot_fdt.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2009-2010 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Semihalf under sponsorship from * the FreeBSD Foundation. @@ -27,9 +26,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <stand.h> #include <fdt_platform.h> diff --git a/stand/uboot/uboot_module.c b/stand/uboot/uboot_module.c index 0951ed6618e4..b3b3a067bc38 100644 --- a/stand/uboot/uboot_module.c +++ b/stand/uboot/uboot_module.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * U-Boot-specific module functionality. */ diff --git a/stand/uboot/version b/stand/uboot/version index 630fe00bb777..0293880a1f90 100644 --- a/stand/uboot/version +++ b/stand/uboot/version @@ -1,6 +1,2 @@ -$FreeBSD$ - -NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this -file is important. Make sure the current version number is on line 6. - +3.0: Lua scripts API stability 1.5: Unified ubldr build diff --git a/stand/usb/Makefile b/stand/usb/Makefile index 63e60155314b..a9c20fc340ad 100644 --- a/stand/usb/Makefile +++ b/stand/usb/Makefile @@ -1,5 +1,4 @@ # -# $FreeBSD$ # # Copyright (c) 2013 Hans Petter Selasky. # Copyright (c) 2014 SRI International @@ -36,7 +35,7 @@ INTERNALLIB= CFLAGS+= -DBOOTPROG=\"usbloader\" CFLAGS+= -ffunction-sections -fdata-sections -CFLAGS+= -Wformat -Wall +CFLAGS+= -Wformat -Wall -Wno-unused CFLAGS+= -g CFLAGS+= -fno-pic diff --git a/stand/usb/storage/umass_common.c b/stand/usb/storage/umass_common.c index 5ddd159297b7..b62412b13637 100644 --- a/stand/usb/storage/umass_common.c +++ b/stand/usb/storage/umass_common.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org> * All rights reserved. @@ -39,8 +38,6 @@ static device_probe_t umass_probe; static device_attach_t umass_attach; static device_detach_t umass_detach; -static devclass_t umass_devclass; - static device_method_t umass_methods[] = { /* Device interface */ DEVMETHOD(device_probe, umass_probe), @@ -55,7 +52,7 @@ static driver_t umass_driver = { .methods = umass_methods, }; -DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0); +DRIVER_MODULE(umass, uhub, umass_driver, NULL, 0); static int umass_probe(device_t dev) diff --git a/stand/usb/storage/umass_common.h b/stand/usb/storage/umass_common.h index a8ffd4987eb9..964f60836e4a 100644 --- a/stand/usb/storage/umass_common.h +++ b/stand/usb/storage/umass_common.h @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org> * All rights reserved. diff --git a/stand/usb/storage/umass_loader.c b/stand/usb/storage/umass_loader.c index 1c12f05c2769..01f1e3602b6a 100644 --- a/stand/usb/storage/umass_loader.c +++ b/stand/usb/storage/umass_loader.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org> * All rights reserved. @@ -61,6 +60,8 @@ struct devsw umass_disk = { .dv_ioctl = umass_disk_ioctl, .dv_print = umass_disk_print, .dv_cleanup = umass_disk_cleanup, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; static int diff --git a/stand/usb/test/Makefile b/stand/usb/test/Makefile index c82b5bac3823..d92ef6dddecb 100644 --- a/stand/usb/test/Makefile +++ b/stand/usb/test/Makefile @@ -1,5 +1,4 @@ # -# $FreeBSD$ # # Copyright (c) 2013 Hans Petter Selasky. All rights reserved. # @@ -36,6 +35,7 @@ PROG= usbloader SRCS= CFLAGS+= -Wall +CFLAGS+= -Wno-error=missing-prototypes -Wno-error=unused-parameter CFLAGS+= -g .if ${MACHINE_CPUARCH} == "amd64" diff --git a/stand/usb/test/bsd_usbloader_test.c b/stand/usb/test/bsd_usbloader_test.c index 35140b87c360..a92bdebfbebe 100644 --- a/stand/usb/test/bsd_usbloader_test.c +++ b/stand/usb/test/bsd_usbloader_test.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * diff --git a/stand/usb/tools/Makefile b/stand/usb/tools/Makefile index 64cf28ca75e8..30144ea5fc22 100644 --- a/stand/usb/tools/Makefile +++ b/stand/usb/tools/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - PROG= sysinit MAN= diff --git a/stand/usb/tools/sysinit.c b/stand/usb/tools/sysinit.c index b968fe0ab858..cb2868a0d728 100644 --- a/stand/usb/tools/sysinit.c +++ b/stand/usb/tools/sysinit.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * diff --git a/stand/usb/usb_busdma_loader.c b/stand/usb/usb_busdma_loader.c index 90dc1692ba01..2ca855e468a1 100644 --- a/stand/usb/usb_busdma_loader.c +++ b/stand/usb/usb_busdma_loader.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /*- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. * diff --git a/stand/usb/usbcore.mk b/stand/usb/usbcore.mk index ae80d06a24e7..13acd41fc174 100644 --- a/stand/usb/usbcore.mk +++ b/stand/usb/usbcore.mk @@ -1,5 +1,4 @@ # -# $FreeBSD$ # # Copyright (c) 2013-2020 Hans Petter Selasky. # Copyright (c) 2014 SRI International diff --git a/stand/userboot/Makefile b/stand/userboot/Makefile index dd2cbe3ad846..f783c93eedea 100644 --- a/stand/userboot/Makefile +++ b/stand/userboot/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> SUBDIR.yes= test diff --git a/stand/userboot/Makefile.inc b/stand/userboot/Makefile.inc index 265f86d1ed55..01b5f23410c8 100644 --- a/stand/userboot/Makefile.inc +++ b/stand/userboot/Makefile.inc @@ -1,3 +1 @@ -# $FreeBSD$ - .include "../Makefile.inc" diff --git a/stand/userboot/test/Makefile b/stand/userboot/test/Makefile index 7c88f264aef4..9e097ac64261 100644 --- a/stand/userboot/test/Makefile +++ b/stand/userboot/test/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - .include <bsd.init.mk> PROG= test diff --git a/stand/userboot/test/Makefile.depend b/stand/userboot/test/Makefile.depend index 6cfaab1c3644..6ef78fac5cbf 100644 --- a/stand/userboot/test/Makefile.depend +++ b/stand/userboot/test/Makefile.depend @@ -1,8 +1,6 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/csu \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/stand/userboot/test/test.c b/stand/userboot/test/test.c index 4ad18176ba6e..22aaf8d7785a 100644 --- a/stand/userboot/test/test.c +++ b/stand/userboot/test/test.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2011 Google, Inc. + * Copyright (c) 2023-2024 Juniper Networks, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <sys/types.h> @@ -37,7 +36,9 @@ #include <fcntl.h> #include <getopt.h> #include <inttypes.h> +#include <libgen.h> #include <limits.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -46,6 +47,8 @@ #include <userboot.h> +char **vars; + char *host_base = NULL; struct termios term, oldterm; char *image; @@ -104,47 +107,164 @@ struct test_file { } tf_u; }; -int -test_open(void *arg, const char *filename, void **h_return) +static int +test_open_internal(void *arg, const char *filename, void **h_return, + struct test_file *tf, int depth) { - struct stat st; - struct test_file *tf; char path[PATH_MAX]; + char linkpath[PATH_MAX]; + char *component, *cp, *linkptr; + ssize_t slen; + int comp_fd, dir_fd, error; + char c; + bool openbase; + + if (depth++ >= MAXSYMLINKS) + return (ELOOP); + + openbase = false; + error = EINVAL; + if (tf == NULL) { + tf = calloc(1, sizeof(struct test_file)); + if (tf == NULL) + return (error); + openbase = true; + } else if (tf->tf_isdir) { + if (filename[0] == '/') { + closedir(tf->tf_u.dir); + openbase = true; + } + } else + return (error); - if (!host_base) - return (ENOENT); - - strlcpy(path, host_base, PATH_MAX); - if (path[strlen(path) - 1] == '/') - path[strlen(path) - 1] = 0; - strlcat(path, filename, PATH_MAX); - tf = malloc(sizeof(struct test_file)); - if (stat(path, &tf->tf_stat) < 0) { - free(tf); - return (errno); - } + if (openbase) { + dir_fd = open(host_base, O_RDONLY); + if (dir_fd < 0) + goto out; - tf->tf_size = st.st_size; - if (S_ISDIR(tf->tf_stat.st_mode)) { tf->tf_isdir = 1; - tf->tf_u.dir = opendir(path); - if (!tf->tf_u.dir) + tf->tf_u.dir = fdopendir(dir_fd); + + if (fstat(dir_fd, &tf->tf_stat) < 0) { + error = errno; goto out; - *h_return = tf; - return (0); + } + tf->tf_size = tf->tf_stat.st_size; } - if (S_ISREG(tf->tf_stat.st_mode)) { - tf->tf_isdir = 0; - tf->tf_u.fd = open(path, O_RDONLY); - if (tf->tf_u.fd < 0) + + strlcpy(path, filename, sizeof(path)); + cp = path; + while (*cp) { + /* + * The test file should be a directory at this point. + * If it is not, then the caller provided an invalid filename. + */ + if (!tf->tf_isdir) + goto out; + + /* Trim leading slashes */ + while (*cp == '/') + cp++; + + /* If we reached the end, we are done */ + if (*cp == '\0') + break; + + /* Get the file descriptor for the directory */ + dir_fd = dirfd(tf->tf_u.dir); + + /* Get the next component path */ + component = cp; + while ((c = *cp) != '\0' && c != '/') + cp++; + if (c == '/') + *cp++ = '\0'; + + /* Get status of the component */ + if (fstatat(dir_fd, component, &tf->tf_stat, + AT_SYMLINK_NOFOLLOW) < 0) { + error = errno; goto out; - *h_return = tf; - return (0); + } + tf->tf_size = tf->tf_stat.st_size; + + /* + * Check that the path component is a directory, regular file, + * or a symlink. + */ + if (!S_ISDIR(tf->tf_stat.st_mode) && + !S_ISREG(tf->tf_stat.st_mode) && + !S_ISLNK(tf->tf_stat.st_mode)) + goto out; + + /* For anything that is not a symlink, open it */ + if (!S_ISLNK(tf->tf_stat.st_mode)) { + comp_fd = openat(dir_fd, component, O_RDONLY); + if (comp_fd < 0) + goto out; + } + + if (S_ISDIR(tf->tf_stat.st_mode)) { + /* Directory */ + + /* close the parent directory */ + closedir(tf->tf_u.dir); + + /* Open the directory from the component descriptor */ + tf->tf_isdir = 1; + tf->tf_u.dir = fdopendir(comp_fd); + if (!tf->tf_u.dir) + goto out; + } else if (S_ISREG(tf->tf_stat.st_mode)) { + /* Regular file */ + + /* close the parent directory */ + closedir(tf->tf_u.dir); + + /* Stash the component descriptor */ + tf->tf_isdir = 0; + tf->tf_u.fd = comp_fd; + } else if (S_ISLNK(tf->tf_stat.st_mode)) { + /* Symlink */ + + /* Read what the symlink points to */ + slen = readlinkat(dir_fd, component, linkpath, + sizeof(linkpath)); + if (slen < 0) + goto out; + /* NUL-terminate the string */ + linkpath[(size_t)slen] = '\0'; + + /* Open the thing that the symlink points to */ + error = test_open_internal(arg, linkpath, NULL, + tf, depth); + if (error != 0) + goto out; + } } + /* Completed the entire path and have a good file/directory */ + if (h_return != NULL) + *h_return = tf; + return (0); + out: + /* Failure of some sort, clean up */ + if (tf->tf_isdir) + closedir(tf->tf_u.dir); + else + close(tf->tf_u.fd); free(tf); - return (EINVAL); + return (error); +} + +int +test_open(void *arg, const char *filename, void **h_return) +{ + if (host_base == NULL) + return (ENOENT); + + return (test_open_internal(arg, filename, h_return, NULL, 0)); } int @@ -396,13 +516,15 @@ test_getmem(void *arg, uint64_t *lowmem, uint64_t *highmem) char * test_getenv(void *arg, int idx) { - static char *vars[] = { - "foo=bar", - "bar=barbar", - NULL + static char *myvars[] = { + "USERBOOT=1" }; + static const int num_myvars = nitems(myvars); - return (vars[idx]); + if (idx < num_myvars) + return (myvars[idx]); + else + return (vars[idx - num_myvars]); } struct loader_callbacks cb = { @@ -446,7 +568,7 @@ usage() } int -main(int argc, char** argv) +main(int argc, char** argv, char ** environment) { void *h; void (*func)(struct loader_callbacks *, void *, int, int) __dead2; @@ -454,6 +576,8 @@ main(int argc, char** argv) const char *userboot_obj = "/boot/userboot.so"; int oflag = O_RDONLY; + vars = environment; + while ((opt = getopt(argc, argv, "wb:d:h:")) != -1) { switch (opt) { case 'b': diff --git a/stand/userboot/userboot.h b/stand/userboot/userboot.h index 810e5b9d3d24..34e8cb1d4bb2 100644 --- a/stand/userboot/userboot.h +++ b/stand/userboot/userboot.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* diff --git a/stand/userboot/userboot/Makefile b/stand/userboot/userboot/Makefile index c5e2e6fe7c7c..2a66c0e3f8fe 100644 --- a/stand/userboot/userboot/Makefile +++ b/stand/userboot/userboot/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_MSDOS_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no @@ -15,45 +13,65 @@ SHLIB_NAME= userboot_${LOADER_INTERP}.so STRIP= LIBDIR= /boot +.if ${MACHINE_CPUARCH} == "amd64" +USERBOOT_KERNEL_SUPPORT= yes +.else +USERBOOT_KERNEL_SUPPORT= no +.endif + .PATH: ${.CURDIR}/../userboot SRCS= autoload.c SRCS+= bcache.c +.if ${MACHINE_CPUARCH} == "amd64" SRCS+= biossmap.c +.endif +.if ${USERBOOT_KERNEL_SUPPORT} == "yes" SRCS+= bootinfo.c SRCS+= bootinfo32.c SRCS+= bootinfo64.c +.endif SRCS+= conf.c SRCS+= copy.c SRCS+= devicename.c +.if ${USERBOOT_KERNEL_SUPPORT} == "yes" SRCS+= elf32_freebsd.c SRCS+= elf64_freebsd.c +.endif SRCS+= host.c SRCS+= main.c SRCS+= userboot_cons.c SRCS+= userboot_disk.c SRCS+= vers.c -SRCS+= gfx_fb_stub.c CFLAGS+= -Wall CFLAGS+= -I${BOOTSRC}/userboot + +.if ${MK_LOADER_ZFS} != "no" CFLAGS.main.c+= -I${BOOTSRC}/libsa/zfs CFLAGS.main.c+= -I${SYSDIR}/contrib/openzfs/include CFLAGS.main.c+= -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs +.endif + CWARNFLAGS.main.c += -Wno-implicit-function-declaration -CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken NEWVERSWHAT= "User boot ${LOADER_INTERP}" ${MACHINE_CPUARCH} -VERSION_FILE= ${.CURDIR}/../userboot/version +VERSION_FILE?= ${.CURDIR}/../userboot/version .if ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP} LINKS+= ${BINDIR}/${SHLIB_NAME} ${BINDIR}/userboot.so .endif +.if ${USERBOOT_KERNEL_SUPPORT} == "yes" +CFLAGS+= -DUSERBOOT_KERNEL_SUPPORT +.endif + .if ${MK_LOADER_ZFS} != "no" CFLAGS+= -DUSERBOOT_ZFS_SUPPORT HAVE_ZFS=yes .endif +HELP_FILENAME= loader.help.userboot + # Always add MI sources .include "${BOOTSRC}/loader.mk" CFLAGS+= -I. diff --git a/stand/userboot/userboot/Makefile.depend b/stand/userboot/userboot/Makefile.depend index 87e0acc0f3b5..8ab1e451bb72 100644 --- a/stand/userboot/userboot/Makefile.depend +++ b/stand/userboot/userboot/Makefile.depend @@ -1,12 +1,8 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ - include \ - include/xlocale \ stand/ficl \ stand/libsa \ - stand/zfs \ .include <dirdeps.mk> diff --git a/stand/userboot/userboot/autoload.c b/stand/userboot/userboot/autoload.c index a86afcfa2b4b..576a7af78cb2 100644 --- a/stand/userboot/userboot/autoload.c +++ b/stand/userboot/userboot/autoload.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - int userboot_autoload(void) { diff --git a/stand/userboot/userboot/biossmap.c b/stand/userboot/userboot/biossmap.c index 9e556be373cc..5e5d1d696726 100644 --- a/stand/userboot/userboot/biossmap.c +++ b/stand/userboot/userboot/biossmap.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> diff --git a/stand/userboot/userboot/bootinfo.c b/stand/userboot/userboot/bootinfo.c index 43088e2a7c0e..40d446100b9b 100644 --- a/stand/userboot/userboot/bootinfo.c +++ b/stand/userboot/userboot/bootinfo.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> @@ -83,31 +80,3 @@ bi_setboothowto(int howto) boot_howto_to_env(howto); } - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -bi_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - CALLBACK(copyin, ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - CALLBACK(copyin, "=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - CALLBACK(copyin, ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - CALLBACK(copyin, "", addr, 1); - addr++; - } - CALLBACK(copyin, "", addr, 1); - addr++; - return(addr); -} diff --git a/stand/userboot/userboot/bootinfo32.c b/stand/userboot/userboot/bootinfo32.c index ecd4ccf2edd8..6ba76cc56479 100644 --- a/stand/userboot/userboot/bootinfo32.c +++ b/stand/userboot/userboot/bootinfo32.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> @@ -34,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <i386/include/bootinfo.h> #include "bootstrap.h" +#include "modinfo.h" #include "libuserboot.h" #ifdef LOADER_GELI_SUPPORT @@ -43,90 +41,6 @@ __FBSDID("$FreeBSD$"); static struct bootinfo bi; /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - CALLBACK(copyin, &x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - CALLBACK(copyin, s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(uint32_t));\ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - CALLBACK(copyin, &s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(uint32_t)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - CALLBACK(copyin, mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(uint32_t));\ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -bi_copymodules32(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - MOD_ADDR(addr, fp->f_addr, c); - MOD_SIZE(addr, fp->f_size, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - MOD_END(addr, c); - return(addr); -} - -/* * Load the information expected by an i386 kernel. * * - The 'boothowto' argument is constructed @@ -139,7 +53,7 @@ int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernendp) { struct preloaded_file *xp, *kfp; - struct i386_devdesc *rootdev; + struct devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; vm_offset_t kernend; @@ -167,12 +81,12 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(userboot_fmtdev((void *)rootdev)); + getrootmount(devformat(rootdev)); bootdevnr = 0; #if 0 if (bootdevnr == -1) { - printf("root device %s invalid\n", i386_fmtdev(rootdev)); + printf("root device %s invalid\n", devformat(rootdev)); return (EINVAL); } #endif @@ -185,18 +99,16 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); /* copy our environment */ envp = addr; - addr = bi_copyenv(addr); + addr = md_copyenv(addr); /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf32 kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ @@ -210,8 +122,8 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t /* Figure out the size and location of the metadata */ *modulep = addr; - size = bi_copymodules32(0); - kernend = roundup(addr + size, PAGE_SIZE); + size = md_copymodules(0, false); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ @@ -219,7 +131,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t bcopy(&kernend, md->md_data, sizeof kernend); /* copy module list and metadata */ - (void)bi_copymodules32(addr); + (void)md_copymodules(addr, false); ssym = esym = 0; md = file_findmetadata(kfp, MODINFOMD_SSYM); @@ -235,13 +147,6 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t kernelname = getenv("kernelname"); userboot_getdev(NULL, kernelname, &kernelpath); bi.bi_version = BOOTINFO_VERSION; - bi.bi_kernelname = 0; /* XXX char * -> kernel name */ - bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ - bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */ -#if 0 - for (i = 0; i < N_BIOS_GEOM; i++) - bi.bi_bios_geom[i] = bd_getbigeom(i); -#endif bi.bi_size = sizeof(bi); CALLBACK(getmem, &lowmem, &highmem); bi.bi_memsizes_valid = 1; diff --git a/stand/userboot/userboot/bootinfo64.c b/stand/userboot/userboot/bootinfo64.c index 60887413e0ec..3e289bbebba0 100644 --- a/stand/userboot/userboot/bootinfo64.c +++ b/stand/userboot/userboot/bootinfo64.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/param.h> #include <sys/reboot.h> @@ -37,96 +34,10 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #include "bootstrap.h" +#include "modinfo.h" #include "libuserboot.h" /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - CALLBACK(copyin, &x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - CALLBACK(copyin, s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(uint64_t));\ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - CALLBACK(copyin, &s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(uint64_t)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - CALLBACK(copyin, mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(uint64_t));\ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -bi_copymodules64(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - uint64_t v; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - v = fp->f_addr; - MOD_ADDR(addr, v, c); - v = fp->f_size; - MOD_SIZE(addr, v, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - MOD_END(addr, c); - return(addr); -} - -/* * Check to see if this CPU supports long mode. */ static int @@ -182,7 +93,7 @@ int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) { struct preloaded_file *xp, *kfp; - struct userboot_devdesc *rootdev; + struct devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; uint64_t kernend; @@ -211,7 +122,7 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(userboot_fmtdev((void *)rootdev)); + getrootmount(devformat(rootdev)); /* find the last module in the chain */ addr = 0; @@ -220,18 +131,16 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); /* copy our environment */ envp = addr; - addr = bi_copyenv(addr); + addr = md_copyenv(addr); /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf64 kernel"); + kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ @@ -242,8 +151,8 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) /* Figure out the size and location of the metadata */ *modulep = addr; - size = bi_copymodules64(0); - kernend = roundup(addr + size, PAGE_SIZE); + size = md_copymodules(0, true); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ @@ -251,7 +160,7 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) bcopy(&kernend, md->md_data, sizeof kernend); /* copy module list and metadata */ - (void)bi_copymodules64(addr); + (void)md_copymodules(addr, true); return(0); } diff --git a/stand/userboot/userboot/conf.c b/stand/userboot/userboot/conf.c index 066c2aa87492..63f64cb97fbe 100644 --- a/stand/userboot/userboot/conf.c +++ b/stand/userboot/userboot/conf.c @@ -31,9 +31,6 @@ * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "libuserboot.h" @@ -86,16 +83,20 @@ struct netif_driver *netif_drivers[] = { * Sort formats so that those that can detect based on arguments * rather than reading the file go first. */ +#if defined(__amd64__) extern struct file_format i386_elf; extern struct file_format i386_elf_obj; extern struct file_format amd64_elf; extern struct file_format amd64_elf_obj; +#endif struct file_format *file_formats[] = { +#if defined(__amd64__) &i386_elf, &i386_elf_obj, &amd64_elf, &amd64_elf_obj, +#endif NULL }; diff --git a/stand/userboot/userboot/copy.c b/stand/userboot/userboot/copy.c index f39c83c57d70..ba88d26a2e2d 100644 --- a/stand/userboot/userboot/copy.c +++ b/stand/userboot/userboot/copy.c @@ -24,9 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include "libuserboot.h" diff --git a/stand/userboot/userboot/devicename.c b/stand/userboot/userboot/devicename.c index e770e6bf4bb1..0c6bbc8f8a27 100644 --- a/stand/userboot/userboot/devicename.c +++ b/stand/userboot/userboot/devicename.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> @@ -34,13 +31,6 @@ __FBSDID("$FreeBSD$"); #include "disk.h" #include "libuserboot.h" -#if defined(USERBOOT_ZFS_SUPPORT) -#include "libzfs.h" -#endif - -static int userboot_parsedev(struct disk_devdesc **dev, const char *devspec, - const char **path); - /* * Point (dev) at an allocated device specifier for the device matching the * path in (devspec). If it contains an explicit device specification, @@ -49,7 +39,7 @@ static int userboot_parsedev(struct disk_devdesc **dev, const char *devspec, int userboot_getdev(void **vdev, const char *devspec, const char **path) { - struct disk_devdesc **dev = (struct disk_devdesc **)vdev; + struct devdesc **dev = (struct devdesc **)vdev; int rv; /* @@ -60,7 +50,7 @@ userboot_getdev(void **vdev, const char *devspec, const char **path) (devspec[0] == '/') || (strchr(devspec, ':') == NULL)) { - rv = userboot_parsedev(dev, getenv("currdev"), NULL); + rv = devparse(dev, getenv("currdev"), NULL); if (rv == 0 && path != NULL) *path = devspec; return (rv); @@ -69,159 +59,5 @@ userboot_getdev(void **vdev, const char *devspec, const char **path) /* * Try to parse the device name off the beginning of the devspec */ - return (userboot_parsedev(dev, devspec, path)); -} - -/* - * Point (dev) at an allocated device specifier matching the string version - * at the beginning of (devspec). Return a pointer to the remaining - * text in (path). - * - * In all cases, the beginning of (devspec) is compared to the names - * of known devices in the device switch, and then any following text - * is parsed according to the rules applied to the device type. - * - * For disk-type devices, the syntax is: - * - * disk<unit>[s<slice>][<partition>]: - * - */ -static int -userboot_parsedev(struct disk_devdesc **dev, const char *devspec, - const char **path) -{ - struct disk_devdesc *idev; - struct devsw *dv; - int i, unit, err; - const char *cp; - const char *np; - - /* minimum length check */ - if (strlen(devspec) < 2) - return (EINVAL); - - /* look for a device that matches */ - for (i = 0, dv = NULL; devsw[i] != NULL; i++) { - if (strncmp(devspec, devsw[i]->dv_name, - strlen(devsw[i]->dv_name)) == 0) { - dv = devsw[i]; - break; - } - } - if (dv == NULL) - return (ENOENT); - idev = malloc(sizeof(struct disk_devdesc)); - err = 0; - np = (devspec + strlen(dv->dv_name)); - - switch (dv->dv_type) { - case DEVT_NONE: /* XXX what to do here? Do we care? */ - break; - - case DEVT_DISK: - err = disk_parsedev(idev, np, path); - if (err != 0) - goto fail; - break; - - case DEVT_CD: - case DEVT_NET: - unit = 0; - - if (*np && (*np != ':')) { - /* get unit number if present */ - unit = strtol(np, (char **)&cp, 0); - if (cp == np) { - err = EUNIT; - goto fail; - } - } else { - cp = np; - } - if (*cp && (*cp != ':')) { - err = EINVAL; - goto fail; - } - - idev->dd.d_unit = unit; - if (path != NULL) - *path = (*cp == 0) ? cp : cp + 1; - break; - - case DEVT_ZFS: -#if defined(USERBOOT_ZFS_SUPPORT) - err = zfs_parsedev((struct zfs_devdesc *)idev, np, path); - if (err != 0) - goto fail; - break; -#else - /* FALLTHROUGH */ -#endif - - default: - err = EINVAL; - goto fail; - } - idev->dd.d_dev = dv; - if (dev == NULL) { - free(idev); - } else { - *dev = idev; - } - return (0); - -fail: - free(idev); - return (err); -} - - -char * -userboot_fmtdev(void *vdev) -{ - struct devdesc *dev = (struct devdesc *)vdev; - static char buf[128]; /* XXX device length constant? */ - - switch(dev->d_dev->dv_type) { - case DEVT_NONE: - strcpy(buf, "(no device)"); - break; - - case DEVT_CD: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); - break; - - case DEVT_DISK: - return (disk_fmtdev(vdev)); - - case DEVT_NET: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); - break; - - case DEVT_ZFS: -#if defined(USERBOOT_ZFS_SUPPORT) - return (zfs_fmtdev(vdev)); -#else - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); -#endif - break; - } - return (buf); -} - - -/* - * Set currdev to suit the value being supplied in (value) - */ -int -userboot_setcurrdev(struct env_var *ev, int flags, const void *value) -{ - struct disk_devdesc *ncurr; - int rv; - - if ((rv = userboot_parsedev(&ncurr, value, NULL)) != 0) - return (rv); - free(ncurr); - - return (mount_currdev(ev, flags, value)); + return (devparse(dev, devspec, path)); } diff --git a/stand/userboot/userboot/elf32_freebsd.c b/stand/userboot/userboot/elf32_freebsd.c index d8ccc3375cfd..c2492dce7397 100644 --- a/stand/userboot/userboot/elf32_freebsd.c +++ b/stand/userboot/userboot/elf32_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/exec.h> #include <sys/linker.h> diff --git a/stand/userboot/userboot/elf64_freebsd.c b/stand/userboot/userboot/elf64_freebsd.c index 12fd3aa04096..5a63fdb4990c 100644 --- a/stand/userboot/userboot/elf64_freebsd.c +++ b/stand/userboot/userboot/elf64_freebsd.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> #include <sys/exec.h> @@ -34,9 +31,10 @@ __FBSDID("$FreeBSD$"); #ifdef DEBUG #include <machine/_inttypes.h> #endif -#include <string.h> -#include <i386/include/bootinfo.h> +#include <vm/vm.h> +#include <vm/pmap.h> #include <machine/elf.h> +#include <machine/segments.h> #include <stand.h> #include "bootstrap.h" @@ -48,35 +46,21 @@ static int elf64_obj_exec(struct preloaded_file *amp); struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; -#define MSR_EFER 0xc0000080 -#define EFER_LME 0x00000100 -#define EFER_LMA 0x00000400 /* Long mode active (R) */ -#define CR4_PAE 0x00000020 -#define CR4_VMXE (1UL << 13) -#define CR4_PSE 0x00000010 -#define CR0_PG 0x80000000 -#define CR0_PE 0x00000001 /* Protected mode Enable */ -#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */ - -#define PG_V 0x001 -#define PG_RW 0x002 -#define PG_PS 0x080 - -typedef uint64_t p4_entry_t; -typedef uint64_t p3_entry_t; -typedef uint64_t p2_entry_t; - #define GUEST_NULL_SEL 0 #define GUEST_CODE_SEL 1 #define GUEST_DATA_SEL 2 #define GUEST_GDTR_LIMIT (3 * 8 - 1) static void -setup_freebsd_gdt(uint64_t *gdtr) +setup_freebsd_gdt(struct user_segment_descriptor *gdt) { - gdtr[GUEST_NULL_SEL] = 0; - gdtr[GUEST_CODE_SEL] = 0x0020980000000000; - gdtr[GUEST_DATA_SEL] = 0x0000900000000000; + gdt[GUEST_NULL_SEL] = (struct user_segment_descriptor) { 0 }; + gdt[GUEST_CODE_SEL] = (struct user_segment_descriptor) { + .sd_p = 1, .sd_long = 1, .sd_type = SDT_MEME + }; + gdt[GUEST_DATA_SEL] = (struct user_segment_descriptor) { + .sd_p = 1, .sd_type = SDT_MEMRO + }; } /* @@ -93,10 +77,10 @@ elf64_exec(struct preloaded_file *fp) int err; int i; uint32_t stack[1024]; - p4_entry_t PT4[512]; - p3_entry_t PT3[512]; - p2_entry_t PT2[512]; - uint64_t gdtr[3]; + pml4_entry_t PT4[512]; + pdp_entry_t PT3[512]; + pd_entry_t PT2[512]; + struct user_segment_descriptor gdt[3]; if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); @@ -125,11 +109,11 @@ elf64_exec(struct preloaded_file *fp) */ for (i = 0; i < 512; i++) { /* Each slot of the level 4 pages points to the same level 3 page */ - PT4[i] = (p4_entry_t) 0x3000; + PT4[i] = (pml4_entry_t) 0x3000; PT4[i] |= PG_V | PG_RW; /* Each slot of the level 3 pages points to the same level 2 page */ - PT3[i] = (p3_entry_t) 0x4000; + PT3[i] = (pdp_entry_t) 0x4000; PT3[i] |= PG_V | PG_RW; /* The level 2 page slots are mapped with 2MB pages for 1GB. */ @@ -157,9 +141,9 @@ elf64_exec(struct preloaded_file *fp) CALLBACK(setcr, 3, 0x2000); CALLBACK(setcr, 0, CR0_PG | CR0_PE | CR0_NE); - setup_freebsd_gdt(gdtr); - CALLBACK(copyin, gdtr, 0x5000, sizeof(gdtr)); - CALLBACK(setgdt, 0x5000, sizeof(gdtr)); + setup_freebsd_gdt(gdt); + CALLBACK(copyin, gdt, 0x5000, sizeof(gdt)); + CALLBACK(setgdt, 0x5000, sizeof(gdt)); CALLBACK(exec, ehdr->e_entry); diff --git a/stand/userboot/userboot/host.c b/stand/userboot/userboot/host.c index 20952983e0d1..8f33bbd82be8 100644 --- a/stand/userboot/userboot/host.c +++ b/stand/userboot/userboot/host.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Read from the host filesystem */ @@ -155,14 +152,14 @@ host_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, } struct fs_ops host_fsops = { - "host", - host_open, - host_close, - host_read, - null_write, - host_seek, - host_stat, - host_readdir + .fs_name = "host", + .fo_open = host_open, + .fo_close = host_close, + .fo_read = host_read, + .fo_write = null_write, + .fo_seek = host_seek, + .fo_stat = host_stat, + .fo_readdir = host_readdir, }; struct devsw host_dev = { @@ -174,5 +171,5 @@ struct devsw host_dev = { .dv_close = host_dev_close, .dv_ioctl = noioctl, .dv_print = host_dev_print, - .dv_cleanup = NULL + .dv_cleanup = nullsys, }; diff --git a/stand/userboot/userboot/libuserboot.h b/stand/userboot/userboot/libuserboot.h index 75732c6c0e38..e1584ec29412 100644 --- a/stand/userboot/userboot/libuserboot.h +++ b/stand/userboot/userboot/libuserboot.h @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include "userboot.h" @@ -57,12 +55,9 @@ extern ssize_t userboot_copyin(const void *, vm_offset_t, size_t); extern ssize_t userboot_copyout(vm_offset_t, void *, size_t); extern ssize_t userboot_readin(readin_handle_t, vm_offset_t, size_t); extern int userboot_getdev(void **, const char *, const char **); -char *userboot_fmtdev(void *vdev); -int userboot_setcurrdev(struct env_var *ev, int flags, const void *value); int bi_getboothowto(char *kargs); void bi_setboothowto(int howto); -vm_offset_t bi_copyenv(vm_offset_t addr); int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernend); int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernend); diff --git a/stand/userboot/userboot/main.c b/stand/userboot/userboot/main.c index 07630945cf80..03f226c08bb9 100644 --- a/stand/userboot/userboot/main.c +++ b/stand/userboot/userboot/main.c @@ -25,20 +25,17 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <setjmp.h> #include <sys/disk.h> -#include <sys/zfs_bootenv.h> #include "bootstrap.h" #include "disk.h" #include "libuserboot.h" #if defined(USERBOOT_ZFS_SUPPORT) +#include <sys/zfs_bootenv.h> #include "libzfs.h" static void userboot_zfs_probe(void); @@ -58,7 +55,16 @@ void *callbacks_arg; static jmp_buf jb; -struct arch_switch archsw; /* MI/MD interface boundary */ +struct arch_switch archsw = { /* MI/MD interface boundary */ + .arch_autoload = userboot_autoload, + .arch_getdev = userboot_getdev, + .arch_copyin = userboot_copyin, + .arch_copyout = userboot_copyout, + .arch_readin = userboot_readin, +#if defined(USERBOOT_ZFS_SUPPORT) + .arch_zfs_probe = userboot_zfs_probe, +#endif +}; static void extract_currdev(void); static void check_interpreter(void); @@ -172,8 +178,7 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks) cons_probe(); /* Set up currdev variable to have hooks in place. */ - env_setenv("currdev", EV_VOLATILE, "", - userboot_setcurrdev, env_nounset); + env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, env_nounset); printf("\n%s", bootprog_info); #if 0 @@ -193,28 +198,18 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks) putenv(var); } - archsw.arch_autoload = userboot_autoload; - archsw.arch_getdev = userboot_getdev; - archsw.arch_copyin = userboot_copyin; - archsw.arch_copyout = userboot_copyout; - archsw.arch_readin = userboot_readin; -#if defined(USERBOOT_ZFS_SUPPORT) - archsw.arch_zfs_probe = userboot_zfs_probe; -#endif - /* * Initialise the block cache. Set the upper limit. */ bcache_init(32768, 512); - /* - * March through the device switch probing for things. - */ - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); - + devinit(); extract_currdev(); +#if !defined(USERBOOT_KERNEL_SUPPORT) + printf("WARNING: This userboot does not support loading a kernel\n"); + delay(1500000); +#endif + /* * Checking the interpreter isn't worth the overhead unless we * actually have the swap_interpreter callback, so we actually version @@ -231,16 +226,6 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks) exit(0); } -static void -set_currdev(const char *devname) -{ - - env_setenv("currdev", EV_VOLATILE, devname, - userboot_setcurrdev, env_nounset); - env_setenv("loaddev", EV_VOLATILE, devname, - env_noset, env_nounset); -} - /* * Set the 'current device' by (if possible) recovering the boot device as * supplied by the initial bootstrap. @@ -252,7 +237,6 @@ extract_currdev(void) struct devdesc *dd; #if defined(USERBOOT_ZFS_SUPPORT) struct zfs_devdesc zdev; - char *buf = NULL; if (userboot_zfs_found) { @@ -260,7 +244,7 @@ extract_currdev(void) bzero(&zdev, sizeof(zdev)); zdev.dd.d_dev = &zfs_dev; - init_zfs_boot_options(zfs_fmtdev(&zdev)); + init_zfs_boot_options(devformat(&zdev.dd)); dd = &zdev.dd; } else #endif @@ -285,21 +269,18 @@ extract_currdev(void) dd = &dev.dd; } - set_currdev(userboot_fmtdev(dd)); + set_currdev(devformat(dd)); #if defined(USERBOOT_ZFS_SUPPORT) if (userboot_zfs_found) { - buf = malloc(VDEV_PAD_SIZE); - if (buf != NULL) { - if (zfs_get_bootonce(&zdev, OS_BOOTONCE, buf, - VDEV_PAD_SIZE) == 0) { - printf("zfs bootonce: %s\n", buf); - set_currdev(buf); - setenv("zfs-bootonce", buf, 1); - } - free(buf); - (void) zfs_attach_nvstore(&zdev); + char buf[VDEV_PAD_SIZE]; + + if (zfs_get_bootonce(&zdev, OS_BOOTONCE, buf, sizeof(buf)) == 0) { + printf("zfs bootonce: %s\n", buf); + set_currdev(buf); + setenv("zfs-bootonce", buf, 1); } + (void)zfs_attach_nvstore(&zdev); } #endif } @@ -319,7 +300,7 @@ userboot_zfs_probe(void) for (unit = 0; unit < userboot_disk_maxunit; unit++) { sprintf(devname, "disk%d:", unit); pool_guid = 0; - zfs_probe_dev(devname, &pool_guid); + zfs_probe_dev(devname, &pool_guid, true); if (pool_guid != 0) userboot_zfs_found = 1; } diff --git a/stand/userboot/userboot/userboot_cons.c b/stand/userboot/userboot/userboot_cons.c index 89c1e70b116f..26c89dc2a37e 100644 --- a/stand/userboot/userboot/userboot_cons.c +++ b/stand/userboot/userboot/userboot_cons.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/font.h> #include "bootstrap.h" @@ -45,14 +42,13 @@ static int userboot_cons_getchar(void); static int userboot_cons_poll(void); struct console userboot_console = { - "userboot", - "userboot", - 0, - userboot_cons_probe, - userboot_cons_init, - userboot_cons_putchar, - userboot_cons_getchar, - userboot_cons_poll, + .c_name = "userboot", + .c_desc = "userboot", + .c_probe = userboot_cons_probe, + .c_init = userboot_cons_init, + .c_out = userboot_cons_putchar, + .c_in = userboot_cons_getchar, + .c_ready = userboot_cons_poll, }; /* @@ -60,14 +56,13 @@ struct console userboot_console = { * console to comconsole without resulting in an error */ struct console userboot_comconsole = { - "comconsole", - "comconsole", - 0, - userboot_comcons_probe, - userboot_comcons_init, - userboot_cons_putchar, - userboot_cons_getchar, - userboot_cons_poll, + .c_name = "comconsole", + .c_desc = "comconsole", + .c_probe = userboot_comcons_probe, + .c_init = userboot_comcons_init, + .c_out = userboot_cons_putchar, + .c_in = userboot_cons_getchar, + .c_ready = userboot_cons_poll, }; static void diff --git a/stand/userboot/userboot/userboot_disk.c b/stand/userboot/userboot/userboot_disk.c index caaa3373812b..9adcad4f00ac 100644 --- a/stand/userboot/userboot/userboot_disk.c +++ b/stand/userboot/userboot/userboot_disk.c @@ -24,9 +24,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* * Userboot disk image handling. */ @@ -63,15 +60,17 @@ static int userdisk_ioctl(struct open_file *f, u_long cmd, void *data); static int userdisk_print(int verbose); struct devsw userboot_disk = { - "disk", - DEVT_DISK, - userdisk_init, - userdisk_strategy, - userdisk_open, - userdisk_close, - userdisk_ioctl, - userdisk_print, - userdisk_cleanup + .dv_name = "disk", + .dv_type = DEVT_DISK, + .dv_init = userdisk_init, + .dv_strategy = userdisk_strategy, + .dv_open = userdisk_open, + .dv_close = userdisk_close, + .dv_ioctl = userdisk_ioctl, + .dv_print = userdisk_print, + .dv_cleanup = userdisk_cleanup, + .dv_fmtdev = disk_fmtdev, + .dv_parsedev = disk_parsedev, }; /* diff --git a/stand/userboot/userboot/version b/stand/userboot/userboot/version index 3796883dbc06..2fba2c27eabc 100644 --- a/stand/userboot/userboot/version +++ b/stand/userboot/userboot/version @@ -1,5 +1,4 @@ -$FreeBSD$ - +3.0: Lua scripts API stability 1.2: Userboot with lua or forth 1.1: Initial userland boot diff --git a/stand/userboot/userboot_4th/Makefile b/stand/userboot/userboot_4th/Makefile index a96efa8a52ba..1f8b1df64cbd 100644 --- a/stand/userboot/userboot_4th/Makefile +++ b/stand/userboot/userboot_4th/Makefile @@ -1,6 +1,5 @@ -# $FreeBSD$ - LOADER_INTERP=4th +INSTALL_LOADER_HELP_FILE=no .include "../userboot/Makefile" diff --git a/stand/userboot/userboot_lua/Makefile b/stand/userboot/userboot_lua/Makefile index d5b95c53641b..ae8fc762c869 100644 --- a/stand/userboot/userboot_lua/Makefile +++ b/stand/userboot/userboot_lua/Makefile @@ -1,5 +1,3 @@ -# $FreeBSD$ - LOADER_INTERP=lua .include "../userboot/Makefile" diff --git a/stand/veriexec.mk b/stand/veriexec.mk index 930e933be0a9..a0ff7d1e8489 100644 --- a/stand/veriexec.mk +++ b/stand/veriexec.mk @@ -1,4 +1,7 @@ .if ${MK_LOADER_VERIEXEC} != "no" +.if exists(${VERSION_FILE}.veriexec) +VERSION_FILE:= ${VERSION_FILE}.veriexec +.endif CFLAGS+= -DLOADER_VERIEXEC -I${SRCTOP}/lib/libsecureboot/h .if ${MK_LOADER_VERIEXEC_VECTX} != "no" CFLAGS+= -DLOADER_VERIEXEC_VECTX |