1 /* $NetBSD: machdep.c,v 1.21 2005/12/24 20:07:20 perry 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 <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.21 2005/12/24 20:07:20 perry Exp $"); 36 37 #include "opt_compat_netbsd.h" 38 #include "opt_mvmetype.h" 39 #include "opt_ddb.h" 40 41 #include <sys/param.h> 42 #include <sys/buf.h> 43 #include <sys/conf.h> 44 #include <sys/device.h> 45 #include <sys/exec.h> 46 #include <sys/extent.h> 47 #include <sys/kernel.h> 48 #include <sys/malloc.h> 49 #include <sys/mbuf.h> 50 #include <sys/mount.h> 51 #include <sys/msgbuf.h> 52 #include <sys/proc.h> 53 #include <sys/reboot.h> 54 #include <sys/sa.h> 55 #include <sys/syscallargs.h> 56 #include <sys/syslog.h> 57 #include <sys/systm.h> 58 #include <sys/user.h> 59 #include <sys/ksyms.h> 60 61 #include <uvm/uvm_extern.h> 62 63 #include <sys/sysctl.h> 64 65 #include <net/netisr.h> 66 67 #include <machine/autoconf.h> 68 #include <machine/bootinfo.h> 69 #include <machine/bus.h> 70 #include <machine/intr.h> 71 #include <machine/pmap.h> 72 #include <machine/platform.h> 73 #include <machine/powerpc.h> 74 #include <machine/trap.h> 75 76 #include <powerpc/oea/bat.h> 77 78 #include <dev/cons.h> 79 80 #if 0 81 #include "vga.h" 82 #if (NVGA > 0) 83 #include <dev/ic/mc6845reg.h> 84 #include <dev/ic/pcdisplayvar.h> 85 #include <dev/ic/vgareg.h> 86 #include <dev/ic/vgavar.h> 87 #endif 88 89 #include "pckbc.h" 90 #if (NPCKBC > 0) 91 #include <dev/isa/isareg.h> 92 #include <dev/ic/i8042reg.h> 93 #include <dev/ic/pckbcvar.h> 94 #endif 95 #endif 96 97 #include "com.h" 98 #if (NCOM > 0) 99 #include <sys/termios.h> 100 #include <dev/ic/comreg.h> 101 #include <dev/ic/comvar.h> 102 void comsoft(void); 103 #endif 104 105 #ifdef DDB 106 #include <machine/db_machdep.h> 107 #include <ddb/db_extern.h> 108 #endif 109 110 #include "ksyms.h" 111 112 void initppc(u_long, u_long, void *); 113 void strayintr(int); 114 int lcsplx(int); 115 void mvmeppc_bus_space_init(void); 116 117 118 /* 119 * Global variables used here and there 120 */ 121 struct mvmeppc_bootinfo bootinfo; 122 123 vaddr_t mvmeppc_intr_reg; /* PReP-compatible interrupt vector register */ 124 125 struct mem_region physmemr[2], availmemr[2]; 126 127 paddr_t avail_end; /* XXX temporary */ 128 129 void 130 initppc(startkernel, endkernel, btinfo) 131 u_long startkernel, endkernel; 132 void *btinfo; 133 { 134 #if NKSYMS || defined(DDB) || defined(LKM) 135 extern void *startsym, *endsym; 136 #endif 137 138 /* 139 * Copy bootinfo. 140 */ 141 memcpy(&bootinfo, btinfo, sizeof(bootinfo)); 142 143 /* 144 * Figure out the board family/type. 145 */ 146 ident_platform(); 147 148 if (platform == NULL) { 149 extern void _mvmeppc_unsup_board(const char *, const char *); 150 char msg[80]; 151 152 sprintf(msg, "Unsupported model: MVME%04x", 153 bootinfo.bi_modelnumber); 154 _mvmeppc_unsup_board(msg, &msg[strlen(msg)]); 155 /* NOTREACHED */ 156 } 157 158 /* 159 * Set memory region 160 */ 161 physmemr[0].start = 0; 162 physmemr[0].size = bootinfo.bi_memsize & ~PGOFSET; 163 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 164 availmemr[0].size = bootinfo.bi_memsize - availmemr[0].start; 165 avail_end = physmemr[0].start + physmemr[0].size; /* XXX temporary */ 166 167 /* 168 * Set CPU clock 169 */ 170 { 171 extern u_long ticks_per_sec, ns_per_tick; 172 173 ticks_per_sec = bootinfo.bi_clocktps; 174 ns_per_tick = 1000000000 / ticks_per_sec; 175 } 176 177 /* 178 * Setup fixed BAT registers. 179 */ 180 oea_batinit( 181 MVMEPPC_PHYS_BASE_IO, BAT_BL_256M, 182 MVMEPPC_PHYS_BASE_MEM, BAT_BL_256M, 183 0); 184 185 /* 186 * Install vectors and interrupt handler. 187 */ 188 oea_init(platform->ext_intr); 189 190 /* 191 * Init bus_space so consinit can work. 192 */ 193 mvmeppc_bus_space_init(); 194 195 #ifdef DEBUG 196 /* 197 * The console should be initialized as early as possible. 198 */ 199 consinit(); 200 #endif 201 202 /* 203 * Set the page size. 204 */ 205 uvm_setpagesize(); 206 207 /* 208 * Initialize pmap module. 209 */ 210 pmap_bootstrap(startkernel, endkernel); 211 212 #if NKSYMS || defined(DDB) || defined(LKM) 213 ksyms_init((int)((u_long)endsym - (u_long)startsym), startsym, endsym); 214 #endif 215 216 #ifdef DDB 217 if (boothowto & RB_KDB) 218 Debugger(); 219 #endif 220 } 221 222 void 223 mem_regions(mem, avail) 224 struct mem_region **mem, **avail; 225 { 226 227 *mem = physmemr; 228 *avail = availmemr; 229 } 230 231 /* 232 * Machine dependent startup code. 233 */ 234 void 235 cpu_startup() 236 { 237 char modelbuf[256]; 238 239 /* 240 * Mapping PReP-compatible interrput vector register. 241 */ 242 mvmeppc_intr_reg = (vaddr_t) mapiodev(MVMEPPC_INTR_REG, PAGE_SIZE); 243 if (!mvmeppc_intr_reg) 244 panic("startup: no room for interrupt register"); 245 246 sprintf(modelbuf, "%s\nCore Speed: %dMHz, Bus Speed: %dMHz\n", 247 platform->model, 248 bootinfo.bi_mpuspeed/1000000, 249 bootinfo.bi_busspeed/1000000); 250 oea_startup(modelbuf); 251 252 /* 253 * Now allow hardware interrupts. 254 */ 255 { 256 int msr; 257 258 splraise(-1); 259 __asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 260 : "=r"(msr) : "K"(PSL_EE)); 261 } 262 263 bus_space_mallocok(); 264 } 265 266 /* 267 * consinit 268 * Initialize system console. 269 */ 270 void 271 consinit() 272 { 273 static int initted = 0; 274 275 if (initted) 276 return; 277 initted = 1; 278 279 #if 0 280 281 #if (NPFB > 0) 282 if (!strcmp(consinfo->devname, "fb")) { 283 pfb_cnattach(consinfo->addr); 284 #if (NPCKBC > 0) 285 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 286 PCKBC_KBD_SLOT); 287 #endif 288 return; 289 } 290 #endif 291 292 #if (NVGA > 0) || (NGTEN > 0) 293 if (!strcmp(consinfo->devname, "vga")) { 294 #if (NGTEN > 0) 295 if (!gten_cnattach(&mvmeppc_mem_space_tag)) 296 goto dokbd; 297 #endif 298 #if (NVGA > 0) 299 if (!vga_cnattach(&mvmeppc_io_space_tag, &mvmeppc_mem_space_tag, 300 -1, 1)) 301 goto dokbd; 302 #endif 303 dokbd: 304 #if (NPCKBC > 0) 305 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 306 PCKBC_KBD_SLOT); 307 #endif 308 return; 309 } 310 #endif /* PC | VGA */ 311 312 #endif 313 314 #if (NCOM > 0) 315 if (!strcmp(bootinfo.bi_consoledev, "PC16550")) { 316 bus_space_tag_t tag = &mvmeppc_isa_io_bs_tag; 317 static const bus_addr_t caddr[2] = {0x3f8, 0x2f8}; 318 int rv; 319 rv = comcnattach(tag, caddr[bootinfo.bi_consolechan], 320 bootinfo.bi_consolespeed, COM_FREQ, COM_TYPE_NORMAL, 321 bootinfo.bi_consolecflag); 322 if (rv) 323 panic("can't init serial console"); 324 325 return; 326 } 327 #endif 328 panic("invalid console device %s", bootinfo.bi_consoledev); 329 } 330 331 /* 332 * Soft tty interrupts. 333 */ 334 void 335 softserial() 336 { 337 338 #if (NCOM > 0) 339 comsoft(); 340 #endif 341 } 342 343 /* 344 * Stray interrupts. 345 */ 346 void 347 strayintr(irq) 348 int irq; 349 { 350 351 log(LOG_ERR, "stray interrupt %d\n", irq); 352 } 353 354 /* 355 * Halt or reboot the machine after syncing/dumping according to howto. 356 */ 357 void 358 cpu_reboot(howto, what) 359 int howto; 360 char *what; 361 { 362 static int syncing; 363 364 if (cold) { 365 howto |= RB_HALT; 366 goto halt_sys; 367 } 368 369 boothowto = howto; 370 if ((howto & RB_NOSYNC) == 0 && syncing == 0) { 371 syncing = 1; 372 vfs_shutdown(); /* sync */ 373 resettodr(); /* set wall clock */ 374 } 375 376 /* Disable intr */ 377 splhigh(); 378 379 /* Do dump if requested */ 380 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 381 oea_dumpsys(); 382 383 halt_sys: 384 doshutdownhooks(); 385 386 if (howto & RB_HALT) { 387 printf("\n"); 388 printf("The operating system has halted.\n"); 389 printf("Please press any key to reboot.\n\n"); 390 cnpollc(1); /* for proper keyboard command handling */ 391 cngetc(); 392 cnpollc(0); 393 } 394 395 printf("rebooting...\n\n"); 396 397 (*platform->reset)(); 398 399 printf("Oops! Board reset failed!\n"); 400 401 for (;;) 402 continue; 403 /* NOTREACHED */ 404 } 405 406 /* 407 * lcsplx() is called from locore; it is an open-coded version of 408 * splx() differing in that it returns the previous priority level. 409 */ 410 int 411 lcsplx(ipl) 412 int ipl; 413 { 414 int oldcpl; 415 416 __asm volatile("sync; eieio\n"); /* reorder protect */ 417 oldcpl = cpl; 418 cpl = ipl; 419 if (ipending & ~ipl) 420 do_pending_int(); 421 __asm volatile("sync; eieio\n"); /* reorder protect */ 422 423 return (oldcpl); 424 } 425 426 427 struct powerpc_bus_space mvmeppc_isa_io_bs_tag = { 428 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE, 429 MVMEPPC_PHYS_BASE_IO, /* 60x-bus address of ISA I/O Space */ 430 0x00000000, /* Corresponds to ISA-bus I/O address 0x0 */ 431 0x00010000, /* End of ISA-bus I/O address space, +1 */ 432 }; 433 434 struct powerpc_bus_space mvmeppc_pci_io_bs_tag = { 435 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE, 436 MVMEPPC_PHYS_BASE_IO, /* 60x-bus address of PCI I/O Space */ 437 0x00000000, /* Corresponds to PCI-bus I/O address 0x0 */ 438 MVMEPPC_PHYS_SIZE_IO, /* End of PCI-bus I/O address space, +1 */ 439 }; 440 441 struct powerpc_bus_space mvmeppc_isa_mem_bs_tag = { 442 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, 443 MVMEPPC_PHYS_BASE_MEM, /* 60x-bus address of ISA Memory Space */ 444 0x00000000, /* Corresponds to ISA-bus Memory addr 0x0 */ 445 0x01000000, /* End of ISA-bus Memory addr space, +1 */ 446 }; 447 448 struct powerpc_bus_space mvmeppc_pci_mem_bs_tag = { 449 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, 450 MVMEPPC_PHYS_BASE_MEM, /* 60x-bus address of PCI Memory Space */ 451 0x00000000, /* Corresponds to PCI-bus Memory addr 0x0 */ 452 MVMEPPC_PHYS_SIZE_MEM, /* End of PCI-bus Memory addr space, +1 */ 453 }; 454 static char ex_storage[MVMEPPC_BUS_SPACE_NUM_REGIONS][EXTENT_FIXED_STORAGE_SIZE(8)] 455 __attribute__((aligned(8))); 456 457 458 void 459 mvmeppc_bus_space_init(void) 460 { 461 462 int error; 463 464 error = bus_space_init(&mvmeppc_pci_io_bs_tag, "pci_io", 465 ex_storage[MVMEPPC_BUS_SPACE_IO], 466 sizeof(ex_storage[MVMEPPC_BUS_SPACE_IO])); 467 468 if (extent_alloc_region(mvmeppc_pci_io_bs_tag.pbs_extent, 469 MVMEPPC_PHYS_RESVD_START_IO, MVMEPPC_PHYS_RESVD_SIZE_IO, 470 EX_NOWAIT) != 0) 471 panic("mvmeppc_bus_space_init: reserving I/O hole"); 472 473 mvmeppc_isa_io_bs_tag.pbs_extent = mvmeppc_pci_io_bs_tag.pbs_extent; 474 error = bus_space_init(&mvmeppc_isa_io_bs_tag, "isa_io", NULL, 0); 475 476 error = bus_space_init(&mvmeppc_pci_mem_bs_tag, "pci_mem", 477 ex_storage[MVMEPPC_BUS_SPACE_MEM], 478 sizeof(ex_storage[MVMEPPC_BUS_SPACE_MEM])); 479 480 mvmeppc_isa_mem_bs_tag.pbs_extent = mvmeppc_pci_mem_bs_tag.pbs_extent; 481 error = bus_space_init(&mvmeppc_isa_mem_bs_tag, "isa_mem", NULL, 0); 482 } 483