diff options
Diffstat (limited to 'stand/mips')
40 files changed, 4222 insertions, 0 deletions
diff --git a/stand/mips/Makefile b/stand/mips/Makefile new file mode 100644 index 0000000..760c557 --- /dev/null +++ b/stand/mips/Makefile @@ -0,0 +1,14 @@ +# $FreeBSD$ + +SUBDIR= uboot + +# +# The BERI boot loader port works only on 64-bit MIPS; not a hard port to +# 32-bit if someone is interested. Build on all 64-bit MIPS platforms to +# ensure it gets adequate build-test coverage. +# +.if ${MACHINE_ARCH} == "mips64" +SUBDIR+= beri +.endif + +.include <bsd.subdir.mk> diff --git a/stand/mips/Makefile.inc b/stand/mips/Makefile.inc new file mode 100644 index 0000000..265f86d --- /dev/null +++ b/stand/mips/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +.include "../Makefile.inc" diff --git a/stand/mips/beri/Makefile b/stand/mips/beri/Makefile new file mode 100644 index 0000000..afcb538 --- /dev/null +++ b/stand/mips/beri/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= boot2 loader + +.include <bsd.subdir.mk> diff --git a/stand/mips/beri/Makefile.inc b/stand/mips/beri/Makefile.inc new file mode 100644 index 0000000..a12699c --- /dev/null +++ b/stand/mips/beri/Makefile.inc @@ -0,0 +1,6 @@ +# $FreeBSD$ + +CFLAGS+= -ffreestanding +LDFLAGS+= -nostdlib + +.include "../Makefile.inc" diff --git a/stand/mips/beri/boot2/Makefile b/stand/mips/beri/boot2/Makefile new file mode 100644 index 0000000..d369340 --- /dev/null +++ b/stand/mips/beri/boot2/Makefile @@ -0,0 +1,86 @@ +#- +# 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$ + +.include <bsd.init.mk> + +INSTALLFLAGS= -b + +LOADERS= flashboot jtagboot +FILES= ${LOADERS} ${LOADERS:S/$/.md5/} + +SRCS= relocate.S \ + start.S \ + boot2.c \ + altera_jtag_uart.c \ + cfi.c \ + sdcard.c + +MAN= + +AFLAGS= -G0 + +CFLAGS= -ffreestanding \ + -I${.CURDIR} \ + -I${SASRC} \ + -I${LDRSRC} \ + -D_KERNEL \ + -Wall \ + -G0 \ + -fno-pic -mno-abicalls \ + -msoft-float \ + -g + +LDFLAGS= -nostdlib \ + -static \ + -Wl,-N \ + -G0 \ + -L${.CURDIR} + +.PATH: ${BOOTSRC}/mips/beri/common +CFLAGS+= -I${BOOTSRC}/mips/beri/common + +flashboot.elf: relocate.o start.o boot2.o altera_jtag_uart.o cfi.o sdcard.o + ${CC} ${LDFLAGS} -T ${.CURDIR}/flashboot.ldscript -o ${.TARGET} \ + ${.ALLSRC} ${LIBSA} +flashboot: flashboot.elf + ${OBJCOPY} -S -O binary ${.TARGET}.elf ${.TARGET} +flashboot.md5: flashboot + md5 flashboot > flashboot.md5 + +jtagboot: start.o boot2.o altera_jtag_uart.o cfi.o sdcard.o + ${CC} ${LDFLAGS} -T ${.CURDIR}/jtagboot.ldscript -o ${.TARGET} \ + ${.ALLSRC} ${LIBSA} +jtagboot.md5: jtagboot + md5 jtagboot > jtagboot.md5 + +CLEANFILES+= flashboot.elf + +.include <bsd.prog.mk> diff --git a/stand/mips/beri/boot2/boot2.c b/stand/mips/beri/boot2/boot2.c new file mode 100644 index 0000000..3db33c4 --- /dev/null +++ b/stand/mips/beri/boot2/boot2.c @@ -0,0 +1,661 @@ +/*- + * 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. + * + * Copyright (c) 1998 Robert Nordier + * All rights reserved. + * + * Redistribution and use in source and binary forms are freely + * permitted provided that the above copyright notice and this + * paragraph and the following disclaimer are duplicated in all + * such forms. + * + * This software is provided "AS IS" and without any express or + * implied warranties, including, without limitation, the implied + * warranties of merchantability and fitness for a particular + * purpose. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/disklabel.h> +#include <sys/diskmbr.h> +#include <sys/dirent.h> +#include <sys/endian.h> +#include <sys/reboot.h> + +#include <machine/bootinfo.h> +#include <machine/elf.h> + +#include <stand.h> +#include <stdarg.h> +#include <string.h> + +#include <beri.h> +#include <cfi.h> +#include <cons.h> +#include <mips.h> +#include <sdcard.h> + +#include "paths.h" +#include "rbx.h" + +static int beri_argc; +static const char **beri_argv, **beri_envv; +static uint64_t beri_memsize; + +#define IO_KEYBOARD 1 +#define IO_SERIAL 2 + +#define SECOND 1 /* Circa that many ticks in a second. */ + +#define ARGS 0x900 +#define NOPT 14 +#define MEM_BASE 0x12 +#define MEM_EXT 0x15 + +/* + * XXXRW: I think this has to do with whether boot2 expects a partition + * table? + */ +#define DRV_HARD 0x80 +#define DRV_MASK 0x7f + +/* Default to using CFI flash. */ +#define TYPE_DEFAULT BOOTINFO_DEV_TYPE_SDCARD + +/* Hard-coded assumption about location of JTAG-loaded kernel. */ +#define DRAM_KERNEL_ADDR ((void *)mips_phys_to_cached(0x20000)) + +extern uint32_t _end; + +static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ +static const unsigned char flags[NOPT] = { + RBX_DUAL, + RBX_SERIAL, + RBX_ASKNAME, + RBX_CDROM, + RBX_CONFIG, + RBX_KDB, + RBX_GDB, + RBX_MUTE, + RBX_NOINTR, + RBX_PAUSE, + RBX_QUIET, + RBX_DFLTROOT, + RBX_SINGLE, + RBX_VERBOSE +}; + +/* These must match BOOTINFO_DEV_TYPE constants. */ +static const char *const dev_nm[] = {"dram", "cfi", "sdcard"}; +static const u_int dev_nm_count = nitems(dev_nm); + +static struct dmadat __dmadat; + +static struct dsk { + unsigned type; /* BOOTINFO_DEV_TYPE_x object type. */ + uintptr_t unitptr; /* Unit number or pointer to object. */ + uint8_t slice; + uint8_t part; +#if 0 + unsigned start; + int init; +#endif +} dsk; +static char cmd[512], cmddup[512], knamebuf[1024]; +static const char *kname; +uint32_t opts; +#if 0 +static int comspeed = SIOSPD; +#endif +struct bootinfo bootinfo; +static uint8_t ioctrl = IO_KEYBOARD; + +void exit(int); +void putchar(int); +static void boot_fromdram(void); +static void boot_fromfs(void); +static void load(void); +static int parse(void); +static int dskread(void *, unsigned, unsigned); +static int xputc(int); +static int xgetc(int); + + +#define UFS_SMALL_CGBASE +#include "ufsread.c" + +static inline int +xfsread(ufs_ino_t inode, void *buf, size_t nbyte) +{ + if ((size_t)fsread(inode, buf, nbyte) != nbyte) { + printf("Invalid %s\n", "format"); + return -1; + } + return 0; +} + +static inline void +getstr(void) +{ + char *s; + int c; + + s = cmd; + for (;;) { + switch (c = xgetc(0)) { + case 0: + break; + case '\177': + case '\b': + if (s > cmd) { + s--; + printf("\b \b"); + } + break; + case '\n': + case '\r': + putchar('\n'); + *s = 0; + return; + default: + if (s - cmd < sizeof(cmd) - 1) + *s++ = c; + putchar(c); + } + } +} + +int +main(u_int argc, const char *argv[], const char *envv[], uint64_t memsize) +{ + uint8_t autoboot; + ufs_ino_t ino; + size_t nbyte; + + /* Arguments from Miniboot. */ + beri_argc = argc; + beri_argv = argv; + beri_envv = envv; + beri_memsize = memsize; + + dmadat = &__dmadat; +#if 0 + /* XXXRW: more here. */ + v86.ctl = V86_FLAGS; + v86.efl = PSL_RESERVED_DEFAULT | PSL_I; + dsk.drive = *(uint8_t *)PTOV(ARGS); +#endif + dsk.type = TYPE_DEFAULT; +#if 0 + dsk.unit = dsk.drive & DRV_MASK; + dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1; +#endif + bootinfo.bi_version = BOOTINFO_VERSION; + bootinfo.bi_size = sizeof(bootinfo); + + /* Process configuration file */ + + autoboot = 1; + + if ((ino = lookup(PATH_CONFIG)) || + (ino = lookup(PATH_DOTCONFIG))) { + nbyte = fsread(ino, cmd, sizeof(cmd) - 1); + cmd[nbyte] = '\0'; + } + + if (*cmd) { + memcpy(cmddup, cmd, sizeof(cmd)); + if (parse()) + autoboot = 0; + if (!OPT_CHECK(RBX_QUIET)) + printf("%s: %s", PATH_CONFIG, cmddup); + /* Do not process this command twice */ + *cmd = 0; + } + + /* + * Try to exec stage 3 boot loader. If interrupted by a keypress, + * or in case of failure, try to load a kernel directly instead. + */ + + if (!kname) { + kname = PATH_LOADER; + if (autoboot && !keyhit(3*SECOND)) { + boot_fromfs(); + kname = PATH_KERNEL; + } + } + + /* Present the user with the boot2 prompt. */ + + for (;;) { + if (!autoboot || !OPT_CHECK(RBX_QUIET)) + printf("\nFreeBSD/mips boot\n" + "Default: %s%ju:%s\n" + "boot: ", + dev_nm[dsk.type], dsk.unitptr, kname); +#if 0 + if (ioctrl & IO_SERIAL) + sio_flush(); +#endif + if (!autoboot || keyhit(3*SECOND)) + getstr(); + else if (!autoboot || !OPT_CHECK(RBX_QUIET)) + putchar('\n'); + autoboot = 0; + if (parse()) + putchar('\a'); + else + load(); + } +} + +/* XXX - Needed for btxld to link the boot2 binary; do not remove. */ +void +exit(int x) +{ +} + +static void +boot(void *entryp, int argc, const char *argv[], const char *envv[]) +{ + + bootinfo.bi_kernelname = (bi_ptr_t)kname; + bootinfo.bi_boot2opts = opts & RBX_MASK; + bootinfo.bi_boot_dev_type = dsk.type; + bootinfo.bi_boot_dev_unitptr = dsk.unitptr; + bootinfo.bi_memsize = beri_memsize; +#if 0 + /* + * XXXRW: A possible future way to distinguish Miniboot passing a memory + * size vs DTB..? + */ + if (beri_memsize <= BERI_MEMVSDTB) + bootinfo.bi_memsize = beri_memsize; + else + bootinfo.bi_dtb = beri_memsize; +#endif + ((void(*)(int, const char **, const char **, void *))entryp)(argc, argv, + envv, &bootinfo); +} + +/* + * Boot a kernel that has mysteriously (i.e., by JTAG) appeared in DRAM; + * assume that it is already properly relocated, etc, and invoke its entry + * address without question or concern. + */ +static void +boot_fromdram(void) +{ + void *kaddr = DRAM_KERNEL_ADDR; /* XXXRW: Something better here. */ + Elf64_Ehdr *ehp = kaddr; + + if (!IS_ELF(*ehp)) { + printf("Invalid %s\n", "format"); + return; + } + boot((void *)ehp->e_entry, beri_argc, beri_argv, beri_envv); +} + +static void +boot_fromfs(void) +{ + union { + Elf64_Ehdr eh; + } hdr; + static Elf64_Phdr ep[2]; +#if 0 + static Elf64_Shdr es[2]; +#endif + caddr_t p; + ufs_ino_t ino; + uint64_t addr; + int i, j; + + if (!(ino = lookup(kname))) { + if (!ls) + printf("No %s\n", kname); + return; + } + if (xfsread(ino, &hdr, sizeof(hdr))) + return; + + if (IS_ELF(hdr.eh)) { + fs_off = hdr.eh.e_phoff; + for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { + if (xfsread(ino, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = (caddr_t)ep[i].p_paddr; + fs_off = ep[i].p_offset; + if (xfsread(ino, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); +#if 0 + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + fs_off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(ino, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + *(Elf32_Word *)p = es[i].sh_size; + p += sizeof(es[i].sh_size); + fs_off = es[i].sh_offset; + if (xfsread(ino, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } +#endif + addr = hdr.eh.e_entry; +#if 0 + bootinfo.bi_esymtab = VTOP(p); +#endif + } else { + printf("Invalid %s\n", "format"); + return; + } + boot((void *)addr, beri_argc, beri_argv, beri_envv); +} + +static void +load(void) +{ + + switch (dsk.type) { + case BOOTINFO_DEV_TYPE_DRAM: + boot_fromdram(); + break; + + default: + boot_fromfs(); + break; + } +} + +static int +parse() +{ + char *arg = cmd; + char *ep, *p, *q; + char unit; + size_t len; + const char *cp; +#if 0 + int c, i, j; +#else + int c, i; +#endif + + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + cp = "yes"; +#if 0 + } else { + opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); + cp = "no"; + } +#endif + printf("Keyboard: %s\n", cp); + continue; +#if 0 + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* Fall through to error below ('S' not in optstr[]). */ +#endif + } + for (i = 0; c != optstr[i]; i++) + if (i == NOPT - 1) + return -1; + opts ^= OPT_SET(flags[i]); + } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; +#if 0 + if (ioctrl & IO_SERIAL) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } +#endif + } else { + /*- + * Parse a device/kernel name. Format(s): + * + * path + * deviceX:path + * + * NB: Utterly incomprehensible but space-efficient ARM/i386 + * parsing removed in favour of larger but easier-to-read C. This + * is still not great, however -- e.g., relating to unit handling. + * + * TODO: it would be nice if a DRAM pointer could be specified + * here. + * + * XXXRW: Pick up pieces here. + */ + + /* + * Search for a parens; if none, then it's just a path. + * Otherwise, it's a devicename. + */ + arg--; + q = strsep(&arg, ":"); + if (arg != NULL) { + len = strlen(q); + if (len < 2) { + printf("Invalid device: name too short\n"); + return (-1); + } + + /* + * First, handle one-digit unit. + */ + unit = q[len-1]; + if (unit < '0' || unit > '9') { + printf("Invalid device: invalid unit\n", q, + unit); + return (-1); + } + unit -= '0'; + q[len-1] = '\0'; + + /* + * Next, find matching device. + */ + for (i = 0; i < dev_nm_count; i++) { + if (strcmp(q, dev_nm[i]) == 0) + break; + } + if (i == dev_nm_count) { + printf("Invalid device: no driver match\n"); + return (-1); + } + dsk.type = i; + dsk.unitptr = unit; /* Someday: also a DRAM pointer? */ + } else + arg = q; + if ((i = ep - arg)) { + if ((size_t)i >= sizeof(knamebuf)) + return -1; + memcpy(knamebuf, arg, i + 1); + kname = knamebuf; + } + } + arg = p; + } + return 0; +} + +static int +drvread(void *buf, unsigned lba, unsigned nblk) +{ + + /* XXXRW: eventually, we may want to pass 'drive' and 'unit' here. */ + switch (dsk.type) { + case BOOTINFO_DEV_TYPE_CFI: + return (cfi_read(buf, lba, nblk)); + + case BOOTINFO_DEV_TYPE_SDCARD: + return (altera_sdcard_read(buf, lba, nblk)); + + default: + return (-1); + } +} + +static int +dskread(void *buf, unsigned lba, unsigned nblk) +{ +#if 0 + /* + * XXXRW: For now, assume no partition table around the file system; it's + * just in raw flash. + */ + struct dos_partition *dp; + struct disklabel *d; + char *sec; + unsigned i; + uint8_t sl; + + if (!dsk_meta) { + sec = dmadat->secbuf; + dsk.start = 0; + if (drvread(sec, DOSBBSECTOR, 1)) + return -1; + dp = (void *)(sec + DOSPARTOFF); + sl = dsk.slice; + if (sl < BASE_SLICE) { + for (i = 0; i < NDOSPART; i++) + if (dp[i].dp_typ == DOSPTYP_386BSD && + (dp[i].dp_flag & 0x80 || sl < BASE_SLICE)) { + sl = BASE_SLICE + i; + if (dp[i].dp_flag & 0x80 || + dsk.slice == COMPATIBILITY_SLICE) + break; + } + if (dsk.slice == WHOLE_DISK_SLICE) + dsk.slice = sl; + } + if (sl != WHOLE_DISK_SLICE) { + if (sl != COMPATIBILITY_SLICE) + dp += sl - BASE_SLICE; + if (dp->dp_typ != DOSPTYP_386BSD) { + printf("Invalid %s\n", "slice"); + return -1; + } + dsk.start = le32toh(dp->dp_start); + } + if (drvread(sec, dsk.start + LABELSECTOR, 1)) + return -1; + d = (void *)(sec + LABELOFFSET); + if (le32toh(d->d_magic) != DISKMAGIC || + le32toh(d->d_magic2) != DISKMAGIC) { + if (dsk.part != RAW_PART) { + printf("Invalid %s\n", "label"); + return -1; + } + } else { + if (!dsk.init) { + if (le16toh(d->d_type) == DTYPE_SCSI) + dsk.type = TYPE_DA; + dsk.init++; + } + if (dsk.part >= le16toh(d->d_npartitions) || + !(le32toh(d->d_partitions[dsk.part].p_size))) { + printf("Invalid %s\n", "partition"); + return -1; + } + dsk.start += le32toh(d->d_partitions[dsk.part].p_offset); + dsk.start -= le32toh(d->d_partitions[RAW_PART].p_offset); + } + } + return drvread(buf, dsk.start + lba, nblk); +#else + return drvread(buf, lba, nblk); +#endif +} + +void +putchar(int c) +{ + if (c == '\n') + xputc('\r'); + xputc(c); +} + +static int +xputc(int c) +{ + if (ioctrl & IO_KEYBOARD) + putc(c); +#if 0 + if (ioctrl & IO_SERIAL) + sio_putc(c); +#endif + return c; +} + +static int +xgetc(int fn) +{ + if (OPT_CHECK(RBX_NOINTR)) + return 0; + for (;;) { + if (ioctrl & IO_KEYBOARD && keyhit(0)) + return fn ? 1 : getc(); +#if 0 + if (ioctrl & IO_SERIAL && sio_ischar()) + return fn ? 1 : sio_getc(); +#endif + if (fn) + return 0; + } +} diff --git a/stand/mips/beri/boot2/flashboot.ldscript b/stand/mips/beri/boot2/flashboot.ldscript new file mode 100644 index 0000000..4d61438 --- /dev/null +++ b/stand/mips/beri/boot2/flashboot.ldscript @@ -0,0 +1,65 @@ +/*- + * 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 + +/* + * When boot2 is loaded via JTAG, it's dropped at 0x10000, and will not need + * to self-relocate, since it will be in DRAM. + */ +__boot2_base__ = 0x100000; +__boot2_base_vaddr__ = __mips64_xkphys_cached__ + __boot2_base__; + +/* + * XXXRW: Currently, miniboot interprets the ELF header rather than jumping + * straight into the loader. For now, give the location where we know it will + * be. + */ +ENTRY(prerelocate_start) +SECTIONS +{ + . = __boot2_base_vaddr__; + . += SIZEOF_HEADERS; + .text ALIGN(0x10): { + relocate.o(.text) + start.o(.text) + *(EXCLUDE_FILE (relocate.o start.o) .text) + } + .data ALIGN(0x10): { *(.data)} + .bss ALIGN(0x10): { *(.bss) } + + __heap = ALIGN(0x8); /* 64-bit aligned heap pointer */ + __data_end = .; + __boot_loader_len__ = . - __boot2_base_vaddr__; + __bss_start = ADDR(.bss); + __bss_end = ALIGN(__bss_start + SIZEOF(.bss), 0x8); +} diff --git a/stand/mips/beri/boot2/jtagboot.ldscript b/stand/mips/beri/boot2/jtagboot.ldscript new file mode 100644 index 0000000..064c6e1 --- /dev/null +++ b/stand/mips/beri/boot2/jtagboot.ldscript @@ -0,0 +1,64 @@ +/*- + * 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 + +/* + * When boot2 is loaded via JTAG, it's dropped at 0x10000, and will not need + * to self-relocate, since it will be in DRAM. + */ +__boot2_base__ = 0x100000; +__boot2_base_vaddr__ = __mips64_xkphys_cached__ + __boot2_base__; + +/* + * XXXRW: Currently, miniboot interprets the ELF header rather than jumping + * straight into the loader. For now, give the location where we know it will + * be. + */ +ENTRY(start) +SECTIONS +{ + . = __boot2_base_vaddr__; + . += SIZEOF_HEADERS; + .text ALIGN(0x10): { + start.o(.text) + *(EXCLUDE_FILE (start.o) .text) + } + .data ALIGN(0x10): { *(.data)} + .bss ALIGN(0x10): { *(.bss) } + + __heap = ALIGN(0x8); /* 64-bit aligned heap pointer */ + __data_end = .; + __boot_loader_len__ = . - __boot2_base_vaddr__; + __bss_start = ADDR(.bss); + __bss_end = ALIGN(__bss_start + SIZEOF(.bss), 0x8); +} diff --git a/stand/mips/beri/boot2/relocate.S b/stand/mips/beri/boot2/relocate.S new file mode 100644 index 0000000..d704eb5 --- /dev/null +++ b/stand/mips/beri/boot2/relocate.S @@ -0,0 +1,103 @@ +/*- + * 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$ + */ + +.set mips64 +.set noreorder +.set nobopt +.set noat + +/* + * Save arguments from the BERI firmware for use in C-land, and jump into + * main. Assume that registers/stack/etc are sufficiently initialised to get + * going. Notice that we use only temporaries while relocating, as we want to + * retain argument registers to pass in to main(). + * + * Note slightly surprising structure: boot2 is linked for a specific address, + * but we may start running the code somewhere else (e.g., in DRAM as inserted + * with JTAG, or in flash). The starting assembly is therefore PIC, but the + * main body of the code is not PIC. + */ + + + .text + .global prerelocate_start + .ent prerelocate_start +prerelocate_start: + + /* + * Calculate the actual run-time, pre-relocated value of + * 'start', which we will use as the source address for + * memcpy(). Note that although a symbol is used here, this + * should generate code for a short relative branch, leaving + * the previous $pc in $ra. + */ + bal baltarget + nop +baltarget: + dsub $t1, $ra, 8 /* Src. */ + + /* + * Relocate boot2 to DRAM where we can write back global + * variable values; jump to it. Assume all values are 32-bit + * aligned. Use an inline PIC version of memcpy() + * pre-relocation; strong alignment assumptions. + */ + dla $t0, __boot2_base_vaddr__ /* Dst. */ + dla $t2, __boot_loader_len__ /* Len. */ + +memcpy_loop: + beq $t2, 0, memcopy_done + nop + lw $at, 0($t1) + sw $at, 0($t0) + daddiu $t0, 4 + daddiu $t1, 4 + daddi $t2, -4 + b memcpy_loop + nop + +memcopy_done: + /* + * We can now jump into the relocated code, running from + * cached DRAM rather than uncached flash. Note that a + * relative branch instruction cannot be used. + */ + dla $at, relocated_start + jr $at + nop + +relocated_start: + dla $at, start + jr $at + nop + + .end prerelocate_start diff --git a/stand/mips/beri/boot2/start.S b/stand/mips/beri/boot2/start.S new file mode 100644 index 0000000..c1fcce5 --- /dev/null +++ b/stand/mips/beri/boot2/start.S @@ -0,0 +1,82 @@ +/*- + * 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$ + */ + +.set mips64 +.set noreorder +.set nobopt +.set noat + +/* + * Save arguments from the BERI firmware for use in C-land, and jump into + * main. Assume that registers/stack/etc are sufficiently initialised to get + * going. Notice that we use only temporaries while relocating, as we want to + * retain argument registers to pass in to main(). + * + * Note slightly surprising structure: boot2 is linked for a specific address, + * but we may start running the code somewhere else (e.g., in DRAM as inserted + * with JTAG, or in flash). The starting assembly is therefore PIC, but the + * main body of the code is not PIC. + */ + + + .text + .global start + .ent start +start: + + /* + * Zero BSS. Run from cached memory as this will speed up + * code execution noticeably. Assuming 64-bit alignment of + * everything here. + */ + dla $t0, __bss_start + dla $t1, __bss_end + +bss_loop: + beq $t0, $t1, bss_done + nop + sd $zero, 0($t0) + daddiu $t0, 8 + b bss_loop + nop + +bss_done: + jal main + nop + + /* + * Ideally we wouldn't get here, but just in case. + */ +loop: + b loop + nop + .end start diff --git a/stand/mips/beri/common/altera_jtag_uart.c b/stand/mips/beri/common/altera_jtag_uart.c new file mode 100644 index 0000000..7edb451 --- /dev/null +++ b/stand/mips/beri/common/altera_jtag_uart.c @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 2011, 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. + * + * $FreeBSD$ + */ + +#include "util.h" +#include "mips.h" + +/*- + * Routines for interacting with the CHERI console UART. Programming details + * from the June 2011 "Embedded Peripherals User Guide" by Altera + * Corporation, tables 6-2 (JTAG UART Core Register Map), 6-3 (Data Register + * Bits), and 6-4 (Control Register Bits). + * + * Hard-coded physical address for the first JTAG UART -- true on all BERI and + * CHERI boards. + */ +#define CHERI_UART_BASE 0x7f000000 /* JTAG UART */ + +/* + * + * Offsets of data and control registers relative to the base. Altera + * conventions are maintained in CHERI. + */ +#define ALTERA_JTAG_UART_DATA_OFF 0x00000000 +#define ALTERA_JTAG_UART_CONTROL_OFF 0x00000004 + +/* + * Offset 0: 'data' register -- bits 31-16 (RAVAIL), 15 (RVALID), + * 14-8 (Reserved), 7-0 (DATA). + * + * DATA - One byte read or written. + * RAVAIL - Bytes available to read (excluding the current byte). + * RVALID - Whether the byte in DATA is valid. + */ +#define ALTERA_JTAG_UART_DATA_DATA 0x000000ff +#define ALTERA_JTAG_UART_DATA_RESERVED 0x00007f00 +#define ALTERA_JTAG_UART_DATA_RVALID 0x00008000 +#define ALTERA_JTAG_UART_DATA_RAVAIL 0xffff0000 +#define ALTERA_JTAG_UART_DATA_RAVAIL_SHIFT 16 + +/*- + * Offset 1: 'control' register -- bits 31-16 (WSPACE), 15-11 (Reserved), + * 10 (AC), 9 (WI), 8 (RI), 7..2 (Reserved), 1 (WE), 0 (RE). + * + * RE - Enable read interrupts. + * WE - Enable write interrupts. + * RI - Read interrupt pending. + * WI - Write interrupt pending. + * AC - Activity bit; set to '1' to clear to '0'. + * WSPACE - Space available in the write FIFO. + */ +#define ALTERA_JTAG_UART_CONTROL_RE 0x00000001 +#define ALTERA_JTAG_UART_CONTROL_WE 0x00000002 +#define ALTERA_JTAG_UART_CONTROL_RESERVED0 0x000000fc +#define ALTERA_JTAG_UART_CONTROL_RI 0x00000100 +#define ALTERA_JTAG_UART_CONTROL_WI 0x00000200 +#define ALTERA_JTAG_UART_CONTROL_AC 0x00000400 +#define ALTERA_JTAG_UART_CONTROL_RESERVED1 0x0000f800 +#define ALTERA_JTAG_UART_CONTROL_WSPACE 0xffff0000 +#define ALTERA_JTAG_UART_CONTROL_WSPACE_SHIFT 16 + +/* + * One-byte buffer as we can't check whether the UART is readable without + * actually reading from it. + */ +static char buffer_data; +static int buffer_valid; + +/* + * Low-level read and write register routines; the Altera UART is little + * endian, so we byte swap 32-bit reads and writes. + */ +static inline uint32_t +uart_data_read(void) +{ + + return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + ALTERA_JTAG_UART_DATA_OFF))); +} + +static inline void +uart_data_write(uint32_t v) +{ + + mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + ALTERA_JTAG_UART_DATA_OFF), v); +} + +static inline uint32_t +uart_control_read(void) +{ + + return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + ALTERA_JTAG_UART_CONTROL_OFF))); +} + +static inline void +uart_control_write(uint32_t v) +{ + + mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + ALTERA_JTAG_UART_DATA_OFF), v); +} + +static int +uart_writable(void) +{ + + return ((uart_control_read() & ALTERA_JTAG_UART_CONTROL_WSPACE) != 0); +} + +static int +uart_readable(void) +{ + uint32_t v; + + if (buffer_valid) + return (1); + v = uart_data_read(); + if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) { + buffer_valid = 1; + buffer_data = (v & ALTERA_JTAG_UART_DATA_DATA); + } + return (0); +} + +int +keyhit(int seconds) +{ + register_t stoptime; + + stoptime = cp0_count_get() + seconds * 100000000; /* 100 MHz. */ + do { + if (uart_readable()) + return (1); + } while (cp0_count_get() < stoptime); + return (0); +} + +int +getc(void) +{ + + while (!(uart_readable())); + buffer_valid = 0; + return (buffer_data); +} + +void +putc(int ch) +{ + + uart_data_write(ch); +} diff --git a/stand/mips/beri/common/beri.h b/stand/mips/beri/common/beri.h new file mode 100644 index 0000000..e6ccae8 --- /dev/null +++ b/stand/mips/beri/common/beri.h @@ -0,0 +1,42 @@ +/*- + * 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_BERI_H_ +#define _BOOT_BERI_H_ + +/* + * Older BERI boot loaders pass in physical memory size as $a3; newer ones + * pass in FDT DTB data. This constant helps us tell the difference. + */ +#define BERI_MEMVSDTB (256*1024*1024*1024ULL) + +#endif diff --git a/stand/mips/beri/common/cfi.c b/stand/mips/beri/common/cfi.c new file mode 100644 index 0000000..a6798f4 --- /dev/null +++ b/stand/mips/beri/common/cfi.c @@ -0,0 +1,75 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#include "util.h" +#include "mips.h" +#include "cfi.h" + +/* + * Memory-mapped Intel StrataFlash mini-driver. Very mini. Nothing fancy -- + * and few seatbelts. + * + * XXXRW: Should we be making some effort to reset isf to a known-good state + * before starting, in case there was a soft reset mid-transaction. + * + * XXXRW: Would be nice to support multiple devices and also handle SD cards + * here ... and probably not too hard. + */ +extern void *__cheri_flash_bootfs_vaddr__; +extern void *__cheri_flash_bootfs_len__; + +#define CHERI_BOOTFS_BASE ((uintptr_t)&__cheri_flash_bootfs_vaddr__) +#define CHERI_BOOTFS_LENGTH ((uintptr_t)&__cheri_flash_bootfs_len__) + +int +cfi_read(void *buf, unsigned lba, unsigned nblk) +{ + + if ((lba << 9) + (nblk << 9) > CHERI_BOOTFS_LENGTH) + return (-1); + memcpy(buf, (void *)(CHERI_BOOTFS_BASE + (lba << 9)), nblk << 9); + return (0); +} + +uint64_t +cfi_get_mediasize(void) +{ + + return (CHERI_BOOTFS_LENGTH); +} + +uint64_t +cfi_get_sectorsize(void) +{ + + return (512); /* Always a good sector size. */ +} diff --git a/stand/mips/beri/common/cfi.h b/stand/mips/beri/common/cfi.h new file mode 100644 index 0000000..3dfe48c --- /dev/null +++ b/stand/mips/beri/common/cfi.h @@ -0,0 +1,40 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#ifndef _CFI_H_ +#define _CFI_H_ + +int cfi_read(void *buf, unsigned lba, unsigned blk); +uint64_t cfi_get_mediasize(void); +uint64_t cfi_get_sectorsize(void); + +#endif diff --git a/stand/mips/beri/common/common.ldscript b/stand/mips/beri/common/common.ldscript new file mode 100644 index 0000000..6266646 --- /dev/null +++ b/stand/mips/beri/common/common.ldscript @@ -0,0 +1,76 @@ +/*- + * 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$ + */ + +/* + * MIPS segment definitions. + */ +__mips_ckseg_cached__ = 0xffffffff80000000; /* BSD kernel here. */ +__mips64_xkphys_cached__ = 0x9800000000000000; /* Device memory here. */ +__mips64_xkphys_uncached__ = 0x9000000000000000; /* Device I/O here. */ + +/* + * Physical addresses of various peripherals. + */ +__cheri_flash_base__ = 0x74000000; +__cheri_sdcard_base__ = 0x7f008000; + +/* + * Location of boot2 in flash. + */ +__cheri_flash_boot_loader_base_ = 0x03fe0000; +__cheri_flash_boot_loader_vaddr__ = __mips64_xkphys_cached__ + + __cheri_flash_base__ + __cheri_flash_boot_loader_base_; + +/* + * Location of boot file system in flash. + */ +__cheri_flash_bootfs_base__ = 0x1820000; +__cheri_flash_bootfs_len__ = 0x27c0000; +__cheri_flash_bootfs_vaddr__ = __mips64_xkphys_cached__ + + __cheri_flash_base__ + __cheri_flash_bootfs_base__; + +/* + * Location of SD card controller. + */ +__cheri_sdcard_vaddr__ = __mips64_xkphys_uncached__ + __cheri_sdcard_base__; + +/* + * Location where the production kernel gets put. This must agree with other + * definitions, such as in the kernel's own linker script. + * + * (As it happens, in the short run, we also place boot2 here, as Miniboot + * expects to find an ELF binary there -- but that will change.) + */ +__kernel_base__ = 0x100000; +__kernel_vaddr__ = __mips64_xkphys_cached__ + __kernel_base__; + +OUTPUT_ARCH(mips) diff --git a/stand/mips/beri/common/cons.h b/stand/mips/beri/common/cons.h new file mode 100644 index 0000000..18a466a --- /dev/null +++ b/stand/mips/beri/common/cons.h @@ -0,0 +1,40 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#ifndef _CONS_H_ +#define _CONS_H_ + +int getc(void); +int keyhit(int); +void putc(int); + +#endif diff --git a/stand/mips/beri/common/mips.h b/stand/mips/beri/common/mips.h new file mode 100644 index 0000000..c63d475 --- /dev/null +++ b/stand/mips/beri/common/mips.h @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2011 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 _MIPS_H_ +#define _MIPS_H_ + +/* + * 64-bit MIPS types. + */ +#if 0 +typedef unsigned long register_t; /* 64-bit MIPS register */ +#endif +typedef unsigned long paddr_t; /* Physical address */ +typedef unsigned long vaddr_t; /* Virtual address */ + +#if 0 +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long uint64_t; +#endif + +/* + * MIPS address space layout. + */ +#define MIPS_XKPHYS_UNCACHED_BASE 0x9000000000000000 +#define MIPS_XKPHYS_CACHED_NC_BASE 0x9800000000000000 + +static inline vaddr_t +mips_phys_to_cached(paddr_t phys) +{ + + return (phys | MIPS_XKPHYS_CACHED_NC_BASE); +} + +static inline vaddr_t +mips_phys_to_uncached(paddr_t phys) +{ + + return (phys | MIPS_XKPHYS_UNCACHED_BASE); +} + +/* + * Endian conversion routines for use in I/O -- most Altera devices are little + * endian, but our processor is big endian. + */ +static inline uint16_t +byteswap16(uint16_t v) +{ + + return ((v & 0xff00) >> 8 | (v & 0xff) << 8); +} + +static inline uint32_t +byteswap32(uint32_t v) +{ + + return ((v & 0xff000000) >> 24 | (v & 0x00ff0000) >> 8 | + (v & 0x0000ff00) << 8 | (v & 0x000000ff) << 24); +} + +/* + * MIPS simple I/O routines -- arguments are virtual addresses so that the + * caller can determine required caching properties. + */ +static inline uint8_t +mips_ioread_uint8(vaddr_t vaddr) +{ + uint8_t v; + + __asm__ __volatile__ ("lb %0, 0(%1)" : "=r" (v) : "r" (vaddr)); + return (v); +} + +static inline void +mips_iowrite_uint8(vaddr_t vaddr, uint8_t v) +{ + + __asm__ __volatile__ ("sb %0, 0(%1)" : : "r" (v), "r" (vaddr)); +} + +static inline uint32_t +mips_ioread_uint32(vaddr_t vaddr) +{ + uint32_t v; + + __asm__ __volatile__ ("lw %0, 0(%1)" : "=r" (v) : "r" (vaddr)); + return (v); +} + +static inline void +mips_iowrite_uint32(vaddr_t vaddr, uint32_t v) +{ + + __asm__ __volatile__ ("sw %0, 0(%1)" : : "r" (v), "r" (vaddr)); +} + +/* + * Little-endian versions of 32-bit I/O routines. + */ +static inline uint32_t +mips_ioread_uint32le(vaddr_t vaddr) +{ + + return (byteswap32(mips_ioread_uint32(vaddr))); +} + +static inline void +mips_iowrite_uint32le(vaddr_t vaddr, uint32_t v) +{ + + mips_iowrite_uint32(vaddr, byteswap32(v)); +} + +/* + * Coprocessor 0 interfaces. + */ +static inline register_t +cp0_count_get(void) +{ + register_t count; + + __asm__ __volatile__ ("dmfc0 %0, $9" : "=r" (count)); + return (count); +} + +#endif diff --git a/stand/mips/beri/common/sdcard.c b/stand/mips/beri/common/sdcard.c new file mode 100644 index 0000000..e50f4e7 --- /dev/null +++ b/stand/mips/beri/common/sdcard.c @@ -0,0 +1,334 @@ +/*- + * Copyright (c) 2012-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 <sys/types.h> +#include <sys/endian.h> + +#include <inttypes.h> +#include <stdio.h> + + +/* + * Altera University Program SD Card micro-driver for boot2 and loader. + * + * XXXRW: It might be nice to add 'unit' arguments to all APIs to allow + * multiple instances to be addressed. + */ + +/* Constants lifted from altera_sdcard.h -- possibly we should share headers? */ +#define ALTERA_SDCARD_OFF_RXTX_BUFFER 0 /* 512-byte I/O buffer */ +#define ALTERA_SDCARD_OFF_CID 512 /* 16-byte Card ID number */ +#define ALTERA_SDCARD_OFF_CSD 528 /* 16-byte Card Specific Data */ +#define ALTERA_SDCARD_OFF_OCR 544 /* Operating Conditions Reg */ +#define ALTERA_SDCARD_OFF_SR 548 /* SD Card Status Register */ +#define ALTERA_SDCARD_OFF_RCA 552 /* Relative Card Address Reg */ +#define ALTERA_SDCARD_OFF_CMD_ARG 556 /* Command Argument Register */ +#define ALTERA_SDCARD_OFF_CMD 560 /* Command Register */ +#define ALTERA_SDCARD_OFF_ASR 564 /* Auxiliary Status Register */ +#define ALTERA_SDCARD_OFF_RR1 568 /* Response R1 */ + +#define ALTERA_SDCARD_SECTORSIZE 512 + +#define ALTERA_SDCARD_CMD_SEND_RCA 0x03 /* Retrieve card RCA. */ +#define ALTERA_SDCARD_CMD_SEND_CSD 0x09 /* Retrieve CSD register. */ +#define ALTERA_SDCARD_CMD_SEND_CID 0x0A /* Retrieve CID register. */ +#define ALTERA_SDCARD_CMD_READ_BLOCK 0x11 /* Read block from disk. */ +#define ALTERA_SDCARD_CMD_WRITE_BLOCK 0x18 /* Write block to disk. */ + +#define ALTERA_SDCARD_ASR_CMDVALID 0x0001 +#define ALTERA_SDCARD_ASR_CARDPRESENT 0x0002 +#define ALTERA_SDCARD_ASR_CMDINPROGRESS 0x0004 +#define ALTERA_SDCARD_ASR_SRVALID 0x0008 +#define ALTERA_SDCARD_ASR_CMDTIMEOUT 0x0010 +#define ALTERA_SDCARD_ASR_CMDDATAERROR 0x0020 + +#define ALTERA_SDCARD_RR1_INITPROCRUNNING 0x0100 +#define ALTERA_SDCARD_RR1_ERASEINTERRUPTED 0x0200 +#define ALTERA_SDCARD_RR1_ILLEGALCOMMAND 0x0400 +#define ALTERA_SDCARD_RR1_COMMANDCRCFAILED 0x0800 +#define ALTERA_SDCARD_RR1_ADDRESSMISALIGNED 0x1000 +#define ALTERA_SDCARD_RR1_ADDRBLOCKRANGE 0x2000 + +#define ALTERA_SDCARD_CSD_STRUCTURE_BYTE 15 +#define ALTERA_SDCARD_CSD_STRUCTURE_MASK 0xc0 /* 2 bits */ +#define ALTERA_SDCARD_CSD_STRUCTURE_RSHIFT 6 +#define ALTERA_SDCARD_CSD_SIZE 16 +#define ALTERA_SDCARD_CSD_READ_BL_LEN_BYTE 10 +#define ALTERA_SDCARD_CSD_READ_BL_LEN_MASK 0x0f /* 4 bits */ +#define ALTERA_SDCARD_CSD_C_SIZE_BYTE0 7 +#define ALTERA_SDCARD_CSD_C_SIZE_MASK0 0xc0 /* top 2 bits */ +#define ALTERA_SDCARD_CSD_C_SIZE_RSHIFT0 6 +#define ALTERA_SDCARD_CSD_C_SIZE_BYTE1 8 +#define ALTERA_SDCARD_CSD_C_SIZE_MASK1 0xff /* 8 bits */ +#define ALTERA_SDCARD_CSD_C_SIZE_LSHIFT1 2 +#define ALTERA_SDCARD_CSD_C_SIZE_BYTE2 9 +#define ALTERA_SDCARD_CSD_C_SIZE_MASK2 0x03 /* bottom 2 bits */ +#define ALTERA_SDCARD_CSD_C_SIZE_LSHIFT2 10 +#define ALTERA_SDCARD_CSD_C_SIZE_MULT_BYTE0 5 +#define ALTERA_SDCARD_CSD_C_SIZE_MULT_MASK0 0x80 /* top 1 bit */ +#define ALTERA_SDCARD_CSD_C_SIZE_MULT_RSHIFT0 7 +#define ALTERA_SDCARD_CSD_C_SIZE_MULT_BYTE1 6 +#define ALTERA_SDCARD_CSD_C_SIZE_MULT_MASK1 0x03 /* bottom 2 bits */ +#define ALTERA_SDCARD_CSD_C_SIZE_MULT_LSHIFT1 1 + +/* + * Not all RR1 values are "errors" per se -- check only for the ones that are + * when performing error handling. + */ +#define ALTERA_SDCARD_RR1_ERRORMASK \ + (ALTERA_SDCARD_RR1_ERASEINTERRUPTED | ALTERA_SDCARD_RR1_ILLEGALCOMMAND | \ + ALTERA_SDCARD_RR1_COMMANDCRCFAILED | ALTERA_SDCARD_RR1_ADDRESSMISALIGNED |\ + ALTERA_SDCARD_RR1_ADDRBLOCKRANGE) + +extern void __cheri_sdcard_vaddr__; + +#define ALTERA_SDCARD_PTR(type, offset) \ + (volatile type *)((uint8_t *)&__cheri_sdcard_vaddr__ + (offset)) + +static __inline uint16_t +altera_sdcard_read_uint16(u_int offset) +{ + volatile uint16_t *p; + + p = ALTERA_SDCARD_PTR(uint16_t, offset); + return (le16toh(*p)); +} + +static __inline void +altera_sdcard_write_uint16(u_int offset, uint16_t v) +{ + volatile uint16_t *p; + + p = ALTERA_SDCARD_PTR(uint16_t, offset); + *p = htole16(v); +} + +static __inline void +altera_sdcard_write_uint32(u_int offset, uint32_t v) +{ + volatile uint32_t *p; + + p = ALTERA_SDCARD_PTR(uint32_t, offset); + *p = htole32(v); +} + +static __inline uint16_t +altera_sdcard_read_asr(void) +{ + + return (altera_sdcard_read_uint16(ALTERA_SDCARD_OFF_ASR)); +} + +static __inline uint16_t +altera_sdcard_read_rr1(void) +{ + + return (altera_sdcard_read_uint16(ALTERA_SDCARD_OFF_RR1)); +} + +static __inline void +altera_sdcard_write_cmd(uint16_t cmd) +{ + + altera_sdcard_write_uint16(ALTERA_SDCARD_OFF_CMD, cmd); +} + +static __inline void +altera_sdcard_write_cmd_arg(uint32_t cmd_arg) +{ + + altera_sdcard_write_uint32(ALTERA_SDCARD_OFF_CMD_ARG, cmd_arg); +} + +/* NB: Use 16-bit aligned buffer due to hardware features, so 16-bit type. */ +static __inline void +altera_sdcard_read_csd(uint16_t *csdp) +{ + volatile uint16_t *hw_csdp; + u_int i; + + hw_csdp = ALTERA_SDCARD_PTR(uint16_t, ALTERA_SDCARD_OFF_CSD); + for (i = 0; i < ALTERA_SDCARD_CSD_SIZE / sizeof(uint16_t); i++) + csdp[i] = hw_csdp[i]; +} + +/* + * Private interface: load exactly one block of size ALTERA_SDCARD_SECTORSIZE + * from block #lba. + */ +static int +altera_sdcard_read_block(void *buf, unsigned lba) +{ + volatile uint32_t *rxtxp; + uint32_t *bufp; + uint16_t asr, rr1; + int i; + + if (!(altera_sdcard_read_asr() & ALTERA_SDCARD_ASR_CARDPRESENT)) { + printf("SD Card: card not present\n"); + return (-1); + } + + bufp = (uint32_t *)buf; + rxtxp = ALTERA_SDCARD_PTR(uint32_t, ALTERA_SDCARD_OFF_RXTX_BUFFER); + + /* + * Issue read block command. + */ + altera_sdcard_write_cmd_arg(lba * ALTERA_SDCARD_SECTORSIZE); + altera_sdcard_write_cmd(ALTERA_SDCARD_CMD_READ_BLOCK); + + /* + * Wait for device to signal completion of command. + */ + while ((asr = altera_sdcard_read_asr()) & + ALTERA_SDCARD_ASR_CMDINPROGRESS); + + /* + * Due to hardware bugs/features, interpretting this field is messy. + */ + rr1 = altera_sdcard_read_rr1(); + rr1 &= ~ALTERA_SDCARD_RR1_COMMANDCRCFAILED; /* HW bug. */ + if (asr & ALTERA_SDCARD_ASR_CMDTIMEOUT) { + printf("SD Card: timeout\n"); + return (-1); + } + if ((asr & ALTERA_SDCARD_ASR_CMDDATAERROR) && + (rr1 & ALTERA_SDCARD_RR1_ERRORMASK)) { + printf("SD Card: asr %u rr1 %u\n", asr, rr1); + return (-1); + } + + /* + * We can't use a regular memcpy() due to byte-enable bugs in the + * Altera IP core: instead copy in 32-bit units. + */ + for (i = 0; i < ALTERA_SDCARD_SECTORSIZE/sizeof(uint32_t); i++) + bufp[i] = rxtxp[i]; + return (0); +} + +/* + * Public interface: load 'nblk' blocks from block #lba into *buf. + */ +int +altera_sdcard_read(void *buf, unsigned lba, unsigned nblk) +{ + uint8_t *bufp = buf; + int i; + + for (i = 0; i < nblk; i++) { + if (altera_sdcard_read_block(bufp + i * + ALTERA_SDCARD_SECTORSIZE, lba + i) < 0) { + printf("SD Card: block read %u failed\n", i); + return (-1); + } + } + return (0); +} + +/* + * Public interface: query (current) media size. + */ +uint64_t +altera_sdcard_get_mediasize(void) +{ + uint64_t mediasize; + uint64_t c_size, c_size_mult, read_bl_len; + uint16_t csd16[ALTERA_SDCARD_CSD_SIZE/sizeof(uint16_t)]; + uint8_t *csd8p = (uint8_t *)&csd16; + uint8_t byte0, byte1, byte2; + + altera_sdcard_read_csd(csd16); /* Provide 16-bit alignment. */ + + read_bl_len = csd8p[ALTERA_SDCARD_CSD_READ_BL_LEN_BYTE]; + read_bl_len &= ALTERA_SDCARD_CSD_READ_BL_LEN_MASK; + + byte0 = csd8p[ALTERA_SDCARD_CSD_C_SIZE_BYTE0]; + byte0 &= ALTERA_SDCARD_CSD_C_SIZE_MASK0; + byte1 = csd8p[ALTERA_SDCARD_CSD_C_SIZE_BYTE1]; + byte2 = csd8p[ALTERA_SDCARD_CSD_C_SIZE_BYTE2]; + byte2 &= ALTERA_SDCARD_CSD_C_SIZE_MASK2; + c_size = (byte0 >> ALTERA_SDCARD_CSD_C_SIZE_RSHIFT0) | + (byte1 << ALTERA_SDCARD_CSD_C_SIZE_LSHIFT1) | + (byte2 << ALTERA_SDCARD_CSD_C_SIZE_LSHIFT2); + + byte0 = csd8p[ALTERA_SDCARD_CSD_C_SIZE_MULT_BYTE0]; + byte0 &= ALTERA_SDCARD_CSD_C_SIZE_MULT_MASK0; + byte1 = csd8p[ALTERA_SDCARD_CSD_C_SIZE_MULT_BYTE1]; + byte1 &= ALTERA_SDCARD_CSD_C_SIZE_MULT_MASK1; + c_size_mult = (byte0 >> ALTERA_SDCARD_CSD_C_SIZE_MULT_RSHIFT0) | + (byte1 << ALTERA_SDCARD_CSD_C_SIZE_MULT_LSHIFT1); + + mediasize = (c_size + 1) * (1 << (c_size_mult + 2)) * + (1 << read_bl_len); + return (mediasize); +} + +/* + * Public interface: is media present / supported? + */ +int +altera_sdcard_get_present(void) +{ + uint16_t csd16[ALTERA_SDCARD_CSD_SIZE/sizeof(uint16_t)]; + uint8_t *csd8p = (uint8_t *)&csd16; + uint8_t csd_structure; + + /* First: does status bit think it is there? */ + if (!(altera_sdcard_read_asr() & ALTERA_SDCARD_ASR_CARDPRESENT)) { + printf("SD Card: not present\n"); + return (0); + } + + /* Second: do we understand the CSD structure version? */ + altera_sdcard_read_csd(csd16); /* Provide 16-bit alignment. */ + csd_structure = csd8p[ALTERA_SDCARD_CSD_STRUCTURE_BYTE]; + csd_structure &= ALTERA_SDCARD_CSD_STRUCTURE_MASK; + csd_structure >>= ALTERA_SDCARD_CSD_STRUCTURE_RSHIFT; + if (csd_structure != 0) { + printf("SD Card: unrecognised csd %u\n", csd_structure); + return (0); + } + + return (1); +} + +/* + * Public interface: query sector size. + */ +uint64_t +altera_sdcard_get_sectorsize(void) +{ + + return (ALTERA_SDCARD_SECTORSIZE); +} diff --git a/stand/mips/beri/common/sdcard.h b/stand/mips/beri/common/sdcard.h new file mode 100644 index 0000000..0eb7760 --- /dev/null +++ b/stand/mips/beri/common/sdcard.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 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 _SDCARD_H_ +#define _SDCARD_H_ + +int altera_sdcard_read(void *buf, unsigned lba, unsigned nblk); +uint64_t altera_sdcard_get_mediasize(void); +int altera_sdcard_get_present(void); +uint64_t altera_sdcard_get_sectorsize(void); + +#endif /* !_SDCARD_H_ */ 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 diff --git a/stand/mips/uboot/Makefile b/stand/mips/uboot/Makefile new file mode 100644 index 0000000..b941ba3 --- /dev/null +++ b/stand/mips/uboot/Makefile @@ -0,0 +1,57 @@ +# $FreeBSD$ + +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_NET_SUPPORT?= yes +LOADER_NFS_SUPPORT?= yes +LOADER_TFTP_SUPPORT?= no +LOADER_GZIP_SUPPORT?= no +LOADER_BZIP2_SUPPORT?= no + +.include <bsd.init.mk> + +FILES+= ubldr + +NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} +INSTALLFLAGS= -b +WARNS?= 1 +# Address at which ubldr will be loaded. +# This varies for different boards and SOCs. +UBLDR_LOADADDR?= 0xffffffff80800000 + +# Architecture-specific loader code +SRCS= start.S conf.c vers.c + +HELP_FILES+= help.uboot ${BOOTSRC}/fdt/help.fdt + +# Always add MI sources +.include "${BOOTSRC}/loader.mk" + +CFLAGS+= -ffreestanding -msoft-float -g + +LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} + +.include "${BOOTSRC}/uboot.mk" + +DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} + +OBJS+= ${SRCS:N*.h:R:S/$/.o/g} + +ldscript.abs: + echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} + +ldscript.pie: + echo "UBLDR_LOADADDR = 0;" >${.TARGET} + +ubldr: ${OBJS} ldscript.abs ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD} + ${CC} ${CFLAGS} -T ldscript.abs ${LDFLAGS} \ + -o ${.TARGET} ${OBJS} ${LDADD} + ${OBJCOPY} -S -O binary ubldr ubldr.bin + +CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin + +.include <bsd.stand.mk> +.include <bsd.prog.mk> diff --git a/stand/mips/uboot/conf.c b/stand/mips/uboot/conf.c new file mode 100644 index 0000000..3579b6a --- /dev/null +++ b/stand/mips/uboot/conf.c @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2008 Semihalf, Rafal Jaworowski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include "bootstrap.h" +#include "libuboot.h" + +#if defined(LOADER_NET_SUPPORT) +#include "dev_net.h" +#endif + +/* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ +void (*exitfn)(int) = exit; + +struct devsw *devsw[] = { +#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) + &uboot_storage, +#endif +#if defined(LOADER_NET_SUPPORT) + &netdev, +#endif + NULL +}; + +struct fs_ops *file_system[] = { +#if defined(LOADER_MSDOS_SUPPORT) + &dosfs_fsops, +#endif +#if defined(LOADER_UFS_SUPPORT) + &ufs_fsops, +#endif +#if defined(LOADER_CD9660_SUPPORT) + &cd9660_fsops, +#endif +#if defined(LOADER_EXT2FS_SUPPORT) + &ext2fs_fsops, +#endif +#if defined(LOADER_NANDFS_SUPPORT) + &nandfs_fsops, +#endif +#if defined(LOADER_NFS_SUPPORT) + &nfs_fsops, +#endif +#if defined(LOADER_TFTP_SUPPORT) + &tftp_fsops, +#endif +#if defined(LOADER_GZIP_SUPPORT) + &gzipfs_fsops, +#endif +#if defined(LOADER_BZIP2_SUPPORT) + &bzipfs_fsops, +#endif + NULL +}; + +struct netif_driver *netif_drivers[] = { +#if defined(LOADER_NET_SUPPORT) + &uboot_net, +#endif + NULL, +}; + +struct file_format *file_formats[] = { + &uboot_elf, + NULL +}; + +extern struct console uboot_console; + +struct console *consoles[] = { + &uboot_console, + NULL +}; + +void +abort(void) +{ + + printf("error: loader abort\n"); + while (1); +} + +void +longjmperror(void) +{ + + printf("error: loader longjmp error\n"); + while (1); +} + +int debug = 1; diff --git a/stand/mips/uboot/help.uboot b/stand/mips/uboot/help.uboot new file mode 100644 index 0000000..c1574af --- /dev/null +++ b/stand/mips/uboot/help.uboot @@ -0,0 +1,27 @@ +$FreeBSD$ + +############################################################################### +# Tubenv DShow or import U-Boot environment variables + + ubenv <import | show> [varname ...] + + Display U-Boot environment variables, or import them into the + loader environment (which makes them available in the kernel). + +############################################################################### +# Tubenv Simport DImport U-Boot env vars + + ubenv import [varname ...] + + If no variable names are specified, all U-Boot environment + variables are imported. Each variable is prefixed with "uboot." + to avoid any possible conflicts with loader or kernel variables. + +############################################################################### +# Tubenv Sshow DShow U-Boot env vars + + ubenv show [varname ...] + + If no variable names are specified, all U-Boot environment + variables are shown. + diff --git a/stand/mips/uboot/ldscript.mips b/stand/mips/uboot/ldscript.mips new file mode 100644 index 0000000..815dabc --- /dev/null +++ b/stand/mips/uboot/ldscript.mips @@ -0,0 +1,134 @@ +/* $FreeBSD$ */ + +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + /*. = UBLDR_LOADADDR + SIZEOF_HEADERS;*/ + . = UBLDR_LOADADDR; + .text : + { + start.o(.text*) + *(EXCLUDE_FILE (start.o) .text*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + _etext = .; + PROVIDE (etext = .); + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss) } + .rela.plt : { *(.rela.plt) } + .rela.sdata : { *(.rela.sdata) } + .rela.sbss : { *(.rela.sbss) } + .rela.sdata2 : { *(.rela.sdata2) } + .rela.sbss2 : { *(.rela.sbss2) } + .init : { *(.init) } =0 + .fini : { *(.fini) } =0 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2) } + .sbss2 : { *(.sbss2) } + /* Adjust the address for the data segment to the next page up. */ + . = ((. + 0x1000) & ~(0x1000 - 1)); + .data : + { + *(.data) + *(.gnu.linkonce.d*) + } + .data1 : { *(.data1) } + .got1 : { *(.got1) } + .dynamic : { *(.dynamic) } + /* Put .ctors and .dtors next to the .got2 section, so that the pointers + get relocated with -mrelocatable. Also put in the .fixup pointers. + The current compiler no longer needs this, but keep it around for 2.7.2 */ + PROVIDE (_GOT2_START_ = .); + .got2 : { *(.got2) } + PROVIDE (__CTOR_LIST__ = .); + .ctors : { *(.ctors) } + PROVIDE (__CTOR_END__ = .); + PROVIDE (__DTOR_LIST__ = .); + .dtors : { *(.dtors) } + PROVIDE (__DTOR_END__ = .); + PROVIDE (_FIXUP_START_ = .); + .fixup : { *(.fixup) } + PROVIDE (_FIXUP_END_ = .); + PROVIDE (_GOT2_END_ = .); + PROVIDE (_GOT_START_ = .); + .got : { *(.got) } + .got.plt : { *(.got.plt) } + PROVIDE (_GOT_END_ = .); + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + .sbss : + { + PROVIDE (__sbss_start = .); + *(.sbss) + *(.scommon) + *(.dynsbss) + PROVIDE (__sbss_end = .); + } + .plt : { *(.plt) } + .bss : + { + PROVIDE (__bss_start = .); + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} diff --git a/stand/mips/uboot/loader.conf b/stand/mips/uboot/loader.conf new file mode 100644 index 0000000..dd2a23a --- /dev/null +++ b/stand/mips/uboot/loader.conf @@ -0,0 +1,13 @@ +# This is defaults/loader.conf for ARM, containing defaults for loader(8). +# Do not modify the contents of this file, instead put your customizations +# into /boot/loader.conf or /boot/loader.conf.local +# $FreeBSD$ + +autoboot_delay=10 +bootfile="kernel" # Kernel name (possibly absolute path) +kernel="kernel" # /boot sub-directory containing kernel and modules +loader_conf_files="/boot/loader.conf /boot/loader.conf.local" +module_path="/boot/kernel;/boot/modules;/boot/dtb;/boot/overlays" +nextboot_conf="/boot/nextboot.conf" +nextboot_enable="NO" +verbose_loading="NO" diff --git a/stand/mips/uboot/start.S b/stand/mips/uboot/start.S new file mode 100644 index 0000000..2ca68b2 --- /dev/null +++ b/stand/mips/uboot/start.S @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2016 Stanislav Galabov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <machine/asm.h> + + .text + .extern _C_LABEL(main) + .weak _DYNAMIC + +/* + * Entry point to the loader that U-Boot passes control to. + */ +ENTRY(_start) + PTR_S sp, uboot_address + j main + nop +END(_start) + +/* + * syscall() + */ +ENTRY(syscall) + PTR_S ra, ret_address + PTR_L t9, syscall_ptr + jalr t9 + nop + PTR_L ra, ret_address + jr ra + nop +END(syscall) + +/* + * Data section + */ + .data + .align 8 + .globl syscall_ptr +syscall_ptr: + .dword 0 + + .globl uboot_address +uboot_address: + .dword 0 + +ret_address: + .dword 0 diff --git a/stand/mips/uboot/version b/stand/mips/uboot/version new file mode 100644 index 0000000..486c412 --- /dev/null +++ b/stand/mips/uboot/version @@ -0,0 +1,9 @@ +$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. + +1.2: Extended with NAND FS support. +1.1: Flattened Device Tree blob support. +1.0: Added storage support. Booting from HDD, USB, etc. is now possible. +0.5: Initial U-Boot/arm version (netbooting only). |