1 /* $NetBSD: machdep.c,v 1.79 2002/09/25 22:21:16 thorpej 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 "opt_compat_netbsd.h" 35 #include "opt_ddb.h" 36 37 #include <sys/param.h> 38 #include <sys/buf.h> 39 #include <sys/exec.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/mount.h> 43 #include <sys/msgbuf.h> 44 #include <sys/proc.h> 45 #include <sys/reboot.h> 46 #include <sys/syscallargs.h> 47 #include <sys/syslog.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/user.h> 51 #include <sys/boot_flag.h> 52 53 #include <uvm/uvm_extern.h> 54 55 #include <net/netisr.h> 56 57 #include <machine/db_machdep.h> 58 #include <ddb/db_extern.h> 59 60 #include <dev/ofw/openfirm.h> 61 62 #include <machine/autoconf.h> 63 #include <machine/bat.h> 64 #include <machine/pmap.h> 65 #include <machine/powerpc.h> 66 #include <machine/trap.h> 67 68 #include <machine/platform.h> 69 70 #include <dev/cons.h> 71 72 /* 73 * Global variables used here and there 74 */ 75 char bootpath[256]; 76 77 int lcsplx(int); /* called from locore.S */ 78 79 static int fake_spl __P((int)); 80 static void fake_splx __P((int)); 81 static void fake_setsoft __P((int)); 82 static void fake_clock_return __P((struct clockframe *, int)); 83 static void *fake_intr_establish __P((int, int, int, int (*)(void *), void *)); 84 static void fake_intr_disestablish __P((void *)); 85 86 struct machvec machine_interface = { 87 fake_spl, 88 fake_spl, 89 fake_splx, 90 fake_setsoft, 91 fake_clock_return, 92 fake_intr_establish, 93 fake_intr_disestablish, 94 }; 95 96 void ofppc_bootstrap_console(void); 97 98 struct pmap ofw_pmap; 99 100 void 101 initppc(startkernel, endkernel, args) 102 u_int startkernel, endkernel; 103 char *args; 104 { 105 #ifdef DDB 106 extern void *startsym, *endsym; 107 #endif 108 109 /* Initialize the bootstrap console. */ 110 ofppc_bootstrap_console(); 111 112 /* 113 * Initialize the bat registers 114 */ 115 mpc6xx_batinit(0); 116 117 /* 118 * Initialize the platform structure. This may add entries 119 * to the BAT table. 120 */ 121 platform_init(); 122 123 #ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */ 124 OF_set_callback(callback); 125 #endif 126 127 mpc6xx_init(NULL); 128 129 /* 130 * Now that translation is enabled (and we can access bus space), 131 * initialize the console. 132 */ 133 (*platform.cons_init)(); 134 135 /* 136 * Parse arg string. 137 */ 138 strcpy(bootpath, args); 139 while (*++args && *args != ' '); 140 if (*args) { 141 for(*args++ = 0; *args; args++) 142 BOOT_FLAG(*args, boothowto); 143 } 144 145 /* 146 * Set the page size. 147 */ 148 uvm_setpagesize(); 149 150 /* 151 * Initialize pmap module. 152 */ 153 pmap_bootstrap(startkernel, endkernel, NULL); 154 155 #ifdef DDB 156 ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym); 157 if (boothowto & RB_KDB) 158 Debugger(); 159 #endif 160 #ifdef IPKDB 161 /* 162 * Now trap to IPKDB 163 */ 164 ipkdb_init(); 165 if (boothowto & RB_KDB) 166 ipkdb_connect(0); 167 #endif 168 } 169 170 /* 171 * Machine dependent startup code. 172 */ 173 void 174 cpu_startup() 175 { 176 177 mpc6xx_startup(NULL); 178 179 /* 180 * Now allow hardware interrupts. 181 */ 182 splhigh(); 183 mtmsr(mfmsr() | PSL_EE | PSL_RI); 184 (*platform.softintr_init)(); 185 } 186 187 void 188 consinit() 189 { 190 191 (*cn_tab->cn_probe)(cn_tab); 192 } 193 194 void ofcons_cnprobe(struct consdev *); 195 int ofppc_cngetc(dev_t); 196 void ofppc_cnputc(dev_t, int); 197 198 struct consdev ofppc_bootcons = { 199 ofcons_cnprobe, NULL, ofppc_cngetc, ofppc_cnputc, nullcnpollc, NULL, 200 makedev(0,0), 1, 201 }; 202 203 int ofppc_stdin_ihandle, ofppc_stdout_ihandle; 204 int ofppc_stdin_phandle, ofppc_stdout_phandle; 205 206 void 207 ofppc_bootstrap_console(void) 208 { 209 int chosen; 210 char data[4]; 211 212 chosen = OF_finddevice("/chosen"); 213 214 if (OF_getprop(chosen, "stdin", data, sizeof(data)) != sizeof(int)) 215 goto nocons; 216 ofppc_stdin_ihandle = of_decode_int(data); 217 ofppc_stdin_phandle = OF_instance_to_package(ofppc_stdin_ihandle); 218 219 if (OF_getprop(chosen, "stdout", data, sizeof(data)) != sizeof(int)) 220 goto nocons; 221 ofppc_stdout_ihandle = of_decode_int(data); 222 ofppc_stdout_phandle = OF_instance_to_package(ofppc_stdout_ihandle); 223 224 cn_tab = &ofppc_bootcons; 225 226 nocons: 227 return; 228 } 229 230 int 231 ofppc_cngetc(dev_t dev) 232 { 233 u_char ch = '\0'; 234 int l; 235 236 while ((l = OF_read(ofppc_stdin_ihandle, &ch, 1)) != 1) 237 if (l != -2 && l != 0) 238 return (-1); 239 240 return (ch); 241 } 242 243 void 244 ofppc_cnputc(dev_t dev, int c) 245 { 246 char ch = c; 247 248 OF_write(ofppc_stdout_ihandle, &ch, 1); 249 } 250 251 /* 252 * Crash dump handling. 253 */ 254 255 /* 256 * Stray interrupts. 257 */ 258 void 259 strayintr(irq) 260 int irq; 261 { 262 log(LOG_ERR, "stray interrupt %d\n", irq); 263 } 264 265 /* 266 * Halt or reboot the machine after syncing/dumping according to howto. 267 */ 268 void 269 cpu_reboot(howto, what) 270 int howto; 271 char *what; 272 { 273 static int syncing; 274 static char str[256]; 275 char *ap = str, *ap1 = ap; 276 277 boothowto = howto; 278 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 279 syncing = 1; 280 vfs_shutdown(); /* sync */ 281 resettodr(); /* set wall clock */ 282 } 283 splhigh(); 284 if (howto & RB_HALT) { 285 doshutdownhooks(); 286 printf("halted\n\n"); 287 ppc_exit(); 288 } 289 if (!cold && (howto & RB_DUMP)) 290 mpc6xx_dumpsys(); 291 doshutdownhooks(); 292 printf("rebooting\n\n"); 293 if (what && *what) { 294 if (strlen(what) > sizeof str - 5) 295 printf("boot string too large, ignored\n"); 296 else { 297 strcpy(str, what); 298 ap1 = ap = str + strlen(str); 299 *ap++ = ' '; 300 } 301 } 302 *ap++ = '-'; 303 if (howto & RB_SINGLE) 304 *ap++ = 's'; 305 if (howto & RB_KDB) 306 *ap++ = 'd'; 307 *ap++ = 0; 308 if (ap[-2] == '-') 309 *ap1 = 0; 310 ppc_boot(str); 311 } 312 313 #ifdef notyet 314 /* 315 * OpenFirmware callback routine 316 */ 317 void 318 callback(p) 319 void *p; 320 { 321 panic("callback"); /* for now XXX */ 322 } 323 #endif 324 325 /* 326 * Perform an `splx()' for locore. 327 */ 328 int 329 lcsplx(int ipl) 330 { 331 332 return (_spllower(ipl)); 333 } 334 335 /* 336 * Initial Machine Interface. 337 */ 338 static int 339 fake_spl(int new) 340 { 341 int scratch; 342 343 asm volatile ("mfmsr %0; andi. %0,%0,%1; mtmsr %0; isync" 344 : "=r"(scratch) : "K"((u_short)~(PSL_EE|PSL_ME))); 345 return (-1); 346 } 347 348 static void 349 fake_setsoft(int ipl) 350 { 351 /* Do nothing */ 352 } 353 354 static void 355 fake_splx(new) 356 int new; 357 { 358 359 (void) fake_spl(0); 360 } 361 362 static void 363 fake_clock_return(frame, nticks) 364 struct clockframe *frame; 365 int nticks; 366 { 367 /* Do nothing */ 368 } 369 370 static void * 371 fake_intr_establish(irq, level, ist, handler, arg) 372 int irq, level, ist; 373 int (*handler) __P((void *)); 374 void *arg; 375 { 376 377 panic("fake_intr_establish"); 378 } 379 380 static void 381 fake_intr_disestablish(cookie) 382 void *cookie; 383 { 384 385 panic("fake_intr_disestablish"); 386 } 387