1 /* $NetBSD: boot.c,v 1.17 2010/03/02 21:52:32 matt 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/reboot.h> 38 #include <sys/boot_flag.h> 39 #include <machine/bootinfo.h> 40 #include <machine/cpu.h> 41 #include <machine/residual.h> 42 #include <powerpc/spr.h> 43 #include <powerpc/oea/spr.h> 44 45 #include "boot.h" 46 47 char *names[] = { 48 "in()", 49 }; 50 #define NUMNAMES (sizeof (names) / sizeof (names[0])) 51 52 #define NAMELEN 128 53 char namebuf[NAMELEN]; 54 char nametmp[NAMELEN]; 55 56 char bootinfo[BOOTINFO_MAXSIZE]; 57 struct btinfo_residual btinfo_residual; 58 struct btinfo_console btinfo_console; 59 struct btinfo_clock btinfo_clock; 60 61 RESIDUAL residual; 62 63 extern u_long ns_per_tick; 64 extern char bootprog_name[], bootprog_rev[], bootprog_maker[], bootprog_date[]; 65 66 void boot(void *, u_long); 67 static void exec_kernel(char *); 68 69 void 70 boot(void *resp, u_long loadaddr) 71 { 72 extern char _end[], _edata[]; 73 int n = 0; 74 int addr, speed; 75 unsigned int cpuvers; 76 char *name, *cnname, *p; 77 78 /* Clear all of BSS */ 79 memset(_edata, 0, _end - _edata); 80 81 /* 82 * console init 83 */ 84 cnname = cninit(&addr, &speed); 85 #ifdef VGA_RESET 86 vga_reset((u_char *)0xc0000000); 87 #endif 88 89 /* make bootinfo */ 90 /* 91 * residual data 92 */ 93 btinfo_residual.common.next = sizeof(btinfo_residual); 94 btinfo_residual.common.type = BTINFO_RESIDUAL; 95 if (resp) { 96 memcpy(&residual, resp, sizeof(residual)); 97 btinfo_residual.addr = (void *)&residual; 98 } else { 99 printf("Warning: no residual data.\n"); 100 btinfo_residual.addr = 0; 101 } 102 103 /* 104 * console 105 */ 106 btinfo_console.common.next = sizeof(btinfo_console); 107 btinfo_console.common.type = BTINFO_CONSOLE; 108 strcpy(btinfo_console.devname, cnname); 109 btinfo_console.addr = addr; 110 btinfo_console.speed = speed; 111 112 /* 113 * clock 114 */ 115 __asm volatile ("mfpvr %0" : "=r"(cpuvers)); 116 cpuvers >>= 16; 117 btinfo_clock.common.next = 0; 118 btinfo_clock.common.type = BTINFO_CLOCK; 119 if (cpuvers == MPC601) { 120 btinfo_clock.ticks_per_sec = 1000000000; 121 } else { 122 btinfo_clock.ticks_per_sec = resp ? 123 residual.VitalProductData.ProcessorBusHz/4 : TICKS_PER_SEC; 124 } 125 ns_per_tick = 1000000000 / btinfo_clock.ticks_per_sec; 126 127 p = bootinfo; 128 memcpy(p, (void *)&btinfo_residual, sizeof(btinfo_residual)); 129 p += sizeof(btinfo_residual); 130 memcpy(p, (void *)&btinfo_console, sizeof(btinfo_console)); 131 p += sizeof(btinfo_console); 132 memcpy(p, (void *)&btinfo_clock, sizeof(btinfo_clock)); 133 134 /* 135 * load kernel if attached 136 */ 137 init_in(loadaddr); 138 139 printf("\n"); 140 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 141 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 142 143 for (;;) { 144 name = names[n++]; 145 if (n >= NUMNAMES) 146 n = 0; 147 148 exec_kernel(name); 149 } 150 } 151 152 /* 153 * Exec kernel 154 */ 155 static void 156 exec_kernel(char *name) 157 { 158 int howto = 0; 159 char c, *ptr; 160 u_long marks[MARK_MAX]; 161 #ifdef DBMONITOR 162 int go_monitor; 163 extern int db_monitor(void); 164 165 ret: 166 #endif /* DBMONITOR */ 167 printf("\nBoot: "); 168 memset(namebuf, 0, sizeof (namebuf)); 169 if (tgets(namebuf) == -1) 170 printf("\n"); 171 172 ptr = namebuf; 173 #ifdef DBMONITOR 174 go_monitor = 0; 175 if (*ptr == '!') { 176 if (*(++ptr) == NULL) { 177 db_monitor(); 178 printf("\n"); 179 goto ret; 180 } else { 181 go_monitor++; 182 } 183 } 184 #endif /* DBMONITOR */ 185 while ((c = *ptr)) { 186 while (c == ' ') 187 c = *++ptr; 188 if (!c) 189 goto next; 190 if (c == '-') { 191 while ((c = *++ptr) && c != ' ') 192 BOOT_FLAG(c, howto); 193 } else { 194 name = ptr; 195 while ((c = *++ptr) && c != ' '); 196 if (c) 197 *ptr++ = 0; 198 } 199 } 200 201 next: 202 printf("Loading %s", name); 203 if (howto) 204 printf(" (howto 0x%x)", howto); 205 printf("\n"); 206 207 marks[MARK_START] = 0; 208 if (loadfile(name, marks, LOAD_ALL) == 0) { 209 #ifdef DBMONITOR 210 if (go_monitor) { 211 db_monitor(); 212 printf("\n"); 213 } 214 #endif /* DBMONITOR */ 215 216 printf("start=0x%lx\n\n", marks[MARK_ENTRY]); 217 delay(1000); 218 __syncicache((void *)marks[MARK_ENTRY], 219 (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); 220 221 run((void *)marks[MARK_SYM], 222 (void *)marks[MARK_END], 223 (void *)howto, 224 (void *)bootinfo, 225 (void *)marks[MARK_ENTRY]); 226 } 227 } 228