1 /* $NetBSD: boot.c,v 1.18 2009/03/18 10:22:26 cegger 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 <lib/libkern/libkern.h> 37 #include <sys/boot_flag.h> 38 #include <sys/reboot.h> 39 #include <machine/bootinfo.h> 40 #include <machine/cpu.h> 41 42 #include "boot.h" 43 44 char *names[] = { 45 "in()", 46 "fd(0,1,0)netbsd", "fd(0,1,0)netbsd.gz", 47 "fd(0,1,0)netbsd.old", "fd(0,1,0)netbsd.old.gz", 48 "fd(0,1,0)onetbsd", "fd(0,1,0)onetbsd.gz" 49 }; 50 #define NUMNAMES (sizeof (names) / sizeof (names[0])) 51 52 #define NAMELEN 128 53 char namebuf[NAMELEN]; 54 char nametmp[NAMELEN]; 55 56 struct btinfo_memory btinfo_memory; 57 struct btinfo_console btinfo_console; 58 struct btinfo_clock btinfo_clock; 59 60 extern char bootprog_name[], bootprog_rev[], bootprog_maker[], bootprog_date[]; 61 62 void main(void); 63 void exec_kernel(char *, void *); 64 65 void 66 main(void) 67 { 68 int n = 0; 69 int addr, speed; 70 char *name, *cnname; 71 void *p, *bootinfo; 72 73 if (whichCPU() == 1) 74 cpu1(); 75 resetCPU1(); 76 77 /* 78 * console init 79 */ 80 cnname = cninit(&addr, &speed); 81 82 /* 83 * make bootinfo 84 */ 85 bootinfo = (void *)0x3030; 86 87 /* 88 * memory 89 */ 90 btinfo_memory.common.next = sizeof (btinfo_memory); 91 btinfo_memory.common.type = BTINFO_MEMORY; 92 btinfo_memory.memsize = *(int *)0x3010; 93 94 /* 95 * console 96 */ 97 btinfo_console.common.next = sizeof (btinfo_console); 98 btinfo_console.common.type = BTINFO_CONSOLE; 99 strcpy(btinfo_console.devname, cnname); 100 btinfo_console.addr = addr; 101 btinfo_console.speed = speed; 102 103 /* 104 * clock 105 */ 106 btinfo_clock.common.next = 0; 107 btinfo_clock.common.type = BTINFO_CLOCK; 108 btinfo_clock.ticks_per_sec = TICKS_PER_SEC; 109 110 p = bootinfo; 111 memcpy(p, (void *)&btinfo_memory, sizeof (btinfo_memory)); 112 p += sizeof (btinfo_memory); 113 memcpy(p, (void *)&btinfo_console, sizeof (btinfo_console)); 114 p += sizeof (btinfo_console); 115 memcpy(p, (void *)&btinfo_clock, sizeof (btinfo_clock)); 116 117 /* 118 * attached kernel check 119 */ 120 init_in(); 121 122 runCPU1((void *)start_CPU1); 123 wait_for(&CPU1_alive); 124 125 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 126 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 127 printf(">> Memory: %d k\n", btinfo_memory.memsize / 1024); 128 129 for (;;) { 130 name = names[n++]; 131 if (n >= NUMNAMES) 132 n = 0; 133 134 exec_kernel(name, bootinfo); 135 } 136 } 137 138 /* 139 * Exec kernel 140 */ 141 void 142 exec_kernel(char *name, void *bootinfo) 143 { 144 int howto = 0; 145 char c, *ptr; 146 u_long marks[MARK_MAX]; 147 #ifdef DBMONITOR 148 int go_monitor; 149 150 ret: 151 #endif /* DBMONITOR */ 152 printf("\nBoot: "); 153 memset(namebuf, 0, sizeof (namebuf)); 154 (void)tgets(namebuf); 155 156 ptr = namebuf; 157 #ifdef DBMONITOR 158 go_monitor = 0; 159 if (*ptr == '!') { 160 if (*(++ptr) == NULL) { 161 db_monitor(); 162 printf("\n"); 163 goto ret; 164 } else { 165 go_monitor++; 166 } 167 } 168 #endif /* DBMONITOR */ 169 while ((c = *ptr)) { 170 while (c == ' ') 171 c = *++ptr; 172 if (!c) 173 goto next; 174 if (c == '-') { 175 while ((c = *++ptr) && c != ' ') 176 BOOT_FLAG(c, howto); 177 } else { 178 name = ptr; 179 while ((c = *++ptr) && c != ' '); 180 if (c) 181 *ptr++ = 0; 182 } 183 } 184 185 next: 186 printf("Loading %s\n", name); 187 188 marks[MARK_START] = 0; 189 if (loadfile(name, marks, LOAD_ALL) == 0) { 190 #ifdef DBMONITOR 191 if (go_monitor) { 192 db_monitor(); 193 printf("\n"); 194 } 195 #endif /* DBMONITOR */ 196 197 printf("start=0x%lx\n\n", marks[MARK_ENTRY]); 198 delay(1000); 199 __syncicache((void *)marks[MARK_ENTRY], 200 (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); 201 202 *(volatile u_long *)0x0080 = marks[MARK_ENTRY]; 203 run((void *)marks[MARK_SYM], 204 (void *)marks[MARK_END], 205 (void *)howto, 206 bootinfo, 207 (void *)marks[MARK_ENTRY]); 208 } 209 } 210