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