summaryrefslogtreecommitdiffstats
path: root/stand/mips/beri/loader
diff options
context:
space:
mode:
authorkevans <kevans@FreeBSD.org>2018-02-12 01:08:44 +0000
committerkevans <kevans@FreeBSD.org>2018-02-12 01:08:44 +0000
commit7d97ee5b28b409c00bfaf12daf5ab497a6038b9d (patch)
tree245306b754606bcf49c0ff17b131b58609b6c7a6 /stand/mips/beri/loader
parent43b278e1b66cf4de337a17034087ea785031bd6f (diff)
downloadFreeBSD-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/Makefile111
-rw-r--r--stand/mips/beri/loader/arch.c97
-rw-r--r--stand/mips/beri/loader/beri_console.c90
-rw-r--r--stand/mips/beri/loader/beri_disk_cfi.c141
-rw-r--r--stand/mips/beri/loader/beri_disk_sdcard.c147
-rw-r--r--stand/mips/beri/loader/devicename.c205
-rw-r--r--stand/mips/beri/loader/exec.c125
-rw-r--r--stand/mips/beri/loader/help.mips1
-rw-r--r--stand/mips/beri/loader/loader.h63
-rw-r--r--stand/mips/beri/loader/loader.ldscript84
-rw-r--r--stand/mips/beri/loader/main.c244
-rw-r--r--stand/mips/beri/loader/metadata.c355
-rw-r--r--stand/mips/beri/loader/start.S49
-rw-r--r--stand/mips/beri/loader/version6
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
OpenPOWER on IntegriCloud