1 /* $NetBSD: machdep.c,v 1.110 2010/12/20 00:25:40 matt Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer 9 * Science Department, The Mach Operating System project at 10 * Carnegie-Mellon University and Ralph Campbell. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 37 */ 38 /* 39 * Copyright (c) 1988 University of Utah. 40 * 41 * This code is derived from software contributed to Berkeley by 42 * the Systems Programming Group of the University of Utah Computer 43 * Science Department, The Mach Operating System project at 44 * Carnegie-Mellon University and Ralph Campbell. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by the University of 57 * California, Berkeley and its contributors. 58 * 4. Neither the name of the University nor the names of its contributors 59 * may be used to endorse or promote products derived from this software 60 * without specific prior written permission. 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 72 * SUCH DAMAGE. 73 * 74 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 75 */ 76 77 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 78 79 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.110 2010/12/20 00:25:40 matt Exp $"); 80 81 /* from: Utah Hdr: machdep.c 1.63 91/04/24 */ 82 83 #include "opt_ddb.h" 84 #include "opt_execfmt.h" 85 #include "opt_modular.h" 86 87 #include <sys/param.h> 88 #include <sys/systm.h> 89 #include <sys/signalvar.h> 90 #include <sys/kernel.h> 91 #include <sys/proc.h> 92 #include <sys/buf.h> 93 #include <sys/reboot.h> 94 #include <sys/conf.h> 95 #include <sys/file.h> 96 #include <sys/malloc.h> 97 #include <sys/mbuf.h> 98 #include <sys/msgbuf.h> 99 #include <sys/ioctl.h> 100 #include <sys/device.h> 101 #include <sys/exec.h> 102 #include <sys/mount.h> 103 #include <sys/syscallargs.h> 104 #include <sys/kcore.h> 105 #include <sys/ksyms.h> 106 107 #include <uvm/uvm_extern.h> 108 109 #include <ufs/mfs/mfs_extern.h> /* mfs_initminiroot() */ 110 111 #include <machine/cpu.h> 112 #include <machine/intr.h> 113 #include <machine/reg.h> 114 #include <machine/psl.h> 115 #include <machine/pte.h> 116 #include <machine/autoconf.h> 117 #include <machine/bootinfo.h> 118 #include <machine/apbus.h> 119 #include <machine/apcall.h> 120 121 #include <mips/cache.h> 122 #include <mips/locore.h> 123 124 #define _NEWSMIPS_BUS_DMA_PRIVATE 125 #include <machine/bus.h> 126 127 #ifdef DDB 128 #include <machine/db_machdep.h> 129 #include <ddb/db_access.h> 130 #include <ddb/db_extern.h> 131 #include <ddb/db_sym.h> 132 #endif 133 134 #include <machine/adrsmap.h> 135 #include <machine/machConst.h> 136 #include <newsmips/newsmips/machid.h> 137 #include <dev/cons.h> 138 139 #include "ksyms.h" 140 141 /* Our exported CPU info; we can have only one. */ 142 struct cpu_info cpu_info_store; 143 144 /* maps for VM objects */ 145 146 struct vm_map *phys_map = NULL; 147 148 char *bootinfo = NULL; /* pointer to bootinfo structure */ 149 int systype; /* what type of NEWS we are */ 150 struct apbus_sysinfo *_sip = NULL; 151 152 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 153 int mem_cluster_cnt; 154 155 struct idrom idrom; 156 void (*hardware_intr)(uint32_t, uint32_t, uint32_t, uint32_t); 157 void (*enable_intr)(void); 158 void (*disable_intr)(void); 159 void (*enable_timer)(void); 160 161 /* 162 * Local functions. 163 */ 164 165 /* initialize bss, etc. from kernel start, before main() is called. */ 166 void mach_init(int, int, int, int); 167 168 void prom_halt(int) __attribute__((__noreturn__)); 169 void to_monitor(int) __attribute__((__noreturn__)); 170 171 #ifdef DEBUG 172 /* stacktrace code violates prototypes to get callee's registers */ 173 extern void stacktrace(void); /*XXX*/ 174 #endif 175 176 /* 177 * safepri is a safe priority for sleep to set for a spin-wait 178 * during autoconfiguration or after a panic. Used as an argument to splx(). 179 * XXX disables interrupt 5 to disable mips3 on-chip clock, which also 180 * disables mips1 FPU interrupts. 181 */ 182 int safepri = MIPS3_PSL_LOWIPL; /* XXX */ 183 184 /* 185 * This is a mask of bits to clear in the SR when we go to a 186 * given interrupt priority level. 187 */ 188 const uint32_t ipl_sr_bits[_IPL_N] = { 189 [IPL_NONE] = 0, 190 [IPL_SOFTCLOCK] = 191 MIPS_SOFT_INT_MASK_0, 192 [IPL_SOFTNET] = 193 MIPS_SOFT_INT_MASK_0 | MIPS_SOFT_INT_MASK_1, 194 [IPL_VM] = 195 MIPS_SOFT_INT_MASK_0 | MIPS_SOFT_INT_MASK_1 | 196 MIPS_INT_MASK_0 | 197 MIPS_INT_MASK_1, 198 [IPL_SCHED] = 199 MIPS_SOFT_INT_MASK_0 | MIPS_SOFT_INT_MASK_1 | 200 MIPS_INT_MASK_0 | 201 MIPS_INT_MASK_1 | 202 MIPS_INT_MASK_2, 203 }; 204 205 extern u_long bootdev; 206 extern char edata[], end[]; 207 208 /* 209 * Do all the stuff that locore normally does before calling main(). 210 * Process arguments passed to us by the prom monitor. 211 * Return the first page address following the system. 212 */ 213 void 214 mach_init(int x_boothowto, int x_bootdev, int x_bootname, int x_maxmem) 215 { 216 u_long first, last; 217 char *kernend; 218 struct btinfo_magic *bi_magic; 219 struct btinfo_bootarg *bi_arg; 220 struct btinfo_systype *bi_systype; 221 #if NKSYMS || defined(DDB) || defined(MODULAR) 222 struct btinfo_symtab *bi_sym; 223 int nsym = 0; 224 char *ssym, *esym; 225 226 ssym = esym = NULL; /* XXX: gcc */ 227 #endif 228 bi_arg = NULL; 229 230 bootinfo = (void *)BOOTINFO_ADDR; /* XXX */ 231 bi_magic = lookup_bootinfo(BTINFO_MAGIC); 232 if (bi_magic && bi_magic->magic == BOOTINFO_MAGIC) { 233 bi_arg = lookup_bootinfo(BTINFO_BOOTARG); 234 if (bi_arg) { 235 x_boothowto = bi_arg->howto; 236 x_bootdev = bi_arg->bootdev; 237 x_maxmem = bi_arg->maxmem; 238 } 239 #if NKSYMS || defined(DDB) || defined(MODULAR) 240 bi_sym = lookup_bootinfo(BTINFO_SYMTAB); 241 if (bi_sym) { 242 nsym = bi_sym->nsym; 243 ssym = (void *)bi_sym->ssym; 244 esym = (void *)bi_sym->esym; 245 } 246 #endif 247 248 bi_systype = lookup_bootinfo(BTINFO_SYSTYPE); 249 if (bi_systype) 250 systype = bi_systype->type; 251 } else { 252 /* 253 * Running kernel is loaded by non-native loader; 254 * clear the BSS segment here. 255 */ 256 memset(edata, 0, end - edata); 257 } 258 259 if (systype == 0) 260 systype = NEWS3400; /* XXX compatibility for old boot */ 261 262 #ifdef news5000 263 if (systype == NEWS5000) { 264 int i; 265 char *bootspec = (char *)x_bootdev; 266 267 if (bi_arg == NULL) 268 panic("news5000 requires BTINFO_BOOTARG to boot"); 269 270 _sip = (void *)bi_arg->sip; 271 x_maxmem = _sip->apbsi_memsize; 272 x_maxmem -= 0x00100000; /* reserve 1MB for ROM monitor */ 273 if (strncmp(bootspec, "scsi", 4) == 0) { 274 x_bootdev = (5 << 28) | 0; /* magic, sd */ 275 bootspec += 4; 276 if (*bootspec != '(' /*)*/) 277 goto bootspec_end; 278 i = strtoul(bootspec + 1, &bootspec, 10); 279 x_bootdev |= (i << 24); /* bus */ 280 if (*bootspec != ',') 281 goto bootspec_end; 282 i = strtoul(bootspec + 1, &bootspec, 10); 283 x_bootdev |= (i / 10) << 20; /* controller */ 284 x_bootdev |= (i % 10) << 16; /* unit */ 285 if (*bootspec != ',') 286 goto bootspec_end; 287 i = strtoul(bootspec + 1, &bootspec, 10); 288 x_bootdev |= (i << 8); /* partition */ 289 } 290 bootspec_end: 291 consinit(); 292 } 293 #endif 294 295 /* 296 * Save parameters into kernel work area. 297 */ 298 *(int *)(MIPS_PHYS_TO_KSEG1(MACH_MAXMEMSIZE_ADDR)) = x_maxmem; 299 *(int *)(MIPS_PHYS_TO_KSEG1(MACH_BOOTDEV_ADDR)) = x_bootdev; 300 *(int *)(MIPS_PHYS_TO_KSEG1(MACH_BOOTSW_ADDR)) = x_boothowto; 301 302 kernend = (char *)mips_round_page(end); 303 #if NKSYMS || defined(DDB) || defined(MODULAR) 304 if (nsym) 305 kernend = (char *)mips_round_page(esym); 306 #endif 307 308 /* 309 * Set the VM page size. 310 */ 311 uvm_setpagesize(); 312 313 boothowto = x_boothowto; 314 bootdev = x_bootdev; 315 physmem = btoc(x_maxmem); 316 317 /* 318 * Now that we know how much memory we have, initialize the 319 * mem cluster array. 320 */ 321 mem_clusters[0].start = 0; /* XXX is this correct? */ 322 mem_clusters[0].size = ctob(physmem); 323 mem_cluster_cnt = 1; 324 325 /* 326 * Copy exception-dispatch code down to exception vector. 327 * Initialize locore-function vector. 328 * Clear out the I and D caches. 329 */ 330 mips_vector_init(); 331 332 /* 333 * We know the CPU type now. Initialize our DMA tags (might 334 * need this early). 335 */ 336 newsmips_bus_dma_init(); 337 338 #if NKSYMS || defined(DDB) || defined(MODULAR) 339 if (nsym) 340 ksyms_addsyms_elf(esym - ssym, ssym, esym); 341 #endif 342 343 #ifdef KADB 344 boothowto |= RB_KDB; 345 #endif 346 347 /* 348 * Check to see if a mini-root was loaded into memory. It resides 349 * at the start of the next page just after the end of BSS. 350 */ 351 if (boothowto & RB_MINIROOT) 352 kernend += round_page(mfs_initminiroot(kernend)); 353 354 /* 355 * Load the rest of the available pages into the VM system. 356 */ 357 first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); 358 last = mem_clusters[0].start + mem_clusters[0].size; 359 uvm_page_physload(atop(first), atop(last), atop(first), atop(last), 360 VM_FREELIST_DEFAULT); 361 362 /* 363 * Initialize error message buffer (at end of core). 364 */ 365 mips_init_msgbuf(); 366 367 /* 368 * Initialize the virtual memory system. 369 */ 370 pmap_bootstrap(); 371 372 /* 373 * Allocate uarea page for lwp0 and set it. 374 */ 375 mips_init_lwp0_uarea(); 376 377 /* 378 * Determine what model of computer we are running on. 379 */ 380 switch (systype) { 381 #ifdef news3400 382 case NEWS3400: 383 news3400_init(); 384 strcpy(cpu_model, idrom.id_machine); 385 if (strcmp(cpu_model, "news3400") == 0 || 386 strcmp(cpu_model, "news3200") == 0 || 387 strcmp(cpu_model, "news3700") == 0) { 388 /* 389 * Set up interrupt handling and I/O addresses. 390 */ 391 hardware_intr = news3400_intr; 392 cpuspeed = 10; 393 } else { 394 printf("kernel not configured for machine %s\n", 395 cpu_model); 396 } 397 break; 398 #endif 399 400 #ifdef news5000 401 case NEWS5000: 402 news5000_init(); 403 strcpy(cpu_model, idrom.id_machine); 404 if (strcmp(cpu_model, "news5000") == 0 || 405 strcmp(cpu_model, "news5900") == 0) { 406 /* 407 * Set up interrupt handling and I/O addresses. 408 */ 409 hardware_intr = news5000_intr; 410 cpuspeed = 50; /* ??? XXX */ 411 } else { 412 printf("kernel not configured for machine %s\n", 413 cpu_model); 414 } 415 break; 416 #endif 417 418 default: 419 printf("kernel not configured for systype %d\n", systype); 420 break; 421 } 422 } 423 424 void 425 mips_machdep_cache_config(void) 426 { 427 /* All r4k news boxen have a 1MB L2 cache. */ 428 if (CPUISMIPS3) 429 mips_sdcache_size = 1024 * 1024; 430 } 431 432 /* 433 * cpu_startup: allocate memory for variable-sized tables, 434 * initialize CPU, and do autoconfiguration. 435 */ 436 void 437 cpu_startup(void) 438 { 439 vaddr_t minaddr, maxaddr; 440 char pbuf[9]; 441 #ifdef DEBUG 442 extern int pmapdebug; 443 int opmapdebug = pmapdebug; 444 445 pmapdebug = 0; 446 #endif 447 448 /* 449 * Good {morning,afternoon,evening,night}. 450 */ 451 printf("%s%s", copyright, version); 452 printf("SONY NET WORK STATION, Model %s, ", idrom.id_model); 453 printf("Machine ID #%d\n", idrom.id_serial); 454 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 455 printf("total memory = %s\n", pbuf); 456 457 minaddr = 0; 458 /* 459 * Allocate a submap for physio 460 */ 461 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 462 VM_PHYS_SIZE, 0, false, NULL); 463 464 /* 465 * No need to allocate an mbuf cluster submap. Mbuf clusters 466 * are allocated via the pool allocator, and we use KSEG to 467 * map those pages. 468 */ 469 470 #ifdef DEBUG 471 pmapdebug = opmapdebug; 472 #endif 473 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 474 printf("avail memory = %s\n", pbuf); 475 } 476 477 /* 478 * lookup_bootinfo: 479 * Look up information in bootinfo of boot loader. 480 */ 481 void * 482 lookup_bootinfo(int type) 483 { 484 struct btinfo_common *bt; 485 char *help = bootinfo; 486 487 /* Check for a bootinfo record first. */ 488 if (help == NULL) 489 return NULL; 490 491 do { 492 bt = (struct btinfo_common *)help; 493 if (bt->type == type) 494 return (void *)help; 495 help += bt->next; 496 } while (bt->next != 0 && 497 (size_t)help < (size_t)bootinfo + BOOTINFO_SIZE); 498 499 return NULL; 500 } 501 502 /* 503 * call PROM to halt or reboot. 504 */ 505 void 506 prom_halt(int howto) 507 508 { 509 #ifdef news5000 510 if (systype == NEWS5000) 511 apcall_exit(howto); 512 #endif 513 #ifdef news3400 514 if (systype == NEWS3400) 515 to_monitor(howto); 516 #endif 517 for (;;); 518 } 519 520 int waittime = -1; 521 522 void 523 cpu_reboot(volatile int howto, char *bootstr) 524 { 525 526 /* take a snap shot before clobbering any registers */ 527 if (curlwp) 528 savectx(curpcb); 529 530 #ifdef DEBUG 531 if (panicstr) 532 stacktrace(); 533 #endif 534 535 /* If system is cold, just halt. */ 536 if (cold) { 537 howto |= RB_HALT; 538 goto haltsys; 539 } 540 541 /* If "always halt" was specified as a boot flag, obey. */ 542 if ((boothowto & RB_HALT) != 0) 543 howto |= RB_HALT; 544 545 boothowto = howto; 546 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 547 /* 548 * Synchronize the disks.... 549 */ 550 waittime = 0; 551 vfs_shutdown(); 552 553 /* 554 * If we've been adjusting the clock, the todr 555 * will be out of synch; adjust it now. 556 */ 557 resettodr(); 558 } 559 560 /* Disable interrupts. */ 561 disable_intr(); 562 563 splhigh(); 564 565 /* If rebooting and a dump is requested do it. */ 566 #if 0 567 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 568 #else 569 if (howto & RB_DUMP) 570 #endif 571 dumpsys(); 572 573 haltsys: 574 575 /* run any shutdown hooks */ 576 doshutdownhooks(); 577 578 pmf_system_shutdown(boothowto); 579 580 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) 581 prom_halt(0x80); /* rom monitor RB_PWOFF */ 582 583 /* Finally, halt/reboot the system. */ 584 printf("%s\n\n", howto & RB_HALT ? "halted." : "rebooting..."); 585 prom_halt(howto & RB_HALT); 586 /*NOTREACHED*/ 587 } 588 589 void 590 delay(int n) 591 { 592 593 DELAY(n); 594 } 595 596 void 597 cpu_intr(uint32_t status, uint32_t cause, vaddr_t pc, uint32_t ipending) 598 { 599 struct cpu_info *ci; 600 601 ci = curcpu(); 602 ci->ci_data.cpu_nintr++; 603 604 /* device interrupts */ 605 ci->ci_idepth++; 606 (*hardware_intr)(status, cause, pc, ipending); 607 ci->ci_idepth--; 608 609 #ifdef __HAVE_FAST_SOFTINTS 610 /* software interrupts */ 611 ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0); 612 if (ipending == 0) 613 return; 614 _clrsoftintr(ipending); 615 softintr_dispatch(ipending); 616 #endif 617 } 618