1 /* $NetBSD: boot.c,v 1.5 2001/06/19 11:56:28 nonaka Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <lib/libsa/stand.h> 35 #include <lib/libsa/loadfile.h> 36 #include <sys/reboot.h> 37 #include <sys/boot_flag.h> 38 #include <machine/bootinfo.h> 39 #include <machine/cpu.h> 40 #include <machine/residual.h> 41 42 #include "boot.h" 43 44 char *names[] = { 45 "in()", 46 #if 0 47 "fd(0,0,0)netbsd", "fd(0,0,0)netbsd.gz", 48 "fd(0,0,0)netbsd.old", "fd(0,0,0)netbsd.old.gz", 49 "fd(0,0,0)onetbsd", "fd(0,0,0)onetbsd.gz" 50 #endif 51 }; 52 #define NUMNAMES (sizeof (names) / sizeof (names[0])) 53 54 #define NAMELEN 128 55 char namebuf[NAMELEN]; 56 char nametmp[NAMELEN]; 57 58 char bootinfo[BOOTINFO_MAXSIZE]; 59 struct btinfo_residual btinfo_residual; 60 struct btinfo_console btinfo_console; 61 struct btinfo_clock btinfo_clock; 62 63 RESIDUAL residual; 64 u_long ladr; 65 66 extern u_long ns_per_tick; 67 extern char bootprog_name[], bootprog_rev[], bootprog_maker[], bootprog_date[]; 68 69 void boot __P((void *, u_long)); 70 static void exec_kernel __P((char *)); 71 72 void 73 boot(resp, loadaddr) 74 void *resp; 75 u_long loadaddr; 76 { 77 int n = 0; 78 int addr, speed; 79 char *name, *cnname, *p; 80 ladr = loadaddr; 81 82 /* 83 * console init 84 */ 85 cnname = cninit(&addr, &speed); 86 87 /* make bootinfo */ 88 /* 89 * residual data 90 */ 91 btinfo_residual.common.next = sizeof(btinfo_residual); 92 btinfo_residual.common.type = BTINFO_RESIDUAL; 93 if (resp) { 94 memcpy(&residual, resp, sizeof(residual)); 95 btinfo_residual.addr = (void *)&residual; 96 } else { 97 printf("Warning: no residual data.\n"); 98 btinfo_residual.addr = 0; 99 } 100 101 /* 102 * console 103 */ 104 btinfo_console.common.next = sizeof(btinfo_console); 105 btinfo_console.common.type = BTINFO_CONSOLE; 106 strcpy(btinfo_console.devname, cnname); 107 btinfo_console.addr = addr; 108 btinfo_console.speed = speed; 109 110 /* 111 * clock 112 */ 113 btinfo_clock.common.next = 0; 114 btinfo_clock.common.type = BTINFO_CLOCK; 115 btinfo_clock.ticks_per_sec = resp ? 116 residual.VitalProductData.ProcessorBusHz / 4 : TICKS_PER_SEC; 117 118 p = bootinfo; 119 memcpy(p, (void *)&btinfo_residual, sizeof(btinfo_residual)); 120 p += sizeof(btinfo_residual); 121 memcpy(p, (void *)&btinfo_console, sizeof(btinfo_console)); 122 p += sizeof(btinfo_console); 123 memcpy(p, (void *)&btinfo_clock, sizeof(btinfo_clock)); 124 125 /* 126 * attached kernel check 127 */ 128 init_in(); 129 130 printf("\n"); 131 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 132 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 133 134 for (;;) { 135 name = names[n++]; 136 if (n >= NUMNAMES) 137 n = 0; 138 139 exec_kernel(name); 140 } 141 } 142 143 /* 144 * Exec kernel 145 */ 146 static void 147 exec_kernel(name) 148 char *name; 149 { 150 int howto = 0; 151 char c, *ptr; 152 u_long marks[MARK_MAX]; 153 #ifdef DBMONITOR 154 int go_monitor; 155 extern int db_monitor __P((void)); 156 #endif /* DBMONITOR */ 157 158 ret: 159 printf("\nBoot: "); 160 memset(namebuf, 0, sizeof (namebuf)); 161 (void)tgets(namebuf); 162 163 ptr = namebuf; 164 #ifdef DBMONITOR 165 go_monitor = 0; 166 if (*ptr == '!') { 167 if (*(++ptr) == NULL) { 168 db_monitor(); 169 printf("\n"); 170 goto ret; 171 } else { 172 go_monitor++; 173 } 174 } 175 #endif /* DBMONITOR */ 176 while ((c = *ptr)) { 177 while (c == ' ') 178 c = *++ptr; 179 if (!c) 180 goto next; 181 if (c == '-') { 182 while ((c = *++ptr) && c != ' ') 183 BOOT_FLAG(c, howto); 184 } else { 185 name = ptr; 186 while ((c = *++ptr) && c != ' '); 187 if (c) 188 *ptr++ = 0; 189 } 190 } 191 192 next: 193 printf("Loading %s", name); 194 if (howto) 195 printf(" (howto 0x%x)", howto); 196 printf("\n"); 197 198 marks[MARK_START] = 0; 199 if (loadfile(name, marks, LOAD_ALL) == 0) { 200 #ifdef DBMONITOR 201 if (go_monitor) { 202 db_monitor(); 203 printf("\n"); 204 } 205 #endif /* DBMONITOR */ 206 207 printf("start=0x%lx\n\n", marks[MARK_ENTRY]); 208 delay(1000); 209 __syncicache((void *)marks[MARK_ENTRY], 210 (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); 211 212 run((void *)marks[MARK_SYM], 213 (void *)marks[MARK_END], 214 (void *)howto, 215 (void *)bootinfo, 216 (void *)marks[MARK_ENTRY]); 217 } 218 } 219