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