diff options
author | kevans <kevans@FreeBSD.org> | 2018-02-12 01:08:44 +0000 |
---|---|---|
committer | kevans <kevans@FreeBSD.org> | 2018-02-12 01:08:44 +0000 |
commit | 7d97ee5b28b409c00bfaf12daf5ab497a6038b9d (patch) | |
tree | 245306b754606bcf49c0ff17b131b58609b6c7a6 /stand/mips/beri/loader | |
parent | 43b278e1b66cf4de337a17034087ea785031bd6f (diff) | |
download | FreeBSD-src-7d97ee5b28b409c00bfaf12daf5ab497a6038b9d.zip FreeBSD-src-7d97ee5b28b409c00bfaf12daf5ab497a6038b9d.tar.gz |
MFC r325834,r325997,326502: Move sys/boot to stand/
This is effectively a direct commit to stable/11, due to differences between
stable/11 and head. Changes to DTS in sys/boot/fdt/dts were often
accompanied by kernel changes. Many of these were also risc-v updates that
likely had many more dependencies to MFC.
Because of this, sys/boot/fdt/dts remains as-is while everything else in
sys/boot relocates to stand/.
r325834: Move sys/boot to stand. Fix all references to new location
r325997: Remove empty directories.
r326502: Document the sys/boot -> stand move in hier.7 and the top-level README.
Diffstat (limited to 'stand/mips/beri/loader')
-rw-r--r-- | stand/mips/beri/loader/Makefile | 111 | ||||
-rw-r--r-- | stand/mips/beri/loader/arch.c | 97 | ||||
-rw-r--r-- | stand/mips/beri/loader/beri_console.c | 90 | ||||
-rw-r--r-- | stand/mips/beri/loader/beri_disk_cfi.c | 141 | ||||
-rw-r--r-- | stand/mips/beri/loader/beri_disk_sdcard.c | 147 | ||||
-rw-r--r-- | stand/mips/beri/loader/devicename.c | 205 | ||||
-rw-r--r-- | stand/mips/beri/loader/exec.c | 125 | ||||
-rw-r--r-- | stand/mips/beri/loader/help.mips | 1 | ||||
-rw-r--r-- | stand/mips/beri/loader/loader.h | 63 | ||||
-rw-r--r-- | stand/mips/beri/loader/loader.ldscript | 84 | ||||
-rw-r--r-- | stand/mips/beri/loader/main.c | 244 | ||||
-rw-r--r-- | stand/mips/beri/loader/metadata.c | 355 | ||||
-rw-r--r-- | stand/mips/beri/loader/start.S | 49 | ||||
-rw-r--r-- | stand/mips/beri/loader/version | 6 |
14 files changed, 1718 insertions, 0 deletions
diff --git a/stand/mips/beri/loader/Makefile b/stand/mips/beri/loader/Makefile new file mode 100644 index 0000000..763b3b3 --- /dev/null +++ b/stand/mips/beri/loader/Makefile @@ -0,0 +1,111 @@ +#- +# Copyright (c) 2013-2014 Robert N. M. Watson +# All rights reserved. +# +# This software was developed by SRI International and the University of +# Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) +# ("CTSRD"), as part of the DARPA CRASH research programme. +# +# 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$ + +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no +LOADER_GZIP_SUPPORT?= yes +LOADER_BZIP2_SUPPORT?= yes + +.include <bsd.init.mk> + +MK_SSP= no +MAN= + +PROG?= loader +NEWVERSWHAT= "BERI loader" ${MACHINE_CPUARCH} +INSTALLFLAGS= -b + +# Architecture-specific loader code +SRCS= start.S \ + main.c \ + devicename.c \ + exec.c \ + metadata.c \ + vers.c \ + arch.c + +# libstand front-ends for shared driver code +SRCS+= beri_console.c \ + beri_disk_cfi.c \ + beri_disk_sdcard.c + +# Common code with boot2 +SRCS+= altera_jtag_uart.c \ + cfi.c \ + sdcard.c + +# Since we don't have a backward compatibility issue, default to this on BERI. +CFLAGS+= -DBOOT_PROMPT_123 + +HELP_FILES+= help.mips + +# Always add MI sources +.include "${BOOTSRC}/loader.mk" + +# BERI files common to boot2 and loader +.PATH: ${BOOTSRC}/mips/beri/common +CFLAGS+= -I${BOOTSRC}/mips/beri/common + +# Loader-specific MD headers +CFLAGS+= -I${.CURDIR} + +# Generate code appropriate for the loader environment +CFLAGS+= -G0 \ + -fno-pic \ + -mno-abicalls \ + -msoft-float \ + -g + +LDFLAGS= -nostdlib \ + -static \ + -T ${.CURDIR}/loader.ldscript \ + -L${.CURDIR} \ + -e __start + +DPADD= ${LIBFICL} ${LIBSA} +LDADD= ${LIBFICL} ${LIBSA} + +.if defined(LOADER_USB_SUPPORT) +# Do garbage collection +CFLAGS+= -ffunction-sections -fdata-sections +CFLAGS+= -Wl,--gc-sections +# Link USB BOOT library +LDADD+= ${BOOTOBJ}/usb/libusbboot.a +CFLAGS+= -I${BOOTSRC}/usb +# Define USB SUPPORT +CFLAGS+= -DLOADER_USB_SUPPORT +.endif + +all: loader + +.include <bsd.prog.mk> diff --git a/stand/mips/beri/loader/arch.c b/stand/mips/beri/loader/arch.c new file mode 100644 index 0000000..5ce8ede --- /dev/null +++ b/stand/mips/beri/loader/arch.c @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2013 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <machine/elf.h> + +#include <stand.h> +#include <bootstrap.h> +#include <loader.h> +#include <mips.h> + +static int beri_arch_autoload(void); +static ssize_t beri_arch_copyin(const void *src, vm_offset_t va, size_t len); +static ssize_t beri_arch_copyout(vm_offset_t va, void *dst, size_t len); +static uint64_t beri_arch_loadaddr(u_int type, void *data, uint64_t addr); +static ssize_t beri_arch_readin(int fd, vm_offset_t va, size_t len); + +struct arch_switch archsw = { + .arch_autoload = beri_arch_autoload, + .arch_getdev = beri_arch_getdev, + .arch_copyin = beri_arch_copyin, + .arch_copyout = beri_arch_copyout, + .arch_loadaddr = beri_arch_loadaddr, + .arch_readin = beri_arch_readin, + +}; + +static int +beri_arch_autoload(void) +{ + + return (0); +} + +static ssize_t +beri_arch_copyin(const void *src, vm_offset_t va, size_t len) +{ + + memcpy((void *)va, src, len); + return (len); +} + +static ssize_t +beri_arch_copyout(vm_offset_t va, void *dst, size_t len) +{ + + memcpy(dst, (void *)va, len); + return (len); +} + +static uint64_t +beri_arch_loadaddr(u_int type, void *data, uint64_t addr) +{ + uint64_t align; + + /* Align ELF objects at page boundaries; others at cache lines. */ + align = (type == LOAD_ELF) ? PAGE_SIZE : CACHE_LINE_SIZE; + return (roundup2(addr, align)); +} + +static ssize_t +beri_arch_readin(int fd, vm_offset_t va, size_t len) +{ + + return (read(fd, (void *)va, len)); +} diff --git a/stand/mips/beri/loader/beri_console.c b/stand/mips/beri/loader/beri_console.c new file mode 100644 index 0000000..9a4ae19 --- /dev/null +++ b/stand/mips/beri/loader/beri_console.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2013 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <bootstrap.h> + +#include <cons.h> + +static void c_probe(struct console *); +static int c_init(int); +static void c_out(int); +static int c_in(void); +static int c_ready(void); + +struct console altera_jtag_uart_console = { + .c_name = "comconsole", + .c_desc = "altera jtag uart", + .c_flags = 0, + .c_probe = c_probe, + .c_init = c_init, + .c_out = c_out, + .c_in = c_in, + .c_ready = c_ready, +}; + +static void +c_probe(struct console *cp) +{ + + cp->c_flags |= C_PRESENTIN|C_PRESENTOUT; +} + +static int +c_init(int arg) +{ + + return (0); +} + +static void +c_out(int c) +{ + + putc(c); +} + +static int +c_in(void) +{ + + return (getc()); +} + +static int +c_ready(void) +{ + + return (keyhit(0)); +} diff --git a/stand/mips/beri/loader/beri_disk_cfi.c b/stand/mips/beri/loader/beri_disk_cfi.c new file mode 100644 index 0000000..a21947f --- /dev/null +++ b/stand/mips/beri/loader/beri_disk_cfi.c @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2013-2014 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <bootstrap.h> +#include <stdarg.h> + +#include <stand.h> +#include <disk.h> + +#include <cfi.h> + +static int beri_cfi_disk_init(void); +static int beri_cfi_disk_open(struct open_file *, ...); +static int beri_cfi_disk_close(struct open_file *); +static int beri_cfi_disk_strategy(void *, int, daddr_t, size_t, + char *, size_t *); +static int beri_cfi_disk_print(int); + +struct devsw beri_cfi_disk = { + .dv_name = "cfi", + .dv_type = DEVT_DISK, + .dv_init = beri_cfi_disk_init, + .dv_strategy = beri_cfi_disk_strategy, + .dv_open = beri_cfi_disk_open, + .dv_close = beri_cfi_disk_close, + .dv_ioctl = noioctl, + .dv_print = beri_cfi_disk_print, + .dv_cleanup = NULL, +}; + +static int +beri_cfi_disk_init(void) +{ + + return (0); +} + +static int +beri_cfi_disk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, + char *buf, size_t *rsizep) +{ + int error; + + flag &= F_MASK; + if (flag == F_WRITE) + return (EROFS); + if (flag != F_READ) + return (EINVAL); + if (rsizep != NULL) + *rsizep = 0; + error = cfi_read(buf, dblk, size >> 9); + if (error == 0 && rsizep != NULL) + *rsizep = size; + else if (error != 0) + printf("%s: error %d\n", __func__, error); + return (error); +} + +static int +beri_cfi_disk_open(struct open_file *f, ...) +{ + va_list ap; + struct disk_devdesc *dev; + + va_start(ap, f); + dev = va_arg(ap, struct disk_devdesc *); + va_end(ap); + + if (dev->d_unit != 0) + return (EIO); + return (disk_open(dev, cfi_get_mediasize(), cfi_get_sectorsize())); +} + +static int +beri_cfi_disk_close(struct open_file *f) +{ + struct disk_devdesc *dev; + + dev = (struct disk_devdesc *)f->f_devdata; + return (disk_close(dev)); +} + +static int +beri_cfi_disk_print(int verbose) +{ + struct disk_devdesc dev; + char line[80]; + int ret; + + printf("%s devices:", beri_cfi_disk.dv_name); + if ((ret = pager_output("\n")) != 0) + return (ret); + + snprintf(line, sizeof(line), " cfi%d CFI flash device\n", 0); + ret = pager_output(line); + if (ret != 0) + return (ret); + dev.d_dev = &beri_cfi_disk; + dev.d_unit = 0; + dev.d_slice = -1; + dev.d_partition = -1; + if (disk_open(&dev, cfi_get_mediasize(), cfi_get_sectorsize()) == 0) { + snprintf(line, sizeof(line), " cfi%d", 0); + ret = disk_print(&dev, line, verbose); + disk_close(&dev); + } + + return (ret); +} diff --git a/stand/mips/beri/loader/beri_disk_sdcard.c b/stand/mips/beri/loader/beri_disk_sdcard.c new file mode 100644 index 0000000..266fb4a --- /dev/null +++ b/stand/mips/beri/loader/beri_disk_sdcard.c @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 2013-2014 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <bootstrap.h> +#include <stdarg.h> + +#include <stand.h> +#include <disk.h> + +#include <sdcard.h> + +static int beri_sdcard_disk_init(void); +static int beri_sdcard_disk_open(struct open_file *, ...); +static int beri_sdcard_disk_close(struct open_file *); +static int beri_sdcard_disk_strategy(void *, int, daddr_t, size_t, + char *, size_t *); +static int beri_sdcard_disk_print(int); + +struct devsw beri_sdcard_disk = { + .dv_name = "sdcard", + .dv_type = DEVT_DISK, + .dv_init = beri_sdcard_disk_init, + .dv_strategy = beri_sdcard_disk_strategy, + .dv_open = beri_sdcard_disk_open, + .dv_close = beri_sdcard_disk_close, + .dv_ioctl = noioctl, + .dv_print = beri_sdcard_disk_print, + .dv_cleanup = NULL, +}; + +static int +beri_sdcard_disk_init(void) +{ + + return (0); +} + +static int +beri_sdcard_disk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, + char *buf, size_t *rsizep) +{ + int error; + + flag &= F_MASK; + if (flag == F_WRITE) + return (EROFS); + if (flag != F_READ) + return (EINVAL); + if (rsizep != NULL) + *rsizep = 0; + error = altera_sdcard_read(buf, dblk, size >> 9); + if (error == 0 && rsizep != NULL) + *rsizep = size; + else if (error != 0) + printf("%s: error %d\n", __func__, error); + return (error); +} + +static int +beri_sdcard_disk_open(struct open_file *f, ...) +{ + va_list ap; + struct disk_devdesc *dev; + + va_start(ap, f); + dev = va_arg(ap, struct disk_devdesc *); + va_end(ap); + + if (!(altera_sdcard_get_present())) { + printf("SD card not present or not supported\n"); + return (ENXIO); + } + + if (dev->d_unit != 0) + return (EIO); + return (disk_open(dev, altera_sdcard_get_mediasize(), + altera_sdcard_get_sectorsize())); +} + +static int +beri_sdcard_disk_close(struct open_file *f) +{ + struct disk_devdesc *dev; + + dev = (struct disk_devdesc *)f->f_devdata; + return (disk_close(dev)); +} + +static int +beri_sdcard_disk_print(int verbose) +{ + struct disk_devdesc dev; + char line[80]; + int ret; + + printf("%s devices:", beri_sdcard_disk.dv_name); + if ((ret = pager_output("\n")) != 0) + return (ret); + + snprintf(line, sizeof(line), " sdcard%d Altera SD card drive\n", 0); + ret = pager_output(line); + if (ret != 0) + return (ret); + dev.d_dev = &beri_sdcard_disk; + dev.d_unit = 0; + dev.d_slice = -1; + dev.d_partition = -1; + if (disk_open(&dev, altera_sdcard_get_mediasize(), + altera_sdcard_get_sectorsize()) == 0) { + snprintf(line, sizeof(line), " sdcard%d", 0); + ret = disk_print(&dev, line, verbose); + disk_close(&dev); + } + return (ret); +} diff --git a/stand/mips/beri/loader/devicename.c b/stand/mips/beri/loader/devicename.c new file mode 100644 index 0000000..4a2c273 --- /dev/null +++ b/stand/mips/beri/loader/devicename.c @@ -0,0 +1,205 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> + +#include "bootstrap.h" +#include "disk.h" + +static int beri_arch_parsedev(struct disk_devdesc **dev, + const char *devspec, const char **path); + +/* + * Point (dev) at an allocated device specifier for the device matching the + * path in (devspec). If it contains an explicit device specification, + * use that. If not, use the default device. + */ +int +beri_arch_getdev(void **vdev, const char *devspec, const char **path) +{ + struct disk_devdesc **dev = (struct disk_devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no + * device, go with the current device. + */ + if ((devspec == NULL) || + (devspec[0] == '/') || + (strchr(devspec, ':') == NULL)) { + + if (((rv = beri_arch_parsedev(dev, getenv("currdev"), NULL)) == 0) && + (path != NULL)) + *path = devspec; + return(rv); + } + + /* + * Try to parse the device name off the beginning of the devspec + */ + return(beri_arch_parsedev(dev, devspec, path)); +} + +/* + * Point (dev) at an allocated device specifier matching the string version + * at the beginning of (devspec). Return a pointer to the remaining + * text in (path). + * + * In all cases, the beginning of (devspec) is compared to the names + * of known devices in the device switch, and then any following text + * is parsed according to the rules applied to the device type. + * + * For disk-type devices, the syntax is: + * + * disk<unit>[s<slice>][<partition>]: + * + */ +static int +beri_arch_parsedev(struct disk_devdesc **dev, const char *devspec, + const char **path) +{ + struct disk_devdesc *idev; + struct devsw *dv; + int i, unit, err; + const char *cp; + const char *np; + + /* minimum length check */ + if (strlen(devspec) < 2) + return(EINVAL); + + /* look for a device that matches */ + for (i = 0, dv = NULL; devsw[i] != NULL; i++) { + if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) { + dv = devsw[i]; + break; + } + } + if (dv == NULL) + return(ENOENT); + idev = malloc(sizeof(struct disk_devdesc)); + err = 0; + np = (devspec + strlen(dv->dv_name)); + + switch(dv->dv_type) { + case DEVT_NONE: /* XXX what to do here? Do we care? */ + break; + + case DEVT_DISK: + err = disk_parsedev(idev, np, path); + if (err != 0) + goto fail; + break; + + case DEVT_CD: + case DEVT_NET: + case DEVT_ZFS: + unit = 0; + + if (*np && (*np != ':')) { + unit = strtol(np, &cp, 0); /* get unit number if present */ + if (cp == np) { + err = EUNIT; + goto fail; + } + } else { + cp = np; + } + if (*cp && (*cp != ':')) { + err = EINVAL; + goto fail; + } + + idev->d_unit = unit; + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + break; + + default: + err = EINVAL; + goto fail; + } + idev->d_dev = dv; + idev->d_type = dv->dv_type; + if (dev == NULL) { + free(idev); + } else { + *dev = idev; + } + return(0); + + fail: + free(idev); + return(err); +} + + +char * +beri_arch_fmtdev(void *vdev) +{ + struct disk_devdesc *dev = (struct disk_devdesc *)vdev; + static char buf[128]; /* XXX device length constant? */ + + switch(dev->d_type) { + case DEVT_NONE: + strcpy(buf, "(no device)"); + break; + + case DEVT_CD: + sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + break; + + case DEVT_DISK: + return (disk_fmtdev(vdev)); + + case DEVT_NET: + case DEVT_ZFS: + sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + break; + } + return(buf); +} + + +/* + * Set currdev to suit the value being supplied in (value) + */ +int +beri_arch_setcurrdev(struct env_var *ev, int flags, const void *value) +{ + struct disk_devdesc *ncurr; + int rv; + + if ((rv = beri_arch_parsedev(&ncurr, value, NULL)) != 0) + return(rv); + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return(0); +} diff --git a/stand/mips/beri/loader/exec.c b/stand/mips/beri/loader/exec.c new file mode 100644 index 0000000..382b6a1 --- /dev/null +++ b/stand/mips/beri/loader/exec.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2013-2014 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker.h> + +#include <machine/bootinfo.h> +#include <machine/elf.h> + +#include <bootstrap.h> +#include <loader.h> +#include <mips.h> +#include <stand.h> + +static int beri_elf64_loadfile(char *, uint64_t, + struct preloaded_file **); +static int beri_elf64_exec(struct preloaded_file *fp); + +struct file_format beri_elf = { + .l_load = beri_elf64_loadfile, + .l_exec = beri_elf64_exec, +}; + +/* + * bootinfo that we will pass onto the kernel; some fields derived from + * *boot2_bootinfop, others filled in by loader. + */ +struct bootinfo bootinfo; + +static int +beri_elf64_loadfile(char *filename, uint64_t dest, + struct preloaded_file **result) +{ + + /* + * Some platforms require invalidation of instruction caches here; we + * don't need that currently. + */ + return (__elfN(loadfile)(filename, dest, result)); +} + +static int +beri_elf64_exec(struct preloaded_file *fp) +{ + void (*entry)(register_t, register_t, register_t, register_t); + struct file_metadata *md; + vm_offset_t mdp; + Elf_Ehdr *ehdr; + int error; + + md = file_findmetadata(fp, MODINFOMD_ELFHDR); + if (md == NULL) { + printf("%s: file_findmetadata failed\n"); + return (EFTYPE); + } + ehdr = (Elf_Ehdr *)md->md_data; + + error = md_load64(fp->f_args, &mdp); + if (error) { + printf("%s: md_load64 failed\n"); + return (error); + } + + entry = (void *)ehdr->e_entry; + printf("Kernel entry at %p\n", entry); + + dev_cleanup(); /* XXXRW: Required? */ + printf("Kernel args: %s\n", fp->f_args); + + /* + * Configure bootinfo for the loaded kernel. Some values are + * inherited from the bootinfo passed to us by boot2 (e.g., DTB + * pointer); others are local to the loader (e.g., kernel boot flags). + */ + bzero(&bootinfo, sizeof(bootinfo)); + bootinfo.bi_version = BOOTINFO_VERSION; + bootinfo.bi_size = sizeof(bootinfo); + bootinfo.bi_boot2opts = boot2_bootinfo.bi_boot2opts; + /* NB: bi_kernelname used only by boot2. */ + /* NB: bi_nfs_diskless not yet. */ + bootinfo.bi_dtb = boot2_bootinfo.bi_dtb; + bootinfo.bi_memsize = boot2_bootinfo.bi_memsize; + bootinfo.bi_modulep = mdp; + + /* + * XXXRW: For now, pass 'memsize' rather than dtb or bootinfo. This + * is the 'old' ABI spoken by Miniboot and the kernel. To pass in + * boot2opts, modules, etc, we will need to fix this to pass in at + * least bootinfop. + */ + (*entry)(boot2_argc, (register_t)boot2_argv, (register_t)boot2_envv, + &bootinfo); + + panic("exec returned"); +} diff --git a/stand/mips/beri/loader/help.mips b/stand/mips/beri/loader/help.mips new file mode 100644 index 0000000..5873eb0 --- /dev/null +++ b/stand/mips/beri/loader/help.mips @@ -0,0 +1 @@ +$FreeBSD$ diff --git a/stand/mips/beri/loader/loader.h b/stand/mips/beri/loader/loader.h new file mode 100644 index 0000000..e4152e7 --- /dev/null +++ b/stand/mips/beri/loader/loader.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2013-2014 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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$ + */ + +#ifndef _BOOT_LOADER_H_ +#define _BOOT_LOADER_H_ + +/* beri_console.c */ +extern struct console altera_jtag_uart_console; + +/* beri_disk.c */ +extern struct devsw beri_cfi_disk; +extern struct devsw beri_sdcard_disk; + +/* devicename.c */ +int beri_arch_setcurrdev(struct env_var *, int, const void *); +char *beri_arch_fmtdev(void *); +int beri_arch_getdev(void **, const char *, const char **); + +/* exec.c */ +extern struct file_format beri_elf; + +/* main.c */ +extern int boot2_argc; +extern char **boot2_argv; +extern char **boot2_envv; +extern struct bootinfo boot2_bootinfo; + +/* metadata.c */ +int md_load64(char *args, vm_offset_t *modulep); + +/* vers.c */ +extern char bootprog_info[]; + +#endif /* !_BOOT_LOADER_H_ */ diff --git a/stand/mips/beri/loader/loader.ldscript b/stand/mips/beri/loader/loader.ldscript new file mode 100644 index 0000000..deb4865 --- /dev/null +++ b/stand/mips/beri/loader/loader.ldscript @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2011-2014 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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$ + */ + +INCLUDE ../common/common.ldscript + +/* + * Location where loader will execute. + */ +__loader_base__ = 0x20000; +__loader_base_vaddr__ = __mips64_xkphys_cached__ + __loader_base__; + +/* + * Highest address the loader is allowed to use below the kernel. + */ +__loader_end__ = 0x100000; +__loader_end_vaddr__ = __mips64_xkphys_cached__ + __loader_end__; + +OUTPUT_ARCH(mips) +ENTRY(start) +SECTIONS +{ + /* + * We rely on boot2 having (a) configured a stack, and (b) loaded us + * to an appropriate bit of physical/virtual memory such that no + * self-relocating code is required here. + */ + . = __loader_base_vaddr__; + . += SIZEOF_HEADERS; + + .text ALIGN(0x10): { + start.o(.text*) + *(EXCLUDE_FILE (start.o) .text*) + *(.rodata*) + + __start_set_Xcommand_set = .; + KEEP(*(set_Xcommand_set)) + __stop_set_Xcommand_set = .; + + __start_set_Xficl_compile_set = .; + KEEP(*(set_Xficl_compile_set)) + __stop_set_Xficl_compile_set = .; + } + .data ALIGN(0x10): { *(.data*)} + .bss ALIGN(0x10): { *(.bss*) } + + __heap = ALIGN(0x8); /* 64-bit aligned heap pointer */ + __data_end = .; + __boot_loader_len__ = . - __loader_base_vaddr__; + __bss_start = ADDR(.bss); + __bss_end = ALIGN(__bss_start + SIZEOF(.bss), 0x8); + + __heap_start = .; + __heap_end = __loader_end_vaddr__; + __heap_len = __heap_end - __heap_start; +} diff --git a/stand/mips/beri/loader/main.c b/stand/mips/beri/loader/main.c new file mode 100644 index 0000000..2d201d8 --- /dev/null +++ b/stand/mips/beri/loader/main.c @@ -0,0 +1,244 @@ +/*- + * Copyright (c) 2013-2014 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker.h> +#include <sys/reboot.h> + +#include <machine/bootinfo.h> +#include <machine/elf.h> + +#include <stand.h> +#include <bootstrap.h> +#include <loader.h> +#include <mips.h> + +#ifdef LOADER_USB_SUPPORT +#include <storage/umass_common.h> +#endif + +static int __elfN(exec)(struct preloaded_file *); +static void extract_currdev(struct bootinfo *); + +struct devsw *devsw[] = { + &beri_cfi_disk, + &beri_sdcard_disk, +#ifdef LOADER_USB_SUPPORT + &umass_disk, +#endif + NULL +}; + +struct arch_switch archsw; + +struct file_format *file_formats[] = { + &beri_elf, + NULL +}; + +struct fs_ops *file_system[] = { +#ifdef LOADER_UFS_SUPPORT + &ufs_fsops, +#endif + NULL +}; + +struct console *consoles[] = { + &altera_jtag_uart_console, + NULL +}; + +extern void __bss_start, __bss_end; +extern void __heap_start, __heap_end; + +static int +__elfN(exec)(struct preloaded_file *fp) +{ + + return (EFTYPE); +} + +/* + * Capture arguments from boot2 for later reuse when launching the kernel. + * Note that we choose not to maintain a pointer to boo2_bootinfop after + * initial argument processing: this is because we might load the kernel over + * the spot where boot2 was running, so we can't pass that pointer on to the + * kernel. To be on the safe side, never reference it outside of the body of + * main(), instead preserving a copy. + */ +int boot2_argc; +char **boot2_argv; +char **boot2_envv; + +struct bootinfo boot2_bootinfo; + +int +main(int argc, char *argv[], char *envv[], struct bootinfo *bootinfop) +{ + struct devsw **dp; + + /* NB: Must be sure to bzero() before using any globals. */ + bzero(&__bss_start, (uintptr_t)&__bss_end - (uintptr_t)&__bss_start); + + boot2_argc = argc; + boot2_argv = argv; + boot2_envv = envv; + boot2_bootinfo = *bootinfop; /* Copy rather than by reference. */ + + setheap((void *)&__heap_start, (void *)&__heap_end); + + /* + * Pick up console settings from boot2; probe console. + */ + if (bootinfop->bi_boot2opts & RB_MULTIPLE) { + if (bootinfop->bi_boot2opts & RB_SERIAL) + setenv("console", "comconsole vidconsole", 1); + else + setenv("console", "vidconsole comconsole", 1); + } else if (bootinfop->bi_boot2opts & RB_SERIAL) + setenv("console", "comconsole", 1); + else if (bootinfop->bi_boot2opts & RB_MUTE) + setenv("console", "nullconsole", 1); + cons_probe(); + setenv("LINES", "24", 1); + + printf("%s(%d, %p, %p, %p (%p))\n", __func__, argc, argv, envv, + bootinfop, (void *)bootinfop->bi_memsize); + + /* + * Initialise devices. + */ + for (dp = devsw; *dp != NULL; dp++) { + if ((*dp)->dv_init != NULL) + (*dp)->dv_init(); + } + extract_currdev(bootinfop); + + printf("\n%s", bootprog_info); +#if 0 + printf("bootpath=\"%s\"\n", bootpath); +#endif + + interact(NULL); + return (0); +} + +static void +extract_currdev(struct bootinfo *bootinfop) +{ + const char *bootdev; + + /* + * Pick up boot device information from boot2. + * + * XXXRW: Someday: device units. + */ + switch(bootinfop->bi_boot_dev_type) { + case BOOTINFO_DEV_TYPE_DRAM: + bootdev = "dram0"; + break; + + case BOOTINFO_DEV_TYPE_CFI: + bootdev = "cfi0"; + break; + + case BOOTINFO_DEV_TYPE_SDCARD: + bootdev = "sdcard0"; + break; + + default: + bootdev = NULL; + } + + if (bootdev != NULL) { + env_setenv("currdev", EV_VOLATILE, bootdev, NULL, env_nounset); + env_setenv("loaddev", EV_VOLATILE, bootdev, env_noset, + env_nounset); + } +} + +void +abort(void) +{ + + printf("error: loader abort\n"); + while (1); +} + +void +exit(int code) +{ + + printf("error: loader exit\n"); + while (1); +} + +void +longjmperror(void) +{ + + printf("error: loader longjmp error\n"); + while (1); +} + +time_t +time(time_t *tloc) +{ + + /* We can't provide time since UTC, so just provide time since boot. */ + return (cp0_count_get() / 100000000); +} + +/* + * Delay - in usecs + * + * NOTE: We are assuming that the CPU is running at 100MHz. + */ +void +delay(int usecs) +{ + uint32_t delta; + uint32_t curr; + uint32_t last; + + last = cp0_count_get(); + while (usecs > 0) { + curr = cp0_count_get(); + delta = curr - last; + while (usecs > 0 && delta >= 100) { + usecs--; + last += 100; + delta -= 100; + } + } +} diff --git a/stand/mips/beri/loader/metadata.c b/stand/mips/beri/loader/metadata.c new file mode 100644 index 0000000..0698cd1 --- /dev/null +++ b/stand/mips/beri/loader/metadata.c @@ -0,0 +1,355 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6 + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/linker.h> + +#include <machine/metadata.h> + +#include "bootstrap.h" + +/* + * Return a 'boothowto' value corresponding to the kernel arguments in + * (kargs) and any relevant environment variables. + */ +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {"boot_askname", RB_ASKNAME}, + {"boot_cdrom", RB_CDROM}, + {"boot_ddb", RB_KDB}, + {"boot_dfltroot", RB_DFLTROOT}, + {"boot_gdb", RB_GDB}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_mute", RB_MUTE}, + {"boot_pause", RB_PAUSE}, + {"boot_serial", RB_SERIAL}, + {"boot_single", RB_SINGLE}, + {"boot_verbose", RB_VERBOSE}, + {NULL, 0} +}; + +int +md_getboothowto(char *kargs) +{ + char *cp; + int howto; + int active; + int i; + + /* Parse kargs */ + howto = 0; + if (kargs != NULL) { + cp = kargs; + active = 0; + while (*cp != 0) { + if (!active && (*cp == '-')) { + active = 1; + } else if (active) + switch (*cp) { + case 'a': + howto |= RB_ASKNAME; + break; + case 'C': + howto |= RB_CDROM; + break; + case 'd': + howto |= RB_KDB; + break; + case 'D': + howto |= RB_MULTIPLE; + break; + case 'm': + howto |= RB_MUTE; + break; + case 'g': + howto |= RB_GDB; + break; + case 'h': + howto |= RB_SERIAL; + break; + case 'p': + howto |= RB_PAUSE; + break; + case 'r': + howto |= RB_DFLTROOT; + break; + case 's': + howto |= RB_SINGLE; + break; + case 'v': + howto |= RB_VERBOSE; + break; + default: + active = 0; + break; + } + cp++; + } + } + /* get equivalents from the environment */ + for (i = 0; howto_names[i].ev != NULL; i++) + if (getenv(howto_names[i].ev) != NULL) + howto |= howto_names[i].mask; + if (!strcmp(getenv("console"), "comconsole")) + howto |= RB_SERIAL; + if (!strcmp(getenv("console"), "nullconsole")) + howto |= RB_MUTE; + 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 +md_copyenv(vm_offset_t addr) +{ + struct env_var *ep; + + /* traverse the environment */ + for (ep = environ; ep != NULL; ep = ep->ev_next) { + archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); + addr += strlen(ep->ev_name); + archsw.arch_copyin("=", addr, 1); + addr++; + if (ep->ev_value != NULL) { + archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value)); + addr += strlen(ep->ev_value); + } + archsw.arch_copyin("", addr, 1); + addr++; + } + archsw.arch_copyin("", addr, 1); + addr++; + return(addr); +} + +/* + * Copy module-related data into the load area, where it can be + * used as a directory for loaded modules. + * + * Module data is presented in a self-describing format. Each datum + * is preceded by a 32-bit identifier and a 32-bit size field. + * + * Currently, the following data are saved: + * + * MOD_NAME (variable) module name (string) + * MOD_TYPE (variable) module type (string) + * MOD_ARGS (variable) module parameters (string) + * MOD_ADDR sizeof(vm_offset_t) module load address + * MOD_SIZE sizeof(size_t) module size + * MOD_METADATA (variable) type-specific metadata + */ + +static int align; + +#define COPY32(v, a, c) { \ + u_int32_t x = (v); \ + if (c) \ + archsw.arch_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(strlen(s) + 1, a, c) \ + if (c) \ + archsw.arch_copyin(s, a, strlen(s) + 1);\ + a += roundup(strlen(s) + 1, align); \ +} + +#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) +#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) +#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) + +#define MOD_VAR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(sizeof(s), a, c); \ + if (c) \ + archsw.arch_copyin(&s, a, sizeof(s)); \ + a += roundup(sizeof(s), align); \ +} + +#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) +#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) + +#define MOD_METADATA(a, mm, c) { \ + COPY32(MODINFO_METADATA | mm->md_type, a, c);\ + COPY32(mm->md_size, a, c); \ + if (c) \ + archsw.arch_copyin(mm->md_data, a, mm->md_size);\ + a += roundup(mm->md_size, align); \ +} + +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ +} + +vm_offset_t +md_copymodules(vm_offset_t addr, int kern64) +{ + struct preloaded_file *fp; + struct file_metadata *md; + uint64_t scratch64; + int c; + + c = addr != 0; + /* start with the first module on the list, should be the kernel */ + for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { + + MOD_NAME(addr, fp->f_name, c); /* this field must come first */ + MOD_TYPE(addr, fp->f_type, c); + if (fp->f_args) + MOD_ARGS(addr, fp->f_args, c); + if (kern64) { + scratch64 = fp->f_addr; + MOD_ADDR(addr, scratch64, c); + scratch64 = fp->f_size; + MOD_SIZE(addr, scratch64, c); + } else { + MOD_ADDR(addr, fp->f_addr, c); + MOD_SIZE(addr, fp->f_size, c); + } + for (md = fp->f_metadata; md != NULL; md = md->md_next) { + if (!(md->md_type & MODINFOMD_NOCOPY)) { + MOD_METADATA(addr, md, c); + } + } + } + MOD_END(addr, c); + return(addr); +} + +/* + * Load the information expected by a powerpc kernel. + * + * - The 'boothowto' argument is constructed + * - The 'bootdev' argument is constructed + * - The kernel environment is copied into kernel space. + * - Module metadata are formatted and placed in kernel space. + */ +int +md_load_dual(char *args, vm_offset_t *modulep, int kern64) +{ + struct preloaded_file *kfp; + struct preloaded_file *xp; + struct file_metadata *md; + vm_offset_t kernend; + vm_offset_t addr; + vm_offset_t envp; + vm_offset_t size; + uint64_t scratch64; + char *rootdevname; + int howto; + + align = kern64 ? 8 : 4; + howto = md_getboothowto(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"); + if (rootdevname == NULL) + rootdevname = getenv("currdev"); + /* Try reading the /etc/fstab file to select the root device */ + getrootmount(rootdevname); + + /* 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; + } + /* pad to a page boundary */ + addr = roundup(addr, PAGE_SIZE); + + /* copy our environment */ + envp = addr; + addr = md_copyenv(addr); + + /* pad to a page boundary */ + addr = roundup(addr, PAGE_SIZE); + + kernend = 0; + kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel"); + if (kfp == NULL) + kfp = file_findfile(NULL, "elf kernel"); + if (kfp == NULL) + panic("can't find kernel file"); + file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); + if (kern64) { + scratch64 = envp; + file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64); + scratch64 = kernend; + file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64); + } else { + file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); + file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); + } + + *modulep = addr; + size = md_copymodules(0, kern64); + kernend = roundup(addr + size, PAGE_SIZE); + + md = file_findmetadata(kfp, MODINFOMD_KERNEND); + if (kern64) { + scratch64 = kernend; + bcopy(&scratch64, md->md_data, sizeof scratch64); + } else { + bcopy(&kernend, md->md_data, sizeof kernend); + } + + (void)md_copymodules(addr, kern64); + + return(0); +} + +int +md_load(char *args, vm_offset_t *modulep) +{ + return (md_load_dual(args, modulep, 0)); +} + +int +md_load64(char *args, vm_offset_t *modulep) +{ + return (md_load_dual(args, modulep, 1)); +} + diff --git a/stand/mips/beri/loader/start.S b/stand/mips/beri/loader/start.S new file mode 100644 index 0000000..d679caa --- /dev/null +++ b/stand/mips/beri/loader/start.S @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2013 Robert N. M. Watson + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 <machine/asm.h> +__FBSDID("$FreeBSD$"); + +.set mips64 +.set noreorder +.set nobopt +.set noat + +ASM_ENTRY(__start) +VECTOR(_loader_start, unknown) + /* Not much here yet. */ + jal main + nop + + /* If main() returns, spin. */ +loop: + b loop + nop +VECTOR_END(_loader_start) diff --git a/stand/mips/beri/loader/version b/stand/mips/beri/loader/version new file mode 100644 index 0000000..ce8e187 --- /dev/null +++ b/stand/mips/beri/loader/version @@ -0,0 +1,6 @@ +$FreeBSD$ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important. Make sure the current version number is on line 6. + +0.1: Initial MIPS version |