1 /* $NetBSD: machdep.c,v 1.199 2011/01/17 14:36:33 tsutsui Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer 9 * Science Department. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * from: Utah Hdr: machdep.c 1.74 92/12/20 36 * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 37 */ 38 39 /* 40 * Copyright (c) 1994, 1995 Gordon W. Ross 41 * Copyright (c) 1993 Adam Glass 42 * Copyright (c) 1988 University of Utah. 43 * 44 * This code is derived from software contributed to Berkeley by 45 * the Systems Programming Group of the University of Utah Computer 46 * Science Department. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. All advertising materials mentioning features or use of this software 57 * must display the following acknowledgement: 58 * This product includes software developed by the University of 59 * California, Berkeley and its contributors. 60 * 4. Neither the name of the University nor the names of its contributors 61 * may be used to endorse or promote products derived from this software 62 * without specific prior written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 74 * SUCH DAMAGE. 75 * 76 * from: Utah Hdr: machdep.c 1.74 92/12/20 77 * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 78 */ 79 80 #include <sys/cdefs.h> 81 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.199 2011/01/17 14:36:33 tsutsui Exp $"); 82 83 #include "opt_ddb.h" 84 #include "opt_kgdb.h" 85 #include "opt_modular.h" 86 87 #include <sys/param.h> 88 #include <sys/systm.h> 89 #include <sys/kernel.h> 90 #include <sys/proc.h> 91 #include <sys/buf.h> 92 #include <sys/reboot.h> 93 #include <sys/conf.h> 94 #include <sys/file.h> 95 #include <sys/device.h> 96 #include <sys/malloc.h> 97 #include <sys/mbuf.h> 98 #include <sys/msgbuf.h> 99 #include <sys/ioctl.h> 100 #include <sys/tty.h> 101 #include <sys/mount.h> 102 #include <sys/exec.h> 103 #include <sys/exec_aout.h> /* for MID_* */ 104 #include <sys/core.h> 105 #include <sys/kcore.h> 106 #include <sys/vnode.h> 107 #include <sys/syscallargs.h> 108 #include <sys/ksyms.h> 109 #include <sys/module.h> 110 #ifdef KGDB 111 #include <sys/kgdb.h> 112 #endif 113 114 #include <uvm/uvm.h> /* XXX: not _extern ... need vm_map_create */ 115 116 #include <sys/sysctl.h> 117 118 #include <dev/cons.h> 119 120 #include <machine/cpu.h> 121 #include <machine/dvma.h> 122 #include <machine/idprom.h> 123 #include <machine/kcore.h> 124 #include <machine/reg.h> 125 #include <machine/pcb.h> 126 #include <machine/psl.h> 127 #include <machine/pte.h> 128 129 #if defined(DDB) 130 #include <machine/db_machdep.h> 131 #include <ddb/db_sym.h> 132 #include <ddb/db_extern.h> 133 #endif 134 135 #include <sun3/sun3/machdep.h> 136 137 #include "ksyms.h" 138 139 /* Defined in locore.s */ 140 extern char kernel_text[]; 141 /* Defined by the linker */ 142 extern char etext[]; 143 144 /* kernel_arch specific values required by module(9) */ 145 const vaddr_t kernbase = KERNBASE3; 146 const vaddr_t kern_end = KERN_END3; 147 148 /* Our exported CPU info; we can have only one. */ 149 struct cpu_info cpu_info_store; 150 151 struct vm_map *phys_map = NULL; 152 153 int physmem; 154 int fputype; 155 void * msgbufaddr; 156 157 /* Virtual page frame for /dev/mem (see mem.c) */ 158 vaddr_t vmmap; 159 160 /* 161 * safepri is a safe priority for sleep to set for a spin-wait 162 * during autoconfiguration or after a panic. 163 */ 164 int safepri = PSL_LOWIPL; 165 166 /* Our private scratch page for dumping the MMU. */ 167 static vaddr_t dumppage; 168 169 static void identifycpu(void); 170 static void initcpu(void); 171 172 /* 173 * Console initialization: called early on from main, 174 * before vm init or cpu_startup. This system is able 175 * to use the console for output immediately (via PROM) 176 * but can not use it for input until after this point. 177 */ 178 void 179 consinit(void) 180 { 181 182 /* 183 * Switch from the PROM console (output only) 184 * to our own console driver. 185 */ 186 cninit(); 187 188 #if NKSYMS || defined(DDB) || defined(MODULAR) 189 { 190 extern int nsym; 191 extern char *ssym, *esym; 192 193 ksyms_addsyms_elf(nsym, ssym, esym); 194 } 195 #endif /* DDB */ 196 197 /* 198 * Now that the console can do input as well as 199 * output, consider stopping for a debugger. 200 */ 201 if (boothowto & RB_KDB) { 202 #ifdef KGDB 203 /* XXX - Ask on console for kgdb_dev? */ 204 /* Note: this will just return if kgdb_dev==NODEV */ 205 kgdb_connect(1); 206 #else /* KGDB */ 207 /* Either DDB or no debugger (just PROM). */ 208 Debugger(); 209 #endif /* KGDB */ 210 } 211 } 212 213 /* 214 * cpu_startup: allocate memory for variable-sized tables, 215 * initialize CPU, and do autoconfiguration. 216 * 217 * This is called early in init_main.c:main(), after the 218 * kernel memory allocator is ready for use, but before 219 * the creation of processes 1,2, and mountroot, etc. 220 */ 221 void 222 cpu_startup(void) 223 { 224 char *v; 225 vaddr_t minaddr, maxaddr; 226 char pbuf[9]; 227 228 /* 229 * Initialize message buffer (for kernel printf). 230 * This is put in physical page zero so it will 231 * always be in the same place after a reboot. 232 * Its mapping was prepared in pmap_bootstrap(). 233 * Also, offset some to avoid PROM scribbles. 234 */ 235 v = (char *)KERNBASE3; 236 msgbufaddr = v + MSGBUFOFF; 237 initmsgbuf(msgbufaddr, MSGBUFSIZE); 238 239 /* 240 * Good {morning,afternoon,evening,night}. 241 */ 242 printf("%s%s", copyright, version); 243 identifycpu(); 244 initfpu(); /* also prints FPU type */ 245 246 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 247 printf("total memory = %s\n", pbuf); 248 249 /* 250 * Get scratch page for dumpsys(). 251 */ 252 dumppage = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_WIRED); 253 if (dumppage == 0) 254 panic("startup: alloc dumppage"); 255 256 257 minaddr = 0; 258 259 /* 260 * Allocate a submap for physio 261 */ 262 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 263 VM_PHYS_SIZE, 0, false, NULL); 264 265 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 266 printf("avail memory = %s\n", pbuf); 267 268 /* 269 * Allocate a virtual page (for use by /dev/mem) 270 * This page is handed to pmap_enter() therefore 271 * it has to be in the normal kernel VA range. 272 */ 273 vmmap = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, 274 UVM_KMF_VAONLY | UVM_KMF_WAITVA); 275 276 /* 277 * Create the DVMA maps. 278 */ 279 dvma_init(); 280 281 /* 282 * Set up CPU-specific registers, cache, etc. 283 */ 284 initcpu(); 285 } 286 287 /* 288 * Set registers on exec. 289 */ 290 void 291 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 292 { 293 struct trapframe *tf = (struct trapframe *)l->l_md.md_regs; 294 struct pcb *pcb = lwp_getpcb(l); 295 296 tf->tf_sr = PSL_USERSET; 297 tf->tf_pc = pack->ep_entry & ~1; 298 tf->tf_regs[D0] = 0; 299 tf->tf_regs[D1] = 0; 300 tf->tf_regs[D2] = 0; 301 tf->tf_regs[D3] = 0; 302 tf->tf_regs[D4] = 0; 303 tf->tf_regs[D5] = 0; 304 tf->tf_regs[D6] = 0; 305 tf->tf_regs[D7] = 0; 306 tf->tf_regs[A0] = 0; 307 tf->tf_regs[A1] = 0; 308 tf->tf_regs[A2] = (int)l->l_proc->p_psstr; 309 tf->tf_regs[A3] = 0; 310 tf->tf_regs[A4] = 0; 311 tf->tf_regs[A5] = 0; 312 tf->tf_regs[A6] = 0; 313 tf->tf_regs[SP] = stack; 314 315 /* restore a null state frame */ 316 pcb->pcb_fpregs.fpf_null = 0; 317 if (fputype) 318 m68881_restore(&pcb->pcb_fpregs); 319 320 l->l_md.md_flags = 0; 321 } 322 323 /* 324 * Info for CTL_HW 325 */ 326 char machine[16] = MACHINE; /* from <machine/param.h> */ 327 char kernel_arch[16] = "sun3"; /* XXX needs a sysctl node */ 328 char cpu_model[120]; 329 330 /* 331 * Determine which Sun3 model we are running on. 332 * We have to do this very early on the Sun3 because 333 * pmap_bootstrap() needs to know if it should avoid 334 * the video memory on the Sun3/50. Therefore, this 335 * function just prints out what we already know. 336 */ 337 void 338 identifycpu(void) 339 { 340 extern char *cpu_string; /* XXX */ 341 342 /* Other stuff? (VAC, mc6888x version, etc.) */ 343 /* Note: miniroot cares about the kernel_arch part. */ 344 sprintf(cpu_model, "%s %s", kernel_arch, cpu_string); 345 346 printf("Model: %s\n", cpu_model); 347 } 348 349 /* 350 * machine dependent system variables. 351 */ 352 #if 0 /* XXX - Not yet... */ 353 static int 354 sysctl_machdep_root_device(SYSCTLFN_ARGS) 355 { 356 struct sysctlnode node = *rnode; 357 358 node.sysctl_data = some permutation on root_device; 359 node.sysctl_size = strlen(root_device) + 1; 360 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 361 } 362 363 static int 364 sysctl_machdep_booted_kernel(SYSCTLFN_ARGS) 365 { 366 struct sysctlnode node = *rnode; 367 368 node.sysctl_data = some permutation on booted_kernel; 369 node.sysctl_size = strlen(booted_kernel) + 1; 370 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 371 } 372 #endif 373 374 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 375 { 376 377 sysctl_createv(clog, 0, NULL, NULL, 378 CTLFLAG_PERMANENT, 379 CTLTYPE_NODE, "machdep", NULL, 380 NULL, 0, NULL, 0, 381 CTL_MACHDEP, CTL_EOL); 382 383 sysctl_createv(clog, 0, NULL, NULL, 384 CTLFLAG_PERMANENT, 385 CTLTYPE_STRUCT, "console_device", NULL, 386 sysctl_consdev, 0, NULL, sizeof(dev_t), 387 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 388 #if 0 /* XXX - Not yet... */ 389 sysctl_createv(clog, 0, NULL, NULL, 390 CTLFLAG_PERMANENT, 391 CTLTYPE_STRING, "root_device", NULL, 392 sysctl_machdep_root_device, 0, NULL, 0, 393 CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL); 394 sysctl_createv(clog, 0, NULL, NULL, 395 CTLFLAG_PERMANENT, 396 CTLTYPE_STRING, "booted_kernel", NULL, 397 sysctl_machdep_booted_kernel, 0, NULL, 0, 398 CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); 399 #endif 400 } 401 402 /* See: sig_machdep.c */ 403 404 /* 405 * Do a sync in preparation for a reboot. 406 * XXX - This could probably be common code. 407 * XXX - And now, most of it is in vfs_shutdown() 408 * XXX - Put waittime checks in there too? 409 */ 410 int waittime = -1; /* XXX - Who else looks at this? -gwr */ 411 static void 412 reboot_sync(void) 413 { 414 415 /* Check waittime here to localize its use to this function. */ 416 if (waittime >= 0) 417 return; 418 waittime = 0; 419 vfs_shutdown(); 420 } 421 422 /* 423 * Common part of the BSD and SunOS reboot system calls. 424 */ 425 __dead void 426 cpu_reboot(int howto, char *user_boot_string) 427 { 428 char *bs, *p; 429 char default_boot_string[8]; 430 431 /* If system is cold, just halt. (early panic?) */ 432 if (cold) 433 goto haltsys; 434 435 /* Un-blank the screen if appropriate. */ 436 cnpollc(1); 437 438 if ((howto & RB_NOSYNC) == 0) { 439 reboot_sync(); 440 /* 441 * If we've been adjusting the clock, the todr 442 * will be out of synch; adjust it now. 443 * 444 * XXX - However, if the kernel has been sitting in ddb, 445 * the time will be way off, so don't set the HW clock! 446 * XXX - Should do sanity check against HW clock. -gwr 447 */ 448 /* resettodr(); */ 449 } 450 451 /* Disable interrupts. */ 452 splhigh(); 453 454 /* Write out a crash dump if asked. */ 455 if (howto & RB_DUMP) 456 dumpsys(); 457 458 /* run any shutdown hooks */ 459 doshutdownhooks(); 460 461 pmf_system_shutdown(boothowto); 462 463 if (howto & RB_HALT) { 464 haltsys: 465 printf("halted.\n"); 466 sunmon_halt(); 467 } 468 469 /* 470 * Automatic reboot. 471 */ 472 bs = user_boot_string; 473 if (bs == NULL) { 474 /* 475 * Build our own boot string with an empty 476 * boot device/file and (maybe) some flags. 477 * The PROM will supply the device/file name. 478 */ 479 bs = default_boot_string; 480 *bs = '\0'; 481 if (howto & (RB_KDB|RB_ASKNAME|RB_SINGLE)) { 482 /* Append the boot flags. */ 483 p = bs; 484 *p++ = ' '; 485 *p++ = '-'; 486 if (howto & RB_KDB) 487 *p++ = 'd'; 488 if (howto & RB_ASKNAME) 489 *p++ = 'a'; 490 if (howto & RB_SINGLE) 491 *p++ = 's'; 492 *p = '\0'; 493 } 494 } 495 printf("rebooting...\n"); 496 sunmon_reboot(bs); 497 for (;;) ; 498 /*NOTREACHED*/ 499 } 500 501 /* 502 * These variables are needed by /sbin/savecore 503 */ 504 uint32_t dumpmag = 0x8fca0101; /* magic number */ 505 int dumpsize = 0; /* pages */ 506 long dumplo = 0; /* blocks */ 507 508 #define DUMP_EXTRA 3 /* CPU-dependent extra pages */ 509 510 /* 511 * This is called by main to set dumplo, dumpsize. 512 * Dumps always skip the first PAGE_SIZE of disk space 513 * in case there might be a disk label stored there. 514 * If there is extra space, put dump at the end to 515 * reduce the chance that swapping trashes it. 516 */ 517 void 518 cpu_dumpconf(void) 519 { 520 const struct bdevsw *bdev; 521 int devblks; /* size of dump device in blocks */ 522 int dumpblks; /* size of dump image in blocks */ 523 int (*getsize)(dev_t); 524 525 if (dumpdev == NODEV) 526 return; 527 528 bdev = bdevsw_lookup(dumpdev); 529 if (bdev == NULL) { 530 dumpdev = NODEV; 531 return; 532 } 533 getsize = bdev->d_psize; 534 if (getsize == NULL) 535 return; 536 devblks = (*getsize)(dumpdev); 537 if (devblks <= ctod(1)) 538 return; 539 devblks &= ~(ctod(1)-1); 540 541 /* 542 * Note: savecore expects dumpsize to be the 543 * number of pages AFTER the dump header. 544 */ 545 dumpsize = physmem; 546 547 /* Position dump image near end of space, page aligned. */ 548 dumpblks = ctod(physmem + DUMP_EXTRA); 549 dumplo = devblks - dumpblks; 550 551 /* If it does not fit, truncate it by moving dumplo. */ 552 /* Note: Must force signed comparison. */ 553 if (dumplo < ((long)ctod(1))) { 554 dumplo = ctod(1); 555 dumpsize = dtoc(devblks - dumplo) - DUMP_EXTRA; 556 } 557 } 558 559 /* Note: gdb looks for "dumppcb" in a kernel crash dump. */ 560 struct pcb dumppcb; 561 extern paddr_t avail_start; 562 563 /* 564 * Write a crash dump. The format while in swap is: 565 * kcore_seg_t cpu_hdr; 566 * cpu_kcore_hdr_t cpu_data; 567 * padding (PAGE_SIZE-sizeof(kcore_seg_t)) 568 * pagemap (2*PAGE_SIZE) 569 * physical memory... 570 */ 571 void 572 dumpsys(void) 573 { 574 const struct bdevsw *dsw; 575 kcore_seg_t *kseg_p; 576 cpu_kcore_hdr_t *chdr_p; 577 struct sun3_kcore_hdr *sh; 578 char *vaddr; 579 paddr_t paddr; 580 int psize, todo, chunk; 581 daddr_t blkno; 582 int error = 0; 583 584 if (dumpdev == NODEV) 585 return; 586 if (dumppage == 0) 587 return; 588 dsw = bdevsw_lookup(dumpdev); 589 if (dsw == NULL || dsw->d_psize == NULL) 590 return; 591 592 /* 593 * For dumps during autoconfiguration, 594 * if dump device has already configured... 595 */ 596 if (dumpsize == 0) 597 cpu_dumpconf(); 598 if (dumplo <= 0) { 599 printf("\ndump to dev %u,%u not possible\n", 600 major(dumpdev), minor(dumpdev)); 601 return; 602 } 603 savectx(&dumppcb); 604 605 psize = (*(dsw->d_psize))(dumpdev); 606 if (psize == -1) { 607 printf("dump area unavailable\n"); 608 return; 609 } 610 611 printf("\ndumping to dev %u,%u offset %ld\n", 612 major(dumpdev), minor(dumpdev), dumplo); 613 614 /* 615 * Prepare the dump header, including MMU state. 616 */ 617 blkno = dumplo; 618 todo = dumpsize; /* pages */ 619 vaddr = (char*)dumppage; 620 memset(vaddr, 0, PAGE_SIZE); 621 622 /* Set pointers to all three parts. */ 623 kseg_p = (kcore_seg_t *)vaddr; 624 chdr_p = (cpu_kcore_hdr_t *) (kseg_p + 1); 625 sh = &chdr_p->un._sun3; 626 627 /* Fill in kcore_seg_t part. */ 628 CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 629 kseg_p->c_size = (ctob(DUMP_EXTRA) - sizeof(*kseg_p)); 630 631 /* Fill in cpu_kcore_hdr_t part. */ 632 strncpy(chdr_p->name, kernel_arch, sizeof(chdr_p->name)); 633 chdr_p->page_size = PAGE_SIZE; 634 chdr_p->kernbase = KERNBASE3; 635 636 /* Fill in the sun3_kcore_hdr part (MMU state). */ 637 pmap_kcore_hdr(sh); 638 639 /* Write out the dump header. */ 640 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); 641 if (error) 642 goto fail; 643 blkno += btodb(PAGE_SIZE); 644 645 /* translation RAM (page zero) */ 646 pmap_get_pagemap((int*)vaddr, 0); 647 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); 648 if (error) 649 goto fail; 650 blkno += btodb(PAGE_SIZE); 651 652 /* translation RAM (page one) */ 653 pmap_get_pagemap((int*)vaddr, PAGE_SIZE); 654 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); 655 if (error) 656 goto fail; 657 blkno += btodb(PAGE_SIZE); 658 659 /* 660 * Now dump physical memory. Have to do it in two chunks. 661 * The first chunk is "unmanaged" (by the VM code) and its 662 * range of physical addresses is not allow in pmap_enter. 663 * However, that segment is mapped linearly, so we can just 664 * use the virtual mappings already in place. The second 665 * chunk is done the normal way, using pmap_enter. 666 * 667 * Note that vaddr==(paddr+KERNBASE) for paddr=0 through etext. 668 */ 669 670 /* Do the first chunk (0 <= PA < avail_start) */ 671 paddr = 0; 672 chunk = btoc(avail_start); 673 if (chunk > todo) 674 chunk = todo; 675 do { 676 if ((todo & 0xf) == 0) 677 printf_nolog("\r%4d", todo); 678 vaddr = (char*)(paddr + KERNBASE3); 679 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); 680 if (error) 681 goto fail; 682 paddr += PAGE_SIZE; 683 blkno += btodb(PAGE_SIZE); 684 --todo; 685 } while (--chunk > 0); 686 687 /* Do the second chunk (avail_start <= PA < dumpsize) */ 688 vaddr = (char*)vmmap; /* Borrow /dev/mem VA */ 689 do { 690 if ((todo & 0xf) == 0) 691 printf_nolog("\r%4d", todo); 692 pmap_kenter_pa(vmmap, paddr | PMAP_NC, VM_PROT_READ, 0); 693 pmap_update(pmap_kernel()); 694 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); 695 pmap_kremove(vmmap, PAGE_SIZE); 696 pmap_update(pmap_kernel()); 697 if (error) 698 goto fail; 699 paddr += PAGE_SIZE; 700 blkno += btodb(PAGE_SIZE); 701 } while (--todo > 0); 702 703 printf("\rdump succeeded\n"); 704 return; 705 fail: 706 printf(" dump error=%d\n", error); 707 } 708 709 static void 710 initcpu(void) 711 { 712 /* XXX: Enable RAM parity/ECC checking? */ 713 /* XXX: parityenable(); */ 714 715 #ifdef HAVECACHE 716 cache_enable(); 717 #endif 718 } 719 720 /* straptrap() in trap.c */ 721 722 /* from hp300: badaddr() */ 723 /* peek_byte(), peek_word() moved to bus_subr.c */ 724 725 /* XXX: parityenable() ? */ 726 /* regdump() moved to regdump.c */ 727 728 /* 729 * cpu_exec_aout_makecmds(): 730 * CPU-dependent a.out format hook for execve(). 731 * 732 * Determine if the given exec package refers to something which we 733 * understand and, if so, set up the vmcmds for it. 734 */ 735 int 736 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 737 { 738 return ENOEXEC; 739 } 740 741 #ifdef MODULAR 742 /* 743 * Push any modules loaded by the bootloader etc. 744 */ 745 void 746 module_init_md(void) 747 { 748 } 749 #endif 750