summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ObsoleteFiles.inc3
-rw-r--r--stand/arm/uboot/Makefile4
-rw-r--r--stand/arm/uboot/ldscript.arm10
-rw-r--r--stand/common/boot.c537
-rw-r--r--stand/common/bootstrap.h15
-rw-r--r--stand/common/commands.c21
-rw-r--r--stand/common/install.c2
-rw-r--r--stand/common/interp.c379
-rw-r--r--stand/common/interp_backslash.c260
-rw-r--r--stand/common/interp_forth.c446
-rw-r--r--stand/common/interp_parse.c259
-rw-r--r--stand/common/interp_simple.c192
-rw-r--r--stand/common/load_elf.c148
-rw-r--r--stand/common/load_elf_obj.c2
-rw-r--r--stand/common/misc.c1
-rw-r--r--stand/common/pnp.c50
-rw-r--r--stand/defs.mk9
-rw-r--r--stand/efi/boot1/Makefile9
-rw-r--r--stand/efi/boot1/boot1.c51
-rw-r--r--stand/efi/fdt/Makefile1
-rw-r--r--stand/efi/include/efi.h2
-rw-r--r--stand/efi/include/efiapi.h12
-rw-r--r--stand/efi/libefi/Makefile5
-rw-r--r--stand/efi/libefi/efichar.c37
-rw-r--r--stand/efi/libefi/env.c160
-rw-r--r--stand/efi/loader/Makefile8
-rw-r--r--stand/efi/loader/arch/arm/ldscript.arm2
-rw-r--r--stand/efi/loader/arch/i386/bootinfo.c275
-rw-r--r--stand/efi/loader/main.c12
-rw-r--r--stand/fdt/Makefile1
-rw-r--r--stand/ficl.mk1
-rw-r--r--stand/ficl/Makefile1
-rw-r--r--stand/forth/Makefile2
-rw-r--r--stand/forth/loader.4th3
-rw-r--r--stand/forth/pcibios.4th47
-rw-r--r--stand/forth/pnp.4th205
-rw-r--r--stand/geli/Makefile5
-rw-r--r--stand/i386/boot0/Makefile1
-rw-r--r--stand/i386/btx/btx/Makefile1
-rw-r--r--stand/i386/btx/btxldr/Makefile1
-rw-r--r--stand/i386/btx/lib/Makefile1
-rw-r--r--stand/i386/cdboot/Makefile1
-rw-r--r--stand/i386/kgzldr/Makefile1
-rw-r--r--stand/i386/libfirewire/Makefile1
-rw-r--r--stand/i386/libfirewire/firewire.c6
-rw-r--r--stand/i386/libi386/Makefile1
-rw-r--r--stand/i386/libi386/biospci.c185
-rw-r--r--stand/i386/libi386/comconsole.c2
-rw-r--r--stand/i386/libi386/libi386.h7
-rw-r--r--stand/i386/loader/Makefile7
-rw-r--r--stand/i386/mbr/Makefile1
-rw-r--r--stand/i386/pmbr/Makefile1
-rw-r--r--stand/kshim/bsd_kernel.h13
-rw-r--r--stand/libsa/Makefile6
-rw-r--r--stand/libsa/environment.c1
-rw-r--r--stand/libsa/libsa.3 (renamed from stand/libsa/libstand.3)44
-rw-r--r--stand/libsa/stand.h1
-rw-r--r--stand/loader.mk7
-rw-r--r--stand/mips/beri/boot2/Makefile2
-rw-r--r--stand/mips/beri/boot2/boot2.c5
-rw-r--r--stand/mips/beri/loader/Makefile7
-rw-r--r--stand/mips/beri/loader/exec.c4
-rw-r--r--stand/mips/uboot/Makefile4
-rw-r--r--stand/ofw/common/main.c14
-rw-r--r--stand/ofw/libofw/Makefile1
-rw-r--r--stand/ofw/libofw/elf_freebsd.c1
-rw-r--r--stand/ofw/libofw/libofw.h2
-rw-r--r--stand/ofw/libofw/ofw_copy.c2
-rw-r--r--stand/ofw/libofw/ofw_memory.c32
-rw-r--r--stand/ofw/libofw/ppc64_elf_freebsd.c1
-rw-r--r--stand/powerpc/boot1.chrp/Makefile2
-rw-r--r--stand/powerpc/kboot/Makefile6
-rw-r--r--stand/powerpc/kboot/conf.c1
-rw-r--r--stand/powerpc/kboot/host_syscall.S11
-rw-r--r--stand/powerpc/kboot/host_syscall.h13
-rw-r--r--stand/powerpc/kboot/hostdisk.c8
-rw-r--r--stand/powerpc/kboot/kerneltramp.S55
-rw-r--r--stand/powerpc/kboot/main.c200
-rw-r--r--stand/powerpc/kboot/metadata.c23
-rw-r--r--stand/powerpc/kboot/ppc64_elf_freebsd.c81
-rw-r--r--stand/powerpc/ofw/Makefile6
-rw-r--r--stand/powerpc/ofw/ldscript.powerpc2
-rw-r--r--stand/powerpc/uboot/Makefile5
-rw-r--r--stand/sparc64/boot1/Makefile1
-rw-r--r--stand/sparc64/loader/Makefile6
-rw-r--r--stand/uboot/fdt/Makefile1
-rw-r--r--stand/uboot/lib/Makefile1
-rw-r--r--stand/usb/test/Makefile (renamed from stand/usb/Makefile.test)15
-rw-r--r--stand/usb/test/bsd_usbloader_test.c (renamed from stand/usb/bsd_usbloader_test.c)0
-rw-r--r--stand/usb/usbcore.mk2
-rw-r--r--stand/userboot/test/Makefile4
-rw-r--r--stand/userboot/userboot/Makefile12
-rw-r--r--stand/zfs/Makefile1
-rw-r--r--sys/kern/link_elf_obj.c24
94 files changed, 1871 insertions, 2150 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 901c54f..ef3e292 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,9 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20180212: Obsolete forth files
+OLD_FILES+=boot/efi.4th
+OLD_FILES+=boot/pcibios.4th
# 20180212: Remove libstand
OLD_FILES+=usr/lib/libstand.a
OLD_FILES+=usr/lib/libstand_p.a
diff --git a/stand/arm/uboot/Makefile b/stand/arm/uboot/Makefile
index 8c4023a..0c906c9 100644
--- a/stand/arm/uboot/Makefile
+++ b/stand/arm/uboot/Makefile
@@ -41,8 +41,8 @@ LDFLAGS+= -Wl,-znotext
CFLAGS+= -fPIC
-DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
diff --git a/stand/arm/uboot/ldscript.arm b/stand/arm/uboot/ldscript.arm
index 8eb604c..b768e00 100644
--- a/stand/arm/uboot/ldscript.arm
+++ b/stand/arm/uboot/ldscript.arm
@@ -32,6 +32,11 @@ SECTIONS
.rela.got : { *(.rela.got) }
.rela.got1 : { *(.rela.got1) }
.rela.got2 : { *(.rela.got2) }
+ .dynamic : { *(.dynamic) }
+ PROVIDE (_GOT_START_ = .);
+ .got : { *(.got) }
+ .got.plt : { *(.got.plt) }
+ PROVIDE (_GOT_END_ = .);
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.init : { *(.rela.init) }
@@ -58,7 +63,6 @@ SECTIONS
}
.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 */
@@ -74,10 +78,6 @@ SECTIONS
.fixup : { *(.fixup) }
PROVIDE (_FIXUP_END_ = .);
PROVIDE (_GOT2_END_ = .);
- PROVIDE (_GOT_START_ = .);
- .got : { *(.got) }
- .got.plt : { *(.got.plt) }
- PROVIDE (_GOT_END_ = .);
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
diff --git a/stand/common/boot.c b/stand/common/boot.c
index 5ee9521..2084122 100644
--- a/stand/common/boot.c
+++ b/stand/common/boot.c
@@ -52,60 +52,60 @@ COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot);
static int
command_boot(int argc, char *argv[])
{
- struct preloaded_file *fp;
-
- /*
- * See if the user has specified an explicit kernel to boot.
- */
- if ((argc > 1) && (argv[1][0] != '-')) {
-
- /* XXX maybe we should discard everything and start again? */
- if (file_findfile(NULL, NULL) != NULL) {
- snprintf(command_errbuf, sizeof(command_errbuf),
- "can't boot '%s', kernel module already loaded", argv[1]);
- return(CMD_ERROR);
+ struct preloaded_file *fp;
+
+ /*
+ * See if the user has specified an explicit kernel to boot.
+ */
+ if ((argc > 1) && (argv[1][0] != '-')) {
+
+ /* XXX maybe we should discard everything and start again? */
+ if (file_findfile(NULL, NULL) != NULL) {
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "can't boot '%s', kernel module already loaded", argv[1]);
+ return(CMD_ERROR);
+ }
+
+ /* find/load the kernel module */
+ if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0)
+ return(CMD_ERROR);
+ /* we have consumed all arguments */
+ argc = 1;
}
- /* find/load the kernel module */
- if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0)
- return(CMD_ERROR);
- /* we have consumed all arguments */
- argc = 1;
- }
-
- /*
- * See if there is a kernel module already loaded
- */
- if (file_findfile(NULL, NULL) == NULL)
- if (loadakernel(0, argc - 1, argv + 1))
- /* we have consumed all arguments */
- argc = 1;
-
- /*
- * Loaded anything yet?
- */
- if ((fp = file_findfile(NULL, NULL)) == NULL) {
- command_errmsg = "no bootable kernel";
- return(CMD_ERROR);
- }
-
- /*
- * If we were given arguments, discard any previous.
- * XXX should we merge arguments? Hard to DWIM.
- */
- if (argc > 1) {
- if (fp->f_args != NULL)
- free(fp->f_args);
- fp->f_args = unargv(argc - 1, argv + 1);
- }
-
- /* Hook for platform-specific autoloading of modules */
- if (archsw.arch_autoload() != 0)
- return(CMD_ERROR);
+ /*
+ * See if there is a kernel module already loaded
+ */
+ if (file_findfile(NULL, NULL) == NULL)
+ if (loadakernel(0, argc - 1, argv + 1))
+ /* we have consumed all arguments */
+ argc = 1;
+
+ /*
+ * Loaded anything yet?
+ */
+ if ((fp = file_findfile(NULL, NULL)) == NULL) {
+ command_errmsg = "no bootable kernel";
+ return(CMD_ERROR);
+ }
+
+ /*
+ * If we were given arguments, discard any previous.
+ * XXX should we merge arguments? Hard to DWIM.
+ */
+ if (argc > 1) {
+ if (fp->f_args != NULL)
+ free(fp->f_args);
+ fp->f_args = unargv(argc - 1, argv + 1);
+ }
- /* Call the exec handler from the loader matching the kernel */
- file_formats[fp->f_loader]->l_exec(fp);
- return(CMD_ERROR);
+ /* Hook for platform-specific autoloading of modules */
+ if (archsw.arch_autoload() != 0)
+ return(CMD_ERROR);
+
+ /* Call the exec handler from the loader matching the kernel */
+ file_formats[fp->f_loader]->l_exec(fp);
+ return(CMD_ERROR);
}
@@ -118,29 +118,29 @@ COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_au
static int
command_autoboot(int argc, char *argv[])
{
- int howlong;
- char *cp, *prompt;
-
- prompt = NULL;
- howlong = -1;
- switch(argc) {
- case 3:
- prompt = argv[2];
- /* FALLTHROUGH */
- case 2:
- howlong = strtol(argv[1], &cp, 0);
- if (*cp != 0) {
- snprintf(command_errbuf, sizeof(command_errbuf),
- "bad delay '%s'", argv[1]);
- return(CMD_ERROR);
+ int howlong;
+ char *cp, *prompt;
+
+ prompt = NULL;
+ howlong = -1;
+ switch(argc) {
+ case 3:
+ prompt = argv[2];
+ /* FALLTHROUGH */
+ case 2:
+ howlong = strtol(argv[1], &cp, 0);
+ if (*cp != 0) {
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "bad delay '%s'", argv[1]);
+ return(CMD_ERROR);
+ }
+ /* FALLTHROUGH */
+ case 1:
+ return(autoboot(howlong, prompt));
}
- /* FALLTHROUGH */
- case 1:
- return(autoboot(howlong, prompt));
- }
- command_errmsg = "too many arguments";
- return(CMD_ERROR);
+ command_errmsg = "too many arguments";
+ return(CMD_ERROR);
}
/*
@@ -150,103 +150,103 @@ command_autoboot(int argc, char *argv[])
void
autoboot_maybe()
{
- char *cp;
+ char *cp;
- cp = getenv("autoboot_delay");
- if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO")))
- autoboot(-1, NULL); /* try to boot automatically */
+ cp = getenv("autoboot_delay");
+ if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO")))
+ autoboot(-1, NULL); /* try to boot automatically */
}
int
autoboot(int timeout, char *prompt)
{
- time_t when, otime, ntime;
- int c, yes;
- char *argv[2], *cp, *ep;
- char *kernelname;
+ time_t when, otime, ntime;
+ int c, yes;
+ char *argv[2], *cp, *ep;
+ char *kernelname;
#ifdef BOOT_PROMPT_123
- const char *seq = "123", *p = seq;
+ const char *seq = "123", *p = seq;
#endif
- autoboot_tried = 1;
+ autoboot_tried = 1;
- if (timeout == -1) {
- timeout = 10;
- /* try to get a delay from the environment */
- if ((cp = getenv("autoboot_delay"))) {
- timeout = strtol(cp, &ep, 0);
- if (cp == ep)
- timeout = 10; /* Unparseable? Set default! */
+ if (timeout == -1) {
+ timeout = 10;
+ /* try to get a delay from the environment */
+ if ((cp = getenv("autoboot_delay"))) {
+ timeout = strtol(cp, &ep, 0);
+ if (cp == ep)
+ timeout = 10; /* Unparseable? Set default! */
+ }
}
- }
- kernelname = getenv("kernelname");
- if (kernelname == NULL) {
- argv[0] = NULL;
- loadakernel(0, 0, argv);
kernelname = getenv("kernelname");
if (kernelname == NULL) {
- command_errmsg = "no valid kernel found";
- return(CMD_ERROR);
+ argv[0] = NULL;
+ loadakernel(0, 0, argv);
+ kernelname = getenv("kernelname");
+ if (kernelname == NULL) {
+ command_errmsg = "no valid kernel found";
+ return(CMD_ERROR);
+ }
}
- }
- if (timeout >= 0) {
- otime = time(NULL);
- when = otime + timeout; /* when to boot */
+ if (timeout >= 0) {
+ otime = time(NULL);
+ when = otime + timeout; /* when to boot */
- yes = 0;
+ yes = 0;
#ifdef BOOT_PROMPT_123
- printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or "
- "1 2 3 sequence for command prompt." : prompt);
+ printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or "
+ "1 2 3 sequence for command prompt." : prompt);
#else
- printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt);
+ printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt);
#endif
- for (;;) {
- if (ischar()) {
- c = getchar();
+ for (;;) {
+ if (ischar()) {
+ c = getchar();
#ifdef BOOT_PROMPT_123
- if ((c == '\r') || (c == '\n')) {
- yes = 1;
- break;
- } else if (c != *p++)
- p = seq;
- if (*p == 0)
- break;
+ if ((c == '\r') || (c == '\n')) {
+ yes = 1;
+ break;
+ } else if (c != *p++)
+ p = seq;
+ if (*p == 0)
+ break;
#else
- if ((c == '\r') || (c == '\n'))
- yes = 1;
- break;
+ if ((c == '\r') || (c == '\n'))
+ yes = 1;
+ break;
#endif
- }
- ntime = time(NULL);
- if (ntime >= when) {
- yes = 1;
- break;
- }
-
- if (ntime != otime) {
- printf("\rBooting [%s] in %d second%s... ",
- kernelname, (int)(when - ntime),
- (when-ntime)==1?"":"s");
- otime = ntime;
- }
- }
- } else {
- yes = 1;
- }
-
- if (yes)
- printf("\rBooting [%s]... ", kernelname);
- putchar('\n');
- if (yes) {
- argv[0] = "boot";
- argv[1] = NULL;
- return(command_boot(1, argv));
- }
- return(CMD_OK);
+ }
+ ntime = time(NULL);
+ if (ntime >= when) {
+ yes = 1;
+ break;
+ }
+
+ if (ntime != otime) {
+ printf("\rBooting [%s] in %d second%s... ",
+ kernelname, (int)(when - ntime),
+ (when-ntime)==1?"":"s");
+ otime = ntime;
+ }
+ }
+ } else {
+ yes = 1;
+ }
+
+ if (yes)
+ printf("\rBooting [%s]... ", kernelname);
+ putchar('\n');
+ if (yes) {
+ argv[0] = "boot";
+ argv[1] = NULL;
+ return(command_boot(1, argv));
+ }
+ return(CMD_OK);
}
/*
@@ -255,43 +255,43 @@ autoboot(int timeout, char *prompt)
static char *
getbootfile(int try)
{
- static char *name = NULL;
- const char *spec, *ep;
- size_t len;
-
- /* we use dynamic storage */
- if (name != NULL) {
- free(name);
- name = NULL;
- }
-
- /*
- * Try $bootfile, then try our builtin default
- */
- if ((spec = getenv("bootfile")) == NULL)
- spec = default_bootfiles;
-
- while ((try > 0) && (spec != NULL)) {
- spec = strchr(spec, ';');
- if (spec)
- spec++; /* skip over the leading ';' */
- try--;
- }
- if (spec != NULL) {
- if ((ep = strchr(spec, ';')) != NULL) {
- len = ep - spec;
- } else {
- len = strlen(spec);
+ static char *name = NULL;
+ const char *spec, *ep;
+ size_t len;
+
+ /* we use dynamic storage */
+ if (name != NULL) {
+ free(name);
+ name = NULL;
+ }
+
+ /*
+ * Try $bootfile, then try our builtin default
+ */
+ if ((spec = getenv("bootfile")) == NULL)
+ spec = default_bootfiles;
+
+ while ((try > 0) && (spec != NULL)) {
+ spec = strchr(spec, ';');
+ if (spec)
+ spec++; /* skip over the leading ';' */
+ try--;
}
- name = malloc(len + 1);
- strncpy(name, spec, len);
- name[len] = 0;
- }
- if (name && name[0] == 0) {
- free(name);
- name = NULL;
- }
- return(name);
+ if (spec != NULL) {
+ if ((ep = strchr(spec, ';')) != NULL) {
+ len = ep - spec;
+ } else {
+ len = strlen(spec);
+ }
+ name = malloc(len + 1);
+ strncpy(name, spec, len);
+ name[len] = 0;
+ }
+ if (name && name[0] == 0) {
+ free(name);
+ name = NULL;
+ }
+ return(name);
}
/*
@@ -307,104 +307,109 @@ getbootfile(int try)
int
getrootmount(char *rootdev)
{
- char lbuf[128], *cp, *ep, *dev, *fstyp, *options;
- int fd, error;
-
- if (getenv("vfs.root.mountfrom") != NULL)
- return(0);
-
- error = 1;
- sprintf(lbuf, "%s/etc/fstab", rootdev);
- if ((fd = open(lbuf, O_RDONLY)) < 0)
- goto notfound;
-
- /* loop reading lines from /etc/fstab What was that about sscanf again? */
- while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) {
- if ((lbuf[0] == 0) || (lbuf[0] == '#'))
- continue;
-
- /* skip device name */
- for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++)
- ;
- if (*cp == 0) /* misformatted */
- continue;
- /* delimit and save */
- *cp++ = 0;
- dev = strdup(lbuf);
-
- /* skip whitespace up to mountpoint */
- while ((*cp != 0) && isspace(*cp))
- cp++;
- /* must have /<space> to be root */
- if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1)))
- continue;
- /* skip whitespace up to fstype */
- cp += 2;
- while ((*cp != 0) && isspace(*cp))
- cp++;
- if (*cp == 0) /* misformatted */
- continue;
- /* skip text to end of fstype and delimit */
- ep = cp;
- while ((*cp != 0) && !isspace(*cp))
- cp++;
- *cp = 0;
- fstyp = strdup(ep);
-
- /* skip whitespace up to mount options */
- cp += 1;
- while ((*cp != 0) && isspace(*cp))
- cp++;
- if (*cp == 0) /* misformatted */
- continue;
- /* skip text to end of mount options and delimit */
- ep = cp;
- while ((*cp != 0) && !isspace(*cp))
- cp++;
- *cp = 0;
- options = strdup(ep);
- /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */
- sprintf(lbuf, "%s:%s", fstyp, dev);
+ char lbuf[128], *cp, *ep, *dev, *fstyp, *options;
+ int fd, error;
+
+ if (getenv("vfs.root.mountfrom") != NULL)
+ return(0);
+
+ error = 1;
+ sprintf(lbuf, "%s/etc/fstab", rootdev);
+ if ((fd = open(lbuf, O_RDONLY)) < 0)
+ goto notfound;
+
+ /* loop reading lines from /etc/fstab What was that about sscanf again? */
+ fstyp = NULL;
+ dev = NULL;
+ while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) {
+ if ((lbuf[0] == 0) || (lbuf[0] == '#'))
+ continue;
+
+ /* skip device name */
+ for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++)
+ ;
+ if (*cp == 0) /* misformatted */
+ continue;
+ /* delimit and save */
+ *cp++ = 0;
+ free(dev);
+ dev = strdup(lbuf);
+
+ /* skip whitespace up to mountpoint */
+ while ((*cp != 0) && isspace(*cp))
+ cp++;
+ /* must have /<space> to be root */
+ if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1)))
+ continue;
+ /* skip whitespace up to fstype */
+ cp += 2;
+ while ((*cp != 0) && isspace(*cp))
+ cp++;
+ if (*cp == 0) /* misformatted */
+ continue;
+ /* skip text to end of fstype and delimit */
+ ep = cp;
+ while ((*cp != 0) && !isspace(*cp))
+ cp++;
+ *cp = 0;
+ free(fstyp);
+ fstyp = strdup(ep);
+
+ /* skip whitespace up to mount options */
+ cp += 1;
+ while ((*cp != 0) && isspace(*cp))
+ cp++;
+ if (*cp == 0) /* misformatted */
+ continue;
+ /* skip text to end of mount options and delimit */
+ ep = cp;
+ while ((*cp != 0) && !isspace(*cp))
+ cp++;
+ *cp = 0;
+ options = strdup(ep);
+ /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */
+ sprintf(lbuf, "%s:%s", fstyp, dev);
+ setenv("vfs.root.mountfrom", lbuf, 0);
+
+ /* Don't override vfs.root.mountfrom.options if it is already set */
+ if (getenv("vfs.root.mountfrom.options") == NULL) {
+ /* save mount options */
+ setenv("vfs.root.mountfrom.options", options, 0);
+ }
+ free(options);
+ error = 0;
+ break;
+ }
+ close(fd);
free(dev);
free(fstyp);
- setenv("vfs.root.mountfrom", lbuf, 0);
-
- /* Don't override vfs.root.mountfrom.options if it is already set */
- if (getenv("vfs.root.mountfrom.options") == NULL) {
- /* save mount options */
- setenv("vfs.root.mountfrom.options", options, 0);
- }
- free(options);
- error = 0;
- break;
- }
- close(fd);
notfound:
- if (error) {
- const char *currdev;
-
- currdev = getenv("currdev");
- if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) {
- cp = strdup(currdev);
- cp[strlen(cp) - 1] = '\0';
- setenv("vfs.root.mountfrom", cp, 0);
- error = 0;
+ if (error) {
+ const char *currdev;
+
+ currdev = getenv("currdev");
+ if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) {
+ cp = strdup(currdev);
+ cp[strlen(cp) - 1] = '\0';
+ setenv("vfs.root.mountfrom", cp, 0);
+ error = 0;
+ free(cp);
+ }
}
- }
- return(error);
+ return(error);
}
static int
loadakernel(int try, int argc, char* argv[])
{
- char *cp;
+ char *cp;
for (try = 0; (cp = getbootfile(try)) != NULL; try++)
- if (mod_loadkld(cp, argc - 1, argv + 1) != 0)
- printf("can't load '%s'\n", cp);
- else
- return 1;
+ if (mod_loadkld(cp, argc - 1, argv + 1) != 0)
+ printf("can't load '%s'\n", cp);
+ else
+ return 1;
return 0;
}
diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
index a570720..2808117 100644
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -46,7 +46,13 @@ extern char command_errbuf[COMMAND_ERRBUFSZ];
/* interp.c */
void interact(void);
-int include(const char *filename);
+void interp_emit_prompt(void);
+int interp_builtin_cmd(int argc, char *argv[]);
+
+/* Called by interp.c for interp_*.c embedded interpreters */
+int interp_include(const char *filename); /* Execute commands from filename */
+void interp_init(void); /* Initialize interpreater */
+int interp_run(const char *line); /* Run a single command */
/* interp_backslash.c */
char *backslash(const char *str);
@@ -54,10 +60,6 @@ char *backslash(const char *str);
/* interp_parse.c */
int parse(int *argc, char ***argv, const char *str);
-/* interp_forth.c */
-void bf_init(void);
-int bf_run(char *line);
-
/* boot.c */
int autoboot(int timeout, char *prompt);
void autoboot_maybe(void);
@@ -315,6 +317,9 @@ struct arch_switch
/* Probe ZFS pool(s), if needed. */
void (*arch_zfs_probe)(void);
+
+ /* For kexec-type loaders, get ksegment structure */
+ void (*arch_kexec_kseg_get)(int *nseg, void **kseg);
};
extern struct arch_switch archsw;
diff --git a/stand/common/commands.c b/stand/common/commands.c
index def7ff2..1d5000b 100644
--- a/stand/common/commands.c
+++ b/stand/common/commands.c
@@ -91,10 +91,8 @@ help_getnext(int fd, char **topic, char **subtopic, char **desc)
cp = ep;
}
if (*topic == NULL) {
- if (*subtopic != NULL)
- free(*subtopic);
- if (*desc != NULL)
- free(*desc);
+ free(*subtopic);
+ free(*desc);
continue;
}
return(1);
@@ -169,7 +167,7 @@ command_help(int argc, char *argv[])
} else if (strcmp(topic, t)) {
/* topic mismatch */
- if(matched) /* nothing more on this topic, stop scanning */
+ if (matched) /* nothing more on this topic, stop scanning */
break;
} else {
@@ -178,7 +176,7 @@ command_help(int argc, char *argv[])
if (((subtopic == NULL) && (s == NULL)) ||
((subtopic != NULL) && (s != NULL) && !strcmp(subtopic, s))) {
/* exact match, print text */
- while((fgetstr(buf, 80, hfd) >= 0) && (buf[0] != '#')) {
+ while ((fgetstr(buf, 80, hfd) >= 0) && (buf[0] != '#')) {
if (pager_output(buf))
break;
if (pager_output("\n"))
@@ -193,24 +191,25 @@ command_help(int argc, char *argv[])
free(t);
free(s);
free(d);
+ t = s = d = NULL;
}
+ free(t);
+ free(s);
+ free(d);
pager_close();
close(hfd);
if (!matched) {
snprintf(command_errbuf, sizeof(command_errbuf),
"no help available for '%s'", topic);
free(topic);
- if (subtopic)
- free(subtopic);
+ free(subtopic);
return(CMD_ERROR);
}
free(topic);
- if (subtopic)
- free(subtopic);
+ free(subtopic);
return(CMD_OK);
}
-
COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
/*
diff --git a/stand/common/install.c b/stand/common/install.c
index 8c19066..0ba73e4 100644
--- a/stand/common/install.c
+++ b/stand/common/install.c
@@ -286,7 +286,7 @@ install(char *pkgname)
fd = open(s, O_RDONLY);
if (fd != -1) {
close(fd);
- error = include(s);
+ error = inter_include(s);
if (error == CMD_ERROR)
goto fail;
}
diff --git a/stand/common/interp.c b/stand/common/interp.c
index 6b1b8bb..8941101 100644
--- a/stand/common/interp.c
+++ b/stand/common/interp.c
@@ -37,102 +37,40 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include "bootstrap.h"
-#ifdef BOOT_FORTH
-#include "ficl.h"
-extern FICL_VM *bf_vm;
-#endif
-
#define MAXARGS 20 /* maximum number of arguments allowed */
-static void prompt(void);
-
-#ifndef BOOT_FORTH
-/*
- * Perform the command
- */
-static int
-perform(int argc, char *argv[])
-{
- int result;
- struct bootblk_command **cmdp;
- bootblk_cmd_t *cmd;
-
- if (argc < 1)
- 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);
- } else {
- command_errmsg = "unknown command";
- }
- return(result);
-}
-#endif /* ! BOOT_FORTH */
-
/*
* Interactive mode
*/
void
interact(void)
{
- static char input[256]; /* big enough? */
-#ifndef BOOT_FORTH
- int argc;
- char **argv;
-#endif
-
-#ifdef BOOT_FORTH
- bf_init();
-#endif
-
- /* Read our default configuration. */
- include("/boot/loader.rc");
-
- printf("\n");
-
- /*
- * Before interacting, we might want to autoboot.
- */
- autoboot_maybe();
-
- /*
- * Not autobooting, go manual
- */
- printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
- if (getenv("prompt") == NULL)
- setenv("prompt", "${interpret}", 1);
- if (getenv("interpret") == NULL)
- setenv("interpret", "OK", 1);
-
-
- for (;;) {
- input[0] = '\0';
- prompt();
- ngets(input, sizeof(input));
-#ifdef BOOT_FORTH
- bf_vm->sourceID.i = 0;
- bf_run(input);
-#else
- if (!parse(&argc, &argv, input)) {
- if (perform(argc, argv))
- printf("%s: %s\n", argv[0], command_errmsg);
- free(argv);
- } else {
- printf("parse error\n");
+ static char input[256]; /* big enough? */
+
+ interp_init();
+
+ printf("\n");
+
+ /*
+ * Before interacting, we might want to autoboot.
+ */
+ autoboot_maybe();
+
+ /*
+ * Not autobooting, go manual
+ */
+ printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
+ if (getenv("prompt") == NULL)
+ setenv("prompt", "${interpret}", 1);
+ if (getenv("interpret") == NULL)
+ setenv("interpret", "OK", 1);
+
+ for (;;) {
+ input[0] = '\0';
+ interp_emit_prompt();
+ ngets(input, sizeof(input));
+ interp_run(input);
}
-#endif
- }
}
/*
@@ -149,214 +87,87 @@ COMMAND_SET(include, "include", "read commands from a file", command_include);
static int
command_include(int argc, char *argv[])
{
- int i;
- int res;
- char **argvbuf;
-
- /*
- * Since argv is static, we need to save it here.
- */
- argvbuf = (char**) calloc((u_int)argc, sizeof(char*));
- for (i = 0; i < argc; i++)
- argvbuf[i] = strdup(argv[i]);
-
- res=CMD_OK;
- for (i = 1; (i < argc) && (res == CMD_OK); i++)
- res = include(argvbuf[i]);
-
- for (i = 0; i < argc; i++)
- free(argvbuf[i]);
- free(argvbuf);
-
- return(res);
+ int i;
+ int res;
+ char **argvbuf;
+
+ /*
+ * Since argv is static, we need to save it here.
+ */
+ argvbuf = (char**) calloc((u_int)argc, sizeof(char*));
+ for (i = 0; i < argc; i++)
+ argvbuf[i] = strdup(argv[i]);
+
+ res=CMD_OK;
+ for (i = 1; (i < argc) && (res == CMD_OK); i++)
+ res = interp_include(argvbuf[i]);
+
+ for (i = 0; i < argc; i++)
+ free(argvbuf[i]);
+ free(argvbuf);
+
+ return(res);
}
/*
- * Header prepended to each line. The text immediately follows the header.
- * We try to make this short in order to save memory -- the loader has
- * limited memory available, and some of the forth files are very long.
+ * Emit the current prompt; use the same syntax as the parser
+ * for embedding environment variables. Does not accept input.
*/
-struct includeline
-{
- struct includeline *next;
-#ifndef BOOT_FORTH
- int flags;
- int line;
-#define SL_QUIET (1<<0)
-#define SL_IGNOREERR (1<<1)
-#endif
- char text[0];
-};
-
-int
-include(const char *filename)
+void
+interp_emit_prompt(void)
{
- struct includeline *script, *se, *sp;
- char input[256]; /* big enough? */
-#ifdef BOOT_FORTH
- int res;
- char *cp;
- int prevsrcid, fd, line;
-#else
- int argc,res;
- char **argv, *cp;
- int fd, flags, line;
-#endif
-
- if (((fd = open(filename, O_RDONLY)) == -1)) {
- snprintf(command_errbuf, sizeof(command_errbuf),
- "can't open '%s': %s", filename, strerror(errno));
- return(CMD_ERROR);
- }
-
- /*
- * Read the script into memory.
- */
- script = se = NULL;
- line = 0;
-
- while (fgetstr(input, sizeof(input), fd) >= 0) {
- line++;
-#ifdef BOOT_FORTH
- cp = input;
-#else
- flags = 0;
- /* Discard comments */
- if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0)
- continue;
- cp = input;
- /* Echo? */
- if (input[0] == '@') {
- cp++;
- flags |= SL_QUIET;
- }
- /* Error OK? */
- if (input[0] == '-') {
- cp++;
- flags |= SL_IGNOREERR;
- }
-#endif
- /* Allocate script line structure and copy line, flags */
- if (*cp == '\0')
- continue; /* ignore empty line, save memory */
- sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
- /* On malloc failure (it happens!), free as much as possible and exit */
- if (sp == NULL) {
- while (script != NULL) {
- se = script;
- script = script->next;
- free(se);
+ char *pr, *p, *cp, *ev;
+
+ if ((cp = getenv("prompt")) == NULL)
+ cp = ">";
+ pr = p = strdup(cp);
+
+ while (*p != 0) {
+ if ((*p == '$') && (*(p+1) == '{')) {
+ for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++)
+ ;
+ *cp = 0;
+ ev = getenv(p + 2);
+
+ if (ev != NULL)
+ printf("%s", ev);
+ p = cp + 1;
+ continue;
}
- snprintf(command_errbuf, sizeof(command_errbuf),
- "file '%s' line %d: memory allocation failure - aborting",
- filename, line);
- return (CMD_ERROR);
- }
- strcpy(sp->text, cp);
-#ifndef BOOT_FORTH
- sp->flags = flags;
- sp->line = line;
-#endif
- sp->next = NULL;
-
- if (script == NULL) {
- script = sp;
- } else {
- se->next = sp;
+ putchar(*p++);
}
- se = sp;
- }
- close(fd);
-
- /*
- * Execute the script
- */
-#ifndef BOOT_FORTH
- argv = NULL;
-#else
- prevsrcid = bf_vm->sourceID.i;
- bf_vm->sourceID.i = fd;
-#endif
- res = CMD_OK;
- for (sp = script; sp != NULL; sp = sp->next) {
-
-#ifdef BOOT_FORTH
- res = bf_run(sp->text);
- if (res != VM_OUTOFTEXT) {
- snprintf(command_errbuf, sizeof(command_errbuf),
- "Error while including %s, in the line:\n%s",
- filename, sp->text);
- res = CMD_ERROR;
- break;
- } else
- res = CMD_OK;
-#else
- /* print if not being quiet */
- if (!(sp->flags & SL_QUIET)) {
- prompt();
- printf("%s\n", sp->text);
- }
-
- /* Parse the command */
- if (!parse(&argc, &argv, sp->text)) {
- if ((argc > 0) && (perform(argc, argv) != 0)) {
- /* normal command */
- printf("%s: %s\n", argv[0], command_errmsg);
- if (!(sp->flags & SL_IGNOREERR)) {
- res=CMD_ERROR;
- break;
- }
- }
- free(argv);
- argv = NULL;
- } else {
- printf("%s line %d: parse error\n", filename, sp->line);
- res=CMD_ERROR;
- break;
- }
-#endif
- }
-#ifndef BOOT_FORTH
- if (argv != NULL)
- free(argv);
-#else
- bf_vm->sourceID.i = prevsrcid;
-#endif
- while(script != NULL) {
- se = script;
- script = script->next;
- free(se);
- }
- return(res);
+ putchar(' ');
+ free(pr);
}
/*
- * Emit the current prompt; use the same syntax as the parser
- * for embedding environment variables.
+ * Perform a builtin command
*/
-static void
-prompt(void)
+int
+interp_builtin_cmd(int argc, char *argv[])
{
- char *pr, *p, *cp, *ev;
-
- if ((cp = getenv("prompt")) == NULL)
- cp = ">";
- pr = p = strdup(cp);
-
- while (*p != 0) {
- if ((*p == '$') && (*(p+1) == '{')) {
- for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++)
- ;
- *cp = 0;
- ev = getenv(p + 2);
-
- if (ev != NULL)
- printf("%s", ev);
- p = cp + 1;
- continue;
+ int result;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
+
+ if (argc < 1)
+ 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);
+ } else {
+ command_errmsg = "unknown command";
}
- putchar(*p++);
- }
- putchar(' ');
- free(pr);
+ return(result);
}
diff --git a/stand/common/interp_backslash.c b/stand/common/interp_backslash.c
index 30874bd..c75081b 100644
--- a/stand/common/interp_backslash.c
+++ b/stand/common/interp_backslash.c
@@ -30,138 +30,138 @@ __FBSDID("$FreeBSD$");
char *
backslash(const char *str)
{
- /*
- * Remove backslashes from the strings. Turn \040 etc. into a single
- * character (we allow eight bit values). Currently NUL is not
- * allowed.
- *
- * Turn "\n" and "\t" into '\n' and '\t' characters. Etc.
- *
- */
- char *new_str;
- int seenbs = 0;
- int i = 0;
-
- if ((new_str = strdup(str)) == NULL)
- return NULL;
-
- while (*str) {
- if (seenbs) {
- seenbs = 0;
- switch (*str) {
- case '\\':
- new_str[i++] = '\\';
- str++;
- break;
-
- /* preserve backslashed quotes, dollar signs */
- case '\'':
- case '"':
- case '$':
- new_str[i++] = '\\';
- new_str[i++] = *str++;
- break;
-
- case 'b':
- new_str[i++] = '\b';
- str++;
- break;
-
- case 'f':
- new_str[i++] = '\f';
- str++;
- break;
-
- case 'r':
- new_str[i++] = '\r';
- str++;
- break;
-
- case 'n':
- new_str[i++] = '\n';
- str++;
- break;
-
- case 's':
- new_str[i++] = ' ';
- str++;
- break;
-
- case 't':
- new_str[i++] = '\t';
- str++;
- break;
-
- case 'v':
- new_str[i++] = '\13';
- str++;
- break;
-
- case 'z':
- str++;
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': {
- char val;
-
- /* Three digit octal constant? */
- if (*str >= '0' && *str <= '3' &&
- *(str + 1) >= '0' && *(str + 1) <= '7' &&
- *(str + 2) >= '0' && *(str + 2) <= '7') {
-
- val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) +
- DIGIT(*(str + 2));
-
- /* Allow null value if user really wants to shoot
- at feet, but beware! */
- new_str[i++] = val;
- str += 3;
- break;
+ /*
+ * Remove backslashes from the strings. Turn \040 etc. into a single
+ * character (we allow eight bit values). Currently NUL is not
+ * allowed.
+ *
+ * Turn "\n" and "\t" into '\n' and '\t' characters. Etc.
+ *
+ */
+ char *new_str;
+ int seenbs = 0;
+ int i = 0;
+
+ if ((new_str = strdup(str)) == NULL)
+ return NULL;
+
+ while (*str) {
+ if (seenbs) {
+ seenbs = 0;
+ switch (*str) {
+ case '\\':
+ new_str[i++] = '\\';
+ str++;
+ break;
+
+ /* preserve backslashed quotes, dollar signs */
+ case '\'':
+ case '"':
+ case '$':
+ new_str[i++] = '\\';
+ new_str[i++] = *str++;
+ break;
+
+ case 'b':
+ new_str[i++] = '\b';
+ str++;
+ break;
+
+ case 'f':
+ new_str[i++] = '\f';
+ str++;
+ break;
+
+ case 'r':
+ new_str[i++] = '\r';
+ str++;
+ break;
+
+ case 'n':
+ new_str[i++] = '\n';
+ str++;
+ break;
+
+ case 's':
+ new_str[i++] = ' ';
+ str++;
+ break;
+
+ case 't':
+ new_str[i++] = '\t';
+ str++;
+ break;
+
+ case 'v':
+ new_str[i++] = '\13';
+ str++;
+ break;
+
+ case 'z':
+ str++;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ char val;
+
+ /* Three digit octal constant? */
+ if (*str >= '0' && *str <= '3' &&
+ *(str + 1) >= '0' && *(str + 1) <= '7' &&
+ *(str + 2) >= '0' && *(str + 2) <= '7') {
+
+ val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) +
+ DIGIT(*(str + 2));
+
+ /* Allow null value if user really wants to shoot
+ at feet, but beware! */
+ new_str[i++] = val;
+ str += 3;
+ break;
+ }
+
+ /* One or two digit hex constant?
+ * If two are there they will both be taken.
+ * Use \z to split them up if this is not wanted.
+ */
+ if (*str == '0' &&
+ (*(str + 1) == 'x' || *(str + 1) == 'X') &&
+ isxdigit(*(str + 2))) {
+ val = DIGIT(*(str + 2));
+ if (isxdigit(*(str + 3))) {
+ val = (val << 4) + DIGIT(*(str + 3));
+ str += 4;
+ }
+ else
+ str += 3;
+ /* Yep, allow null value here too */
+ new_str[i++] = val;
+ break;
+ }
+ }
+ break;
+
+ default:
+ new_str[i++] = *str++;
+ break;
+ }
}
-
- /* One or two digit hex constant?
- * If two are there they will both be taken.
- * Use \z to split them up if this is not wanted.
- */
- if (*str == '0' &&
- (*(str + 1) == 'x' || *(str + 1) == 'X') &&
- isxdigit(*(str + 2))) {
- val = DIGIT(*(str + 2));
- if (isxdigit(*(str + 3))) {
- val = (val << 4) + DIGIT(*(str + 3));
- str += 4;
- }
- else
- str += 3;
- /* Yep, allow null value here too */
- new_str[i++] = val;
- break;
+ else {
+ if (*str == '\\') {
+ seenbs = 1;
+ str++;
+ }
+ else
+ new_str[i++] = *str++;
}
- }
- break;
-
- default:
- new_str[i++] = *str++;
- break;
- }
- }
- else {
- if (*str == '\\') {
- seenbs = 1;
- str++;
- }
- else
- new_str[i++] = *str++;
}
- }
- if (seenbs) {
- /*
- * The final character was a '\'. Put it in as a single backslash.
- */
- new_str[i++] = '\\';
- }
- new_str[i] = '\0';
- return new_str;
+ if (seenbs) {
+ /*
+ * The final character was a '\'. Put it in as a single backslash.
+ */
+ new_str[i++] = '\\';
+ }
+ new_str[i] = '\0';
+ return new_str;
}
diff --git a/stand/common/interp_forth.c b/stand/common/interp_forth.c
index d617ce8..f3a97e3 100644
--- a/stand/common/interp_forth.c
+++ b/stand/common/interp_forth.c
@@ -71,91 +71,91 @@ FICL_VM *bf_vm;
static void
bf_command(FICL_VM *vm)
{
- char *name, *line, *tail, *cp;
- size_t len;
- struct bootblk_command **cmdp;
- bootblk_cmd_t *cmd;
- int nstrings, i;
- int argc, result;
- char **argv;
-
- /* Get the name of the current word */
- name = vm->runningWord->name;
-
- /* Find our command structure */
- cmd = NULL;
- SET_FOREACH(cmdp, Xcommand_set) {
- if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name))
- cmd = (*cmdp)->c_fn;
- }
- if (cmd == NULL)
- panic("callout for unknown command '%s'", name);
-
- /* Check whether we have been compiled or are being interpreted */
- if (stackPopINT(vm->pStack)) {
+ char *name, *line, *tail, *cp;
+ size_t len;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
+ int nstrings, i;
+ int argc, result;
+ char **argv;
+
+ /* Get the name of the current word */
+ name = vm->runningWord->name;
+
+ /* Find our command structure */
+ cmd = NULL;
+ SET_FOREACH(cmdp, Xcommand_set) {
+ if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name))
+ cmd = (*cmdp)->c_fn;
+ }
+ if (cmd == NULL)
+ panic("callout for unknown command '%s'", name);
+
+ /* Check whether we have been compiled or are being interpreted */
+ if (stackPopINT(vm->pStack)) {
+ /*
+ * Get parameters from stack, in the format:
+ * an un ... a2 u2 a1 u1 n --
+ * Where n is the number of strings, a/u are pairs of
+ * address/size for strings, and they will be concatenated
+ * in LIFO order.
+ */
+ nstrings = stackPopINT(vm->pStack);
+ for (i = 0, len = 0; i < nstrings; i++)
+ len += stackFetch(vm->pStack, i * 2).i + 1;
+ line = malloc(strlen(name) + len + 1);
+ strcpy(line, name);
+
+ if (nstrings)
+ for (i = 0; i < nstrings; i++) {
+ len = stackPopINT(vm->pStack);
+ cp = stackPopPtr(vm->pStack);
+ strcat(line, " ");
+ strncat(line, cp, len);
+ }
+ } else {
+ /* Get remainder of invocation */
+ tail = vmGetInBuf(vm);
+ for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++)
+ ;
+
+ line = malloc(strlen(name) + len + 2);
+ strcpy(line, name);
+ if (len > 0) {
+ strcat(line, " ");
+ strncat(line, tail, len);
+ vmUpdateTib(vm, tail + len);
+ }
+ }
+ DEBUG("cmd '%s'", line);
+
+ command_errmsg = command_errbuf;
+ command_errbuf[0] = 0;
+ if (!parse(&argc, &argv, line)) {
+ result = (cmd)(argc, argv);
+ free(argv);
+ } else {
+ result=BF_PARSE;
+ }
+
+ switch (result) {
+ case CMD_CRIT:
+ printf("%s\n", command_errmsg);
+ break;
+ case CMD_FATAL:
+ panic("%s\n", command_errmsg);
+ }
+
+ free(line);
/*
- * Get parameters from stack, in the format:
- * an un ... a2 u2 a1 u1 n --
- * Where n is the number of strings, a/u are pairs of
- * address/size for strings, and they will be concatenated
- * in LIFO order.
+ * If there was error during nested ficlExec(), we may no longer have
+ * valid environment to return. Throw all exceptions from here.
*/
- nstrings = stackPopINT(vm->pStack);
- for (i = 0, len = 0; i < nstrings; i++)
- len += stackFetch(vm->pStack, i * 2).i + 1;
- line = malloc(strlen(name) + len + 1);
- strcpy(line, name);
-
- if (nstrings)
- for (i = 0; i < nstrings; i++) {
- len = stackPopINT(vm->pStack);
- cp = stackPopPtr(vm->pStack);
- strcat(line, " ");
- strncat(line, cp, len);
- }
- } else {
- /* Get remainder of invocation */
- tail = vmGetInBuf(vm);
- for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++)
- ;
-
- line = malloc(strlen(name) + len + 2);
- strcpy(line, name);
- if (len > 0) {
- strcat(line, " ");
- strncat(line, tail, len);
- vmUpdateTib(vm, tail + len);
- }
- }
- DEBUG("cmd '%s'", line);
-
- command_errmsg = command_errbuf;
- command_errbuf[0] = 0;
- if (!parse(&argc, &argv, line)) {
- result = (cmd)(argc, argv);
- free(argv);
- } else {
- result=BF_PARSE;
- }
-
- switch (result) {
- case CMD_CRIT:
- printf("%s\n", command_errmsg);
- break;
- case CMD_FATAL:
- panic("%s\n", command_errmsg);
- }
-
- free(line);
- /*
- * If there was error during nested ficlExec(), we may no longer have
- * valid environment to return. Throw all exceptions from here.
- */
- if (result != CMD_OK)
- vmThrow(vm, result);
-
- /* This is going to be thrown!!! */
- stackPushINT(vm->pStack,result);
+ if (result != CMD_OK)
+ vmThrow(vm, result);
+
+ /* This is going to be thrown!!! */
+ stackPushINT(vm->pStack,result);
}
/*
@@ -226,25 +226,25 @@ bf_command(FICL_VM *vm)
* (if you edit this definition, pay attention to trailing spaces after
* each word -- I warned you! :-) )
*/
-#define BUILTIN_CONSTRUCTOR \
-": builtin: " \
- ">in @ " /* save the tib index pointer */ \
- "' " /* get next word's xt */ \
- "swap >in ! " /* point again to next word */ \
- "create " /* create a new definition of the next word */ \
- ", " /* save previous definition's xt */ \
- "immediate " /* make the new definition an immediate word */ \
- \
- "does> " /* Now, the *new* definition will: */ \
- "state @ if " /* if in compiling state: */ \
- "1 postpone literal " /* pass 1 flag to indicate compile */ \
- "@ compile, " /* compile in previous definition */ \
- "postpone throw " /* throw stack-returned result */ \
- "else " /* if in interpreting state: */ \
- "0 swap " /* pass 0 flag to indicate interpret */ \
- "@ execute " /* call previous definition */ \
- "throw " /* throw stack-returned result */ \
- "then ; "
+#define BUILTIN_CONSTRUCTOR \
+ ": builtin: " \
+ ">in @ " /* save the tib index pointer */ \
+ "' " /* get next word's xt */ \
+ "swap >in ! " /* point again to next word */ \
+ "create " /* create a new definition of the next word */ \
+ ", " /* save previous definition's xt */ \
+ "immediate " /* make the new definition an immediate word */ \
+ \
+ "does> " /* Now, the *new* definition will: */ \
+ "state @ if " /* if in compiling state: */ \
+ "1 postpone literal " /* pass 1 flag to indicate compile */ \
+ "@ compile, " /* compile in previous definition */ \
+ "postpone throw " /* throw stack-returned result */ \
+ "else " /* if in interpreting state: */ \
+ "0 swap " /* pass 0 flag to indicate interpret */ \
+ "@ execute " /* call previous definition */ \
+ "throw " /* throw stack-returned result */ \
+ "then ; "
/*
* Initialise the Forth interpreter, create all our commands as words.
@@ -252,76 +252,192 @@ bf_command(FICL_VM *vm)
void
bf_init(void)
{
- struct bootblk_command **cmdp;
- char create_buf[41]; /* 31 characters-long builtins */
- int fd;
-
- bf_sys = ficlInitSystem(BF_DICTSIZE);
- bf_vm = ficlNewVM(bf_sys);
-
- /* Put all private definitions in a "builtins" vocabulary */
- ficlExec(bf_vm, "vocabulary builtins also builtins definitions");
-
- /* Builtin constructor word */
- ficlExec(bf_vm, BUILTIN_CONSTRUCTOR);
-
- /* make all commands appear as Forth words */
- SET_FOREACH(cmdp, Xcommand_set) {
- ficlBuild(bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT);
- ficlExec(bf_vm, "forth definitions builtins");
- sprintf(create_buf, "builtin: %s", (*cmdp)->c_name);
- ficlExec(bf_vm, create_buf);
- ficlExec(bf_vm, "builtins definitions");
- }
- ficlExec(bf_vm, "only forth definitions");
-
- /* Export some version numbers so that code can detect the loader/host version */
- ficlSetEnv(bf_sys, "FreeBSD_version", __FreeBSD_version);
- ficlSetEnv(bf_sys, "loader_version", bootprog_rev);
-
- /* try to load and run init file if present */
- if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) {
- (void)ficlExecFD(bf_vm, fd);
- close(fd);
- }
+ struct bootblk_command **cmdp;
+ char create_buf[41]; /* 31 characters-long builtins */
+ int fd;
+
+ bf_sys = ficlInitSystem(BF_DICTSIZE);
+ bf_vm = ficlNewVM(bf_sys);
+
+ /* Put all private definitions in a "builtins" vocabulary */
+ ficlExec(bf_vm, "vocabulary builtins also builtins definitions");
+
+ /* Builtin constructor word */
+ ficlExec(bf_vm, BUILTIN_CONSTRUCTOR);
+
+ /* make all commands appear as Forth words */
+ SET_FOREACH(cmdp, Xcommand_set) {
+ ficlBuild(bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT);
+ ficlExec(bf_vm, "forth definitions builtins");
+ sprintf(create_buf, "builtin: %s", (*cmdp)->c_name);
+ ficlExec(bf_vm, create_buf);
+ ficlExec(bf_vm, "builtins definitions");
+ }
+ ficlExec(bf_vm, "only forth definitions");
+
+ /* Export some version numbers so that code can detect the loader/host version */
+ ficlSetEnv(bf_sys, "FreeBSD_version", __FreeBSD_version);
+ ficlSetEnv(bf_sys, "loader_version", bootprog_rev);
+
+ /* try to load and run init file if present */
+ if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) {
+ (void)ficlExecFD(bf_vm, fd);
+ close(fd);
+ }
}
/*
* Feed a line of user input to the Forth interpreter
*/
+static int
+bf_run(const char *line)
+{
+ int result;
+
+ /*
+ * ficl would require extensive changes to accept a const char *
+ * interface. Instead, cast it away here and hope for the best.
+ * We know at the present time the caller for us in the boot
+ * forth loader can tolerate the string being modified because
+ * the string is passed in here and then not touched again.
+ */
+ result = ficlExec(bf_vm, __DECONST(char *, line));
+
+ DEBUG("ficlExec '%s' = %d", line, result);
+ switch (result) {
+ case VM_OUTOFTEXT:
+ case VM_ABORTQ:
+ case VM_QUIT:
+ case VM_ERREXIT:
+ break;
+ case VM_USEREXIT:
+ printf("No where to leave to!\n");
+ break;
+ case VM_ABORT:
+ printf("Aborted!\n");
+ break;
+ case BF_PARSE:
+ printf("Parse error!\n");
+ break;
+ default:
+ if (command_errmsg != NULL) {
+ printf("%s\n", command_errmsg);
+ command_errmsg = NULL;
+ }
+ }
+
+ if (result == VM_USEREXIT)
+ panic("interpreter exit");
+ setenv("interpret", bf_vm->state ? "" : "OK", 1);
+
+ return (result);
+}
+
+void
+interp_init(void)
+{
+
+ setenv("script.lang", "forth", 1);
+ bf_init();
+ /* Read our default configuration. */
+ interp_include("/boot/loader.rc");
+}
+
+int
+interp_run(const char *input)
+{
+
+ bf_vm->sourceID.i = 0;
+ return bf_run(input);
+}
+
+/*
+ * Header prepended to each line. The text immediately follows the header.
+ * We try to make this short in order to save memory -- the loader has
+ * limited memory available, and some of the forth files are very long.
+ */
+struct includeline
+{
+ struct includeline *next;
+ char text[0];
+};
+
int
-bf_run(char *line)
+interp_include(const char *filename)
{
- int result;
-
- result = ficlExec(bf_vm, line);
-
- DEBUG("ficlExec '%s' = %d", line, result);
- switch (result) {
- case VM_OUTOFTEXT:
- case VM_ABORTQ:
- case VM_QUIT:
- case VM_ERREXIT:
- break;
- case VM_USEREXIT:
- printf("No where to leave to!\n");
- break;
- case VM_ABORT:
- printf("Aborted!\n");
- break;
- case BF_PARSE:
- printf("Parse error!\n");
- break;
- default:
- if (command_errmsg != NULL) {
- printf("%s\n", command_errmsg);
- command_errmsg = NULL;
+ struct includeline *script, *se, *sp;
+ char input[256]; /* big enough? */
+ int res;
+ char *cp;
+ int prevsrcid, fd, line;
+
+ if (((fd = open(filename, O_RDONLY)) == -1)) {
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "can't open '%s': %s", filename, strerror(errno));
+ return(CMD_ERROR);
}
- }
-
- if (result == VM_USEREXIT)
- panic("interpreter exit");
- setenv("interpret", bf_vm->state ? "" : "OK", 1);
- return (result);
+ /*
+ * Read the script into memory.
+ */
+ script = se = NULL;
+ line = 0;
+
+ while (fgetstr(input, sizeof(input), fd) >= 0) {
+ line++;
+ cp = input;
+ /* Allocate script line structure and copy line, flags */
+ if (*cp == '\0')
+ continue; /* ignore empty line, save memory */
+ sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
+ /* On malloc failure (it happens!), free as much as possible and exit */
+ if (sp == NULL) {
+ while (script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "file '%s' line %d: memory allocation failure - aborting",
+ filename, line);
+ close(fd);
+ return (CMD_ERROR);
+ }
+ strcpy(sp->text, cp);
+ sp->next = NULL;
+
+ if (script == NULL) {
+ script = sp;
+ } else {
+ se->next = sp;
+ }
+ se = sp;
+ }
+ close(fd);
+
+ /*
+ * Execute the script
+ */
+ prevsrcid = bf_vm->sourceID.i;
+ bf_vm->sourceID.i = fd;
+ res = CMD_OK;
+ for (sp = script; sp != NULL; sp = sp->next) {
+ res = bf_run(sp->text);
+ if (res != VM_OUTOFTEXT) {
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "Error while including %s, in the line:\n%s",
+ filename, sp->text);
+ res = CMD_ERROR;
+ break;
+ } else
+ res = CMD_OK;
+ }
+ bf_vm->sourceID.i = prevsrcid;
+
+ while (script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ return(res);
}
diff --git a/stand/common/interp_parse.c b/stand/common/interp_parse.c
index 670273e..c46a497 100644
--- a/stand/common/interp_parse.c
+++ b/stand/common/interp_parse.c
@@ -50,143 +50,146 @@ static char *args[MAXARGS];
*/
#define PARSE_FAIL(expr) \
-if (expr) { \
- printf("fail at line %d\n", __LINE__); \
- clean(); \
- free(copy); \
- free(buf); \
- return 1; \
-}
+ if (expr) { \
+ printf("fail at line %d\n", __LINE__); \
+ clean(); \
+ free(copy); \
+ free(buf); \
+ return 1; \
+ }
/* Accept the usual delimiters for a variable, returning counterpart */
static char
isdelim(int ch)
{
- if (ch == '{')
- return '}';
- else if (ch == '(')
- return ')';
- return '\0';
+
+ if (ch == '{')
+ return '}';
+ else if (ch == '(')
+ return ')';
+ return '\0';
}
static int
isquote(int ch)
{
- return (ch == '\'');
+
+ return (ch == '\'');
}
static int
isdquote(int ch)
{
- return (ch == '"');
+
+ return (ch == '"');
}
int
parse(int *argc, char ***argv, const char *str)
{
- int ac;
- char *val, *p, *q, *copy = NULL;
- size_t i = 0;
- char token, tmp, quote, dquote, *buf;
- enum { STR, VAR, WHITE } state;
-
- ac = *argc = 0;
- dquote = quote = 0;
- if (!str || (p = copy = backslash(str)) == NULL)
- return 1;
-
- /* Initialize vector and state */
- clean();
- state = STR;
- buf = (char *)malloc(PARSE_BUFSIZE);
- token = 0;
-
- /* And awaaaaaaaaay we go! */
- while (*p) {
- switch (state) {
- case STR:
- if ((*p == '\\') && p[1]) {
- p++;
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else if (isquote(*p)) {
- quote = quote ? 0 : *p;
- if (dquote) { /* keep quote */
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else
- ++p;
- } else if (isdquote(*p)) {
- dquote = dquote ? 0 : *p;
- if (quote) { /* keep dquote */
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else
- ++p;
- } else if (isspace(*p) && !quote && !dquote) {
- state = WHITE;
- if (i) {
- buf[i] = '\0';
- PARSE_FAIL(insert(&ac, buf));
- i = 0;
+ int ac;
+ char *val, *p, *q, *copy = NULL;
+ size_t i = 0;
+ char token, tmp, quote, dquote, *buf;
+ enum { STR, VAR, WHITE } state;
+
+ ac = *argc = 0;
+ dquote = quote = 0;
+ if (!str || (p = copy = backslash(str)) == NULL)
+ return 1;
+
+ /* Initialize vector and state */
+ clean();
+ state = STR;
+ buf = (char *)malloc(PARSE_BUFSIZE);
+ token = 0;
+
+ /* And awaaaaaaaaay we go! */
+ while (*p) {
+ switch (state) {
+ case STR:
+ if ((*p == '\\') && p[1]) {
+ p++;
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else if (isquote(*p)) {
+ quote = quote ? 0 : *p;
+ if (dquote) { /* keep quote */
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else
+ ++p;
+ } else if (isdquote(*p)) {
+ dquote = dquote ? 0 : *p;
+ if (quote) { /* keep dquote */
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else
+ ++p;
+ } else if (isspace(*p) && !quote && !dquote) {
+ state = WHITE;
+ if (i) {
+ buf[i] = '\0';
+ PARSE_FAIL(insert(&ac, buf));
+ i = 0;
+ }
+ ++p;
+ } else if (*p == '$' && !quote) {
+ token = isdelim(*(p + 1));
+ if (token)
+ p += 2;
+ else
+ ++p;
+ state = VAR;
+ } else {
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ }
+ break;
+
+ case WHITE:
+ if (isspace(*p))
+ ++p;
+ else
+ state = STR;
+ break;
+
+ case VAR:
+ if (token) {
+ PARSE_FAIL((q = strchr(p, token)) == NULL);
+ } else {
+ q = p;
+ while (*q && !isspace(*q))
+ ++q;
+ }
+ tmp = *q;
+ *q = '\0';
+ if ((val = variable_lookup(p)) != NULL) {
+ size_t len = strlen(val);
+
+ strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1));
+ i += min(len, PARSE_BUFSIZE - 1);
+ }
+ *q = tmp; /* restore value */
+ p = q + (token ? 1 : 0);
+ state = STR;
+ break;
}
- ++p;
- } else if (*p == '$' && !quote) {
- token = isdelim(*(p + 1));
- if (token)
- p += 2;
- else
- ++p;
- state = VAR;
- } else {
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- }
- break;
-
- case WHITE:
- if (isspace(*p))
- ++p;
- else
- state = STR;
- break;
-
- case VAR:
- if (token) {
- PARSE_FAIL((q = strchr(p, token)) == NULL);
- } else {
- q = p;
- while (*q && !isspace(*q))
- ++q;
- }
- tmp = *q;
- *q = '\0';
- if ((val = variable_lookup(p)) != NULL) {
- size_t len = strlen(val);
-
- strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1));
- i += min(len, PARSE_BUFSIZE - 1);
- }
- *q = tmp; /* restore value */
- p = q + (token ? 1 : 0);
- state = STR;
- break;
}
- }
- /* missing terminating ' or " */
- PARSE_FAIL(quote || dquote);
- /* If at end of token, add it */
- if (i && state == STR) {
- buf[i] = '\0';
- PARSE_FAIL(insert(&ac, buf));
- }
- args[ac] = NULL;
- *argc = ac;
- *argv = (char **)malloc((sizeof(char *) * ac + 1));
- bcopy(args, *argv, sizeof(char *) * ac + 1);
- free(buf);
- free(copy);
- return 0;
+ /* missing terminating ' or " */
+ PARSE_FAIL(quote || dquote);
+ /* If at end of token, add it */
+ if (i && state == STR) {
+ buf[i] = '\0';
+ PARSE_FAIL(insert(&ac, buf));
+ }
+ args[ac] = NULL;
+ *argc = ac;
+ *argv = (char **)malloc((sizeof(char *) * ac + 1));
+ bcopy(args, *argv, sizeof(char *) * ac + 1);
+ free(buf);
+ free(copy);
+ return 0;
}
#define MAXARGS 20
@@ -195,28 +198,30 @@ parse(int *argc, char ***argv, const char *str)
static void
clean(void)
{
- int i;
+ int i;
- for (i = 0; i < MAXARGS; i++) {
- if (args[i] != NULL) {
- free(args[i]);
- args[i] = NULL;
+ for (i = 0; i < MAXARGS; i++) {
+ if (args[i] != NULL) {
+ free(args[i]);
+ args[i] = NULL;
+ }
}
- }
}
static int
insert(int *argcp, char *buf)
{
- if (*argcp >= MAXARGS)
- return 1;
- args[(*argcp)++] = strdup(buf);
- return 0;
+
+ if (*argcp >= MAXARGS)
+ return 1;
+ args[(*argcp)++] = strdup(buf);
+ return 0;
}
static char *
variable_lookup(char *name)
{
- /* XXX search "special variable" space first? */
- return (char *)getenv(name);
+
+ /* XXX search "special variable" space first? */
+ return (char *)getenv(name);
}
diff --git a/stand/common/interp_simple.c b/stand/common/interp_simple.c
new file mode 100644
index 0000000..83eb83c
--- /dev/null
+++ b/stand/common/interp_simple.c
@@ -0,0 +1,192 @@
+/*-
+ * 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$");
+
+/*
+ * Simple commandline interpreter, toplevel and misc.
+ */
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+
+void
+interp_init(void)
+{
+
+ setenv("script.lang", "simple", 1);
+ /* Read our default configuration. */
+ interp_include("/boot/loader.rc");
+}
+
+int
+interp_run(const char *input)
+{
+ int argc;
+ char **argv;
+
+ if (parse(&argc, &argv, input)) {
+ printf("parse error\n");
+ return CMD_ERROR;
+ }
+
+ if (interp_builtin_cmd(argc, argv)) {
+ printf("%s: %s\n", argv[0], command_errmsg);
+ free(argv);
+ return CMD_ERROR;
+ }
+ free(argv);
+ return CMD_OK;
+}
+
+/*
+ * Header prepended to each line. The text immediately follows the header.
+ * We try to make this short in order to save memory -- the loader has
+ * limited memory available, and some of the forth files are very long.
+ */
+struct includeline
+{
+ struct includeline *next;
+ int flags;
+ int line;
+#define SL_QUIET (1<<0)
+#define SL_IGNOREERR (1<<1)
+ char text[0];
+};
+
+int
+interp_include(const char *filename)
+{
+ struct includeline *script, *se, *sp;
+ char input[256]; /* big enough? */
+ int argc,res;
+ char **argv, *cp;
+ int fd, flags, line;
+
+ if (((fd = open(filename, O_RDONLY)) == -1)) {
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "can't open '%s': %s", filename, strerror(errno));
+ return(CMD_ERROR);
+ }
+
+ /*
+ * Read the script into memory.
+ */
+ script = se = NULL;
+ line = 0;
+
+ while (fgetstr(input, sizeof(input), fd) >= 0) {
+ line++;
+ flags = 0;
+ /* Discard comments */
+ if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0)
+ continue;
+ cp = input;
+ /* Echo? */
+ if (input[0] == '@') {
+ cp++;
+ flags |= SL_QUIET;
+ }
+ /* Error OK? */
+ if (input[0] == '-') {
+ cp++;
+ flags |= SL_IGNOREERR;
+ }
+
+ /* Allocate script line structure and copy line, flags */
+ if (*cp == '\0')
+ continue; /* ignore empty line, save memory */
+ sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
+ /* On malloc failure (it happens!), free as much as possible and exit */
+ if (sp == NULL) {
+ while (script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ snprintf(command_errbuf, sizeof(command_errbuf),
+ "file '%s' line %d: memory allocation failure - aborting",
+ filename, line);
+ close(fd);
+ return (CMD_ERROR);
+ }
+ strcpy(sp->text, cp);
+ sp->flags = flags;
+ sp->line = line;
+ sp->next = NULL;
+
+ if (script == NULL) {
+ script = sp;
+ } else {
+ se->next = sp;
+ }
+ se = sp;
+ }
+ close(fd);
+
+ /*
+ * Execute the script
+ */
+ argv = NULL;
+ res = CMD_OK;
+ for (sp = script; sp != NULL; sp = sp->next) {
+
+ /* print if not being quiet */
+ if (!(sp->flags & SL_QUIET)) {
+ interp_emit_prompt();
+ printf("%s\n", sp->text);
+ }
+
+ /* Parse the command */
+ if (!parse(&argc, &argv, sp->text)) {
+ if ((argc > 0) && (interp_builtin_cmd(argc, argv) != 0)) {
+ /* normal command */
+ printf("%s: %s\n", argv[0], command_errmsg);
+ if (!(sp->flags & SL_IGNOREERR)) {
+ res=CMD_ERROR;
+ break;
+ }
+ }
+ free(argv);
+ argv = NULL;
+ } else {
+ printf("%s line %d: parse error\n", filename, sp->line);
+ res=CMD_ERROR;
+ break;
+ }
+ }
+ if (argv != NULL)
+ free(argv);
+
+ while (script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
+ }
+ return(res);
+}
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index 4c1277b..89c0733 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -29,6 +29,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/endian.h>
#include <sys/exec.h>
#include <sys/linker.h>
#include <sys/module.h>
@@ -86,6 +87,112 @@ const char *__elfN(moduletype) = "elf module";
u_int64_t __elfN(relocation_offset) = 0;
+extern void elf_wrong_field_size(void);
+#define CONVERT_FIELD(b, f, e) \
+ switch (sizeof((b)->f)) { \
+ case 2: \
+ (b)->f = e ## 16toh((b)->f); \
+ break; \
+ case 4: \
+ (b)->f = e ## 32toh((b)->f); \
+ break; \
+ case 8: \
+ (b)->f = e ## 64toh((b)->f); \
+ break; \
+ default: \
+ /* Force a link time error. */ \
+ elf_wrong_field_size(); \
+ break; \
+ }
+
+#define CONVERT_SWITCH(h, d, f) \
+ switch ((h)->e_ident[EI_DATA]) { \
+ case ELFDATA2MSB: \
+ f(d, be); \
+ break; \
+ case ELFDATA2LSB: \
+ f(d, le); \
+ break; \
+ default: \
+ return (EINVAL); \
+ }
+
+
+static int elf_header_convert(Elf_Ehdr *ehdr)
+{
+ /*
+ * Fixup ELF header endianness.
+ *
+ * The Xhdr structure was loaded using block read call to optimize file
+ * accesses. It might happen, that the endianness of the system memory
+ * is different that endianness of the ELF header. Swap fields here to
+ * guarantee that Xhdr always contain valid data regardless of
+ * architecture.
+ */
+#define HEADER_FIELDS(b, e) \
+ CONVERT_FIELD(b, e_type, e); \
+ CONVERT_FIELD(b, e_machine, e); \
+ CONVERT_FIELD(b, e_version, e); \
+ CONVERT_FIELD(b, e_entry, e); \
+ CONVERT_FIELD(b, e_phoff, e); \
+ CONVERT_FIELD(b, e_shoff, e); \
+ CONVERT_FIELD(b, e_flags, e); \
+ CONVERT_FIELD(b, e_ehsize, e); \
+ CONVERT_FIELD(b, e_phentsize, e); \
+ CONVERT_FIELD(b, e_phnum, e); \
+ CONVERT_FIELD(b, e_shentsize, e); \
+ CONVERT_FIELD(b, e_shnum, e); \
+ CONVERT_FIELD(b, e_shstrndx, e)
+
+ CONVERT_SWITCH(ehdr, ehdr, HEADER_FIELDS);
+
+#undef HEADER_FIELDS
+
+ return (0);
+}
+
+static int elf_program_header_convert(const Elf_Ehdr *ehdr, Elf_Phdr *phdr)
+{
+#define PROGRAM_HEADER_FIELDS(b, e) \
+ CONVERT_FIELD(b, p_type, e); \
+ CONVERT_FIELD(b, p_flags, e); \
+ CONVERT_FIELD(b, p_offset, e); \
+ CONVERT_FIELD(b, p_vaddr, e); \
+ CONVERT_FIELD(b, p_paddr, e); \
+ CONVERT_FIELD(b, p_filesz, e); \
+ CONVERT_FIELD(b, p_memsz, e); \
+ CONVERT_FIELD(b, p_align, e)
+
+ CONVERT_SWITCH(ehdr, phdr, PROGRAM_HEADER_FIELDS);
+
+#undef PROGRAM_HEADER_FIELDS
+
+ return (0);
+}
+
+static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr)
+{
+#define SECTION_HEADER_FIELDS(b, e) \
+ CONVERT_FIELD(b, sh_name, e); \
+ CONVERT_FIELD(b, sh_type, e); \
+ CONVERT_FIELD(b, sh_link, e); \
+ CONVERT_FIELD(b, sh_info, e); \
+ CONVERT_FIELD(b, sh_flags, e); \
+ CONVERT_FIELD(b, sh_addr, e); \
+ CONVERT_FIELD(b, sh_offset, e); \
+ CONVERT_FIELD(b, sh_size, e); \
+ CONVERT_FIELD(b, sh_addralign, e); \
+ CONVERT_FIELD(b, sh_entsize, e)
+
+ CONVERT_SWITCH(ehdr, shdr, SECTION_HEADER_FIELDS);
+
+#undef SECTION_HEADER_FIELDS
+
+ return (0);
+}
+#undef CONVERT_SWITCH
+#undef CONVERT_FIELD
+
static int
__elfN(load_elf_header)(char *filename, elf_file_t ef)
{
@@ -118,11 +225,19 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef)
err = EFTYPE;
goto error;
}
+
if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */
ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
- ehdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */
- ehdr->e_version != EV_CURRENT ||
- ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */
+ ehdr->e_ident[EI_VERSION] != EV_CURRENT) /* Version ? */ {
+ err = EFTYPE;
+ goto error;
+ }
+
+ err = elf_header_convert(ehdr);
+ if (err)
+ goto error;
+
+ if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */
err = EFTYPE;
goto error;
}
@@ -391,6 +506,9 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
+ if (elf_program_header_convert(ehdr, phdr))
+ continue;
+
/* We want to load PT_LOAD segments only.. */
if (phdr[i].p_type != PT_LOAD)
continue;
@@ -465,6 +583,10 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
"_loadimage: failed to read section headers");
goto nosyms;
}
+
+ for (i = 0; i < ehdr->e_shnum; i++)
+ elf_section_header_convert(ehdr, &shdr[i]);
+
file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr);
/*
@@ -540,8 +662,15 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
break;
}
#endif
-
size = shdr[i].sh_size;
+#if defined(__powerpc__)
+ #if __ELF_WORD_SIZE == 64
+ size = htobe64(size);
+ #else
+ size = htobe32(size);
+ #endif
+#endif
+
archsw.arch_copyin(&size, lastaddr, sizeof(size));
lastaddr += sizeof(size);
@@ -582,6 +711,17 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
printf("]");
#endif
+#if defined(__powerpc__)
+ /* On PowerPC we always need to provide BE data to the kernel */
+ #if __ELF_WORD_SIZE == 64
+ ssym = htobe64((uint64_t)ssym);
+ esym = htobe64((uint64_t)esym);
+ #else
+ ssym = htobe32((uint32_t)ssym);
+ esym = htobe32((uint32_t)esym);
+ #endif
+#endif
+
file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym);
diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c
index 57df57a..f053a45 100644
--- a/stand/common/load_elf_obj.c
+++ b/stand/common/load_elf_obj.c
@@ -280,6 +280,8 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
switch (shdr[i].sh_type) {
case SHT_REL:
case SHT_RELA:
+ if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
+ break;
lastaddr = roundup(lastaddr, shdr[i].sh_addralign);
shdr[i].sh_addr = (Elf_Addr)lastaddr;
lastaddr += shdr[i].sh_size;
diff --git a/stand/common/misc.c b/stand/common/misc.c
index 9b938af..4c0273f 100644
--- a/stand/common/misc.c
+++ b/stand/common/misc.c
@@ -138,6 +138,7 @@ kern_pread(int fd, vm_offset_t dest, size_t len, off_t off)
* Read the specified part of a file to a malloced buffer. The file
* pointer is advanced to the end of the read data.
*/
+/* coverity[ -tainted_data_return ] */
void *
alloc_pread(int fd, off_t off, size_t len)
{
diff --git a/stand/common/pnp.c b/stand/common/pnp.c
index 6197776..31a0de9 100644
--- a/stand/common/pnp.c
+++ b/stand/common/pnp.c
@@ -17,9 +17,6 @@ __FBSDID("$FreeBSD$");
#include <stand.h>
#include <string.h>
#include <bootstrap.h>
-#ifdef BOOT_FORTH
-#include "ficl.h"
-#endif
static struct pnpinfo_stql pnp_devices;
static int pnp_devices_initted = 0;
@@ -187,50 +184,3 @@ pnp_eisaformat(u_int8_t *data)
idbuf[7] = 0;
return(idbuf);
}
-
-#ifdef BOOT_FORTH
-void
-ficlPnpdevices(FICL_VM *pVM)
-{
- static int pnp_devices_initted = 0;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
-
- if(!pnp_devices_initted) {
- STAILQ_INIT(&pnp_devices);
- pnp_devices_initted = 1;
- }
-
- stackPushPtr(pVM->pStack, &pnp_devices);
-
- return;
-}
-
-void
-ficlPnphandlers(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
-
- stackPushPtr(pVM->pStack, pnphandlers);
-
- return;
-}
-
-/*
- * Glue function to add the appropriate forth words to access pnp BIOS
- * functionality.
- */
-static void ficlCompilePnp(FICL_SYSTEM *pSys)
-{
- FICL_DICT *dp = pSys->dp;
- assert (dp);
-
- dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT);
- dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT);
-}
-
-FICL_COMPILE_SET(ficlCompilePnp);
-#endif
diff --git a/stand/defs.mk b/stand/defs.mk
index 79e5269..3b646c6 100644
--- a/stand/defs.mk
+++ b/stand/defs.mk
@@ -7,6 +7,15 @@ WARNS?=1
.if !defined(__BOOT_DEFS_MK__)
__BOOT_DEFS_MK__=${MFILE}
+MK_CTF= no
+MK_SSP= no
+MK_PROFILE= no
+MAN=
+.if !defined(PIC)
+NO_PIC=
+INTERNALLIB=
+.endif
+
BOOTSRC= ${SRCTOP}/stand
EFISRC= ${BOOTSRC}/efi
EFIINC= ${EFISRC}/include
diff --git a/stand/efi/boot1/Makefile b/stand/efi/boot1/Makefile
index 7791b78..02ca947 100644
--- a/stand/efi/boot1/Makefile
+++ b/stand/efi/boot1/Makefile
@@ -1,12 +1,7 @@
# $FreeBSD$
-MAN=
-
.include <bsd.init.mk>
-MK_SSP= no
-MK_FORTH= no
-
PROG= boot1.sym
INTERNALPROG=
WARNS?= 6
@@ -110,7 +105,7 @@ boot1.efi: ${PROG}
# The following inserts our objects into a template FAT file system
# created by generate-fat.sh
-.include "${.CURDIR}/Makefile.fat"
+.include "Makefile.fat"
boot1.efifat: boot1.efi
@set -- `ls -l ${.ALLSRC}`; \
@@ -120,7 +115,7 @@ boot1.efifat: boot1.efi
exit 1; \
fi
echo ${.OBJDIR}
- xz -d -c ${.CURDIR}/fat-${MACHINE}.tmpl.xz > ${.TARGET}
+ xz -d -c ${BOOTSRC}/efi/boot1/fat-${MACHINE}.tmpl.xz > ${.TARGET}
${DD} if=${.ALLSRC} of=${.TARGET} seek=${BOOT1_OFFSET} conv=notrunc
CLEANFILES+= boot1.efi boot1.efifat
diff --git a/stand/efi/boot1/boot1.c b/stand/efi/boot1/boot1.c
index 7b51f03..35f3332d 100644
--- a/stand/efi/boot1/boot1.c
+++ b/stand/efi/boot1/boot1.c
@@ -55,6 +55,7 @@ static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID;
+static EFI_GUID GlobalBootVarGUID = UEFI_BOOT_VAR_GUID;
/*
* Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
@@ -80,14 +81,33 @@ Free(void *buf, const char *file __unused, int line __unused)
}
static EFI_STATUS
+efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len)
+{
+ size_t ul;
+ CHAR16 *uv;
+ UINT32 attr;
+ UINTN dl;
+ EFI_STATUS rv;
+
+ uv = NULL;
+ if (utf8_to_ucs2(v, &uv, &ul) != 0)
+ return (EFI_OUT_OF_RESOURCES);
+ dl = *len;
+ rv = RS->GetVariable(uv, g, &attr, &dl, data);
+ if (rv == EFI_SUCCESS)
+ *len = dl;
+ free(uv);
+ return (rv);
+}
+
+static EFI_STATUS
efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr)
{
CHAR16 *var = NULL;
size_t len;
EFI_STATUS rv;
- utf8_to_ucs2(varname, &var, &len);
- if (var == NULL)
+ if (utf8_to_ucs2(varname, &var, &len) != 0)
return (EFI_OUT_OF_RESOURCES);
rv = RS->SetVariable(var, &FreeBSDBootVarGUID,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
@@ -411,6 +431,9 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
CHAR16 *text;
+ UINT16 boot_current;
+ size_t sz;
+ UINT16 boot_order[100];
/* Basic initialization*/
ST = Xsystab;
@@ -480,12 +503,32 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
}
}
+ boot_current = 0;
+ sz = sizeof(boot_current);
+ efi_getenv(&GlobalBootVarGUID, "BootCurrent", &boot_current, &sz);
+ printf(" BootCurrent: %04x\n", boot_current);
+
+ sz = sizeof(boot_order);
+ efi_getenv(&GlobalBootVarGUID, "BootOrder", &boot_order, &sz);
+ printf(" BootOrder:");
+ for (i = 0; i < sz / sizeof(boot_order[0]); i++)
+ printf(" %04x", boot_order[i]);
+ printf("\n");
+
+#ifdef TEST_FAILURE
+ /*
+ * For testing failover scenarios, it's nice to be able to fail fast.
+ * Define TEST_FAILURE to create a boot1.efi that always fails after
+ * reporting the boot manager protocol details.
+ */
+ BS->Exit(IH, EFI_OUT_OF_RESOURCES, 0, NULL);
+#endif
+
/* Get all the device handles */
hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
handles = malloc(hsize);
- if (handles == NULL) {
+ if (handles == NULL)
printf("Failed to allocate %d handles\n", NUM_HANDLES_INIT);
- }
status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
&hsize, handles);
diff --git a/stand/efi/fdt/Makefile b/stand/efi/fdt/Makefile
index 6bae439..8166f48 100644
--- a/stand/efi/fdt/Makefile
+++ b/stand/efi/fdt/Makefile
@@ -5,7 +5,6 @@
.PATH: ${LDRSRC}
LIB= efi_fdt
-INTERNALLIB=
WARNS?= 6
SRCS= efi_fdt.c
diff --git a/stand/efi/include/efi.h b/stand/efi/include/efi.h
index a91e881..9164ec9 100644
--- a/stand/efi/include/efi.h
+++ b/stand/efi/include/efi.h
@@ -59,5 +59,7 @@ Revision History
*/
#define FREEBSD_BOOT_VAR_GUID \
{ 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} }
+#define UEFI_BOOT_VAR_GUID \
+ { 0x8be4df61, 0x93ca, 0x11d2, {0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c} }
#endif
diff --git a/stand/efi/include/efiapi.h b/stand/efi/include/efiapi.h
index 8bab217..01a064b 100644
--- a/stand/efi/include/efiapi.h
+++ b/stand/efi/include/efiapi.h
@@ -840,6 +840,9 @@ typedef struct {
#define SMBIOS_TABLE_GUID \
{ 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+#define SMBIOS3_TABLE_GUID \
+ { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} }
+
#define SAL_SYSTEM_TABLE_GUID \
{ 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
@@ -852,6 +855,15 @@ typedef struct {
#define HOB_LIST_TABLE_GUID \
{ 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+#define LZMA_DECOMPRESSION_GUID \
+ { 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x3, 0xcf} }
+
+#define ARM_MP_CORE_INFO_TABLE_GUID \
+ { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
+
+#define ESRT_TABLE_GUID \
+ { 0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80} }
+
#define MEMORY_TYPE_INFORMATION_TABLE_GUID \
{ 0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa} }
diff --git a/stand/efi/libefi/Makefile b/stand/efi/libefi/Makefile
index f5cf71e..c88eb4d 100644
--- a/stand/efi/libefi/Makefile
+++ b/stand/efi/libefi/Makefile
@@ -2,12 +2,7 @@
.include <bsd.init.mk>
-.if ${MK_FORTH} != "no"
-.include "${BOOTSRC}/ficl.mk"
-.endif
-
LIB= efi
-INTERNALLIB=
WARNS?= 2
SRCS= delay.c devpath.c efi_console.c efichar.c efinet.c efipart.c env.c errno.c \
diff --git a/stand/efi/libefi/efichar.c b/stand/efi/libefi/efichar.c
index 15aa5ca..233027f 100644
--- a/stand/efi/libefi/efichar.c
+++ b/stand/efi/libefi/efichar.c
@@ -116,8 +116,10 @@ ucs2_to_utf8(const efi_char *nm, char **name)
if (len >= sz) {
/* Absent bugs, we'll never return EOVERFLOW */
- if (freeit)
+ if (freeit) {
free(*name);
+ *name = NULL;
+ }
return (EOVERFLOW);
}
*cp++ = '\0';
@@ -137,6 +139,8 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len)
sz = strlen(name) * 2 + 2;
if (*nmp == NULL)
*nmp = malloc(sz);
+ if (*nmp == NULL)
+ return (ENOMEM);
nm = *nmp;
*len = sz;
@@ -150,11 +154,8 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len)
*/
if ((c & 0xc0) != 0x80) {
/* Initial characters. */
- if (bytes != 0) {
- if (freeit)
- free(nm);
- return (EILSEQ);
- }
+ if (bytes != 0)
+ goto ilseq;
if ((c & 0xf8) == 0xf0) {
ucs4 = c & 0x07;
bytes = 3;
@@ -173,29 +174,31 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len)
if (bytes > 0) {
ucs4 = (ucs4 << 6) + (c & 0x3f);
bytes--;
- } else if (bytes == 0) {
- if (freeit)
- free(nm);
- return (EILSEQ);
- }
+ } else if (bytes == 0)
+ goto ilseq;
}
if (bytes == 0) {
- if (ucs4 > 0xffff) {
- if (freeit)
- free(nm);
- return (EILSEQ);
- }
+ if (ucs4 > 0xffff)
+ goto ilseq;
*nm++ = (efi_char)ucs4;
sz -= 2;
}
}
if (sz < 2) {
- if (freeit)
+ if (freeit) {
free(nm);
+ *nmp = NULL;
+ }
return (EDOOFUS);
}
sz -= 2;
*nm = 0;
*len -= sz;
return (0);
+ilseq:
+ if (freeit) {
+ free(nm);
+ *nmp = NULL;
+ }
+ return (EILSEQ);
}
diff --git a/stand/efi/libefi/env.c b/stand/efi/libefi/env.c
index ceec7b2..6b2d176 100644
--- a/stand/efi/libefi/env.c
+++ b/stand/efi/libefi/env.c
@@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$");
#include <uuid.h>
#include <stdbool.h>
#include "bootstrap.h"
-#ifdef BOOT_FORTH
-#include "ficl.h"
-#endif
/*
* Simple wrappers to the underlying UEFI functions.
@@ -375,160 +372,3 @@ command_efi_unset(int argc, char *argv[])
}
return (CMD_OK);
}
-
-#ifdef BOOT_FORTH
-/*
- * FreeBSD's loader interaction words and extras
- *
- * efi-setenv ( value n name n guid n attr -- 0 | -1)
- * efi-getenv ( guid n addr n -- addr' n' | -1 )
- * efi-unsetenv ( name n guid n'' -- )
- */
-
-/*
- * efi-setenv
- * efi-setenv ( value n name n guid n attr -- 0 | -1)
- *
- * Set environment variables using the SetVariable EFI runtime service.
- *
- * Value and guid are passed through in binary form (so guid needs to be
- * converted to binary form from its string form). Name is converted from
- * ASCII to CHAR16. Since ficl doesn't have support for internationalization,
- * there's no native CHAR16 interface provided.
- *
- * attr is an int in the bitmask of the following attributes for this variable.
- *
- * 1 Non volatile
- * 2 Boot service access
- * 4 Run time access
- * (corresponding to the same bits in the UEFI spec).
- */
-static void
-ficlEfiSetenv(FICL_VM *pVM)
-{
- char *value = NULL, *guid = NULL;
- CHAR16 *name = NULL;
- int i;
- char *namep, *valuep, *guidp;
- int names, values, guids, attr;
- EFI_STATUS status;
- uuid_t u;
- uint32_t ustatus;
- bool error = true;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 6, 0);
-#endif
- attr = stackPopINT(pVM->pStack);
- guids = stackPopINT(pVM->pStack);
- guidp = (char*)stackPopPtr(pVM->pStack);
- names = stackPopINT(pVM->pStack);
- namep = (char*)stackPopPtr(pVM->pStack);
- values = stackPopINT(pVM->pStack);
- valuep = (char*)stackPopPtr(pVM->pStack);
-
- guid = (char*)ficlMalloc(guids);
- if (guid == NULL)
- goto out;
- memcpy(guid, guidp, guids);
- uuid_from_string(guid, &u, &ustatus);
- if (ustatus != uuid_s_ok) {
- stackPushINT(pVM->pStack, -1);
- goto out;
- }
-
- name = ficlMalloc((names + 1) * sizeof(CHAR16));
- if (name == NULL)
- goto out;
- for (i = 0; i < names; i++)
- name[i] = namep[i];
- name[names] = 0;
-
- value = ficlMalloc(values + 1);
- if (value == NULL)
- goto out;
- memcpy(value, valuep, values);
-
- status = efi_set_variable(name, (EFI_GUID *)&u, attr, values, value);
- if (status == EFI_SUCCESS)
- stackPushINT(pVM->pStack, 0);
- else
- stackPushINT(pVM->pStack, -1);
- error = false;
-out:
- ficlFree(name);
- ficlFree(value);
- ficlFree(guid);
-
- if (error == true)
- vmThrowErr(pVM, "Error: out of memory");
-}
-
-static void
-ficlEfiGetenv(FICL_VM *pVM)
-{
- char *name, *value;
- char *namep;
- int names;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 2);
-#endif
- names = stackPopINT(pVM->pStack);
- namep = (char*) stackPopPtr(pVM->pStack);
-
- name = (char*) ficlMalloc(names+1);
- if (name == NULL)
- vmThrowErr(pVM, "Error: out of memory");
- strncpy(name, namep, names);
- name[names] = '\0';
-
- value = getenv(name);
- ficlFree(name);
-
- if(value != NULL) {
- stackPushPtr(pVM->pStack, value);
- stackPushINT(pVM->pStack, strlen(value));
- } else
- stackPushINT(pVM->pStack, -1);
-}
-
-static void
-ficlEfiUnsetenv(FICL_VM *pVM)
-{
- char *name;
- char *namep;
- int names;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- names = stackPopINT(pVM->pStack);
- namep = (char*) stackPopPtr(pVM->pStack);
-
- name = (char*) ficlMalloc(names+1);
- if (name == NULL)
- vmThrowErr(pVM, "Error: out of memory");
- strncpy(name, namep, names);
- name[names] = '\0';
-
- unsetenv(name);
- ficlFree(name);
-}
-
-/**************************************************************************
-** Add FreeBSD UEFI platform extensions into the system dictionary
-**************************************************************************/
-void ficlEfiCompilePlatform(FICL_SYSTEM *pSys)
-{
- FICL_DICT *dp = pSys->dp;
- assert (dp);
-
- dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT);
- dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT);
- dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT);
-}
-
-FICL_COMPILE_SET(ficlEfiCompilePlatform);
-
-#endif /* BOOT_FORTH */
diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile
index 7102555..ea920b8 100644
--- a/stand/efi/loader/Makefile
+++ b/stand/efi/loader/Makefile
@@ -1,7 +1,5 @@
# $FreeBSD$
-MAN=
-
LOADER_NET_SUPPORT?= yes
LOADER_MSDOS_SUPPORT?= yes
LOADER_UFS_SUPPORT?= yes
@@ -10,8 +8,6 @@ LOADER_EXT2FS_SUPPORT?= no
.include <bsd.init.mk>
-MK_SSP= no
-
PROG= loader.sym
INTERNALPROG=
WARNS?= 3
@@ -129,8 +125,8 @@ loader.efi: ${PROG}
LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a
-DPADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} \
+DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} \
${LDSCRIPT}
-LDADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA}
.include <bsd.prog.mk>
diff --git a/stand/efi/loader/arch/arm/ldscript.arm b/stand/efi/loader/arch/arm/ldscript.arm
index 9f6e7c2..68775a8 100644
--- a/stand/efi/loader/arch/arm/ldscript.arm
+++ b/stand/efi/loader/arch/arm/ldscript.arm
@@ -35,6 +35,7 @@ SECTIONS
. = ALIGN(4);
PROVIDE (__bss_end = .);
}
+ .dynamic : { *(.dynamic) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
@@ -54,7 +55,6 @@ SECTIONS
}
__gp = .;
.plt : { *(.plt) }
- .dynamic : { *(.dynamic) }
.reloc : { *(.reloc) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
diff --git a/stand/efi/loader/arch/i386/bootinfo.c b/stand/efi/loader/arch/i386/bootinfo.c
deleted file mode 100644
index cbd6e4e..0000000
--- a/stand/efi/loader/arch/i386/bootinfo.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*-
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * 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 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 <string.h>
-#include <sys/param.h>
-#include <sys/reboot.h>
-#include <sys/linker.h>
-#include <sys/boot.h>
-
-#include <efi.h>
-#include <efilib.h>
-
-#include "bootstrap.h"
-#include "libi386.h"
-#include <machine/bootinfo.h>
-
-static const char howto_switches[] = "aCdrgDmphsv";
-static int howto_masks[] = {
- RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
- RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
-};
-
-int
-bi_getboothowto(char *kargs)
-{
- const char *sw;
- char *opts;
- int howto, i;
-
- howto = 0;
-
- /* Get the boot options from the environment first. */
- for (i = 0; howto_names[i].ev != NULL; i++) {
- if (getenv(howto_names[i].ev) != NULL)
- howto |= howto_names[i].mask;
- }
-
- /* Parse kargs */
- if (kargs == NULL)
- return (howto);
-
- opts = strchr(kargs, '-');
- while (opts != NULL) {
- while (*(++opts) != '\0') {
- sw = strchr(howto_switches, *opts);
- if (sw == NULL)
- break;
- howto |= howto_masks[sw - howto_switches];
- }
- opts = strchr(opts, '-');
- }
-
- 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.
- */
-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 (i386_copyin(ep->ev_name, addr, len) != len)
- break;
- addr += len;
- if (i386_copyin("=", addr, 1) != 1)
- break;
- addr++;
- if (ep->ev_value != NULL) {
- len = strlen(ep->ev_value);
- if (i386_copyin(ep->ev_value, addr, len) != len)
- break;
- addr += len;
- }
- if (i386_copyin("", addr, 1) != 1)
- break;
- last = ++addr;
- }
-
- if (i386_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) { \
- u_int32_t x = (v); \
- i386_copyin(&x, a, sizeof(x)); \
- a += sizeof(x); \
-}
-
-#define MOD_STR(t, a, s) { \
- COPY32(t, a); \
- COPY32(strlen(s) + 1, a); \
- i386_copyin(s, a, strlen(s) + 1); \
- a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
-}
-
-#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
-#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
-#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s)
-
-#define MOD_VAR(t, a, s) { \
- COPY32(t, a); \
- COPY32(sizeof(s), a); \
- i386_copyin(&s, a, sizeof(s)); \
- a += roundup(sizeof(s), sizeof(u_int64_t)); \
-}
-
-#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
-#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
-
-#define MOD_METADATA(a, mm) { \
- COPY32(MODINFO_METADATA | mm->md_type, a); \
- COPY32(mm->md_size, a); \
- i386_copyin(mm->md_data, a, mm->md_size); \
- a += roundup(mm->md_size, sizeof(u_int64_t));\
-}
-
-#define MOD_END(a) { \
- COPY32(MODINFO_END, a); \
- COPY32(0, a); \
-}
-
-vm_offset_t
-bi_copymodules(vm_offset_t addr)
-{
- struct preloaded_file *fp;
- struct file_metadata *md;
-
- /* Start with the first module on the list, should be the kernel. */
- for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
- /* The name field must come first. */
- MOD_NAME(addr, fp->f_name);
- MOD_TYPE(addr, fp->f_type);
- if (fp->f_args)
- MOD_ARGS(addr, fp->f_args);
- MOD_ADDR(addr, fp->f_addr);
- MOD_SIZE(addr, fp->f_size);
- for (md = fp->f_metadata; md != NULL; md = md->md_next) {
- if (!(md->md_type & MODINFOMD_NOCOPY))
- MOD_METADATA(addr, md);
- }
- }
- MOD_END(addr);
- return(addr);
-}
-
-/*
- * Load the information expected by the kernel.
- *
- * - The kernel environment is copied into kernel space.
- * - Module metadata are formatted and placed in kernel space.
- */
-int
-bi_load(struct preloaded_file *fp, uint64_t *bi_addr)
-{
- struct bootinfo bi;
- struct preloaded_file *xp;
- struct file_metadata *md;
- struct devdesc *rootdev;
- char *rootdevname;
- vm_offset_t addr, ssym, esym;
-
- bzero(&bi, sizeof(struct bootinfo));
- bi.bi_version = 1;
-// bi.bi_boothowto = bi_getboothowto(fp->f_args);
-
- /*
- * Allow the environment variable 'rootdev' to override the supplied
- * device. This should perhaps go to MI code and/or have $rootdev
- * tested/set by MI code before launching the kernel.
- */
- rootdevname = getenv("rootdev");
- i386_getdev((void**)&rootdev, rootdevname, NULL);
- if (rootdev != NULL) {
- /* Try reading /etc/fstab to select the root device. */
- getrootmount(i386_fmtdev(rootdev));
- free(rootdev);
- }
-
- md = file_findmetadata(fp, MODINFOMD_SSYM);
- ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
- md = file_findmetadata(fp, MODINFOMD_ESYM);
- esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
- if (ssym != 0 && esym != 0) {
- bi.bi_symtab = ssym;
- bi.bi_esymtab = esym;
- }
-
- /* Find the last module in the chain. */
- addr = 0;
- for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
- if (addr < (xp->f_addr + xp->f_size))
- addr = xp->f_addr + xp->f_size;
- }
-
- addr = (addr + 15) & ~15;
-
- /* Copy module list and metadata. */
- bi.bi_modulep = addr;
- addr = bi_copymodules(addr);
- if (addr <= bi.bi_modulep) {
- addr = bi.bi_modulep;
- bi.bi_modulep = 0;
- }
-
- addr = (addr + 15) & ~15;
-
- /* Copy our environment. */
- bi.bi_envp = addr;
- addr = bi_copyenv(addr);
- if (addr <= bi.bi_envp) {
- addr = bi.bi_envp;
- bi.bi_envp = 0;
- }
-
- addr = (addr + PAGE_MASK) & ~PAGE_MASK;
- bi.bi_kernend = addr;
-
- return (ldr_bootinfo(&bi, bi_addr));
-}
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index 516c47e..9b5dfd8 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -65,8 +65,12 @@ EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
EFI_GUID mps = MPS_TABLE_GUID;
EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
EFI_GUID smbios = SMBIOS_TABLE_GUID;
+EFI_GUID smbios3 = SMBIOS3_TABLE_GUID;
EFI_GUID dxe = DXE_SERVICES_TABLE_GUID;
EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
+EFI_GUID lzmadecomp = LZMA_DECOMPRESSION_GUID;
+EFI_GUID mpcore = ARM_MP_CORE_INFO_TABLE_GUID;
+EFI_GUID esrt = ESRT_TABLE_GUID;
EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
EFI_GUID fdtdtb = FDT_TABLE_GUID;
@@ -655,10 +659,18 @@ command_configuration(int argc, char *argv[])
else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
printf("SMBIOS Table %p",
ST->ConfigurationTable[i].VendorTable);
+ else if (!memcmp(guid, &smbios3, sizeof(EFI_GUID)))
+ printf("SMBIOS3 Table");
else if (!memcmp(guid, &dxe, sizeof(EFI_GUID)))
printf("DXE Table");
else if (!memcmp(guid, &hoblist, sizeof(EFI_GUID)))
printf("HOB List Table");
+ else if (!memcmp(guid, &lzmadecomp, sizeof(EFI_GUID)))
+ printf("LZMA Compression");
+ else if (!memcmp(guid, &mpcore, sizeof(EFI_GUID)))
+ printf("ARM MpCore Information Table");
+ else if (!memcmp(guid, &esrt, sizeof(EFI_GUID)))
+ printf("ESRT Table");
else if (!memcmp(guid, &memtype, sizeof(EFI_GUID)))
printf("Memory Type Information Table");
else if (!memcmp(guid, &debugimg, sizeof(EFI_GUID)))
diff --git a/stand/fdt/Makefile b/stand/fdt/Makefile
index 3e13441..b4767ed 100644
--- a/stand/fdt/Makefile
+++ b/stand/fdt/Makefile
@@ -5,7 +5,6 @@
.PATH: ${SYSDIR}/contrib/libfdt/
LIB= fdt
-INTERNALLIB=
# Vendor sources of libfdt.
SRCS+= fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c \
diff --git a/stand/ficl.mk b/stand/ficl.mk
index 14ae631..3fe7109 100644
--- a/stand/ficl.mk
+++ b/stand/ficl.mk
@@ -17,5 +17,4 @@ CFLAGS+= -fPIC
.endif
CFLAGS+= -I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC}
-CFLAGS+= -DBOOT_FORTH
CFLAGS+= -DBF_DICTSIZE=15000
diff --git a/stand/ficl/Makefile b/stand/ficl/Makefile
index a3aad2c..1e64ae0 100644
--- a/stand/ficl/Makefile
+++ b/stand/ficl/Makefile
@@ -20,7 +20,6 @@ PROG= testmain
.include <bsd.prog.mk>
.else
LIB= ficl
-INTERNALLIB=
.include <bsd.lib.mk>
.endif
diff --git a/stand/forth/Makefile b/stand/forth/Makefile
index 74d9ed7..3d79dc1 100644
--- a/stand/forth/Makefile
+++ b/stand/forth/Makefile
@@ -19,7 +19,6 @@ FILES+= brand-fbsd.4th
FILES+= check-password.4th
FILES+= color.4th
FILES+= delay.4th
-FILES+= efi.4th
FILES+= frames.4th
FILES+= loader.4th
FILES+= logo-beastie.4th
@@ -30,7 +29,6 @@ FILES+= logo-orbbw.4th
FILES+= menu.4th
FILES+= menu-commands.4th
FILES+= menusets.4th
-FILES+= pcibios.4th
FILES+= screen.4th
FILES+= shortcuts.4th
FILES+= support.4th
diff --git a/stand/forth/loader.4th b/stand/forth/loader.4th
index 9486237..6c2f7b3 100644
--- a/stand/forth/loader.4th
+++ b/stand/forth/loader.4th
@@ -46,9 +46,6 @@ include /boot/support.4th
include /boot/color.4th
include /boot/delay.4th
include /boot/check-password.4th
-s" efi-version" getenv? [if]
- include /boot/efi.4th
-[then]
only forth definitions
diff --git a/stand/forth/pcibios.4th b/stand/forth/pcibios.4th
deleted file mode 100644
index 71702da..0000000
--- a/stand/forth/pcibios.4th
+++ /dev/null
@@ -1,47 +0,0 @@
-\ Copyright (c) 2014 M. Warner Losh <imp@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.
-\
-\ $FreeBSD$
-
-only forth also support-functions also builtins definitions
-
-\ pci-device-count pci-id
-\
-\ Counts the number of instances of pci-id in the system and reports
-\ it to the user.
-: pci-device-count
- 0= if ( interpreted ) get_arguments then
-
- 0= if ." Need an argument" cr abort then
- \ First argument is 0 when we're interprated. See support.4th
- \ for get_arguments reading the rest of the line and parsing it
- \ stack: argN lenN ... arg1 len1 N
- hex ?number decimal
- 0= if ." Bad pci-id given (must be legal hex value)" cr abort then
- dup pcibios-device-count ." Found " . ." instances of " hex . decimal cr
-;
-
-also forth definitions also builtins
-
-builtin: pci-device-count
diff --git a/stand/forth/pnp.4th b/stand/forth/pnp.4th
deleted file mode 100644
index 5ce2355..0000000
--- a/stand/forth/pnp.4th
+++ /dev/null
@@ -1,205 +0,0 @@
-\ Copyright (c) 2000 Daniel C. Sobral <dcs@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.
-\
-\ $FreeBSD$
-
-
-\ The following pnp code is used in pnp.4th and pnp.c
-structure: STAILQ_HEAD
- ptr stqh_first \ type*
- ptr stqh_last \ type**
-;structure
-
-structure: STAILQ_ENTRY
- ptr stqe_next \ type*
-;structure
-
-structure: pnphandler
- ptr pnph.name
- ptr pnph.enumerate
-;structure
-
-structure: pnpident
- ptr pnpid.ident \ char*
- sizeof STAILQ_ENTRY cells member: pnpid.link \ pnpident
-;structure
-
-structure: pnpinfo \ sync with stand/config/bootstrap.h
- ptr pnpi.desc
- int pnpi.revision
- ptr pnpi.module \ (char*) module args
- int pnpi.argc
- ptr pnpi.argv
- ptr pnpi.handler \ pnphandler
- sizeof STAILQ_HEAD member: pnpi.ident \ pnpident
- sizeof STAILQ_ENTRY member: pnpi.link \ pnpinfo
-;structure
-\ end of pnp support
-
-pnpdevices drop
-
-: enumerate
- pnphandlers begin
- dup @
- while
- ." Probing " dup @ pnph.name @ dup strlen type ." ..." cr
- 0 over @ pnph.enumerate @ ccall drop
- cell+
- repeat
-;
-
-: summary
- ." PNP scan summary:" cr
- pnpdevices stqh_first @
- begin
- dup
- while
- dup pnpi.ident stqh_first @ pnpid.ident @ dup strlen type
- dup pnpi.desc @ ?dup if
- ." : "
- dup strlen type
- then
- cr
- pnpi.link stqe_next @
- repeat
- drop
-;
-
-: compare-pnpid ( addr addr' -- flag )
- begin
- over c@ over c@ <> if drop drop false exit then
- over c@ over c@ and
- while
- char+ swap char+ swap
- repeat
- c@ swap c@ or 0=
-;
-
-: search-pnpid ( id -- flag )
- >r
- pnpdevices stqh_first @
- begin ( pnpinfo )
- dup
- while
- dup pnpi.ident stqh_first @
- begin ( pnpinfo pnpident )
- dup pnpid.ident @ r@ compare-pnpid
- if
- r> drop
- \ XXX Temporary debugging message
- ." Found " pnpid.ident @ dup strlen type
- pnpi.desc @ ?dup if
- ." : " dup strlen type
- then cr
- \ drop drop
- true
- exit
- then
- pnpid.link stqe_next @
- ?dup 0=
- until
- pnpi.link stqe_next @
- repeat
- r> drop
- drop
- false
-;
-
-: skip-space ( addr -- addr' )
- begin
- dup c@ bl =
- over c@ 9 = or
- while
- char+
- repeat
-;
-
-: skip-to-space ( addr -- addr' )
- begin
- dup c@ bl <>
- over c@ 9 <> and
- over c@ and
- while
- char+
- repeat
-;
-
-: premature-end? ( addr -- addr flag )
- postpone dup postpone c@ postpone 0=
- postpone if postpone exit postpone then
-; immediate
-
-0 value filename
-0 value timestamp
-0 value id
-
-only forth also support-functions
-
-: (load) load ;
-
-: check-pnpid ( -- )
- line_buffer .addr @
- \ Search for filename
- skip-space premature-end?
- dup to filename
- \ Search for end of filename
- skip-to-space premature-end?
- 0 over c! char+
- \ Search for timestamp
- skip-space premature-end?
- dup to timestamp
- skip-to-space premature-end?
- 0 over c! char+
- \ Search for ids
- begin
- skip-space premature-end?
- dup to id
- skip-to-space dup c@ >r
- 0 over c! char+
- id search-pnpid if
- filename dup strlen 1 ['] (load) catch if
- drop drop drop
- ." Error loading " filename dup strlen type cr
- then
- r> drop exit
- then
- r> 0=
- until
-;
-
-: load-pnp
- 0 to end_of_file?
- reset_line_reading
- s" /boot/pnpid.conf" O_RDONLY fopen fd !
- fd @ -1 <> if
- begin
- end_of_file? 0=
- while
- read_line
- check-pnpid
- repeat
- fd @ fclose
- then
-;
-
diff --git a/stand/geli/Makefile b/stand/geli/Makefile
index ce54f82..24faf12 100644
--- a/stand/geli/Makefile
+++ b/stand/geli/Makefile
@@ -1,16 +1,11 @@
# $FreeBSD$
# libgeliboot
-MAN=
DO32=1
.include <bsd.init.mk>
-MK_SSP= no
LIB= geliboot
-INTERNALLIB=
-MK_PROFILE= no
-NO_PIC=
# Our password input method
SRCS+= pwgets.c
diff --git a/stand/i386/boot0/Makefile b/stand/i386/boot0/Makefile
index 39c0072..82eb9ee 100644
--- a/stand/i386/boot0/Makefile
+++ b/stand/i386/boot0/Makefile
@@ -3,7 +3,6 @@
PROG?= boot0
STRIP=
BINMODE=${NOBINMODE}
-MAN=
SRCS= ${PROG}.S
# Additional options that you can specify with make OPTS="..."
diff --git a/stand/i386/btx/btx/Makefile b/stand/i386/btx/btx/Makefile
index f42e20d..8afe98f 100644
--- a/stand/i386/btx/btx/Makefile
+++ b/stand/i386/btx/btx/Makefile
@@ -4,7 +4,6 @@
PROG= btx
INTERNALPROG=
-MAN=
SRCS= btx.S
.if defined(BOOT_BTX_NOHANG)
diff --git a/stand/i386/btx/btxldr/Makefile b/stand/i386/btx/btxldr/Makefile
index 3279597..6a11276 100644
--- a/stand/i386/btx/btxldr/Makefile
+++ b/stand/i386/btx/btxldr/Makefile
@@ -4,7 +4,6 @@
PROG= btxldr
INTERNALPROG=
-MAN=
SRCS= btxldr.S
CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS}
diff --git a/stand/i386/btx/lib/Makefile b/stand/i386/btx/lib/Makefile
index 8de6255..2988f42 100644
--- a/stand/i386/btx/lib/Makefile
+++ b/stand/i386/btx/lib/Makefile
@@ -4,7 +4,6 @@
PROG= crt0.o
INTERNALPROG=
-MAN=
SRCS= btxcsu.S btxsys.s btxv86.s
CFLAGS+=-I${BOOTSRC}/i386/common
LDFLAGS+=-Wl,-r
diff --git a/stand/i386/cdboot/Makefile b/stand/i386/cdboot/Makefile
index 7acd404..093ec49 100644
--- a/stand/i386/cdboot/Makefile
+++ b/stand/i386/cdboot/Makefile
@@ -5,7 +5,6 @@
PROG= cdboot
STRIP=
BINMODE=${NOBINMODE}
-MAN=
SRCS= ${PROG}.S
CFLAGS+=-I${BOOTSRC}/i386/common
diff --git a/stand/i386/kgzldr/Makefile b/stand/i386/kgzldr/Makefile
index 5a03b83..82136f9 100644
--- a/stand/i386/kgzldr/Makefile
+++ b/stand/i386/kgzldr/Makefile
@@ -6,7 +6,6 @@ PROG= kgzldr.o
STRIP=
BINMODE=${LIBMODE}
BINDIR= ${LIBDIR}
-MAN=
SRCS= start.s boot.c inflate.c lib.c crt.s sio.s
CFLAGS= -Os
diff --git a/stand/i386/libfirewire/Makefile b/stand/i386/libfirewire/Makefile
index f6e594f..6a34efd 100644
--- a/stand/i386/libfirewire/Makefile
+++ b/stand/i386/libfirewire/Makefile
@@ -3,7 +3,6 @@
.include <bsd.init.mk>
LIB= firewire
-INTERNALLIB=
.PATH: ${SYSDIR}/dev/dcons ${SYSDIR}/dev/firewire
SRCS+= firewire.c fwohci.c dconsole.c
diff --git a/stand/i386/libfirewire/firewire.c b/stand/i386/libfirewire/firewire.c
index 4840325..e0b0bf9 100644
--- a/stand/i386/libfirewire/firewire.c
+++ b/stand/i386/libfirewire/firewire.c
@@ -108,11 +108,11 @@ fw_probe(int index, struct fwohci_softc *sc)
biospci_write_config(sc->locator,
0x4 /* command */,
0x6 /* enable bus master and memory mapped I/O */,
- 1 /* word */);
+ BIOSPCI_16BITS);
- biospci_read_config(sc->locator, 0x00 /*devid*/, 2 /*dword*/,
+ biospci_read_config(sc->locator, 0x00 /*devid*/, BIOSPCI_32BITS,
&sc->devid);
- biospci_read_config(sc->locator, 0x10 /*base_addr*/, 2 /*dword*/,
+ biospci_read_config(sc->locator, 0x10 /*base_addr*/, BIOSPCI_32BITS,
&sc->base_addr);
sc->handle = (uint32_t)PTOV(sc->base_addr);
diff --git a/stand/i386/libi386/Makefile b/stand/i386/libi386/Makefile
index f54052c..6825d17 100644
--- a/stand/i386/libi386/Makefile
+++ b/stand/i386/libi386/Makefile
@@ -5,7 +5,6 @@ HAVE_GELI= yes
.include <bsd.init.mk>
LIB= i386
-INTERNALLIB=
SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \
biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
diff --git a/stand/i386/libi386/biospci.c b/stand/i386/libi386/biospci.c
index 098e30c..e13a5b9 100644
--- a/stand/i386/libi386/biospci.c
+++ b/stand/i386/libi386/biospci.c
@@ -38,9 +38,6 @@ __FBSDID("$FreeBSD$");
#include <isapnp.h>
#include <btxv86.h>
#include "libi386.h"
-#ifdef BOOT_FORTH
-#include "ficl.h"
-#endif
/*
* Stupid PCI BIOS interface doesn't let you simply enumerate everything
@@ -285,7 +282,7 @@ biospci_enumerate(void)
break;
/* Read the device identifier from the nominated device */
- err = biospci_read_config(locator, 0, 2, &devid);
+ err = biospci_read_config(locator, 0, BIOSPCI_32BITS, &devid);
if (err != 0)
break;
@@ -406,183 +403,3 @@ biospci_locator(int8_t bus, uint8_t device, uint8_t function)
return ((bus << 8) | ((device & 0x1f) << 3) | (function & 0x7));
}
-
-/*
- * Counts the number of instances of devid we have in the system, as least as
- * far as the PCI BIOS is able to tell.
- */
-static int
-biospci_count_device_type(uint32_t devid)
-{
- int i;
-
- for (i = 0; 1; i++) {
- v86.ctl = V86_FLAGS;
- v86.addr = PCI_INT;
- v86.eax = FIND_PCI_DEVICE;
- v86.edx = devid & 0xffff; /* EDX - Vendor ID */
- v86.ecx = (devid >> 16) & 0xffff; /* ECX - Device ID */
- v86.esi = i;
- v86int();
- if (V86_CY(v86.efl) || (v86.eax & 0xff00))
- break;
-
- }
- return i;
-}
-
-#ifdef BOOT_FORTH
-/*
- * pcibios-device-count (devid -- count)
- *
- * Returns the PCI BIOS' count of how many devices matching devid are in the system.
- * devid is the 32-bit vendor + device.
- */
-static void
-ficlPciBiosCountDevices(FICL_VM *pVM)
-{
- uint32_t devid;
- int i;
-
- devid = stackPopINT(pVM->pStack);
-
- i = biospci_count_device_type(devid);
-
- stackPushINT(pVM->pStack, i);
-}
-
-/*
- * pcibios-write-config (locator offset width value -- )
- *
- * Writes the specified config register.
- * Locator is bus << 8 | device << 3 | fuction
- * offset is the pci config register
- * width is 0 for byte, 1 for word, 2 for dword
- * value is the value to write
- */
-static void
-ficlPciBiosWriteConfig(FICL_VM *pVM)
-{
- uint32_t value, width, offset, locator;
-
- value = stackPopINT(pVM->pStack);
- width = stackPopINT(pVM->pStack);
- offset = stackPopINT(pVM->pStack);
- locator = stackPopINT(pVM->pStack);
-
- biospci_write_config(locator, offset, width, value);
-}
-
-/*
- * pcibios-read-config (locator offset width -- value)
- *
- * Reads the specified config register.
- * Locator is bus << 8 | device << 3 | fuction
- * offset is the pci config register
- * width is 0 for byte, 1 for word, 2 for dword
- * value is the value to read from the register
- */
-static void
-ficlPciBiosReadConfig(FICL_VM *pVM)
-{
- uint32_t value, width, offset, locator;
-
- width = stackPopINT(pVM->pStack);
- offset = stackPopINT(pVM->pStack);
- locator = stackPopINT(pVM->pStack);
-
- biospci_read_config(locator, offset, width, &value);
-
- stackPushINT(pVM->pStack, value);
-}
-
-/*
- * pcibios-find-devclass (class index -- locator)
- *
- * Finds the index'th instance of class in the pci tree.
- * must be an exact match.
- * class is the class to search for.
- * index 0..N (set to 0, increment until error)
- *
- * Locator is bus << 8 | device << 3 | fuction (or -1 on error)
- */
-static void
-ficlPciBiosFindDevclass(FICL_VM *pVM)
-{
- uint32_t index, class, locator;
-
- index = stackPopINT(pVM->pStack);
- class = stackPopINT(pVM->pStack);
-
- if (biospci_find_devclass(class, index, &locator))
- locator = 0xffffffff;
-
- stackPushINT(pVM->pStack, locator);
-}
-
-/*
- * pcibios-find-device(devid index -- locator)
- *
- * Finds the index'th instance of devid in the pci tree.
- * must be an exact match.
- * class is the class to search for.
- * index 0..N (set to 0, increment until error)
- *
- * Locator is bus << 8 | device << 3 | fuction (or -1 on error)
- */
-static void
-ficlPciBiosFindDevice(FICL_VM *pVM)
-{
- uint32_t index, devid, locator;
-
- index = stackPopINT(pVM->pStack);
- devid = stackPopINT(pVM->pStack);
-
- if (biospci_find_device(devid, index, &locator))
- locator = 0xffffffff;
-
- stackPushINT(pVM->pStack, locator);
-}
-
-/*
- * pcibios-find-device(bus device function -- locator)
- *
- * converts bus, device, function to locator.
- *
- * Locator is bus << 8 | device << 3 | fuction
- */
-static void
-ficlPciBiosLocator(FICL_VM *pVM)
-{
- uint32_t bus, device, function, locator;
-
- function = stackPopINT(pVM->pStack);
- device = stackPopINT(pVM->pStack);
- bus = stackPopINT(pVM->pStack);
-
- locator = biospci_locator(bus, device, function);
-
- stackPushINT(pVM->pStack, locator);
-}
-
-/*
- * Glue function to add the appropriate forth words to access pci bios
- * functionality.
- */
-static void ficlCompilePciBios(FICL_SYSTEM *pSys)
-{
- FICL_DICT *dp = pSys->dp;
- assert (dp);
-
- dictAppendWord(dp, "pcibios-device-count", ficlPciBiosCountDevices, FW_DEFAULT);
- dictAppendWord(dp, "pcibios-read-config", ficlPciBiosReadConfig, FW_DEFAULT);
- dictAppendWord(dp, "pcibios-write-config", ficlPciBiosWriteConfig, FW_DEFAULT);
- dictAppendWord(dp, "pcibios-find-devclass", ficlPciBiosFindDevclass, FW_DEFAULT);
- dictAppendWord(dp, "pcibios-find-device", ficlPciBiosFindDevice, FW_DEFAULT);
- dictAppendWord(dp, "pcibios-locator", ficlPciBiosLocator, FW_DEFAULT);
-
- ficlSetEnv(pSys, "pcibios-version", biospci_version);
-}
-
-FICL_COMPILE_SET(ficlCompilePciBios);
-#endif
diff --git a/stand/i386/libi386/comconsole.c b/stand/i386/libi386/comconsole.c
index f98a1f7..b9fcf03 100644
--- a/stand/i386/libi386/comconsole.c
+++ b/stand/i386/libi386/comconsole.c
@@ -263,7 +263,7 @@ comc_pcidev_handle(uint32_t locator)
uint32_t port;
if (biospci_read_config(locator & 0xffff,
- (locator & 0xff0000) >> 16, 2, &port) == -1) {
+ (locator & 0xff0000) >> 16, BIOSPCI_32BITS, &port) == -1) {
printf("Cannot read bar at 0x%x\n", locator);
return (CMD_ERROR);
}
diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h
index e65a060..297d493 100644
--- a/stand/i386/libi386/libi386.h
+++ b/stand/i386/libi386/libi386.h
@@ -135,6 +135,13 @@ extern vm_offset_t memtop_copyin; /* memtop less heap size for the cases */
extern uint32_t high_heap_size; /* extended memory region available */
extern vm_offset_t high_heap_base; /* for use as the heap */
+/*
+ * Values for width parameter to biospci_{read,write}_config
+ */
+#define BIOSPCI_8BITS 0
+#define BIOSPCI_16BITS 1
+#define BIOSPCI_32BITS 2
+
void biospci_detect(void);
int biospci_find_devclass(uint32_t class, int index, uint32_t *locator);
int biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val);
diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile
index ca0d822..92ac5b9 100644
--- a/stand/i386/loader/Makefile
+++ b/stand/i386/loader/Makefile
@@ -14,11 +14,8 @@ LOADER_BZIP2_SUPPORT?= yes
.include <bsd.init.mk>
-MK_SSP= no
-
LOADER?= loader
PROG= ${LOADER}.sym
-MAN=
INTERNALPROG=
NEWVERSWHAT?= "bootstrap loader" x86
VERSION_FILE= ${.CURDIR}/../loader/version
@@ -74,8 +71,8 @@ FILESMODE_${LOADER}= ${BINMODE} -b
# XXX crt0.o needs to be first for pxeboot(8) to work
OBJS= ${BTXCRT}
-DPADD= ${LIBFICL32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32}
-LDADD= ${LIBFICL32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32}
+DPADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32}
+LDADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32}
.if ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -DLOADER_PREFER_AMD64
diff --git a/stand/i386/mbr/Makefile b/stand/i386/mbr/Makefile
index 9bfa0bd..26018ff 100644
--- a/stand/i386/mbr/Makefile
+++ b/stand/i386/mbr/Makefile
@@ -3,7 +3,6 @@
PROG= mbr
STRIP=
BINMODE=${NOBINMODE}
-MAN=
SRCS= ${PROG}.s
# MBR flags: 0x80 -- try packet interface (also known as EDD or LBA)
diff --git a/stand/i386/pmbr/Makefile b/stand/i386/pmbr/Makefile
index 1bfe0ee..bfd6209 100644
--- a/stand/i386/pmbr/Makefile
+++ b/stand/i386/pmbr/Makefile
@@ -3,7 +3,6 @@
PROG= pmbr
STRIP=
BINMODE=${NOBINMODE}
-MAN=
SRCS= ${PROG}.s
ORG= 0x600
diff --git a/stand/kshim/bsd_kernel.h b/stand/kshim/bsd_kernel.h
index 66106ac..4dfe307 100644
--- a/stand/kshim/bsd_kernel.h
+++ b/stand/kshim/bsd_kernel.h
@@ -50,6 +50,8 @@
#define USB_BUS_EXPLORE_PROC(bus) (usb_process + 0)
#define USB_BUS_CONTROL_XFER_PROC(bus) (usb_process + 1)
#define SYSCTL_DECL(...)
+struct sysctl_ctx_list {
+};
struct sysctl_req {
void *newptr;
};
@@ -59,6 +61,13 @@ struct sysctl_req {
#define SYSCTL_INT(...)
#define SYSCTL_UINT(...)
#define SYSCTL_PROC(...)
+#define SYSCTL_ADD_NODE(...) NULL
+#define SYSCTL_ADD_U16(...) NULL
+#define SYSCTL_ADD_PROC(...) NULL
+#define sysctl_handle_int(...) EOPNOTSUPP
+#define sysctl_handle_string(...) EOPNOTSUPP
+#define sysctl_ctx_init(ctx) do { (void)(ctx); } while (0)
+#define sysctl_ctx_free(ctx) do { (void)(ctx); } while (0)
#define TUNABLE_INT(...)
#define MALLOC_DECLARE(...)
#define MALLOC_DEFINE(...)
@@ -178,6 +187,10 @@ struct thread;
struct malloc_type;
struct usb_process;
+#ifndef INT32_MAX
+#define INT32_MAX 0x7fffffff
+#endif
+
#ifndef HAVE_STANDARD_DEFS
#define _UINT8_T_DECLARED
typedef unsigned char uint8_t;
diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile
index ff50dd6..988ac30 100644
--- a/stand/libsa/Makefile
+++ b/stand/libsa/Makefile
@@ -6,18 +6,12 @@
# quite large.
#
-PACKAGE=lib${LIB}
-MK_PROFILE= no
-MK_SSP= no
-
.include <bsd.init.mk>
-INTERNALLIB=
LIBSA_CPUARCH?=${MACHINE_CPUARCH}
LIBC_SRC= ${SRCTOP}/lib/libc
LIB?= sa
-NO_PIC=
# 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 \
diff --git a/stand/libsa/environment.c b/stand/libsa/environment.c
index 83349f1..36409cc 100644
--- a/stand/libsa/environment.c
+++ b/stand/libsa/environment.c
@@ -138,6 +138,7 @@ env_setenv(const char *name, int flags, const void *value,
return(0);
}
+/* coverity[ -tainted_string_return_content ] */
char *
getenv(const char *name)
{
diff --git a/stand/libsa/libstand.3 b/stand/libsa/libsa.3
index acb979f..0c9fbf6 100644
--- a/stand/libsa/libstand.3
+++ b/stand/libsa/libsa.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 6, 2004
+.Dd February 1, 2018
.Dt LIBSTAND 3
.Os
.Sh NAME
@@ -161,6 +161,10 @@ may be used to prevent a variable being unset.
.Bl -hang -width 10n
.It Xo
.Ft int
+.Fn abs "int i"
+.Xc
+.It Xo
+.Ft int
.Fn getopt "int argc" "char * const *argv" "const char *optstring"
.Xc
.It Xo
@@ -168,8 +172,20 @@ may be used to prevent a variable being unset.
.Fn strtol "const char *nptr" "char **endptr" "int base"
.Xc
.It Xo
+.Ft long long
+.Fn strtoll "const char *nptr" "char **endptr" "int base"
+.Xc
+.It Xo
+.Ft long
+.Fn strtoul "const char *nptr" "char **endptr" "int base"
+.Xc
+.It Xo
+.Ft long long
+.Fn strtoull "const char *nptr" "char **endptr" "int base"
+.Xc
+.It Xo
.Ft void
-.Fn srandom "unsigned long seed"
+.Fn srandom "unsigned int seed"
.Xc
.It Xo
.Ft "long"
@@ -350,6 +366,22 @@ ptr,
.Xc
.It Xo
.Ft int
+.Fn isalnum "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn iscntrl "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn isgraph "int c"
+.Xc
+.It Xo
+.Ft int
+.Fn ispunct "int c"
+.Xc
+.It Xo
+.Ft int
.Fn toupper "int c"
.Xc
.It Xo
@@ -583,6 +615,14 @@ 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
+.Xc
+.Pp
+Calls
+.Fn panic
+with a fixed string.
+.It Xo
+.Ft void
.Fn panic "const char *msg" "..."
.Xc
.Pp
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
index dd94b48..6968c3e 100644
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -68,6 +68,7 @@
/* this header intentionally exports NULL from <string.h> */
#include <string.h>
+#define strcoll(a, b) strcmp((a), (b))
#define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args)
#define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args); getchar();}
diff --git a/stand/loader.mk b/stand/loader.mk
index b811c93..e2c4718 100644
--- a/stand/loader.mk
+++ b/stand/loader.mk
@@ -61,6 +61,8 @@ SRCS+= pnp.c
.if ${MK_FORTH} != "no"
SRCS+= interp_forth.c
.include "${BOOTSRC}/ficl.mk"
+.else
+SRCS+= interp_simple.c
.endif
.if defined(BOOT_PROMPT_123)
@@ -128,14 +130,15 @@ LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a
.endif
.endif
-# NB: The makefiles depend on these being empty when we don't build forth.
-.if ${MK_FORTH} != "no"
LIBFICL= ${BOOTOBJ}/ficl/libficl.a
.if ${MACHINE} == "i386"
LIBFICL32= ${LIBFICL}
.else
LIBFICL32= ${BOOTOBJ}/ficl32/libficl.a
.endif
+.if ${MK_FORTH} != no
+LDR_INTERP= ${LIBFICL}
+LDR_INTERP32= ${LIBFICL32}
.endif
CLEANFILES+= vers.c
diff --git a/stand/mips/beri/boot2/Makefile b/stand/mips/beri/boot2/Makefile
index ce09b6e..f4b433c 100644
--- a/stand/mips/beri/boot2/Makefile
+++ b/stand/mips/beri/boot2/Makefile
@@ -43,8 +43,6 @@ SRCS= relocate.S \
cfi.c \
sdcard.c
-MAN=
-
AFLAGS= -G0
CFLAGS+= -I${LDRSRC} \
diff --git a/stand/mips/beri/boot2/boot2.c b/stand/mips/beri/boot2/boot2.c
index 4e15b64..3c8cc3d 100644
--- a/stand/mips/beri/boot2/boot2.c
+++ b/stand/mips/beri/boot2/boot2.c
@@ -118,8 +118,6 @@ static const unsigned char flags[NOPT] = {
static const char *const dev_nm[] = {"dram", "cfi", "sdcard"};
static const u_int dev_nm_count = nitems(dev_nm);
-static struct dmadat __dmadat;
-
static struct dsk {
unsigned type; /* BOOTINFO_DEV_TYPE_x object type. */
uintptr_t unitptr; /* Unit number or pointer to object. */
@@ -148,10 +146,11 @@ static int dskread(void *, unsigned, unsigned);
static int xputc(int);
static int xgetc(int);
-
#define UFS_SMALL_CGBASE
#include "ufsread.c"
+static struct dmadat __dmadat;
+
static inline int
xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
diff --git a/stand/mips/beri/loader/Makefile b/stand/mips/beri/loader/Makefile
index 46b927f..f8c1bd9 100644
--- a/stand/mips/beri/loader/Makefile
+++ b/stand/mips/beri/loader/Makefile
@@ -38,9 +38,6 @@ LOADER_BZIP2_SUPPORT?= yes
.include <bsd.init.mk>
-MK_SSP= no
-MAN=
-
PROG?= loader
NEWVERSWHAT= "BERI loader" ${MACHINE_CPUARCH}
INSTALLFLAGS= -b
@@ -90,8 +87,8 @@ LDFLAGS+= -static \
-L${.CURDIR} \
-e __start
-DPADD= ${LIBFICL} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBSA}
.if defined(LOADER_USB_SUPPORT)
# Do garbage collection
diff --git a/stand/mips/beri/loader/exec.c b/stand/mips/beri/loader/exec.c
index 68e149d..3c1b7a6 100644
--- a/stand/mips/beri/loader/exec.c
+++ b/stand/mips/beri/loader/exec.c
@@ -80,14 +80,14 @@ beri_elf64_exec(struct preloaded_file *fp)
md = file_findmetadata(fp, MODINFOMD_ELFHDR);
if (md == NULL) {
- printf("%s: file_findmetadata failed\n");
+ printf("%s: file_findmetadata failed\n", fp->f_name);
return (EFTYPE);
}
ehdr = (Elf_Ehdr *)md->md_data;
error = md_load64(fp->f_args, &mdp);
if (error) {
- printf("%s: md_load64 failed\n");
+ printf("%s: md_load64 failed\n", fp->f_name);
return (error);
}
diff --git a/stand/mips/uboot/Makefile b/stand/mips/uboot/Makefile
index 4a7350a..4323f45 100644
--- a/stand/mips/uboot/Makefile
+++ b/stand/mips/uboot/Makefile
@@ -35,8 +35,8 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
.include "${BOOTSRC}/uboot.mk"
-DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
diff --git a/stand/ofw/common/main.c b/stand/ofw/common/main.c
index 128542c9..b8c7a17 100644
--- a/stand/ofw/common/main.c
+++ b/stand/ofw/common/main.c
@@ -42,23 +42,17 @@ u_int32_t acells, scells;
static char bootargs[128];
-#define HEAP_SIZE 0x100000
+#define HEAP_SIZE 0x800000
+static char heap[HEAP_SIZE]; // In BSS, so uses no space
#define OF_puts(fd, text) OF_write(fd, text, strlen(text))
void
init_heap(void)
{
- void *base;
- ihandle_t stdout;
+ bzero(heap, HEAP_SIZE);
- if ((base = ofw_alloc_heap(HEAP_SIZE)) == (void *)0xffffffff) {
- OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
- OF_puts(stdout, "Heap memory claim failed!\n");
- OF_enter();
- }
-
- setheap(base, (void *)((int)base + HEAP_SIZE));
+ setheap(heap, (void *)((int)heap + HEAP_SIZE));
}
uint64_t
diff --git a/stand/ofw/libofw/Makefile b/stand/ofw/libofw/Makefile
index 6818e27..80ca993 100644
--- a/stand/ofw/libofw/Makefile
+++ b/stand/ofw/libofw/Makefile
@@ -3,7 +3,6 @@
.include <bsd.init.mk>
LIB= ofw
-INTERNALLIB=
SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \
ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
diff --git a/stand/ofw/libofw/elf_freebsd.c b/stand/ofw/libofw/elf_freebsd.c
index a2e48a7..456b0cd 100644
--- a/stand/ofw/libofw/elf_freebsd.c
+++ b/stand/ofw/libofw/elf_freebsd.c
@@ -87,7 +87,6 @@ __elfN(ofw_exec)(struct preloaded_file *fp)
printf("Kernel entry at 0x%lx ...\n", e->e_entry);
dev_cleanup();
- ofw_release_heap();
if (dtbp != 0) {
OF_quiesce();
((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0,
diff --git a/stand/ofw/libofw/libofw.h b/stand/ofw/libofw/libofw.h
index b8c4014..24a5d08 100644
--- a/stand/ofw/libofw/libofw.h
+++ b/stand/ofw/libofw/libofw.h
@@ -58,8 +58,6 @@ extern int ofw_boot(void);
extern int ofw_autoload(void);
void ofw_memmap(int);
-void *ofw_alloc_heap(unsigned int);
-void ofw_release_heap(void);
struct preloaded_file;
struct file_format;
diff --git a/stand/ofw/libofw/ofw_copy.c b/stand/ofw/libofw/ofw_copy.c
index ffd6987..d83dbed 100644
--- a/stand/ofw/libofw/ofw_copy.c
+++ b/stand/ofw/libofw/ofw_copy.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#define READIN_BUF (4 * 1024)
#define PAGE_SIZE 0x1000
#define PAGE_MASK 0x0fff
-#define MAPMEM_PAGE_INC 16
+#define MAPMEM_PAGE_INC 128 /* Half-MB at a time */
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
diff --git a/stand/ofw/libofw/ofw_memory.c b/stand/ofw/libofw/ofw_memory.c
index 5616184..f05881e 100644
--- a/stand/ofw/libofw/ofw_memory.c
+++ b/stand/ofw/libofw/ofw_memory.c
@@ -35,9 +35,6 @@ __FBSDID("$FreeBSD$");
#include "libofw.h"
#include "openfirm.h"
-static void *heap_base = NULL;
-static unsigned int heap_size = 0;
-
struct ofw_mapping {
vm_offset_t va;
int len;
@@ -115,32 +112,3 @@ ofw_memmap(int acells)
pager_close();
}
-void *
-ofw_alloc_heap(unsigned int size)
-{
- phandle_t memoryp, root;
- cell_t available[4];
- cell_t acells;
-
- root = OF_finddevice("/");
- acells = 1;
- OF_getprop(root, "#address-cells", &acells, sizeof(acells));
-
- memoryp = OF_instance_to_package(memory);
- OF_getprop(memoryp, "available", available, sizeof(available));
-
- heap_base = OF_claim((void *)available[acells-1], size,
- sizeof(register_t));
-
- if (heap_base != (void *)-1) {
- heap_size = size;
- }
-
- return (heap_base);
-}
-
-void
-ofw_release_heap(void)
-{
- OF_release(heap_base, heap_size);
-}
diff --git a/stand/ofw/libofw/ppc64_elf_freebsd.c b/stand/ofw/libofw/ppc64_elf_freebsd.c
index 9132e9d..6d85029 100644
--- a/stand/ofw/libofw/ppc64_elf_freebsd.c
+++ b/stand/ofw/libofw/ppc64_elf_freebsd.c
@@ -90,7 +90,6 @@ ppc64_ofw_elf_exec(struct preloaded_file *fp)
printf("Kernel entry at 0x%lx ...\n", entry);
dev_cleanup();
- ofw_release_heap();
if (dtbp != 0) {
OF_quiesce();
diff --git a/stand/powerpc/boot1.chrp/Makefile b/stand/powerpc/boot1.chrp/Makefile
index d865248..8fbc1e5 100644
--- a/stand/powerpc/boot1.chrp/Makefile
+++ b/stand/powerpc/boot1.chrp/Makefile
@@ -9,8 +9,6 @@ INSTALLFLAGS= -b
FILES= boot1.hfs
SRCS= boot1.c ashldi3.c syncicache.c
-MAN=
-
CFLAGS+=-I${LDRSRC}
LDFLAGS=-nostdlib -static -Wl,-N
diff --git a/stand/powerpc/kboot/Makefile b/stand/powerpc/kboot/Makefile
index e91421d..d5b2025 100644
--- a/stand/powerpc/kboot/Makefile
+++ b/stand/powerpc/kboot/Makefile
@@ -11,8 +11,6 @@ LOADER_GZIP_SUPPORT?= yes
LOADER_BZIP2_SUPPORT?= no
.include <bsd.init.mk>
-MK_SSP= no
-MAN=
PROG= loader.kboot
NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH}
@@ -41,7 +39,7 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc
# 64-bit bridge extensions
CFLAGS+= -Wa,-mppc64bridge
-DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA}
.include <bsd.prog.mk>
diff --git a/stand/powerpc/kboot/conf.c b/stand/powerpc/kboot/conf.c
index 104dd93..22562e8 100644
--- a/stand/powerpc/kboot/conf.c
+++ b/stand/powerpc/kboot/conf.c
@@ -78,6 +78,7 @@ struct fs_ops *file_system[] = {
#if defined(LOADER_BZIP2_SUPPORT)
&bzipfs_fsops,
#endif
+ &dosfs_fsops,
NULL
};
diff --git a/stand/powerpc/kboot/host_syscall.S b/stand/powerpc/kboot/host_syscall.S
index 3607fdb..1cb9016 100644
--- a/stand/powerpc/kboot/host_syscall.S
+++ b/stand/powerpc/kboot/host_syscall.S
@@ -14,7 +14,6 @@ ENTRY(host_read)
li %r3, 0
blr
-
ENTRY(host_write)
li %r0, 4 # SYS_write
sc
@@ -28,6 +27,11 @@ ENTRY(host_seek)
sc
blr
+ENTRY(host_llseek)
+ li %r0, 140 # SYS_llseek
+ sc
+ blr
+
ENTRY(host_open)
li %r0, 5 # SYS_open
sc
@@ -47,6 +51,11 @@ ENTRY(host_mmap)
sc
blr
+ENTRY(host_uname)
+ li %r0, 122 # SYS_uname
+ sc
+ blr
+
ENTRY(host_gettimeofday)
li %r0, 78 # SYS_gettimeofday
sc
diff --git a/stand/powerpc/kboot/host_syscall.h b/stand/powerpc/kboot/host_syscall.h
index 349c54e..50b0725 100644
--- a/stand/powerpc/kboot/host_syscall.h
+++ b/stand/powerpc/kboot/host_syscall.h
@@ -34,9 +34,18 @@ ssize_t host_read(int fd, void *buf, size_t nbyte);
ssize_t host_write(int fd, const void *buf, size_t nbyte);
ssize_t host_seek(int fd, int64_t offset, int whence);
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, int);
#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 {
int tv_sec;
int tv_usec;
@@ -44,8 +53,8 @@ struct host_timeval {
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(vm_offset_t start, int nsegs, void *segs);
-int host_reboot(int, int, int, void *);
+int kexec_load(uint32_t start, int nsegs, uint32_t segs);
+int host_reboot(int, int, int, uint32_t);
int host_getdents(int fd, void *dirp, int count);
#endif
diff --git a/stand/powerpc/kboot/hostdisk.c b/stand/powerpc/kboot/hostdisk.c
index 26d3959..3c36f2d 100644
--- a/stand/powerpc/kboot/hostdisk.c
+++ b/stand/powerpc/kboot/hostdisk.c
@@ -64,10 +64,14 @@ hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
struct devdesc *desc = devdata;
daddr_t pos;
int n;
-
+ uint64_t res;
+ uint32_t posl, posh;
+
pos = dblk * 512;
- if (host_seek(desc->d_unit, pos, 0) < 0) {
+ posl = pos & 0xffffffff;
+ posh = (pos >> 32) & 0xffffffff;
+ if (host_llseek(desc->d_unit, posh, posl, &res, 0) < 0) {
printf("Seek error\n");
return (EIO);
}
diff --git a/stand/powerpc/kboot/kerneltramp.S b/stand/powerpc/kboot/kerneltramp.S
index a394c95..15fdfc2 100644
--- a/stand/powerpc/kboot/kerneltramp.S
+++ b/stand/powerpc/kboot/kerneltramp.S
@@ -20,6 +20,18 @@ CNAME(kerneltramp):
bl 2f
.space 24 /* branch address, r3-r7 */
+/*
+ * MUST BE IN SYNC WITH:
+ * struct trampoline_data {
+ * uint32_t kernel_entry;
+ * uint32_t dtb;
+ * uint32_t phys_mem_offset;
+ * uint32_t of_entry;
+ * uint32_t mdp;
+ * uint32_t mdp_size;
+ * };
+ */
+
. = kerneltramp + 0x40 /* AP spinlock */
.long 0
@@ -36,18 +48,53 @@ CNAME(kerneltramp):
sync
ba 0x100
-2: /* Continuation of kerneltramp */
+2: /* Continuation of kerneltramp */
mflr %r8
mtlr %r9
- lwz %r3,0(%r8)
- mtctr %r3
+
+ mfmsr %r10
+ andi. %r10, %r10, 1 /* test MSR_LE */
+ bne little_endian
+
+/* We're starting in BE */
+big_endian:
lwz %r3,4(%r8)
lwz %r4,8(%r8)
lwz %r5,12(%r8)
lwz %r6,16(%r8)
lwz %r7,20(%r8)
+
+ lwz %r10, 0(%r8)
+ mtctr %r10
bctr
-
+
+/* We're starting in LE */
+little_endian:
+
+ /* Entries are BE, swap them during load. */
+ li %r10, 4
+ lwbrx %r3, %r8, %r10
+ li %r10, 8
+ lwbrx %r4, %r8, %r10
+ li %r10, 12
+ lwbrx %r5, %r8, %r10
+ li %r10, 16
+ lwbrx %r6, %r8, %r10
+ li %r10, 20
+ lwbrx %r7, %r8, %r10
+
+ /* Clear MSR_LE flag to enter the BE world */
+ mfmsr %r10
+ clrrdi %r10, %r10, 1
+ mtsrr1 %r10
+
+ /* Entry is at 0(%r8) */
+ li %r10, 0
+ lwbrx %r10, %r8, %r10
+ mtsrr0 %r10
+
+ rfid
+
endkerneltramp:
.data
diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c
index cbd1161..d4f59ab 100644
--- a/stand/powerpc/kboot/main.c
+++ b/stand/powerpc/kboot/main.c
@@ -27,6 +27,7 @@
__FBSDID("$FreeBSD$");
#include <stand.h>
+#include <sys/endian.h>
#include <sys/param.h>
#include <fdt_platform.h>
@@ -35,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h"
#include "host_syscall.h"
+
struct arch_switch archsw;
extern void *_end;
@@ -47,9 +49,170 @@ ssize_t kboot_readin(const int 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);
int kboot_setcurrdev(struct env_var *ev, int flags, const void *value);
+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)
{
@@ -94,7 +257,7 @@ main(int argc, const char **argv)
{
void *heapbase;
const size_t heapsize = 15*1024*1024;
- const char *bootdev = argv[1];
+ const char *bootdev;
/*
* Set the heap to one page after the end of the loader.
@@ -107,6 +270,12 @@ main(int argc, const char **argv)
*/
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;
@@ -115,6 +284,7 @@ main(int argc, const char **argv)
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);
@@ -181,7 +351,7 @@ static ssize_t
get_phys_buffer(vm_offset_t dest, const size_t len, void **buf)
{
int i = 0;
- const size_t segsize = 2*1024*1024;
+ const size_t segsize = 4*1024*1024;
for (i = 0; i < nkexec_segments; i++) {
if (dest >= (vm_offset_t)loaded_segments[i].mem &&
@@ -194,6 +364,7 @@ get_phys_buffer(vm_offset_t dest, const size_t len, void **buf)
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++;
@@ -283,19 +454,34 @@ kboot_autoload(void)
uint64_t
kboot_loadaddr(u_int type, void *data, uint64_t addr)
{
- /*
- * Need to stay out of the way of Linux. /chosen/linux,kernel-end does
- * a better job here, but use a fixed offset for now.
- */
if (type == LOAD_ELF)
addr = roundup(addr, PAGE_SIZE);
else
- addr += 64*1024*1024; /* Stay out of the way of Linux */
+ 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)
{
diff --git a/stand/powerpc/kboot/metadata.c b/stand/powerpc/kboot/metadata.c
index 1e8c314..2892ce506 100644
--- a/stand/powerpc/kboot/metadata.c
+++ b/stand/powerpc/kboot/metadata.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <stand.h>
#include <sys/param.h>
+#include <sys/endian.h>
#include <sys/reboot.h>
#include <sys/linker.h>
#include <sys/boot.h>
@@ -157,7 +158,7 @@ md_copyenv(vm_offset_t addr)
static int align;
#define COPY32(v, a, c) { \
- u_int32_t x = (v); \
+ u_int32_t x = htobe32(v); \
if (c) \
archsw.arch_copyin(&x, a, sizeof(x)); \
a += sizeof(x); \
@@ -254,11 +255,12 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64)
vm_offset_t fdtp;
vm_offset_t size;
uint64_t scratch64;
+ uint32_t scratch32;
char *rootdevname;
int howto;
align = kern64 ? 8 : 4;
- howto = md_getboothowto(args);
+ howto = htobe32(md_getboothowto(args));
/*
* Allow the environment variable 'rootdev' to override the supplied device
@@ -300,16 +302,19 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64)
panic("can't find kernel file");
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
if (kern64) {
- scratch64 = envp;
+ scratch64 = htobe64(envp);
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64);
- scratch64 = fdtp;
+ scratch64 = htobe64(fdtp);
file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch64, &scratch64);
- scratch64 = kernend;
+ scratch64 = htobe64(kernend);
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64);
} else {
- file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
- file_addmetadata(kfp, MODINFOMD_DTBP, sizeof fdtp, &fdtp);
- file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ scratch32 = htobe32(envp);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch32, &scratch32);
+ scratch32 = htobe32(fdtp);
+ file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch32, &scratch32);
+ scratch32 = htobe32(kernend);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch32, &scratch32);
}
*modulep = addr;
@@ -318,7 +323,7 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64)
md = file_findmetadata(kfp, MODINFOMD_KERNEND);
if (kern64) {
- scratch64 = kernend;
+ scratch64 = htobe64(kernend);
bcopy(&scratch64, md->md_data, sizeof scratch64);
} else {
bcopy(&kernend, md->md_data, sizeof kernend);
diff --git a/stand/powerpc/kboot/ppc64_elf_freebsd.c b/stand/powerpc/kboot/ppc64_elf_freebsd.c
index 987565e..9547077 100644
--- a/stand/powerpc/kboot/ppc64_elf_freebsd.c
+++ b/stand/powerpc/kboot/ppc64_elf_freebsd.c
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#define __ELF_WORD_SIZE 64
#include <sys/param.h>
+#include <sys/endian.h>
#include <sys/linker.h>
#include <machine/metadata.h>
@@ -43,8 +44,15 @@ __FBSDID("$FreeBSD$");
extern char end[];
extern void *kerneltramp;
extern size_t szkerneltramp;
-extern int nkexec_segments;
-extern void * loaded_segments;
+
+struct trampoline_data {
+ uint32_t kernel_entry;
+ uint32_t dtb;
+ uint32_t phys_mem_offset;
+ uint32_t of_entry;
+ uint32_t mdp;
+ uint32_t mdp_size;
+};
vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb);
@@ -70,53 +78,90 @@ ppc64_elf_exec(struct preloaded_file *fp)
int error;
uint32_t *trampoline;
uint64_t entry;
- vm_offset_t trampolinebase;
+ uint64_t trampolinebase;
+ struct trampoline_data *trampoline_data;
+ int nseg;
+ void *kseg;
if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
return(EFTYPE);
}
e = (Elf_Ehdr *)&fmp->md_data;
- /* Figure out where to put it */
+ /*
+ * 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).
+ *
+ * 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);
-
+ printf("Load address at %#jx\n", (uintmax_t)trampolinebase);
+ printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset);
+
/* Set up loader trampoline */
trampoline = malloc(szkerneltramp);
memcpy(trampoline, &kerneltramp, szkerneltramp);
+
/* Parse function descriptor for ELFv1 kernels */
if ((e->e_flags & 3) == 2)
entry = e->e_entry;
- else
+ else {
archsw.arch_copyout(e->e_entry + elf64_relocation_offset,
&entry, 8);
- trampoline[2] = entry + elf64_relocation_offset;
- trampoline[4] = 0; /* Phys. mem offset */
- trampoline[5] = 0; /* OF entry point */
+ entry = be64toh(entry);
+ }
+
+ /*
+ * Placeholder for trampoline data is at trampolinebase + 0x08
+ * CAUTION: all data must be Big Endian
+ */
+ trampoline_data = (void*)&trampoline[2];
+ trampoline_data->kernel_entry = htobe32(entry + elf64_relocation_offset);
+ trampoline_data->phys_mem_offset = htobe32(0);
+ trampoline_data->of_entry = htobe32(0);
if ((error = md_load64(fp->f_args, &mdp, &dtb)) != 0)
return (error);
- trampoline[3] = dtb;
- trampoline[6] = mdp;
- trampoline[7] = 0xfb5d104d;
- printf("Kernel entry at %#jx (%#x) ...\n", e->e_entry, trampoline[2]);
- printf("DTB at %#x, mdp at %#x\n", dtb, mdp);
+ trampoline_data->dtb = htobe32(dtb);
+ trampoline_data->mdp = htobe32(mdp);
+ trampoline_data->mdp_size = htobe32(0xfb5d104d);
+
+ printf("Kernel entry at %#jx (%#x) ...\n",
+ entry, be32toh(trampoline_data->kernel_entry));
+ printf("DTB at %#x, mdp at %#x\n",
+ be32toh(trampoline_data->dtb), be32toh(trampoline_data->mdp));
dev_cleanup();
archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp);
free(trampoline);
- error = kexec_load(trampolinebase, nkexec_segments, &loaded_segments);
+ if (archsw.arch_kexec_kseg_get == NULL)
+ panic("architecture did not provide kexec segment mapping");
+ archsw.arch_kexec_kseg_get(&nseg, &kseg);
+
+ error = kexec_load(trampolinebase, nseg, (uintptr_t)kseg);
if (error != 0)
panic("kexec_load returned error: %d", error);
+
error = host_reboot(0xfee1dead, 672274793,
- 0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, NULL);
+ 0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, (uintptr_t)NULL);
if (error != 0)
panic("reboot returned error: %d", error);
- while (1) {}
- panic("exec returned");
+ while (1) {}
}
struct file_format ppc_elf64 =
diff --git a/stand/powerpc/ofw/Makefile b/stand/powerpc/ofw/Makefile
index e24b7af..ce24844 100644
--- a/stand/powerpc/ofw/Makefile
+++ b/stand/powerpc/ofw/Makefile
@@ -11,8 +11,6 @@ LOADER_GZIP_SUPPORT?= yes
LOADER_BZIP2_SUPPORT?= no
.include <bsd.init.mk>
-MK_SSP= no
-MAN=
PROG= loader
NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH}
@@ -48,7 +46,7 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc
LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a
CFLAGS+= -I${BOOTSRC}/ofw/libofw
-DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA}
.include <bsd.prog.mk>
diff --git a/stand/powerpc/ofw/ldscript.powerpc b/stand/powerpc/ofw/ldscript.powerpc
index 3a27650..e0dc5e2 100644
--- a/stand/powerpc/ofw/ldscript.powerpc
+++ b/stand/powerpc/ofw/ldscript.powerpc
@@ -9,7 +9,7 @@ PROVIDE (__stack = 0);
SECTIONS
{
/* Read-only sections, merged into text segment: */
- . = 0x01c00000 + SIZEOF_HEADERS;
+ . = 0x02c00000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
diff --git a/stand/powerpc/uboot/Makefile b/stand/powerpc/uboot/Makefile
index 623c464..8d9d8e3 100644
--- a/stand/powerpc/uboot/Makefile
+++ b/stand/powerpc/uboot/Makefile
@@ -14,7 +14,6 @@ LOADER_BZIP2_SUPPORT?= no
PROG= ubldr
NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH}
INSTALLFLAGS= -b
-MAN=
# Architecture-specific loader code
SRCS= start.S conf.c vers.c
@@ -28,7 +27,7 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc
.include "${BOOTSRC}/uboot.mk"
-DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA}
.include <bsd.prog.mk>
diff --git a/stand/sparc64/boot1/Makefile b/stand/sparc64/boot1/Makefile
index 97bfa67..7dbd297 100644
--- a/stand/sparc64/boot1/Makefile
+++ b/stand/sparc64/boot1/Makefile
@@ -4,7 +4,6 @@
PROG= boot1.elf
INTERNALPROG=
-MAN=
FILES?= boot1
SRCS= _start.s boot1.c
CLEANFILES+=${FILES} boot1.aout
diff --git a/stand/sparc64/loader/Makefile b/stand/sparc64/loader/Makefile
index 5b7c09a..7f57409 100644
--- a/stand/sparc64/loader/Makefile
+++ b/stand/sparc64/loader/Makefile
@@ -13,8 +13,6 @@ LOADER_BZIP2_SUPPORT?= no
LOADER_DEBUG?= no
.include <bsd.init.mk>
-MK_SSP= no
-MAN=
PROG?= loader
NEWVERSWHAT?= "bootstrap loader" sparc64
@@ -42,7 +40,7 @@ LDFLAGS+= -static
LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a
CFLAGS+= -I${BOOTSRC}/ofw/libofw/
-DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA}
-LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA}
+DPADD= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA}
+LDADD= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA}
.include <bsd.prog.mk>
diff --git a/stand/uboot/fdt/Makefile b/stand/uboot/fdt/Makefile
index d88789d..b1e9f8e 100644
--- a/stand/uboot/fdt/Makefile
+++ b/stand/uboot/fdt/Makefile
@@ -5,7 +5,6 @@
.PATH: ${LDRSRC}
LIB= uboot_fdt
-INTERNALLIB=
WARNS?= 2
SRCS= uboot_fdt.c
diff --git a/stand/uboot/lib/Makefile b/stand/uboot/lib/Makefile
index 5e8a5f4..19e4d3a 100644
--- a/stand/uboot/lib/Makefile
+++ b/stand/uboot/lib/Makefile
@@ -5,7 +5,6 @@
.PATH: ${LDRSRC}
LIB= uboot
-INTERNALLIB=
WARNS?= 2
SRCS= console.c copy.c devicename.c elf_freebsd.c glue.c
diff --git a/stand/usb/Makefile.test b/stand/usb/test/Makefile
index decee69..c82b5ba 100644
--- a/stand/usb/Makefile.test
+++ b/stand/usb/test/Makefile
@@ -30,9 +30,9 @@
#
.PATH: ${.CURDIR}
+.SUFFIXES: .a
PROG= usbloader
-MAN=
SRCS=
CFLAGS+= -Wall
@@ -46,12 +46,15 @@ LDFLAGS+= -Wl,--gc-sections
SRCS+= bsd_usbloader_test.c
-LDADD+= libusbboot.a
-DPADD+= libusbboot.a
+USBLIB?= ${.OBJDIR}/../libusbboot.a
+
+LDADD+= ${USBLIB}
+DPADD+= ${USBLIB}
+
+MAN=
.include <bsd.prog.mk>
-${PROG}: libusbboot.a
+${USBLIB}:
+ make -C ${.CURDIR}/.. USBCOREDIR=${.CURDIR}/..
-libusbboot.a:
- make -f Makefile
diff --git a/stand/usb/bsd_usbloader_test.c b/stand/usb/test/bsd_usbloader_test.c
index 35140b8..35140b8 100644
--- a/stand/usb/bsd_usbloader_test.c
+++ b/stand/usb/test/bsd_usbloader_test.c
diff --git a/stand/usb/usbcore.mk b/stand/usb/usbcore.mk
index 153a1d4..b43d9d2 100644
--- a/stand/usb/usbcore.mk
+++ b/stand/usb/usbcore.mk
@@ -32,7 +32,7 @@
#
USBCOREDIR:= ${.PARSEDIR}
-S=${USBCOREDIR}/../..
+S=${USBCOREDIR}/../../sys
MACHDEP_DIRS=
diff --git a/stand/userboot/test/Makefile b/stand/userboot/test/Makefile
index e40a7bc..7c88f26 100644
--- a/stand/userboot/test/Makefile
+++ b/stand/userboot/test/Makefile
@@ -1,10 +1,6 @@
# $FreeBSD$
-
-MAN=
-
.include <bsd.init.mk>
-MK_SSP= no
PROG= test
INTERNALPROG=
diff --git a/stand/userboot/userboot/Makefile b/stand/userboot/userboot/Makefile
index 5946257..2aa4161 100644
--- a/stand/userboot/userboot/Makefile
+++ b/stand/userboot/userboot/Makefile
@@ -1,18 +1,14 @@
# $FreeBSD$
-MAN=
-
LOADER_MSDOS_SUPPORT?= yes
LOADER_UFS_SUPPORT?= yes
LOADER_CD9660_SUPPORT?= no
LOADER_EXT2FS_SUPPORT?= no
+PIC=yes
.include <bsd.init.mk>
-MK_SSP= no
-
SHLIB_NAME= userboot.so
-MK_CTF= no
STRIP=
LIBDIR= /boot
@@ -48,10 +44,10 @@ CFLAGS+= -DUSERBOOT_ZFS_SUPPORT
LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a
.endif
-# Always add MI sources
+# Always add MI sources
.include "${BOOTSRC}/loader.mk"
CFLAGS+= -I.
-DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA}
-LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA}
+DPADD+= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBSA}
+LDADD+= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBSA}
.include <bsd.lib.mk>
diff --git a/stand/zfs/Makefile b/stand/zfs/Makefile
index e86c84b..3116b32 100644
--- a/stand/zfs/Makefile
+++ b/stand/zfs/Makefile
@@ -3,7 +3,6 @@
.include <bsd.init.mk>
LIB= zfsboot
-INTERNALLIB=
.PATH: ${ZFSSRC}
SRCS+= zfs.c skein.c skein_block.c
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 08ae922..fa8a02d 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -267,9 +267,17 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
symstrindex = shdr[i].sh_link;
break;
case SHT_REL:
+ /*
+ * Ignore relocation tables for sections not
+ * loaded by the loader.
+ */
+ if (shdr[shdr[i].sh_info].sh_addr == 0)
+ break;
ef->nreltab++;
break;
case SHT_RELA:
+ if (shdr[shdr[i].sh_info].sh_addr == 0)
+ break;
ef->nrelatab++;
break;
}
@@ -391,12 +399,16 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
pb++;
break;
case SHT_REL:
+ if (shdr[shdr[i].sh_info].sh_addr == 0)
+ break;
ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr;
ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
ef->reltab[rl].sec = shdr[i].sh_info;
rl++;
break;
case SHT_RELA:
+ if (shdr[shdr[i].sh_info].sh_addr == 0)
+ break;
ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr;
ef->relatab[ra].nrela =
shdr[i].sh_size / sizeof(Elf_Rela);
@@ -607,9 +619,17 @@ link_elf_load_file(linker_class_t cls, const char *filename,
symstrindex = shdr[i].sh_link;
break;
case SHT_REL:
+ /*
+ * Ignore relocation tables for unallocated
+ * sections.
+ */
+ if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
+ break;
ef->nreltab++;
break;
case SHT_RELA:
+ if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
+ break;
ef->nrelatab++;
break;
case SHT_STRTAB:
@@ -863,6 +883,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
pb++;
break;
case SHT_REL:
+ if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
+ break;
ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER,
M_WAITOK);
ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
@@ -881,6 +903,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
rl++;
break;
case SHT_RELA:
+ if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
+ break;
ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER,
M_WAITOK);
ef->relatab[ra].nrela =
OpenPOWER on IntegriCloud