1 1.7 riastrad /* $NetBSD: boot.c,v 1.7 2022/02/16 23:49:27 riastradh Exp $ */ 2 1.1 garbled 3 1.1 garbled /* 4 1.1 garbled * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 1.1 garbled * Copyright (C) 1995, 1996 TooLs GmbH. 6 1.1 garbled * All rights reserved. 7 1.1 garbled * 8 1.1 garbled * Redistribution and use in source and binary forms, with or without 9 1.1 garbled * modification, are permitted provided that the following conditions 10 1.1 garbled * are met: 11 1.1 garbled * 1. Redistributions of source code must retain the above copyright 12 1.1 garbled * notice, this list of conditions and the following disclaimer. 13 1.1 garbled * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 garbled * notice, this list of conditions and the following disclaimer in the 15 1.1 garbled * documentation and/or other materials provided with the distribution. 16 1.1 garbled * 3. All advertising materials mentioning features or use of this software 17 1.1 garbled * must display the following acknowledgement: 18 1.1 garbled * This product includes software developed by TooLs GmbH. 19 1.1 garbled * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 1.1 garbled * derived from this software without specific prior written permission. 21 1.1 garbled * 22 1.1 garbled * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 1.1 garbled * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 garbled * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 garbled * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 1.1 garbled * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 1.1 garbled * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 1.1 garbled * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 garbled * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 1.1 garbled * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 1.1 garbled * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 garbled */ 33 1.1 garbled 34 1.1 garbled #include <lib/libsa/stand.h> 35 1.1 garbled #include <lib/libsa/loadfile.h> 36 1.1 garbled #include <lib/libkern/libkern.h> 37 1.1 garbled #include <sys/reboot.h> 38 1.1 garbled #include <sys/boot_flag.h> 39 1.1 garbled #include <machine/bootinfo.h> 40 1.1 garbled #include <machine/cpu.h> 41 1.2 garbled #include <machine/iplcb.h> 42 1.1 garbled #include <powerpc/spr.h> 43 1.4 matt #include <powerpc/oea/spr.h> 44 1.1 garbled 45 1.1 garbled #include "boot.h" 46 1.1 garbled 47 1.1 garbled char *names[] = { 48 1.1 garbled "in()", 49 1.1 garbled }; 50 1.1 garbled #define NUMNAMES (sizeof (names) / sizeof (names[0])) 51 1.1 garbled 52 1.1 garbled #define NAMELEN 128 53 1.1 garbled char namebuf[NAMELEN]; 54 1.1 garbled char nametmp[NAMELEN]; 55 1.1 garbled 56 1.1 garbled unsigned char cregs[10]; 57 1.1 garbled 58 1.1 garbled char bootinfo[BOOTINFO_MAXSIZE]; 59 1.1 garbled struct btinfo_iplcb btinfo_iplcb; 60 1.1 garbled struct btinfo_console btinfo_console; 61 1.1 garbled 62 1.1 garbled /*struct ipl_cb iplcb; 63 1.1 garbled struct ipl_directory ipldir;*/ 64 1.1 garbled 65 1.1 garbled extern u_long ns_per_tick; 66 1.5 joerg extern char bootprog_name[], bootprog_rev[]; 67 1.1 garbled 68 1.1 garbled void boot(void *, void *); 69 1.1 garbled static void exec_kernel(char *); 70 1.1 garbled 71 1.1 garbled #define PSL_DR (1<<4) 72 1.1 garbled #define PSL_EE 0x00008000 73 1.1 garbled #define BAT_BL_128K 0x00000000 74 1.1 garbled #define BAT_BL_1M 0x0000001c 75 1.1 garbled #define BAT_BL_2M 0x0000003c 76 1.1 garbled #define BAT_W 0x00000040 77 1.1 garbled #define BAT_I 0x00000020 78 1.1 garbled #define BAT_M 0x00000010 79 1.1 garbled #define BAT_G 0x00000008 80 1.1 garbled #define BAT_X 0x00000004 81 1.1 garbled #define BAT_Vs 0x00000002 82 1.1 garbled #define BAT_Vu 0x00000001 83 1.1 garbled #define BAT_PP_RW 0x00000002 84 1.1 garbled #define BAT_RPN (~0x1ffff) 85 1.1 garbled #define BAT_EPI (~0x1ffffL) 86 1.1 garbled #define BAT_V (BAT_Vs|BAT_Vu) 87 1.1 garbled #define BAT_BL 0x00001ffc 88 1.1 garbled 89 1.1 garbled #define BATU(va, len, v) \ 90 1.1 garbled (((va) & BAT_EPI) | ((len) & BAT_BL) | ((v) & BAT_V)) 91 1.1 garbled #define BATL(pa, wimg, pp) \ 92 1.1 garbled (((pa) & BAT_RPN) | (wimg) | (pp)) 93 1.1 garbled 94 1.1 garbled 95 1.1 garbled static void 96 1.1 garbled setled(uint32_t val) 97 1.1 garbled { 98 1.1 garbled #ifdef POWER 99 1.1 garbled register_t savemsr, msr, savesr15; 100 1.1 garbled 101 1.1 garbled __asm volatile ("mfmsr %0" : "=r"(savemsr)); 102 1.1 garbled msr = savemsr & ~PSL_DR; 103 1.1 garbled __asm volatile ("mtmsr %0" : : "r"(msr)); 104 1.1 garbled 105 1.1 garbled __asm volatile ("mfsr %0,15;isync" : "=r"(savesr15)); 106 1.1 garbled __asm volatile ("mtsr 15,%0" : : "r"(0x82040080)); 107 1.1 garbled __asm volatile ("mtmsr %0" : : "r"(msr|PSL_DR)); 108 1.1 garbled __asm volatile ("isync"); 109 1.1 garbled *(uint32_t *)0xF0A00300 = val; 110 1.1 garbled __asm volatile ("mtmsr %0" : : "r"(savemsr)); 111 1.1 garbled __asm volatile ("mtsr 15,%0;isync" : : "r"(savesr15)); 112 1.1 garbled #else 113 1.1 garbled #ifdef NOTYET 114 1.1 garbled register_t savemsr, msr, batu, batl; 115 1.1 garbled 116 1.1 garbled /* turn on DR */ 117 1.1 garbled __asm volatile ("mfmsr %0" : "=r"(savemsr)); 118 1.1 garbled msr = savemsr|PSL_DR; 119 1.1 garbled __asm volatile ("mtmsr %0" : : "r"(msr)); 120 1.1 garbled __asm volatile ("isync"); 121 1.1 garbled 122 1.1 garbled /* set up a bat and map the whole NVRAM chunk */ 123 1.1 garbled batl = BATL(0xFF600000, BAT_I|BAT_G, BAT_PP_RW); 124 1.1 garbled batu = BATU(0xFF600000, BAT_BL_1M, BAT_Vs); 125 1.1 garbled __asm volatile ("mtdbatl 1,%0; mtdbatu 1,%1;" 126 1.1 garbled :: "r"(batl), "r"(batu)); 127 1.1 garbled __asm volatile ("isync"); 128 1.1 garbled 129 1.1 garbled *(volatile uint32_t *)0xFF600300 = val; 130 1.7 riastrad __asm volatile ("eieio" ::: "memory"); 131 1.1 garbled __asm volatile ("isync"); 132 1.1 garbled 133 1.1 garbled /* put back to normal */ 134 1.1 garbled __asm volatile ("mtmsr %0" : : "r"(savemsr)); 135 1.1 garbled __asm volatile ("isync"); 136 1.1 garbled #endif /* NOTYET */ 137 1.1 garbled #endif 138 1.1 garbled } 139 1.1 garbled 140 1.1 garbled 141 1.1 garbled void 142 1.1 garbled boot(void *iplcb_p, void *extiplcb_p) 143 1.1 garbled { 144 1.1 garbled extern char _end[], _edata[]; 145 1.1 garbled int n = 0; 146 1.1 garbled int addr, speed; 147 1.1 garbled /*unsigned int cpuvers;*/ 148 1.1 garbled char *name, *cnname, *p; 149 1.1 garbled struct ipl_cb *iplcb_ptr; 150 1.1 garbled struct ipl_directory *dirp; 151 1.1 garbled struct ipl_info *infop; 152 1.1 garbled 153 1.1 garbled //setled(0x30100000); /* we have control */ 154 1.1 garbled //for (;;); 155 1.1 garbled iplcb_ptr = (struct ipl_cb *)iplcb_p; 156 1.1 garbled dirp = &(iplcb_ptr->dir); 157 1.1 garbled 158 1.1 garbled /* Clear all of BSS */ 159 1.1 garbled memset(_edata, 0, _end - _edata); 160 1.1 garbled 161 1.1 garbled /* 162 1.1 garbled * console init 163 1.1 garbled */ 164 1.1 garbled //setled(0x30000000); /* attempting r14 setup */ 165 1.1 garbled setup_iocc(); 166 1.1 garbled //setled(0x31000000); /* attempting console init */ 167 1.1 garbled cnname = cninit(&addr, &speed); 168 1.1 garbled printf("\n"); 169 1.1 garbled //setled(0x31100000); /* we have the console */ 170 1.1 garbled 171 1.6 rin printf("IPLCB ptr = %p\n", iplcb_p); 172 1.1 garbled 173 1.1 garbled infop = (struct ipl_info *)((char *)iplcb_p + dirp->iplinfo_off); 174 1.1 garbled printf("Machine model = 0x%x\n", infop->model); 175 1.1 garbled printf("RAM = 0x%x\n", infop->ram_size); 176 1.1 garbled 177 1.1 garbled //dump_iplcb(iplcb_p); 178 1.1 garbled 179 1.1 garbled /* make bootinfo */ 180 1.1 garbled /* 181 1.1 garbled * ipl control block 182 1.1 garbled */ 183 1.1 garbled btinfo_iplcb.common.next = sizeof(btinfo_iplcb); 184 1.1 garbled btinfo_iplcb.common.type = BTINFO_IPLCB; 185 1.1 garbled if (iplcb_ptr) { 186 1.1 garbled btinfo_iplcb.addr = (void *)iplcb_p; 187 1.1 garbled } else { 188 1.1 garbled printf("Warning: no IPL Control Block.\n"); 189 1.1 garbled btinfo_iplcb.addr = 0; 190 1.1 garbled } 191 1.1 garbled 192 1.1 garbled /* 193 1.1 garbled * console 194 1.1 garbled */ 195 1.1 garbled btinfo_console.common.next = sizeof(btinfo_console); 196 1.1 garbled btinfo_console.common.type = BTINFO_CONSOLE; 197 1.1 garbled strcpy(btinfo_console.devname, cnname); 198 1.1 garbled btinfo_console.addr = addr; 199 1.1 garbled btinfo_console.speed = speed; 200 1.1 garbled 201 1.1 garbled p = bootinfo; 202 1.1 garbled memcpy(p, (void *)&btinfo_iplcb, sizeof(btinfo_iplcb)); 203 1.1 garbled p += sizeof(btinfo_iplcb); 204 1.1 garbled memcpy(p, (void *)&btinfo_console, sizeof(btinfo_console)); 205 1.1 garbled p += sizeof(btinfo_console); 206 1.1 garbled 207 1.1 garbled /* 208 1.1 garbled * load kernel if attached 209 1.1 garbled */ 210 1.1 garbled init_in(RELOC); 211 1.1 garbled 212 1.1 garbled setled(0x38000000); /* attempting boot */ 213 1.1 garbled printf("\n"); 214 1.1 garbled printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 215 1.1 garbled 216 1.1 garbled for (;;) { 217 1.1 garbled name = names[n++]; 218 1.1 garbled if (n >= NUMNAMES) 219 1.1 garbled n = 0; 220 1.1 garbled setled(0x38100000 + (0x100000 * n)); 221 1.1 garbled exec_kernel(name); 222 1.1 garbled setled(0x39900000); /* boot failed! */ 223 1.1 garbled } 224 1.1 garbled } 225 1.1 garbled 226 1.1 garbled /* 227 1.1 garbled * Exec kernel 228 1.1 garbled */ 229 1.1 garbled static void 230 1.1 garbled exec_kernel(char *name) 231 1.1 garbled { 232 1.1 garbled int howto = 0; 233 1.1 garbled char c, *ptr; 234 1.1 garbled u_long marks[MARK_MAX]; 235 1.1 garbled #ifdef DBMONITOR 236 1.1 garbled int go_monitor; 237 1.3 dsl extern int db_monitor(void); 238 1.1 garbled 239 1.1 garbled ret: 240 1.1 garbled #endif /* DBMONITOR */ 241 1.1 garbled printf("\nBoot: "); 242 1.1 garbled memset(namebuf, 0, sizeof (namebuf)); 243 1.1 garbled if (tgets(namebuf) == -1) 244 1.1 garbled printf("\n"); 245 1.1 garbled 246 1.1 garbled ptr = namebuf; 247 1.1 garbled #ifdef DBMONITOR 248 1.1 garbled go_monitor = 0; 249 1.1 garbled if (*ptr == '!') { 250 1.1 garbled if (*(++ptr) == NULL) { 251 1.1 garbled db_monitor(); 252 1.1 garbled printf("\n"); 253 1.1 garbled goto ret; 254 1.1 garbled } else { 255 1.1 garbled go_monitor++; 256 1.1 garbled } 257 1.1 garbled } 258 1.1 garbled #endif /* DBMONITOR */ 259 1.1 garbled while ((c = *ptr)) { 260 1.1 garbled while (c == ' ') 261 1.1 garbled c = *++ptr; 262 1.1 garbled if (!c) 263 1.1 garbled goto next; 264 1.1 garbled if (c == '-') { 265 1.1 garbled while ((c = *++ptr) && c != ' ') 266 1.1 garbled BOOT_FLAG(c, howto); 267 1.1 garbled } else { 268 1.1 garbled name = ptr; 269 1.1 garbled while ((c = *++ptr) && c != ' '); 270 1.1 garbled if (c) 271 1.1 garbled *ptr++ = 0; 272 1.1 garbled } 273 1.1 garbled } 274 1.1 garbled 275 1.1 garbled next: 276 1.1 garbled printf("Loading %s", name); 277 1.1 garbled if (howto) 278 1.1 garbled printf(" (howto 0x%x)", howto); 279 1.1 garbled printf("\n"); 280 1.1 garbled 281 1.1 garbled marks[MARK_START] = 0; 282 1.1 garbled if (loadfile(name, marks, LOAD_ALL) == 0) { 283 1.1 garbled #ifdef DBMONITOR 284 1.1 garbled if (go_monitor) { 285 1.1 garbled db_monitor(); 286 1.1 garbled printf("\n"); 287 1.1 garbled } 288 1.1 garbled #endif /* DBMONITOR */ 289 1.1 garbled 290 1.1 garbled printf("start=0x%lx\n\n", marks[MARK_ENTRY]); 291 1.1 garbled delay(1000); 292 1.1 garbled __syncicache((void *)marks[MARK_ENTRY], 293 1.1 garbled (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); 294 1.1 garbled printf("About to run\n"); 295 1.1 garbled run((void *)marks[MARK_SYM], 296 1.1 garbled (void *)marks[MARK_END], 297 1.1 garbled (void *)howto, 298 1.1 garbled (void *)bootinfo, 299 1.1 garbled (void *)marks[MARK_ENTRY]); 300 1.1 garbled } 301 1.1 garbled } 302