1 /* $NetBSD: boot.c,v 1.16 2005/12/11 12:17:04 christos 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 <loadfile.h> 36 #include <sys/boot_flag.h> 37 #include <sys/reboot.h> 38 #include <machine/bootinfo.h> 39 #include "boot.h" 40 41 char *names[] = { 42 "in()", 43 "fd(0,1,0)netbsd", "fd(0,1,0)netbsd.gz", 44 "fd(0,1,0)netbsd.old", "fd(0,1,0)netbsd.old.gz", 45 "fd(0,1,0)onetbsd", "fd(0,1,0)onetbsd.gz" 46 }; 47 #define NUMNAMES (sizeof (names) / sizeof (names[0])) 48 49 #define NAMELEN 128 50 char namebuf[NAMELEN]; 51 char nametmp[NAMELEN]; 52 53 struct btinfo_memory btinfo_memory; 54 struct btinfo_console btinfo_console; 55 struct btinfo_clock btinfo_clock; 56 57 extern char bootprog_name[], bootprog_rev[], bootprog_maker[], bootprog_date[]; 58 59 void exec_kernel __P((char *, void *)); 60 61 void 62 main() 63 { 64 int n = 0; 65 int addr, speed; 66 char *name, *cnname; 67 void *p, *bootinfo; 68 69 if (whichCPU() == 1) 70 cpu1(); 71 resetCPU1(); 72 73 /* 74 * console init 75 */ 76 cnname = cninit(&addr, &speed); 77 78 /* 79 * make bootinfo 80 */ 81 bootinfo = (void *)0x3030; 82 83 /* 84 * memory 85 */ 86 btinfo_memory.common.next = sizeof (btinfo_memory); 87 btinfo_memory.common.type = BTINFO_MEMORY; 88 btinfo_memory.memsize = *(int *)0x3010; 89 90 /* 91 * console 92 */ 93 btinfo_console.common.next = sizeof (btinfo_console); 94 btinfo_console.common.type = BTINFO_CONSOLE; 95 strcpy(btinfo_console.devname, cnname); 96 btinfo_console.addr = addr; 97 btinfo_console.speed = speed; 98 99 /* 100 * clock 101 */ 102 btinfo_clock.common.next = 0; 103 btinfo_clock.common.type = BTINFO_CLOCK; 104 btinfo_clock.ticks_per_sec = TICKS_PER_SEC; 105 106 p = bootinfo; 107 memcpy(p, (void *)&btinfo_memory, sizeof (btinfo_memory)); 108 p += sizeof (btinfo_memory); 109 memcpy(p, (void *)&btinfo_console, sizeof (btinfo_console)); 110 p += sizeof (btinfo_console); 111 memcpy(p, (void *)&btinfo_clock, sizeof (btinfo_clock)); 112 113 /* 114 * attached kernel check 115 */ 116 init_in(); 117 118 runCPU1((void *)start_CPU1); 119 wait_for(&CPU1_alive); 120 121 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 122 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 123 printf(">> Memory: %d k\n", btinfo_memory.memsize / 1024); 124 125 for (;;) { 126 name = names[n++]; 127 if (n >= NUMNAMES) 128 n = 0; 129 130 exec_kernel(name, bootinfo); 131 } 132 } 133 134 /* 135 * Exec kernel 136 */ 137 void 138 exec_kernel(name, bootinfo) 139 char *name; 140 void *bootinfo; 141 { 142 int howto = 0; 143 char c, *ptr; 144 u_long marks[MARK_MAX]; 145 #ifdef DBMONITOR 146 int go_monitor; 147 extern int db_monitor __P((void)); 148 #endif /* DBMONITOR */ 149 extern int tgets __P((char *buf)); 150 151 ret: 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%x\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