1 /* $NetBSD: machdep.c,v 1.74 2002/09/25 22:21:06 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 #include "opt_ipkdb.h" 37 38 #include <sys/param.h> 39 #include <sys/buf.h> 40 #include <sys/conf.h> 41 #include <sys/device.h> 42 #include <sys/exec.h> 43 #include <sys/kernel.h> 44 #include <sys/malloc.h> 45 #include <sys/mbuf.h> 46 #include <sys/mount.h> 47 #include <sys/msgbuf.h> 48 #include <sys/proc.h> 49 #include <sys/reboot.h> 50 #include <sys/syscallargs.h> 51 #include <sys/syslog.h> 52 #include <sys/systm.h> 53 #include <sys/user.h> 54 55 #ifdef DDB 56 #include <machine/db_machdep.h> 57 #include <ddb/db_extern.h> 58 #endif 59 60 #include <uvm/uvm_extern.h> 61 62 #include <net/netisr.h> 63 64 #include <powerpc/mpc6xx/bat.h> 65 #include <machine/bootinfo.h> 66 #include <machine/autoconf.h> 67 #define _POWERPC_BUS_DMA_PRIVATE 68 #include <machine/bus.h> 69 #include <machine/intr.h> 70 #include <machine/pmap.h> 71 #include <machine/powerpc.h> 72 #include <machine/trap.h> 73 74 #include <dev/cons.h> 75 76 #include "pfb.h" 77 78 #include "pc.h" 79 #if (NPC > 0) 80 #include <machine/pccons.h> 81 #endif 82 83 #include "vga.h" 84 #if (NVGA > 0) 85 #include <dev/ic/mc6845reg.h> 86 #include <dev/ic/pcdisplayvar.h> 87 #include <dev/ic/vgareg.h> 88 #include <dev/ic/vgavar.h> 89 #endif 90 91 #include "pckbc.h" 92 #if (NPCKBC > 0) 93 #include <dev/isa/isareg.h> 94 #include <dev/ic/i8042reg.h> 95 #include <dev/ic/pckbcvar.h> 96 #endif 97 98 #include "com.h" 99 #if (NCOM > 0) 100 #include <sys/termios.h> 101 #include <dev/ic/comreg.h> 102 #include <dev/ic/comvar.h> 103 #endif 104 105 /* 106 * Global variables used here and there 107 */ 108 char bootinfo[BOOTINFO_MAXSIZE]; 109 110 paddr_t bebox_mb_reg; /* BeBox MotherBoard register */ 111 112 #define OFMEMREGIONS 32 113 struct mem_region physmemr[OFMEMREGIONS], availmemr[OFMEMREGIONS]; 114 115 char *bootpath; 116 117 paddr_t avail_end; /* XXX temporary */ 118 119 extern void *startsym, *endsym; 120 121 void 122 initppc(startkernel, endkernel, args, btinfo) 123 u_int startkernel, endkernel, args; 124 void *btinfo; 125 { 126 extern void consinit __P((void)); 127 extern void ext_intr __P((void)); 128 129 /* 130 * copy bootinfo 131 */ 132 memcpy(bootinfo, btinfo, sizeof (bootinfo)); 133 134 /* 135 * BeBox memory region set 136 */ 137 { 138 struct btinfo_memory *meminfo; 139 140 meminfo = 141 (struct btinfo_memory *)lookup_bootinfo(BTINFO_MEMORY); 142 if (!meminfo) 143 panic("not found memory information in bootinfo"); 144 physmemr[0].start = 0; 145 physmemr[0].size = meminfo->memsize & ~PGOFSET; 146 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 147 availmemr[0].size = meminfo->memsize - availmemr[0].start; 148 } 149 avail_end = physmemr[0].start + physmemr[0].size; /* XXX temporary */ 150 151 /* 152 * Get CPU clock 153 */ 154 { 155 struct btinfo_clock *clockinfo; 156 extern u_long ticks_per_sec, ns_per_tick; 157 158 clockinfo = 159 (struct btinfo_clock *)lookup_bootinfo(BTINFO_CLOCK); 160 if (!clockinfo) 161 panic("not found clock information in bootinfo"); 162 ticks_per_sec = clockinfo->ticks_per_sec; 163 ns_per_tick = 1000000000 / ticks_per_sec; 164 } 165 166 /* 167 * BeBox MotherBoard's Register 168 * Interrupt Mask Reset 169 */ 170 *(volatile u_int *)(MOTHER_BOARD_REG + CPU0_INT_MASK) = 0x0ffffffc; 171 *(volatile u_int *)(MOTHER_BOARD_REG + CPU0_INT_MASK) = 0x80000023; 172 *(volatile u_int *)(MOTHER_BOARD_REG + CPU1_INT_MASK) = 0x0ffffffc; 173 174 /* 175 * boothowto 176 */ 177 boothowto = args; 178 179 /* 180 * Init the I/O stuff before the console 181 */ 182 bebox_bus_space_init(); 183 184 /* 185 * i386 port says, that this shouldn't be here, 186 * but I really think the console should be initialized 187 * as early as possible. 188 */ 189 consinit(); 190 191 /* 192 * Set up initial BAT table 193 */ 194 mpc6xx_batinit( 195 BEBOX_BUS_SPACE_IO, BAT_BL_256M, 196 BEBOX_BUS_SPACE_MEM, BAT_BL_256M, 197 0); 198 199 /* 200 * Initialize the vector table and interrupt routine. 201 */ 202 mpc6xx_init(ext_intr); 203 204 /* 205 * Set the page size. 206 */ 207 uvm_setpagesize(); 208 209 /* 210 * Initialize pmap module. 211 */ 212 pmap_bootstrap(startkernel, endkernel, NULL); 213 214 #ifdef DDB 215 ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym); 216 #endif 217 #ifdef IPKDB 218 /* 219 * Now trap to IPKDB 220 */ 221 ipkdb_init(); 222 if (boothowto & RB_KDB) 223 ipkdb_connect(0); 224 #endif 225 } 226 227 void 228 mem_regions(mem, avail) 229 struct mem_region **mem, **avail; 230 { 231 *mem = physmemr; 232 *avail = availmemr; 233 } 234 235 /* 236 * Machine dependent startup code. 237 */ 238 void 239 cpu_startup() 240 { 241 /* 242 * BeBox Mother Board's Register Mapping 243 */ 244 bebox_mb_reg = (vaddr_t) mapiodev(MOTHER_BOARD_REG, NBPG); 245 if (!bebox_mb_reg) 246 panic("cpu_startup: no room for interrupt register"); 247 248 /* 249 * Do common VM initialization 250 */ 251 mpc6xx_startup(NULL); 252 253 /* 254 * Now that we have VM, malloc's are OK in bus_space. 255 */ 256 bebox_bus_space_mallocok(); 257 258 /* 259 * Now allow hardware interrupts. 260 */ 261 { 262 int msr; 263 264 splhigh(); 265 __asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 266 : "=r"(msr) : "K"(PSL_EE)); 267 } 268 } 269 270 /* 271 * lookup_bootinfo: 272 * Look up information in bootinfo of boot loader. 273 */ 274 void * 275 lookup_bootinfo(type) 276 int type; 277 { 278 struct btinfo_common *bt; 279 struct btinfo_common *help = (struct btinfo_common *)bootinfo; 280 281 do { 282 bt = help; 283 if (bt->type == type) 284 return (help); 285 help = (struct btinfo_common *)((char*)help + bt->next); 286 } while (bt->next && 287 (size_t)help < (size_t)bootinfo + sizeof (bootinfo)); 288 289 return (NULL); 290 } 291 292 /* 293 * consinit 294 * Initialize system console. 295 */ 296 void 297 consinit() 298 { 299 struct btinfo_console *consinfo; 300 static int initted; 301 302 if (initted) 303 return; 304 initted = 1; 305 306 consinfo = (struct btinfo_console *)lookup_bootinfo(BTINFO_CONSOLE); 307 if (!consinfo) 308 panic("not found console information in bootinfo"); 309 310 #if (NPFB > 0) 311 if (!strcmp(consinfo->devname, "be")) { 312 pfb_cnattach(consinfo->addr); 313 #if (NPCKBC > 0) 314 pckbc_cnattach(&bebox_isa_io_bs_tag, IO_KBD, KBCMDP, 315 PCKBC_KBD_SLOT); 316 #endif 317 return; 318 } 319 #endif 320 321 #if (NPC > 0) || (NVGA > 0) 322 if (!strcmp(consinfo->devname, "vga")) { 323 #if (NVGA > 0) 324 if (!vga_cnattach(&bebox_io_bs_tag, &bebox_mem_bs_tag, 325 -1, 1)) 326 goto dokbd; 327 #endif 328 #if (NPC > 0) 329 pccnattach(); 330 #endif 331 dokbd: 332 #if (NPCKBC > 0) 333 pckbc_cnattach(&bebox_isa_io_bs_tag, IO_KBD, KBCMDP, 334 PCKBC_KBD_SLOT); 335 #endif 336 return; 337 } 338 #endif /* PC | VGA */ 339 340 #if (NCOM > 0) 341 if (!strcmp(consinfo->devname, "com")) { 342 bus_space_tag_t tag = &bebox_isa_io_bs_tag; 343 344 if(comcnattach(tag, consinfo->addr, consinfo->speed, COM_FREQ, 345 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8))) 346 panic("can't init serial console"); 347 348 return; 349 } 350 #endif 351 panic("invalid console device %s", consinfo->devname); 352 } 353 354 #if (NPCKBC > 0) && (NPCKBD == 0) 355 /* 356 * glue code to support old console code with the 357 * mi keyboard controller driver 358 */ 359 int 360 pckbc_machdep_cnattach(kbctag, kbcslot) 361 pckbc_tag_t kbctag; 362 pckbc_slot_t kbcslot; 363 { 364 #if (NPC > 0) 365 return (pcconskbd_cnattach(kbctag, kbcslot)); 366 #else 367 return (ENXIO); 368 #endif 369 } 370 #endif 371 372 /* 373 * Stray interrupts. 374 */ 375 void 376 strayintr(irq) 377 int irq; 378 { 379 log(LOG_ERR, "stray interrupt %d\n", irq); 380 } 381 382 /* 383 * Halt or reboot the machine after syncing/dumping according to howto. 384 */ 385 void 386 cpu_reboot(howto, what) 387 int howto; 388 char *what; 389 { 390 static int syncing; 391 static char str[256]; 392 char *ap = str, *ap1 = ap; 393 394 boothowto = howto; 395 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 396 syncing = 1; 397 vfs_shutdown(); /* sync */ 398 resettodr(); /* set wall clock */ 399 } 400 splhigh(); 401 if (howto & RB_HALT) { 402 doshutdownhooks(); 403 printf("halted\n\n"); 404 #if 0 405 ppc_exit(); 406 #endif 407 } 408 if (!cold && (howto & RB_DUMP)) 409 mpc6xx_dumpsys(); 410 doshutdownhooks(); 411 printf("rebooting\n\n"); 412 if (what && *what) { 413 if (strlen(what) > sizeof str - 5) 414 printf("boot string too large, ignored\n"); 415 else { 416 strcpy(str, what); 417 ap1 = ap = str + strlen(str); 418 *ap++ = ' '; 419 } 420 } 421 *ap++ = '-'; 422 if (howto & RB_SINGLE) 423 *ap++ = 's'; 424 if (howto & RB_KDB) 425 *ap++ = 'd'; 426 *ap++ = 0; 427 if (ap[-2] == '-') 428 *ap1 = 0; 429 #if 0 430 ppc_boot(str); 431 #endif 432 while (1); 433 } 434 435 void 436 lcsplx(ipl) 437 int ipl; 438 { 439 splx(ipl); 440 } 441