1/*- 2 * Copyright (c) 2013-2014 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * This software was developed by SRI International and the University of 6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 7 * ("CTSRD"), as part of the DARPA CRASH research programme. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD$"); 33 34#include <sys/param.h> 35#include <sys/linker.h> 36#include <sys/reboot.h> 37 38#include <machine/bootinfo.h> 39#include <machine/elf.h> 40 41#include <stand.h> 42#include <bootstrap.h> 43#include <loader.h> 44#include <mips.h> 45 46#ifdef LOADER_USB_SUPPORT 47#include <storage/umass_common.h> 48#endif 49 50static int __elfN(exec)(struct preloaded_file *); 51static void extract_currdev(struct bootinfo *); 52 53struct devsw *devsw[] = { 54 &beri_cfi_disk, 55 &beri_sdcard_disk, 56#ifdef LOADER_USB_SUPPORT 57 &umass_disk, 58#endif 59 NULL 60}; 61 62struct file_format *file_formats[] = { 63 &beri_elf, 64 NULL 65}; 66 67struct fs_ops *file_system[] = { 68#ifdef LOADER_UFS_SUPPORT 69 &ufs_fsops, 70#endif 71 NULL 72}; 73 74struct console *consoles[] = { 75 &altera_jtag_uart_console, 76 NULL 77}; 78 79extern uint8_t __bss_start, __bss_end; 80extern uint8_t __heap_start, __heap_end; 81 82static int 83__elfN(exec)(struct preloaded_file *fp) 84{ 85 86 return (EFTYPE); 87} 88 89/* 90 * Capture arguments from boot2 for later reuse when launching the kernel. 91 * Note that we choose not to maintain a pointer to boo2_bootinfop after 92 * initial argument processing: this is because we might load the kernel over 93 * the spot where boot2 was running, so we can't pass that pointer on to the 94 * kernel. To be on the safe side, never reference it outside of the body of 95 * main(), instead preserving a copy. 96 */ 97int boot2_argc; 98char **boot2_argv; 99char **boot2_envv; 100 101struct bootinfo boot2_bootinfo; 102 103int 104main(int argc, char *argv[], char *envv[], struct bootinfo *bootinfop) 105{ 106 struct devsw **dp; 107 108 /* NB: Must be sure to bzero() before using any globals. */ 109 bzero(&__bss_start, &__bss_end - &__bss_start); 110 111 boot2_argc = argc; 112 boot2_argv = argv; 113 boot2_envv = envv; 114 boot2_bootinfo = *bootinfop; /* Copy rather than by reference. */ 115 116 setheap(&__heap_start, &__heap_end); 117 118 /* 119 * Pick up console settings from boot2; probe console. 120 */ 121 if (bootinfop->bi_boot2opts & RB_MULTIPLE) { 122 if (bootinfop->bi_boot2opts & RB_SERIAL) 123 setenv("console", "comconsole vidconsole", 1); 124 else 125 setenv("console", "vidconsole comconsole", 1); 126 } else if (bootinfop->bi_boot2opts & RB_SERIAL) 127 setenv("console", "comconsole", 1); 128 else if (bootinfop->bi_boot2opts & RB_MUTE) 129 setenv("console", "nullconsole", 1); 130 cons_probe(); 131 setenv("LINES", "24", 1); 132 133 printf("%s(%d, %p, %p, %p (%p))\n", __func__, argc, argv, envv, 134 bootinfop, (void *)bootinfop->bi_memsize); 135 136 /* 137 * Initialise devices. 138 */ 139 for (dp = devsw; *dp != NULL; dp++) { 140 if ((*dp)->dv_init != NULL) 141 (*dp)->dv_init(); 142 } 143 extract_currdev(bootinfop); 144 145 printf("\n%s", bootprog_info); 146#if 0 147 printf("bootpath=\"%s\"\n", bootpath); 148#endif 149 150 interact(); 151 return (0); 152} 153 154static void 155extract_currdev(struct bootinfo *bootinfop) 156{ 157 const char *bootdev; 158 159 /* 160 * Pick up boot device information from boot2. 161 * 162 * XXXRW: Someday: device units. 163 */ 164 switch(bootinfop->bi_boot_dev_type) { 165 case BOOTINFO_DEV_TYPE_DRAM: 166 bootdev = "dram0"; 167 break; 168 169 case BOOTINFO_DEV_TYPE_CFI: 170 bootdev = "cfi0"; 171 break; 172 173 case BOOTINFO_DEV_TYPE_SDCARD: 174 bootdev = "sdcard0"; 175 break; 176 177 default: 178 bootdev = NULL; 179 } 180 181 if (bootdev != NULL) { 182 env_setenv("currdev", EV_VOLATILE, bootdev, NULL, env_nounset); 183 env_setenv("loaddev", EV_VOLATILE, bootdev, env_noset, 184 env_nounset); 185 } 186} 187 188void 189abort(void) 190{ 191 192 printf("error: loader abort\n"); 193 while (1); 194 __unreachable(); 195} 196 197void 198exit(int code) 199{ 200 201 printf("error: loader exit\n"); 202 while (1); 203 __unreachable(); 204} 205 206void 207longjmperror(void) 208{ 209 210 printf("error: loader longjmp error\n"); 211 while (1); 212 __unreachable(); 213} 214 215time_t 216time(time_t *tloc) 217{ 218 219 /* We can't provide time since UTC, so just provide time since boot. */ 220 return (cp0_count_get() / 100000000); 221} 222 223/* 224 * Delay - in usecs 225 * 226 * NOTE: We are assuming that the CPU is running at 100MHz. 227 */ 228void 229delay(int usecs) 230{ 231 uint32_t delta; 232 uint32_t curr; 233 uint32_t last; 234 235 last = cp0_count_get(); 236 while (usecs > 0) { 237 curr = cp0_count_get(); 238 delta = curr - last; 239 while (usecs > 0 && delta >= 100) { 240 usecs--; 241 last += 100; 242 delta -= 100; 243 } 244 } 245} 246