1 /* $NetBSD: machdep.c,v 1.158 2002/05/23 03:05:30 gmcgarry Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1982, 1986, 1990, 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. 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. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * from: Utah $Hdr: machdep.c 1.74 92/12/20$ 41 * 42 * @(#)machdep.c 8.10 (Berkeley) 4/20/94 43 */ 44 45 #include <sys/cdefs.h> 46 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.158 2002/05/23 03:05:30 gmcgarry Exp $"); 47 48 #include "opt_ddb.h" 49 #include "opt_compat_hpux.h" 50 #include "opt_compat_netbsd.h" 51 #include "hil.h" 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/callout.h> 56 #include <sys/buf.h> 57 #include <sys/clist.h> 58 #include <sys/conf.h> 59 #include <sys/exec.h> 60 #include <sys/file.h> 61 #include <sys/ioctl.h> 62 #include <sys/kernel.h> 63 #include <sys/device.h> 64 #include <sys/malloc.h> 65 #include <sys/map.h> 66 #include <sys/mbuf.h> 67 #include <sys/mount.h> 68 #include <sys/msgbuf.h> 69 #include <sys/proc.h> 70 #include <sys/reboot.h> 71 #include <sys/signalvar.h> 72 #include <sys/syscallargs.h> 73 #include <sys/tty.h> 74 #include <sys/user.h> 75 #include <sys/exec.h> 76 #include <sys/core.h> 77 #include <sys/kcore.h> 78 #include <sys/vnode.h> 79 80 #ifdef DDB 81 #include <machine/db_machdep.h> 82 #include <ddb/db_sym.h> 83 #include <ddb/db_extern.h> 84 #ifdef __ELF__ 85 #include <sys/exec_elf.h> 86 #endif 87 #endif /* DDB */ 88 89 #include <machine/autoconf.h> 90 #include <machine/bootinfo.h> 91 #include <machine/bus.h> 92 #include <machine/cpu.h> 93 #include <machine/hp300spu.h> 94 #include <machine/reg.h> 95 #include <machine/psl.h> 96 #include <machine/pte.h> 97 98 #include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */ 99 100 #include <dev/cons.h> 101 102 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 103 #include <uvm/uvm_extern.h> 104 105 #include <sys/sysctl.h> 106 107 #include "opt_useleds.h" 108 109 #include <hp300/dev/hilreg.h> 110 #include <hp300/dev/hilioctl.h> 111 #include <hp300/dev/hilvar.h> 112 #ifdef USELEDS 113 #include <hp300/hp300/leds.h> 114 #endif 115 116 /* the following is used externally (sysctl_hw) */ 117 char machine[] = MACHINE; /* from <machine/param.h> */ 118 119 /* Our exported CPU info; we can have only one. */ 120 struct cpu_info cpu_info_store; 121 122 struct vm_map *exec_map = NULL; 123 struct vm_map *mb_map = NULL; 124 struct vm_map *phys_map = NULL; 125 126 extern paddr_t avail_end; 127 128 /* 129 * bootinfo base (physical and virtual). The bootinfo is placed, by 130 * the boot loader, into the first page of kernel text, which is zero 131 * filled (see locore.s) and not mapped at 0. It is remapped to a 132 * different address in pmap_bootstrap(). 133 */ 134 paddr_t bootinfo_pa; 135 vaddr_t bootinfo_va; 136 137 caddr_t msgbufaddr; 138 int maxmem; /* max memory per process */ 139 int physmem = MAXMEM; /* max supported memory, changes to actual */ 140 /* 141 * safepri is a safe priority for sleep to set for a spin-wait 142 * during autoconfiguration or after a panic. 143 */ 144 int safepri = PSL_LOWIPL; 145 146 extern u_int lowram; 147 extern short exframesize[]; 148 149 #ifdef COMPAT_HPUX 150 extern struct emul emul_hpux; 151 #endif 152 153 /* prototypes for local functions */ 154 void parityenable __P((void)); 155 int parityerror __P((struct frame *)); 156 int parityerrorfind __P((void)); 157 void identifycpu __P((void)); 158 void initcpu __P((void)); 159 160 int cpu_dumpsize __P((void)); 161 int cpu_dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *)); 162 void cpu_init_kcore_hdr __P((void)); 163 164 /* functions called from locore.s */ 165 void dumpsys __P((void)); 166 void hp300_init __P((void)); 167 void straytrap __P((int, u_short)); 168 void nmihand __P((struct frame)); 169 170 /* 171 * Machine-dependent crash dump header info. 172 */ 173 cpu_kcore_hdr_t cpu_kcore_hdr; 174 175 /* 176 * Note that the value of delay_divisor is roughly 177 * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020 178 * and 68030 systems. See clock.c for the delay 179 * calibration algorithm. 180 */ 181 int cpuspeed; /* relative cpu speed; XXX skewed on 68040 */ 182 int delay_divisor; /* delay constant */ 183 184 /* 185 * Early initialization, before main() is called. 186 */ 187 void 188 hp300_init() 189 { 190 struct btinfo_magic *bt_mag; 191 int i; 192 193 extern paddr_t avail_start, avail_end; 194 195 /* 196 * Tell the VM system about available physical memory. The 197 * hp300 only has one segment. 198 */ 199 uvm_page_physload(atop(avail_start), atop(avail_end), 200 atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT); 201 202 /* Initialize the interrupt handlers. */ 203 intr_init(); 204 205 /* Calibrate the delay loop. */ 206 hp300_calibrate_delay(); 207 208 /* 209 * Initialize error message buffer (at end of core). 210 * avail_end was pre-decremented in pmap_bootstrap to compensate. 211 */ 212 for (i = 0; i < btoc(MSGBUFSIZE); i++) 213 pmap_kenter_pa((vaddr_t)msgbufaddr + i * NBPG, 214 avail_end + i * NBPG, VM_PROT_READ|VM_PROT_WRITE); 215 pmap_update(pmap_kernel()); 216 initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); 217 218 /* 219 * Map in the bootinfo page, and make sure the bootinfo 220 * exists by searching for the MAGIC record. If it's not 221 * there, disable bootinfo. 222 */ 223 pmap_enter(pmap_kernel(), bootinfo_va, bootinfo_pa, 224 VM_PROT_READ|VM_PROT_WRITE, 225 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); 226 pmap_update(pmap_kernel()); 227 bt_mag = lookup_bootinfo(BTINFO_MAGIC); 228 if (bt_mag == NULL || 229 bt_mag->magic1 != BOOTINFO_MAGIC1 || 230 bt_mag->magic2 != BOOTINFO_MAGIC2) { 231 pmap_remove(pmap_kernel(), bootinfo_va, bootinfo_va + NBPG); 232 pmap_update(pmap_kernel()); 233 bootinfo_va = 0; 234 } 235 } 236 237 /* 238 * Console initialization: called early on from main, 239 * before vm init or startup. Do enough configuration 240 * to choose and initialize a console. 241 */ 242 void 243 consinit() 244 { 245 extern struct map extiomap[]; 246 247 /* 248 * Initialize the DIO resource map. 249 */ 250 rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16); 251 252 /* 253 * Initialize the console before we print anything out. 254 */ 255 256 hp300_cninit(); 257 258 /* 259 * Issue a warning if the boot loader didn't provide bootinfo. 260 */ 261 if (bootinfo_va == 0) 262 printf("WARNING: boot loader did not provide bootinfo\n"); 263 264 #ifdef DDB 265 { 266 extern int end; 267 extern int *esym; 268 269 #ifndef __ELF__ 270 ddb_init(*(int *)&end, ((int *)&end) + 1, esym); 271 #else 272 ddb_init((int)esym - (int)&end - sizeof(Elf32_Ehdr), 273 (void *)&end, esym); 274 #endif 275 } 276 if (boothowto & RB_KDB) 277 Debugger(); 278 #endif 279 } 280 281 /* 282 * cpu_startup: allocate memory for variable-sized tables, 283 * initialize cpu 284 */ 285 void 286 cpu_startup() 287 { 288 extern char *etext; 289 unsigned i; 290 caddr_t v; 291 int base, residual; 292 vaddr_t minaddr, maxaddr; 293 vsize_t size; 294 char pbuf[9]; 295 #ifdef DEBUG 296 extern int pmapdebug; 297 int opmapdebug = pmapdebug; 298 299 pmapdebug = 0; 300 #endif 301 302 /* 303 * Initialize the kernel crash dump header. 304 */ 305 cpu_init_kcore_hdr(); 306 307 /* 308 * Good {morning,afternoon,evening,night}. 309 */ 310 printf(version); 311 identifycpu(); 312 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 313 printf("total memory = %s\n", pbuf); 314 315 /* 316 * Find out how much space we need, allocate it, 317 * and the give everything true virtual addresses. 318 */ 319 size = (vsize_t)allocsys(NULL, NULL); 320 if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(size))) == 0) 321 panic("startup: no room for tables"); 322 if ((allocsys(v, NULL) - v) != size) 323 panic("startup: table size inconsistency"); 324 325 /* 326 * Now allocate buffers proper. They are different than the above 327 * in that they usually occupy more virtual memory than physical. 328 */ 329 size = MAXBSIZE * nbuf; 330 if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size), 331 NULL, UVM_UNKNOWN_OFFSET, 0, 332 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 333 UVM_ADV_NORMAL, 0)) != 0) 334 panic("startup: cannot allocate VM for buffers"); 335 minaddr = (vaddr_t)buffers; 336 base = bufpages / nbuf; 337 residual = bufpages % nbuf; 338 for (i = 0; i < nbuf; i++) { 339 vsize_t curbufsize; 340 vaddr_t curbuf; 341 struct vm_page *pg; 342 343 /* 344 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 345 * that MAXBSIZE space, we allocate and map (base+1) pages 346 * for the first "residual" buffers, and then we allocate 347 * "base" pages for the rest. 348 */ 349 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 350 curbufsize = NBPG * ((i < residual) ? (base+1) : base); 351 352 while (curbufsize) { 353 pg = uvm_pagealloc(NULL, 0, NULL, 0); 354 if (pg == NULL) 355 panic("cpu_startup: not enough memory for " 356 "buffer cache"); 357 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 358 VM_PROT_READ|VM_PROT_WRITE); 359 curbuf += PAGE_SIZE; 360 curbufsize -= PAGE_SIZE; 361 } 362 } 363 pmap_update(pmap_kernel()); 364 365 /* 366 * Allocate a submap for exec arguments. This map effectively 367 * limits the number of processes exec'ing at any time. 368 */ 369 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 370 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 371 372 /* 373 * Allocate a submap for physio 374 */ 375 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 376 VM_PHYS_SIZE, 0, FALSE, NULL); 377 378 /* 379 * Finally, allocate mbuf cluster submap. 380 */ 381 mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 382 nmbclusters * mclbytes, VM_MAP_INTRSAFE, 383 FALSE, NULL); 384 385 #ifdef DEBUG 386 pmapdebug = opmapdebug; 387 #endif 388 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 389 printf("avail memory = %s\n", pbuf); 390 format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG); 391 printf("using %d buffers containing %s of memory\n", nbuf, pbuf); 392 393 /* 394 * Tell the VM system that page 0 isn't mapped. 395 * 396 * XXX This is bogus; should just fix KERNBASE and 397 * XXX VM_MIN_KERNEL_ADDRESS, but not right now. 398 */ 399 if (uvm_map_protect(kernel_map, 0, NBPG, UVM_PROT_NONE, TRUE) != 0) 400 panic("can't mark page 0 off-limits"); 401 402 /* 403 * Tell the VM system that writing to kernel text isn't allowed. 404 * If we don't, we might end up COW'ing the text segment! 405 * 406 * XXX Should be m68k_trunc_page(&kernel_text) instead 407 * XXX of NBPG. 408 */ 409 if (uvm_map_protect(kernel_map, NBPG, m68k_round_page(&etext), 410 UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) 411 panic("can't protect kernel text"); 412 413 /* 414 * Set up CPU-specific registers, cache, etc. 415 */ 416 initcpu(); 417 418 /* 419 * Set up buffers, so they can be used to read disk labels. 420 */ 421 bufinit(); 422 } 423 424 /* 425 * Set registers on exec. 426 */ 427 void 428 setregs(p, pack, stack) 429 struct proc *p; 430 struct exec_package *pack; 431 u_long stack; 432 { 433 struct frame *frame = (struct frame *)p->p_md.md_regs; 434 435 frame->f_sr = PSL_USERSET; 436 frame->f_pc = pack->ep_entry & ~1; 437 frame->f_regs[D0] = 0; 438 frame->f_regs[D1] = 0; 439 frame->f_regs[D2] = 0; 440 frame->f_regs[D3] = 0; 441 frame->f_regs[D4] = 0; 442 frame->f_regs[D5] = 0; 443 frame->f_regs[D6] = 0; 444 frame->f_regs[D7] = 0; 445 frame->f_regs[A0] = 0; 446 frame->f_regs[A1] = 0; 447 frame->f_regs[A2] = (int)p->p_psstr; 448 frame->f_regs[A3] = 0; 449 frame->f_regs[A4] = 0; 450 frame->f_regs[A5] = 0; 451 frame->f_regs[A6] = 0; 452 frame->f_regs[SP] = stack; 453 454 /* restore a null state frame */ 455 p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0; 456 if (fputype) 457 m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); 458 } 459 460 /* 461 * Info for CTL_HW 462 */ 463 char cpu_model[120]; 464 465 struct hp300_model { 466 int id; 467 int mmuid; 468 const char *name; 469 const char *speed; 470 }; 471 472 const struct hp300_model hp300_models[] = { 473 { HP_320, -1, "320", "16.67" }, 474 { HP_330, -1, "318/319/330", "16.67" }, 475 { HP_340, -1, "340", "16.67" }, 476 { HP_345, -1, "345", "50" }, 477 { HP_350, -1, "350", "25" }, 478 { HP_360, -1, "360", "25" }, 479 { HP_370, -1, "370", "33.33" }, 480 { HP_375, -1, "375", "50" }, 481 { HP_380, -1, "380", "25" }, 482 { HP_385, -1, "385", "33" }, 483 { HP_400, -1, "400", "50" }, 484 { HP_425, MMUID_425_T, "425t", "25" }, 485 { HP_425, MMUID_425_S, "425s", "25" }, 486 { HP_425, MMUID_425_E, "425e", "25" }, 487 { HP_425, -1, "425", "25" }, 488 { HP_433, MMUID_433_T, "433t", "33" }, 489 { HP_433, MMUID_433_S, "433s", "33" }, 490 { HP_433, -1, "433", "33" }, 491 { 0, -1, NULL, NULL }, 492 }; 493 494 void 495 identifycpu() 496 { 497 const char *t, *mc, *s; 498 int i, len; 499 500 /* 501 * Find the model number. 502 */ 503 for (t = s = NULL, i = 0; hp300_models[i].name != NULL; i++) { 504 if (hp300_models[i].id == machineid) { 505 if (hp300_models[i].mmuid != -1 && 506 hp300_models[i].mmuid != mmuid) 507 continue; 508 t = hp300_models[i].name; 509 s = hp300_models[i].speed; 510 break; 511 } 512 } 513 if (t == NULL) { 514 printf("\nunknown machineid %d\n", machineid); 515 goto lose; 516 } 517 518 /* 519 * ...and the CPU type. 520 */ 521 switch (cputype) { 522 case CPU_68040: 523 mc = "40"; 524 break; 525 case CPU_68030: 526 mc = "30"; 527 break; 528 case CPU_68020: 529 mc = "20"; 530 break; 531 default: 532 printf("\nunknown cputype %d\n", cputype); 533 goto lose; 534 } 535 536 sprintf(cpu_model, "HP 9000/%s (%sMHz MC680%s CPU", t, s, mc); 537 538 /* 539 * ...and the MMU type. 540 */ 541 switch (mmutype) { 542 case MMU_68040: 543 case MMU_68030: 544 strcat(cpu_model, "+MMU"); 545 break; 546 case MMU_68851: 547 strcat(cpu_model, ", MC68851 MMU"); 548 break; 549 case MMU_HP: 550 strcat(cpu_model, ", HP MMU"); 551 break; 552 default: 553 printf("%s\nunknown MMU type %d\n", cpu_model, mmutype); 554 panic("startup"); 555 } 556 557 len = strlen(cpu_model); 558 559 /* 560 * ...and the FPU type. 561 */ 562 switch (fputype) { 563 case FPU_68040: 564 len += sprintf(cpu_model + len, "+FPU"); 565 break; 566 case FPU_68882: 567 len += sprintf(cpu_model + len, ", %sMHz MC68882 FPU", s); 568 break; 569 case FPU_68881: 570 len += sprintf(cpu_model + len, ", %sMHz MC68881 FPU", 571 machineid == HP_350 ? "20" : "16.67"); 572 break; 573 default: 574 len += sprintf(cpu_model + len, ", unknown FPU"); 575 } 576 577 /* 578 * ...and finally, the cache type. 579 */ 580 if (cputype == CPU_68040) 581 sprintf(cpu_model + len, ", 4k on-chip physical I/D caches"); 582 else { 583 switch (ectype) { 584 case EC_VIRT: 585 sprintf(cpu_model + len, 586 ", %dK virtual-address cache", 587 machineid == HP_320 ? 16 : 32); 588 break; 589 case EC_PHYS: 590 sprintf(cpu_model + len, 591 ", %dK physical-address cache", 592 machineid == HP_370 ? 64 : 32); 593 break; 594 } 595 } 596 597 strcat(cpu_model, ")"); 598 printf("%s\n", cpu_model); 599 #ifdef DIAGNOSTIC 600 printf("cpu: delay divisor %d", delay_divisor); 601 if (mmuid) 602 printf(", mmuid %d", mmuid); 603 printf("\n"); 604 #endif 605 606 /* 607 * Now that we have told the user what they have, 608 * let them know if that machine type isn't configured. 609 */ 610 switch (machineid) { 611 case -1: /* keep compilers happy */ 612 #if !defined(HP320) 613 case HP_320: 614 #endif 615 #if !defined(HP330) 616 case HP_330: 617 #endif 618 #if !defined(HP340) 619 case HP_340: 620 #endif 621 #if !defined(HP345) 622 case HP_345: 623 #endif 624 #if !defined(HP350) 625 case HP_350: 626 #endif 627 #if !defined(HP360) 628 case HP_360: 629 #endif 630 #if !defined(HP370) 631 case HP_370: 632 #endif 633 #if !defined(HP375) 634 case HP_375: 635 #endif 636 #if !defined(HP380) 637 case HP_380: 638 #endif 639 #if !defined(HP385) 640 case HP_385: 641 #endif 642 #if !defined(HP400) 643 case HP_400: 644 #endif 645 #if !defined(HP425) 646 case HP_425: 647 #endif 648 #if !defined(HP433) 649 case HP_433: 650 #endif 651 panic("SPU type not configured"); 652 default: 653 break; 654 } 655 656 return; 657 lose: 658 panic("startup"); 659 } 660 661 /* 662 * machine dependent system variables. 663 */ 664 int 665 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 666 int *name; 667 u_int namelen; 668 void *oldp; 669 size_t *oldlenp; 670 void *newp; 671 size_t newlen; 672 struct proc *p; 673 { 674 dev_t consdev; 675 676 /* all sysctl names at this level are terminal */ 677 if (namelen != 1) 678 return (ENOTDIR); /* overloaded */ 679 680 switch (name[0]) { 681 case CPU_CONSDEV: 682 if (cn_tab != NULL) 683 consdev = cn_tab->cn_dev; 684 else 685 consdev = NODEV; 686 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 687 sizeof consdev)); 688 default: 689 return (EOPNOTSUPP); 690 } 691 /* NOTREACHED */ 692 } 693 694 int waittime = -1; 695 696 void 697 cpu_reboot(howto, bootstr) 698 int howto; 699 char *bootstr; 700 { 701 702 #if __GNUC__ /* XXX work around lame compiler problem (gcc 2.7.2) */ 703 (void)&howto; 704 #endif 705 /* take a snap shot before clobbering any registers */ 706 if (curproc && curproc->p_addr) 707 savectx(&curproc->p_addr->u_pcb); 708 709 /* If system is cold, just halt. */ 710 if (cold) { 711 howto |= RB_HALT; 712 goto haltsys; 713 } 714 715 boothowto = howto; 716 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 717 waittime = 0; 718 vfs_shutdown(); 719 /* 720 * If we've been adjusting the clock, the todr 721 * will be out of synch; adjust it now. 722 */ 723 resettodr(); 724 } 725 726 /* Disable interrupts. */ 727 splhigh(); 728 729 /* If rebooting and a dump is requested do it. */ 730 if (howto & RB_DUMP) 731 dumpsys(); 732 733 haltsys: 734 /* Run any shutdown hooks. */ 735 doshutdownhooks(); 736 737 #if defined(PANICWAIT) && !defined(DDB) 738 if ((howto & RB_HALT) == 0 && panicstr) { 739 printf("hit any key to reboot...\n"); 740 (void)cngetc(); 741 printf("\n"); 742 } 743 #endif 744 745 /* Finally, halt/reboot the system. */ 746 if (howto & RB_HALT) { 747 printf("System halted. Hit any key to reboot.\n\n"); 748 (void)cngetc(); 749 } 750 751 printf("rebooting...\n"); 752 DELAY(1000000); 753 doboot(); 754 /*NOTREACHED*/ 755 } 756 757 /* 758 * Initialize the kernel crash dump header. 759 */ 760 void 761 cpu_init_kcore_hdr() 762 { 763 cpu_kcore_hdr_t *h = &cpu_kcore_hdr; 764 struct m68k_kcore_hdr *m = &h->un._m68k; 765 extern int end; 766 767 memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr)); 768 769 /* 770 * Initialize the `dispatcher' portion of the header. 771 */ 772 strcpy(h->name, machine); 773 h->page_size = NBPG; 774 h->kernbase = KERNBASE; 775 776 /* 777 * Fill in information about our MMU configuration. 778 */ 779 m->mmutype = mmutype; 780 m->sg_v = SG_V; 781 m->sg_frame = SG_FRAME; 782 m->sg_ishift = SG_ISHIFT; 783 m->sg_pmask = SG_PMASK; 784 m->sg40_shift1 = SG4_SHIFT1; 785 m->sg40_mask2 = SG4_MASK2; 786 m->sg40_shift2 = SG4_SHIFT2; 787 m->sg40_mask3 = SG4_MASK3; 788 m->sg40_shift3 = SG4_SHIFT3; 789 m->sg40_addr1 = SG4_ADDR1; 790 m->sg40_addr2 = SG4_ADDR2; 791 m->pg_v = PG_V; 792 m->pg_frame = PG_FRAME; 793 794 /* 795 * Initialize pointer to kernel segment table. 796 */ 797 m->sysseg_pa = (u_int32_t)(pmap_kernel()->pm_stpa); 798 799 /* 800 * Initialize relocation value such that: 801 * 802 * pa = (va - KERNBASE) + reloc 803 */ 804 m->reloc = lowram; 805 806 /* 807 * Define the end of the relocatable range. 808 */ 809 m->relocend = (u_int32_t)&end; 810 811 /* 812 * hp300 has one contiguous memory segment. 813 */ 814 m->ram_segs[0].start = lowram; 815 m->ram_segs[0].size = ctob(physmem); 816 } 817 818 /* 819 * Compute the size of the machine-dependent crash dump header. 820 * Returns size in disk blocks. 821 */ 822 int 823 cpu_dumpsize() 824 { 825 int size; 826 827 size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); 828 return (btodb(roundup(size, dbtob(1)))); 829 } 830 831 /* 832 * Called by dumpsys() to dump the machine-dependent header. 833 */ 834 int 835 cpu_dump(dump, blknop) 836 int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 837 daddr_t *blknop; 838 { 839 int buf[dbtob(1) / sizeof(int)]; 840 cpu_kcore_hdr_t *chdr; 841 kcore_seg_t *kseg; 842 int error; 843 844 kseg = (kcore_seg_t *)buf; 845 chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) / 846 sizeof(int)]; 847 848 /* Create the segment header. */ 849 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 850 kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t)); 851 852 memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t)); 853 error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf)); 854 *blknop += btodb(sizeof(buf)); 855 return (error); 856 } 857 858 /* 859 * These variables are needed by /sbin/savecore 860 */ 861 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 862 int dumpsize = 0; /* pages */ 863 long dumplo = 0; /* blocks */ 864 865 /* 866 * This is called by main to set dumplo and dumpsize. 867 * Dumps always skip the first NBPG of disk space 868 * in case there might be a disk label stored there. 869 * If there is extra space, put dump at the end to 870 * reduce the chance that swapping trashes it. 871 */ 872 void 873 cpu_dumpconf() 874 { 875 int chdrsize; /* size of dump header */ 876 int nblks; /* size of dump area */ 877 int maj; 878 879 if (dumpdev == NODEV) 880 return; 881 maj = major(dumpdev); 882 if (maj < 0 || maj >= nblkdev) 883 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 884 if (bdevsw[maj].d_psize == NULL) 885 return; 886 nblks = (*bdevsw[maj].d_psize)(dumpdev); 887 chdrsize = cpu_dumpsize(); 888 889 dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size); 890 891 /* 892 * Check do see if we will fit. Note we always skip the 893 * first NBPG in case there is a disk label there. 894 */ 895 if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) { 896 dumpsize = 0; 897 dumplo = -1; 898 return; 899 } 900 901 /* 902 * Put dump at the end of the partition. 903 */ 904 dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize; 905 } 906 907 /* 908 * Dump physical memory onto the dump device. Called by cpu_reboot(). 909 */ 910 void 911 dumpsys() 912 { 913 daddr_t blkno; /* current block to write */ 914 /* dump routine */ 915 int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 916 int pg; /* page being dumped */ 917 paddr_t maddr; /* PA being dumped */ 918 int error; /* error code from (*dump)() */ 919 920 /* XXX initialized here because of gcc lossage */ 921 maddr = lowram; 922 pg = 0; 923 924 /* Make sure dump device is valid. */ 925 if (dumpdev == NODEV) 926 return; 927 if (dumpsize == 0) { 928 cpu_dumpconf(); 929 if (dumpsize == 0) 930 return; 931 } 932 if (dumplo <= 0) { 933 printf("\ndump to dev %u,%u not possible\n", major(dumpdev), 934 minor(dumpdev)); 935 return; 936 } 937 dump = bdevsw[major(dumpdev)].d_dump; 938 blkno = dumplo; 939 940 printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), 941 minor(dumpdev), dumplo); 942 943 printf("dump "); 944 945 /* Write the dump header. */ 946 error = cpu_dump(dump, &blkno); 947 if (error) 948 goto bad; 949 950 for (pg = 0; pg < dumpsize; pg++) { 951 #define NPGMB (1024*1024/NBPG) 952 /* print out how many MBs we have dumped */ 953 if (pg && (pg % NPGMB) == 0) 954 printf("%d ", pg / NPGMB); 955 #undef NPGMB 956 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr, 957 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 958 959 pmap_update(pmap_kernel()); 960 error = (*dump)(dumpdev, blkno, vmmap, NBPG); 961 bad: 962 switch (error) { 963 case 0: 964 maddr += NBPG; 965 blkno += btodb(NBPG); 966 break; 967 968 case ENXIO: 969 printf("device bad\n"); 970 return; 971 972 case EFAULT: 973 printf("device not ready\n"); 974 return; 975 976 case EINVAL: 977 printf("area improper\n"); 978 return; 979 980 case EIO: 981 printf("i/o error\n"); 982 return; 983 984 case EINTR: 985 printf("aborted from console\n"); 986 return; 987 988 default: 989 printf("error %d\n", error); 990 return; 991 } 992 } 993 printf("succeeded\n"); 994 } 995 996 void 997 initcpu() 998 { 999 1000 #ifdef MAPPEDCOPY 1001 /* 1002 * Initialize lower bound for doing copyin/copyout using 1003 * page mapping (if not already set). We don't do this on 1004 * VAC machines as it loses big time. 1005 */ 1006 if (ectype == EC_VIRT) 1007 mappedcopysize = -1; /* in case it was patched */ 1008 else 1009 mappedcopysize = NBPG; 1010 #endif 1011 parityenable(); 1012 #ifdef USELEDS 1013 ledinit(); 1014 #endif 1015 } 1016 1017 void 1018 straytrap(pc, evec) 1019 int pc; 1020 u_short evec; 1021 { 1022 printf("unexpected trap (vector offset %x) from %x\n", 1023 evec & 0xFFF, pc); 1024 } 1025 1026 /* XXX should change the interface, and make one badaddr() function */ 1027 1028 int *nofault; 1029 1030 int 1031 badaddr(addr) 1032 caddr_t addr; 1033 { 1034 int i; 1035 label_t faultbuf; 1036 1037 nofault = (int *) &faultbuf; 1038 if (setjmp((label_t *)nofault)) { 1039 nofault = (int *) 0; 1040 return(1); 1041 } 1042 i = *(volatile short *)addr; 1043 nofault = (int *) 0; 1044 return(0); 1045 } 1046 1047 int 1048 badbaddr(addr) 1049 caddr_t addr; 1050 { 1051 int i; 1052 label_t faultbuf; 1053 1054 nofault = (int *) &faultbuf; 1055 if (setjmp((label_t *)nofault)) { 1056 nofault = (int *) 0; 1057 return(1); 1058 } 1059 i = *(volatile char *)addr; 1060 nofault = (int *) 0; 1061 return(0); 1062 } 1063 1064 /* 1065 * lookup_bootinfo: 1066 * 1067 * Look up information in bootinfo from boot loader. 1068 */ 1069 void * 1070 lookup_bootinfo(type) 1071 int type; 1072 { 1073 struct btinfo_common *bt; 1074 char *help = (char *)bootinfo_va; 1075 1076 /* Check for a bootinfo record first. */ 1077 if (help == NULL) 1078 return (NULL); 1079 1080 do { 1081 bt = (struct btinfo_common *)help; 1082 if (bt->type == type) 1083 return (help); 1084 help += bt->next; 1085 } while (bt->next != 0 && 1086 (size_t)help < (size_t)bootinfo_va + BOOTINFO_SIZE); 1087 1088 return (NULL); 1089 } 1090 1091 #ifdef PANICBUTTON 1092 /* 1093 * Declare these so they can be patched. 1094 */ 1095 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 1096 int candbdiv = 2; /* give em half a second (hz / candbdiv) */ 1097 1098 void candbtimer __P((void *)); 1099 1100 int crashandburn; 1101 1102 struct callout candbtimer_ch = CALLOUT_INITIALIZER; 1103 1104 void 1105 candbtimer(arg) 1106 void *arg; 1107 { 1108 1109 crashandburn = 0; 1110 } 1111 #endif /* PANICBUTTON */ 1112 1113 static int innmihand; /* simple mutex */ 1114 1115 /* 1116 * Level 7 interrupts can be caused by the keyboard or parity errors. 1117 */ 1118 void 1119 nmihand(frame) 1120 struct frame frame; 1121 { 1122 1123 /* Prevent unwanted recursion. */ 1124 if (innmihand) 1125 return; 1126 innmihand = 1; 1127 1128 #if NHIL > 0 1129 /* Check for keyboard <CRTL>+<SHIFT>+<RESET>. */ 1130 if (kbdnmi()) { 1131 printf("Got a keyboard NMI"); 1132 1133 /* 1134 * We can: 1135 * 1136 * - enter DDB 1137 * 1138 * - Start the crashandburn sequence 1139 * 1140 * - Ignore it. 1141 */ 1142 #ifdef DDB 1143 printf(": entering debugger\n"); 1144 Debugger(); 1145 #else 1146 #ifdef PANICBUTTON 1147 if (panicbutton) { 1148 if (crashandburn) { 1149 crashandburn = 0; 1150 printf(": CRASH AND BURN!\n"); 1151 panic("forced crash"); 1152 } else { 1153 /* Start the crashandburn sequence */ 1154 printf("\n"); 1155 crashandburn = 1; 1156 callout_reset(&candbtimer_ch, hz / candbdiv, 1157 candbtiner, NULL); 1158 } 1159 } else 1160 #endif /* PANICBUTTON */ 1161 printf(": ignoring\n"); 1162 #endif /* DDB */ 1163 1164 goto nmihand_out; /* no more work to do */ 1165 } 1166 #endif 1167 1168 if (parityerror(&frame)) 1169 return; 1170 /* panic?? */ 1171 printf("unexpected level 7 interrupt ignored\n"); 1172 1173 #if NHIL > 0 1174 nmihand_out: 1175 innmihand = 0; 1176 #endif 1177 } 1178 1179 /* 1180 * Parity error section. Contains magic. 1181 */ 1182 #define PARREG ((volatile short *)IIOV(0x5B0000)) 1183 static int gotparmem = 0; 1184 #ifdef DEBUG 1185 int ignorekperr = 0; /* ignore kernel parity errors */ 1186 #endif 1187 1188 /* 1189 * Enable parity detection 1190 */ 1191 void 1192 parityenable() 1193 { 1194 label_t faultbuf; 1195 1196 nofault = (int *) &faultbuf; 1197 if (setjmp((label_t *)nofault)) { 1198 nofault = (int *) 0; 1199 printf("Parity detection disabled\n"); 1200 return; 1201 } 1202 *PARREG = 1; 1203 nofault = (int *) 0; 1204 gotparmem = 1; 1205 } 1206 1207 /* 1208 * Determine if level 7 interrupt was caused by a parity error 1209 * and deal with it if it was. Returns 1 if it was a parity error. 1210 */ 1211 int 1212 parityerror(fp) 1213 struct frame *fp; 1214 { 1215 if (!gotparmem) 1216 return(0); 1217 *PARREG = 0; 1218 DELAY(10); 1219 *PARREG = 1; 1220 if (panicstr) { 1221 printf("parity error after panic ignored\n"); 1222 return(1); 1223 } 1224 if (!parityerrorfind()) 1225 printf("WARNING: transient parity error ignored\n"); 1226 else if (USERMODE(fp->f_sr)) { 1227 printf("pid %d: parity error\n", curproc->p_pid); 1228 uprintf("sorry, pid %d killed due to memory parity error\n", 1229 curproc->p_pid); 1230 psignal(curproc, SIGKILL); 1231 #ifdef DEBUG 1232 } else if (ignorekperr) { 1233 printf("WARNING: kernel parity error ignored\n"); 1234 #endif 1235 } else { 1236 regdump((struct trapframe *)fp, 128); 1237 panic("kernel parity error"); 1238 } 1239 return(1); 1240 } 1241 1242 /* 1243 * Yuk! There has got to be a better way to do this! 1244 * Searching all of memory with interrupts blocked can lead to disaster. 1245 */ 1246 int 1247 parityerrorfind() 1248 { 1249 static label_t parcatch; 1250 static int looking = 0; 1251 volatile int pg, o, s; 1252 volatile int *ip; 1253 int i; 1254 int found; 1255 1256 #ifdef lint 1257 i = o = pg = 0; if (i) return(0); 1258 #endif 1259 /* 1260 * If looking is true we are searching for a known parity error 1261 * and it has just occurred. All we do is return to the higher 1262 * level invocation. 1263 */ 1264 if (looking) 1265 longjmp(&parcatch); 1266 s = splhigh(); 1267 /* 1268 * If setjmp returns true, the parity error we were searching 1269 * for has just occurred (longjmp above) at the current pg+o 1270 */ 1271 if (setjmp(&parcatch)) { 1272 printf("Parity error at 0x%x\n", ctob(pg)|o); 1273 found = 1; 1274 goto done; 1275 } 1276 /* 1277 * If we get here, a parity error has occurred for the first time 1278 * and we need to find it. We turn off any external caches and 1279 * loop thru memory, testing every longword til a fault occurs and 1280 * we regain control at setjmp above. Note that because of the 1281 * setjmp, pg and o need to be volatile or their values will be lost. 1282 */ 1283 looking = 1; 1284 ecacheoff(); 1285 for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) { 1286 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, ctob(pg), 1287 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 1288 pmap_update(pmap_kernel()); 1289 ip = (int *)vmmap; 1290 for (o = 0; o < NBPG; o += sizeof(int)) 1291 i = *ip++; 1292 } 1293 /* 1294 * Getting here implies no fault was found. Should never happen. 1295 */ 1296 printf("Couldn't locate parity error\n"); 1297 found = 0; 1298 done: 1299 looking = 0; 1300 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, (vaddr_t)&vmmap[NBPG]); 1301 pmap_update(pmap_kernel()); 1302 ecacheon(); 1303 splx(s); 1304 return(found); 1305 } 1306 1307 /* 1308 * cpu_exec_aout_makecmds(): 1309 * cpu-dependent a.out format hook for execve(). 1310 * 1311 * Determine of the given exec package refers to something which we 1312 * understand and, if so, set up the vmcmds for it. 1313 * 1314 * XXX what are the special cases for the hp300? 1315 * XXX why is this COMPAT_NOMID? was something generating 1316 * hp300 binaries with an a_mid of 0? i thought that was only 1317 * done on little-endian machines... -- cgd 1318 */ 1319 int 1320 cpu_exec_aout_makecmds(p, epp) 1321 struct proc *p; 1322 struct exec_package *epp; 1323 { 1324 #if defined(COMPAT_NOMID) || defined(COMPAT_44) 1325 u_long midmag, magic; 1326 u_short mid; 1327 int error; 1328 struct exec *execp = epp->ep_hdr; 1329 1330 midmag = ntohl(execp->a_midmag); 1331 mid = (midmag >> 16) & 0xffff; 1332 magic = midmag & 0xffff; 1333 1334 midmag = mid << 16 | magic; 1335 1336 switch (midmag) { 1337 #ifdef COMPAT_NOMID 1338 case (MID_ZERO << 16) | ZMAGIC: 1339 error = exec_aout_prep_oldzmagic(p, epp); 1340 return(error); 1341 #endif 1342 #ifdef COMPAT_44 1343 case (MID_HP300 << 16) | ZMAGIC: 1344 error = exec_aout_prep_oldzmagic(p, epp); 1345 return(error); 1346 #endif 1347 } 1348 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */ 1349 1350 return ENOEXEC; 1351 } 1352