1 /* $NetBSD: machdep.c,v 1.240 2024/12/21 17:53:21 tsutsui 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. 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 * from: Utah $Hdr: machdep.c 1.74 92/12/20$ 37 * 38 * @(#)machdep.c 8.10 (Berkeley) 4/20/94 39 */ 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.240 2024/12/21 17:53:21 tsutsui Exp $"); 43 44 #include "opt_ddb.h" 45 #include "opt_compat_netbsd.h" 46 #include "opt_fpu_emulate.h" 47 #include "opt_modular.h" 48 #include "opt_panicbutton.h" 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/callout.h> 53 #include <sys/buf.h> 54 #include <sys/conf.h> 55 #include <sys/exec.h> 56 #include <sys/exec_aout.h> /* for MID_* */ 57 #include <sys/file.h> 58 #include <sys/ioctl.h> 59 #include <sys/kernel.h> 60 #include <sys/device.h> 61 #include <sys/malloc.h> 62 #include <sys/mbuf.h> 63 #include <sys/mount.h> 64 #include <sys/msgbuf.h> 65 #include <sys/proc.h> 66 #include <sys/reboot.h> 67 #include <sys/signalvar.h> 68 #include <sys/syscallargs.h> 69 #include <sys/tty.h> 70 #include <sys/core.h> 71 #include <sys/kcore.h> 72 #include <sys/vnode.h> 73 #include <sys/ksyms.h> 74 #include <sys/module.h> 75 #include <sys/cpu.h> 76 77 #ifdef DDB 78 #include <machine/db_machdep.h> 79 #include <ddb/db_sym.h> 80 #include <ddb/db_extern.h> 81 #endif /* DDB */ 82 #include <sys/exec_elf.h> 83 84 #include <machine/autoconf.h> 85 #include <machine/bootinfo.h> 86 #include <machine/bus.h> 87 #include <machine/cpu.h> 88 #include <machine/hp300spu.h> 89 #include <machine/reg.h> 90 #include <machine/pcb.h> 91 #include <machine/psl.h> 92 #include <machine/pte.h> 93 94 #include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */ 95 96 #include <dev/cons.h> 97 #include <dev/mm.h> 98 99 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 100 #include <uvm/uvm_extern.h> 101 102 #include <sys/sysctl.h> 103 104 #include "opt_useleds.h" 105 106 #ifdef USELEDS 107 #include <hp300/hp300/leds.h> 108 #endif 109 110 #include "ksyms.h" 111 112 /* the following is used externally (sysctl_hw) */ 113 char machine[] = MACHINE; /* from <machine/param.h> */ 114 115 /* Our exported CPU info; we can have only one. */ 116 struct cpu_info cpu_info_store; 117 118 struct vm_map *phys_map = NULL; 119 120 extern paddr_t avail_end; 121 122 /* 123 * bootinfo base (physical and virtual). The bootinfo is placed, by 124 * the boot loader, into the first page of kernel text, which is zero 125 * filled (see locore.s) and not mapped at 0. It is remapped to a 126 * different address in pmap_bootstrap(). 127 */ 128 paddr_t bootinfo_pa; 129 vaddr_t bootinfo_va; 130 131 int maxmem; /* max memory per process */ 132 133 extern u_int lowram; 134 extern short exframesize[]; 135 136 /* prototypes for local functions */ 137 static void parityenable(void); 138 static int parityerror(struct frame *); 139 static int parityerrorfind(void); 140 static void identifycpu(void); 141 static void initcpu(void); 142 143 static int cpu_dumpsize(void); 144 static int cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *); 145 static void cpu_init_kcore_hdr(void); 146 147 /* functions called from locore.s */ 148 void dumpsys(void); 149 void hp300_init(void); 150 void straytrap(int, u_short); 151 void nmihand(struct frame); 152 153 /* 154 * Machine-dependent crash dump header info. 155 */ 156 static cpu_kcore_hdr_t cpu_kcore_hdr; 157 158 /* 159 * Note that the value of delay_divisor is roughly 160 * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020 161 * and 68030 systems. See clock.c for the delay 162 * calibration algorithm. 163 */ 164 int cpuspeed; /* relative CPU speed; XXX skewed on 68040 */ 165 int delay_divisor; /* delay constant */ 166 167 /* 168 * Early initialization, before main() is called. 169 */ 170 void 171 hp300_init(void) 172 { 173 struct btinfo_magic *bt_mag; 174 int i; 175 176 extern paddr_t avail_start, avail_end; 177 178 #ifdef CACHE_HAVE_VAC 179 /* 180 * Determine VA aliasing distance if any 181 */ 182 switch (machineid) { 183 case HP_320: 184 pmap_aliasmask = 0x3fff; /* 16KB */ 185 break; 186 case HP_350: 187 pmap_aliasmask = 0x7fff; /* 32KB */ 188 break; 189 default: 190 break; 191 } 192 #endif 193 194 /* 195 * Tell the VM system about available physical memory. The 196 * hp300 only has one segment. 197 */ 198 uvm_page_physload(atop(avail_start), atop(avail_end), 199 atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT); 200 201 /* Calibrate the delay loop. */ 202 hp300_calibrate_delay(); 203 204 /* 205 * Initialize error message buffer (at end of core). 206 * avail_end was pre-decremented in pmap_bootstrap to compensate. 207 */ 208 for (i = 0; i < btoc(MSGBUFSIZE); i++) 209 pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE, 210 avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 0); 211 pmap_update(pmap_kernel()); 212 initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); 213 214 /* 215 * Map in the bootinfo page, and make sure the bootinfo 216 * exists by searching for the MAGIC record. If it's not 217 * there, disable bootinfo. 218 */ 219 bootinfo_va = virtual_avail; 220 virtual_avail += PAGE_SIZE; 221 pmap_enter(pmap_kernel(), bootinfo_va, bootinfo_pa, 222 VM_PROT_READ|VM_PROT_WRITE, 223 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); 224 pmap_update(pmap_kernel()); 225 bt_mag = lookup_bootinfo(BTINFO_MAGIC); 226 if (bt_mag == NULL || 227 bt_mag->magic1 != BOOTINFO_MAGIC1 || 228 bt_mag->magic2 != BOOTINFO_MAGIC2) { 229 pmap_remove(pmap_kernel(), bootinfo_va, 230 bootinfo_va + PAGE_SIZE); 231 pmap_update(pmap_kernel()); 232 virtual_avail -= PAGE_SIZE; 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(void) 244 { 245 246 /* 247 * Initialize the external I/O extent map. 248 */ 249 iomap_init(); 250 251 /* 252 * Initialize the console before we print anything out. 253 */ 254 255 hp300_cninit(); 256 257 /* 258 * Issue a warning if the boot loader didn't provide bootinfo. 259 */ 260 if (bootinfo_va != 0) 261 printf("bootinfo found at 0x%08lx\n", bootinfo_pa); 262 else 263 printf("WARNING: boot loader did not provide bootinfo\n"); 264 265 #if NKSYMS || defined(DDB) || defined(MODULAR) 266 { 267 extern int end; 268 extern int *esym; 269 270 ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr), 271 (void *)&end, esym); 272 } 273 #endif 274 #ifdef DDB 275 if (boothowto & RB_KDB) 276 Debugger(); 277 #endif 278 } 279 280 /* 281 * cpu_startup: allocate memory for variable-sized tables, 282 * initialize CPU 283 */ 284 void 285 cpu_startup(void) 286 { 287 vaddr_t minaddr, maxaddr; 288 char pbuf[9]; 289 #ifdef DEBUG 290 extern int pmapdebug; 291 int opmapdebug = pmapdebug; 292 293 pmapdebug = 0; 294 #endif 295 296 hp300_cninit_deferred(); 297 298 if (fputype != FPU_NONE) 299 m68k_make_fpu_idle_frame(); 300 301 /* 302 * Initialize the kernel crash dump header. 303 */ 304 cpu_init_kcore_hdr(); 305 306 /* 307 * Good {morning,afternoon,evening,night}. 308 */ 309 printf("%s%s", copyright, version); 310 identifycpu(); 311 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 312 printf("total memory = %s\n", pbuf); 313 314 minaddr = 0; 315 316 /* 317 * Allocate a submap for physio 318 */ 319 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 320 VM_PHYS_SIZE, 0, false, NULL); 321 322 #ifdef DEBUG 323 pmapdebug = opmapdebug; 324 #endif 325 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false))); 326 printf("avail memory = %s\n", pbuf); 327 328 /* 329 * Set up CPU-specific registers, cache, etc. 330 */ 331 initcpu(); 332 333 /* Safe to use malloc for extio_ex now. */ 334 extio_ex_malloc_safe = 1; 335 } 336 337 struct hp300_model { 338 int id; 339 int mmuid; 340 const char *name; 341 const char *speed; 342 }; 343 344 static const struct hp300_model hp300_models[] = { 345 { HP_320, -1, "320", "16.67" }, 346 { HP_330, -1, "318/319/330", "16.67" }, 347 { HP_340, -1, "340", "16.67" }, 348 { HP_345, -1, "345", "50" }, 349 { HP_350, -1, "350", "25" }, 350 { HP_360, -1, "360", "25" }, 351 { HP_362, -1, "362", "25" }, 352 { HP_370, -1, "370", "33.33" }, 353 { HP_375, -1, "375", "50" }, 354 { HP_380, -1, "380", "25" }, 355 { HP_382, -1, "382", "25" }, 356 { HP_385, -1, "385", "33" }, 357 { HP_400, -1, "400", "50" }, 358 { HP_425, MMUID_425_T, "425t", "25" }, 359 { HP_425, MMUID_425_S, "425s", "25" }, 360 { HP_425, MMUID_425_E, "425e", "25" }, 361 { HP_425, -1, "425", "25" }, 362 { HP_433, MMUID_433_T, "433t", "33" }, 363 { HP_433, MMUID_433_S, "433s", "33" }, 364 { HP_433, -1, "433", "33" }, 365 { 0, -1, NULL, NULL }, 366 }; 367 368 static void 369 identifycpu(void) 370 { 371 const char *t, *cpu, *s, *mmu; 372 int i; 373 char fpu[64], cache[64]; 374 375 /* 376 * Find the model number. 377 */ 378 for (t = s = NULL, i = 0; hp300_models[i].name != NULL; i++) { 379 if (hp300_models[i].id == machineid) { 380 if (hp300_models[i].mmuid != -1 && 381 hp300_models[i].mmuid != mmuid) 382 continue; 383 t = hp300_models[i].name; 384 s = hp300_models[i].speed; 385 break; 386 } 387 } 388 if (t == NULL) { 389 printf("\nunknown machineid %d\n", machineid); 390 goto lose; 391 } 392 393 /* 394 * ...and the CPU type. 395 */ 396 switch (cputype) { 397 case CPU_68040: 398 cpu = "MC68040"; 399 break; 400 case CPU_68030: 401 cpu = "MC68030"; 402 break; 403 case CPU_68020: 404 cpu = "MC68020"; 405 break; 406 default: 407 printf("\nunknown cputype %d\n", cputype); 408 goto lose; 409 } 410 411 412 /* 413 * ...and the MMU type. 414 */ 415 switch (mmutype) { 416 case MMU_68040: 417 case MMU_68030: 418 mmu = "+MMU"; 419 break; 420 case MMU_68851: 421 mmu = ", MC68851 MMU"; 422 break; 423 case MMU_HP: 424 mmu = ", HP MMU"; 425 break; 426 default: 427 printf("%s\nunknown MMU type %d\n", cpu, mmutype); 428 panic("startup"); 429 } 430 431 /* 432 * ...and the FPU type. 433 */ 434 fpu[0] = '\0'; 435 switch (fputype) { 436 case FPU_68040: 437 strlcpy(fpu, "+FPU", sizeof(fpu)); 438 break; 439 case FPU_68882: 440 snprintf(fpu, sizeof(fpu), ", %sMHz MC68882 FPU", s); 441 break; 442 case FPU_68881: 443 snprintf(fpu, sizeof(fpu), ", %sMHz MC68881 FPU", 444 machineid == HP_350 ? "20" : "16.67"); 445 break; 446 case FPU_NONE: 447 #ifdef FPU_EMULATE 448 strlcpy(fpu, ", emulated FPU", sizeof(fpu)); 449 #else 450 strlcpy(fpu, ", no FPU", sizeof(fpu)); 451 #endif 452 break; 453 default: 454 strlcpy(fpu, ", unknown FPU", sizeof(fpu)); 455 } 456 457 /* 458 * ...and finally, the cache type. 459 */ 460 cache[0] = '\0'; 461 if (cputype == CPU_68040) 462 snprintf(cache, sizeof(cache), 463 ", 4k on-chip physical I/D caches"); 464 else { 465 switch (ectype) { 466 case EC_VIRT: 467 snprintf(cache, sizeof(cache), 468 ", %dK virtual-address cache", 469 machineid == HP_320 ? 16 : 32); 470 break; 471 case EC_PHYS: 472 snprintf(cache, sizeof(cache), 473 ", %dK physical-address cache", 474 machineid == HP_370 ? 64 : 32); 475 break; 476 } 477 } 478 479 cpu_setmodel("HP 9000/%s (%sMHz %s CPU%s%s%s)", t, s, cpu, 480 mmu, fpu, cache); 481 printf("%s\n", cpu_getmodel()); 482 #ifdef DIAGNOSTIC 483 printf("cpu: delay divisor %d", delay_divisor); 484 if (mmuid) 485 printf(", mmuid %d", mmuid); 486 printf("\n"); 487 #endif 488 489 /* 490 * Now that we have told the user what they have, 491 * let them know if that machine type isn't configured. 492 */ 493 switch (machineid) { 494 case -1: /* keep compilers happy */ 495 #if !defined(HP320) 496 case HP_320: 497 #endif 498 #if !defined(HP330) 499 case HP_330: 500 #endif 501 #if !defined(HP340) 502 case HP_340: 503 #endif 504 #if !defined(HP345) 505 case HP_345: 506 #endif 507 #if !defined(HP350) 508 case HP_350: 509 #endif 510 #if !defined(HP360) 511 case HP_360: 512 #endif 513 #if !defined(HP362) 514 case HP_362: 515 #endif 516 #if !defined(HP370) 517 case HP_370: 518 #endif 519 #if !defined(HP375) 520 case HP_375: 521 #endif 522 #if !defined(HP380) 523 case HP_380: 524 #endif 525 #if !defined(HP382) 526 case HP_382: 527 #endif 528 #if !defined(HP385) 529 case HP_385: 530 #endif 531 #if !defined(HP400) 532 case HP_400: 533 #endif 534 #if !defined(HP425) 535 case HP_425: 536 #endif 537 #if !defined(HP433) 538 case HP_433: 539 #endif 540 panic("SPU type not configured"); 541 default: 542 break; 543 } 544 545 return; 546 lose: 547 panic("startup"); 548 } 549 550 /* 551 * machine dependent system variables. 552 */ 553 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 554 { 555 556 sysctl_createv(clog, 0, NULL, NULL, 557 CTLFLAG_PERMANENT, 558 CTLTYPE_NODE, "machdep", NULL, 559 NULL, 0, NULL, 0, 560 CTL_MACHDEP, CTL_EOL); 561 562 sysctl_createv(clog, 0, NULL, NULL, 563 CTLFLAG_PERMANENT, 564 CTLTYPE_STRUCT, "console_device", NULL, 565 sysctl_consdev, 0, NULL, sizeof(dev_t), 566 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 567 } 568 569 int waittime = -1; 570 571 void 572 cpu_reboot(int howto, char *bootstr) 573 { 574 struct pcb *pcb = lwp_getpcb(curlwp); 575 576 /* take a snap shot before clobbering any registers */ 577 if (pcb != NULL) 578 savectx(pcb); 579 580 /* If system is cold, just halt. */ 581 if (cold) { 582 howto |= RB_HALT; 583 goto haltsys; 584 } 585 586 boothowto = howto; 587 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 588 waittime = 0; 589 vfs_shutdown(); 590 } 591 592 /* Disable interrupts. */ 593 splhigh(); 594 595 /* If rebooting and a dump is requested do it. */ 596 if (howto & RB_DUMP) 597 dumpsys(); 598 599 haltsys: 600 /* Run any shutdown hooks. */ 601 doshutdownhooks(); 602 603 pmf_system_shutdown(boothowto); 604 605 #if defined(PANICWAIT) && !defined(DDB) 606 if ((howto & RB_HALT) == 0 && panicstr) { 607 printf("hit any key to reboot...\n"); 608 cnpollc(1); 609 (void)cngetc(); 610 cnpollc(0); 611 printf("\n"); 612 } 613 #endif 614 615 /* Finally, halt/reboot the system. */ 616 if (howto & RB_HALT) { 617 printf("System halted. Hit any key to reboot.\n\n"); 618 cnpollc(1); 619 (void)cngetc(); 620 cnpollc(0); 621 } 622 623 printf("rebooting...\n"); 624 DELAY(1000000); 625 doboot(); 626 /* NOTREACHED */ 627 } 628 629 /* 630 * Initialize the kernel crash dump header. 631 */ 632 static void 633 cpu_init_kcore_hdr(void) 634 { 635 cpu_kcore_hdr_t *h = &cpu_kcore_hdr; 636 struct m68k_kcore_hdr *m = &h->un._m68k; 637 extern int end; 638 639 memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr)); 640 641 /* 642 * Initialize the `dispatcher' portion of the header. 643 */ 644 strcpy(h->name, machine); 645 h->page_size = PAGE_SIZE; 646 h->kernbase = KERNBASE; 647 648 /* 649 * Fill in information about our MMU configuration. 650 */ 651 m->mmutype = mmutype; 652 m->sg_v = SG_V; 653 m->sg_frame = SG_FRAME; 654 m->sg_ishift = SG_ISHIFT; 655 m->sg_pmask = SG_PMASK; 656 m->sg40_shift1 = SG4_SHIFT1; 657 m->sg40_mask2 = SG4_MASK2; 658 m->sg40_shift2 = SG4_SHIFT2; 659 m->sg40_mask3 = SG4_MASK3; 660 m->sg40_shift3 = SG4_SHIFT3; 661 m->sg40_addr1 = SG4_ADDR1; 662 m->sg40_addr2 = SG4_ADDR2; 663 m->pg_v = PG_V; 664 m->pg_frame = PG_FRAME; 665 666 /* 667 * Initialize pointer to kernel segment table. 668 */ 669 m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa); 670 671 /* 672 * Initialize relocation value such that: 673 * 674 * pa = (va - KERNBASE) + reloc 675 */ 676 m->reloc = lowram; 677 678 /* 679 * Define the end of the relocatable range. 680 */ 681 m->relocend = (uint32_t)&end; 682 683 /* 684 * hp300 has one contiguous memory segment. 685 */ 686 m->ram_segs[0].start = lowram; 687 m->ram_segs[0].size = ctob(physmem); 688 } 689 690 /* 691 * Compute the size of the machine-dependent crash dump header. 692 * Returns size in disk blocks. 693 */ 694 695 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t))) 696 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1)) 697 698 static int 699 cpu_dumpsize(void) 700 { 701 702 return btodb(MDHDRSIZE); 703 } 704 705 /* 706 * Called by dumpsys() to dump the machine-dependent header. 707 */ 708 static int 709 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop) 710 { 711 int buf[MDHDRSIZE / sizeof(int)]; 712 cpu_kcore_hdr_t *chdr; 713 kcore_seg_t *kseg; 714 int error; 715 716 kseg = (kcore_seg_t *)buf; 717 chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) / 718 sizeof(int)]; 719 720 /* Create the segment header. */ 721 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 722 kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t)); 723 724 memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t)); 725 error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf)); 726 *blknop += btodb(sizeof(buf)); 727 return error; 728 } 729 730 /* 731 * These variables are needed by /sbin/savecore 732 */ 733 uint32_t dumpmag = 0x8fca0101; /* magic number */ 734 int dumpsize = 0; /* pages */ 735 long dumplo = 0; /* blocks */ 736 737 /* 738 * This is called by main to set dumplo and dumpsize. 739 * Dumps always skip the first PAGE_SIZE of disk space 740 * in case there might be a disk label stored there. 741 * If there is extra space, put dump at the end to 742 * reduce the chance that swapping trashes it. 743 */ 744 void 745 cpu_dumpconf(void) 746 { 747 int chdrsize; /* size of dump header */ 748 int nblks; /* size of dump area */ 749 750 if (dumpdev == NODEV) 751 return; 752 nblks = bdev_size(dumpdev); 753 chdrsize = cpu_dumpsize(); 754 755 dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size); 756 757 /* 758 * Check do see if we will fit. Note we always skip the 759 * first PAGE_SIZE in case there is a disk label there. 760 */ 761 if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) { 762 dumpsize = 0; 763 dumplo = -1; 764 return; 765 } 766 767 /* 768 * Put dump at the end of the partition. 769 */ 770 dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize; 771 } 772 773 /* 774 * Dump physical memory onto the dump device. Called by cpu_reboot(). 775 */ 776 void 777 dumpsys(void) 778 { 779 const struct bdevsw *bdev; 780 daddr_t blkno; /* current block to write */ 781 /* dump routine */ 782 int (*dump)(dev_t, daddr_t, void *, size_t); 783 int pg; /* page being dumped */ 784 paddr_t maddr; /* PA being dumped */ 785 int error; /* error code from (*dump)() */ 786 787 /* XXX initialized here because of gcc lossage */ 788 maddr = lowram; 789 pg = 0; 790 791 /* Make sure dump device is valid. */ 792 if (dumpdev == NODEV) 793 return; 794 bdev = bdevsw_lookup(dumpdev); 795 if (bdev == NULL) 796 return; 797 if (dumpsize == 0) { 798 cpu_dumpconf(); 799 if (dumpsize == 0) 800 return; 801 } 802 if (dumplo <= 0) { 803 printf("\ndump to dev %u,%u not possible\n", 804 major(dumpdev), minor(dumpdev)); 805 return; 806 } 807 dump = bdev->d_dump; 808 blkno = dumplo; 809 810 printf("\ndumping to dev %u,%u offset %ld\n", 811 major(dumpdev), minor(dumpdev), dumplo); 812 813 printf("dump "); 814 815 /* Write the dump header. */ 816 error = cpu_dump(dump, &blkno); 817 if (error) 818 goto bad; 819 820 for (pg = 0; pg < dumpsize; pg++) { 821 #define NPGMB (1024*1024/PAGE_SIZE) 822 /* print out how many MBs we have dumped */ 823 if (pg && (pg % NPGMB) == 0) 824 printf("%d ", pg / NPGMB); 825 #undef NPGMB 826 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr, 827 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 828 829 pmap_update(pmap_kernel()); 830 error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE); 831 bad: 832 switch (error) { 833 case 0: 834 maddr += PAGE_SIZE; 835 blkno += btodb(PAGE_SIZE); 836 break; 837 838 case ENXIO: 839 printf("device bad\n"); 840 return; 841 842 case EFAULT: 843 printf("device not ready\n"); 844 return; 845 846 case EINVAL: 847 printf("area improper\n"); 848 return; 849 850 case EIO: 851 printf("i/o error\n"); 852 return; 853 854 case EINTR: 855 printf("aborted from console\n"); 856 return; 857 858 default: 859 printf("error %d\n", error); 860 return; 861 } 862 } 863 printf("succeeded\n"); 864 } 865 866 static void 867 initcpu(void) 868 { 869 870 parityenable(); 871 #ifdef USELEDS 872 ledinit(); 873 #endif 874 } 875 876 void 877 straytrap(int pc, u_short evec) 878 { 879 printf("unexpected trap (vector offset %x) from %x\n", 880 evec & 0xFFF, pc); 881 } 882 883 /* XXX should change the interface, and make one badaddr() function */ 884 885 int *nofault; 886 887 int 888 badaddr(void *addr) 889 { 890 int i; 891 label_t faultbuf; 892 893 nofault = (int *)&faultbuf; 894 if (setjmp((label_t *)nofault)) { 895 nofault = (int *)0; 896 return 1; 897 } 898 i = *(volatile short *)addr; 899 __USE(i); 900 nofault = (int *)0; 901 return 0; 902 } 903 904 int 905 badbaddr(void *addr) 906 { 907 int i; 908 label_t faultbuf; 909 910 nofault = (int *)&faultbuf; 911 if (setjmp((label_t *)nofault)) { 912 nofault = (int *)0; 913 return 1; 914 } 915 i = *(volatile char *)addr; 916 __USE(i); 917 nofault = (int *) 0; 918 return 0; 919 } 920 921 /* 922 * lookup_bootinfo: 923 * 924 * Look up information in bootinfo from boot loader. 925 */ 926 void * 927 lookup_bootinfo(int type) 928 { 929 struct btinfo_common *bt; 930 char *help = (char *)bootinfo_va; 931 932 /* Check for a bootinfo record first. */ 933 if (help == NULL) 934 return NULL; 935 936 do { 937 bt = (struct btinfo_common *)help; 938 if (bt->type == type) 939 return help; 940 help += bt->next; 941 } while (bt->next != 0 && 942 (size_t)help < (size_t)bootinfo_va + BOOTINFO_SIZE); 943 944 return NULL; 945 } 946 947 #if defined(PANICBUTTON) && !defined(DDB) 948 /* 949 * Declare these so they can be patched. 950 */ 951 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 952 int candbdiv = 2; /* give em half a second (hz / candbdiv) */ 953 954 static void candbtimer(void *); 955 956 int crashandburn; 957 958 callout_t candbtimer_ch; 959 960 void 961 candbtimer(void *arg) 962 { 963 964 crashandburn = 0; 965 } 966 #endif /* PANICBUTTON & !DDB */ 967 968 static int innmihand; /* simple mutex */ 969 970 /* 971 * Level 7 interrupts can be caused by HIL keyboards (in cooked mode only, 972 * but we run them in raw mode) or parity errors. 973 */ 974 void 975 nmihand(struct frame frame) 976 { 977 978 /* Prevent unwanted recursion. */ 979 if (innmihand) 980 return; 981 innmihand = 1; 982 983 if (parityerror(&frame)) 984 return; 985 /* panic?? */ 986 printf("unexpected level 7 interrupt ignored\n"); 987 988 innmihand = 0; 989 } 990 991 /* 992 * Parity error section. Contains magic. 993 */ 994 #define PARREG ((volatile short *)IIOV(0x5B0000)) 995 static int gotparmem = 0; 996 #ifdef DEBUG 997 int ignorekperr = 0; /* ignore kernel parity errors */ 998 #endif 999 1000 /* 1001 * Enable parity detection 1002 */ 1003 static void 1004 parityenable(void) 1005 { 1006 label_t faultbuf; 1007 1008 nofault = (int *)&faultbuf; 1009 if (setjmp((label_t *)nofault)) { 1010 nofault = (int *)0; 1011 printf("Parity detection disabled\n"); 1012 return; 1013 } 1014 *PARREG = 1; 1015 nofault = (int *)0; 1016 gotparmem = 1; 1017 } 1018 1019 /* 1020 * Determine if level 7 interrupt was caused by a parity error 1021 * and deal with it if it was. Returns 1 if it was a parity error. 1022 */ 1023 static int 1024 parityerror(struct frame *fp) 1025 { 1026 if (!gotparmem) 1027 return 0; 1028 *PARREG = 0; 1029 DELAY(10); 1030 *PARREG = 1; 1031 if (panicstr) { 1032 printf("parity error after panic ignored\n"); 1033 return 1; 1034 } 1035 if (!parityerrorfind()) 1036 printf("WARNING: transient parity error ignored\n"); 1037 else if (USERMODE(fp->f_sr)) { 1038 printf("pid %d: parity error\n", curproc->p_pid); 1039 uprintf("sorry, pid %d killed due to memory parity error\n", 1040 curproc->p_pid); 1041 psignal(curproc, SIGKILL); 1042 #ifdef DEBUG 1043 } else if (ignorekperr) { 1044 printf("WARNING: kernel parity error ignored\n"); 1045 #endif 1046 } else { 1047 regdump((struct trapframe *)fp, 128); 1048 panic("kernel parity error"); 1049 } 1050 return 1; 1051 } 1052 1053 /* 1054 * Yuk! There has got to be a better way to do this! 1055 * Searching all of memory with interrupts blocked can lead to disaster. 1056 */ 1057 static int 1058 parityerrorfind(void) 1059 { 1060 static label_t parcatch; 1061 static int looking = 0; 1062 volatile int pg, o, s; 1063 volatile int *ip; 1064 int i; 1065 int found; 1066 1067 /* 1068 * If looking is true we are searching for a known parity error 1069 * and it has just occurred. All we do is return to the higher 1070 * level invocation. 1071 */ 1072 if (looking) 1073 longjmp(&parcatch); 1074 s = splhigh(); 1075 /* 1076 * If setjmp returns true, the parity error we were searching 1077 * for has just occurred (longjmp above) at the current pg+o 1078 */ 1079 if (setjmp(&parcatch)) { 1080 printf("Parity error at 0x%x\n", ctob(pg)|o); 1081 found = 1; 1082 goto done; 1083 } 1084 /* 1085 * If we get here, a parity error has occurred for the first time 1086 * and we need to find it. We turn off any external caches and 1087 * loop thru memory, testing every longword til a fault occurs and 1088 * we regain control at setjmp above. Note that because of the 1089 * setjmp, pg and o need to be volatile or their values will be lost. 1090 */ 1091 looking = 1; 1092 ecacheoff(); 1093 for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) { 1094 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, ctob(pg), 1095 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 1096 pmap_update(pmap_kernel()); 1097 ip = (int *)vmmap; 1098 for (o = 0; o < PAGE_SIZE; o += sizeof(int)) 1099 i = *ip++; 1100 } 1101 __USE(i); 1102 /* 1103 * Getting here implies no fault was found. Should never happen. 1104 */ 1105 printf("Couldn't locate parity error\n"); 1106 found = 0; 1107 done: 1108 looking = 0; 1109 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, (vaddr_t)&vmmap[PAGE_SIZE]); 1110 pmap_update(pmap_kernel()); 1111 ecacheon(); 1112 splx(s); 1113 return found; 1114 } 1115 1116 /* 1117 * cpu_exec_aout_makecmds(): 1118 * CPU-dependent a.out format hook for execve(). 1119 * 1120 * Determine of the given exec package refers to something which we 1121 * understand and, if so, set up the vmcmds for it. 1122 * 1123 * XXX what are the special cases for the hp300? 1124 * XXX why is this COMPAT_NOMID? was something generating 1125 * hp300 binaries with an a_mid of 0? i thought that was only 1126 * done on little-endian machines... -- cgd 1127 */ 1128 int 1129 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 1130 { 1131 #if defined(COMPAT_NOMID) || defined(COMPAT_44) 1132 u_long midmag, magic; 1133 u_short mid; 1134 int error; 1135 struct exec *execp = epp->ep_hdr; 1136 1137 midmag = ntohl(execp->a_midmag); 1138 mid = (midmag >> 16) & 0xffff; 1139 magic = midmag & 0xffff; 1140 1141 midmag = mid << 16 | magic; 1142 1143 switch (midmag) { 1144 #ifdef COMPAT_NOMID 1145 case (MID_ZERO << 16) | ZMAGIC: 1146 error = exec_aout_prep_oldzmagic(l, epp); 1147 return error; 1148 #endif 1149 #ifdef COMPAT_44 1150 case (MID_HP300 << 16) | ZMAGIC: 1151 error = exec_aout_prep_oldzmagic(l, epp); 1152 return error; 1153 #endif 1154 } 1155 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */ 1156 1157 return ENOEXEC; 1158 } 1159 1160 int 1161 mm_md_physacc(paddr_t pa, vm_prot_t prot) 1162 { 1163 1164 /* 1165 * On the hp300, physical RAM is always located at the end of 1166 * the physical address space, i.e. from 0xffffffff to lowram. 1167 */ 1168 return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0; 1169 } 1170 1171 int 1172 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) 1173 { 1174 1175 /* 1176 * Do not allow reading intio or dio device space. This could lead 1177 * to corruption of device registers. 1178 */ 1179 *handled = false; 1180 return (ISIIOVA(ptr) || ((uint8_t *)ptr >= extiobase && 1181 (uint8_t *)ptr < extiobase + (EIOMAPSIZE * PAGE_SIZE))) 1182 ? EFAULT : 0; 1183 } 1184 1185 #ifdef MODULAR 1186 /* 1187 * Push any modules loaded by the bootloader etc. 1188 */ 1189 void 1190 module_init_md(void) 1191 { 1192 } 1193 #endif 1194