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