1 /* $NetBSD: machdep.c,v 1.87 2003/04/26 11:05:21 ragge 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 * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 42 */ 43 44 #include "opt_ddb.h" 45 #include "opt_kgdb.h" 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/proc.h> 51 #include <sys/buf.h> 52 #include <sys/reboot.h> 53 #include <sys/conf.h> 54 #include <sys/file.h> 55 #include <sys/device.h> 56 #include <sys/malloc.h> 57 #include <sys/mbuf.h> 58 #include <sys/msgbuf.h> 59 #include <sys/ioctl.h> 60 #include <sys/tty.h> 61 #include <sys/mount.h> 62 #include <sys/user.h> 63 #include <sys/exec.h> 64 #include <sys/core.h> 65 #include <sys/kcore.h> 66 #include <sys/vnode.h> 67 #include <sys/sa.h> 68 #include <sys/syscallargs.h> 69 #include <sys/ksyms.h> 70 #ifdef KGDB 71 #include <sys/kgdb.h> 72 #endif 73 74 #include <uvm/uvm_extern.h> 75 76 #include <sys/sysctl.h> 77 78 #include <dev/cons.h> 79 80 #include <machine/cpu.h> 81 #include <machine/dvma.h> 82 #include <machine/idprom.h> 83 #include <machine/kcore.h> 84 #include <machine/reg.h> 85 #include <machine/psl.h> 86 #include <machine/pte.h> 87 88 #if defined(DDB) 89 #include <machine/db_machdep.h> 90 #include <ddb/db_sym.h> 91 #include <ddb/db_extern.h> 92 #endif 93 94 #include <sun3/sun3/machdep.h> 95 96 #include "ksyms.h" 97 98 /* Defined in locore.s */ 99 extern char kernel_text[]; 100 /* Defined by the linker */ 101 extern char etext[]; 102 103 /* Our exported CPU info; we can have only one. */ 104 struct cpu_info cpu_info_store; 105 106 struct vm_map *exec_map = NULL; 107 struct vm_map *mb_map = NULL; 108 struct vm_map *phys_map = NULL; 109 110 int physmem; 111 int fputype; 112 caddr_t msgbufaddr; 113 114 /* Virtual page frame for /dev/mem (see mem.c) */ 115 vaddr_t vmmap; 116 117 union sun3sir sun3sir; 118 119 /* 120 * safepri is a safe priority for sleep to set for a spin-wait 121 * during autoconfiguration or after a panic. 122 */ 123 int safepri = PSL_LOWIPL; 124 125 u_char cpu_machine_id = 0; 126 char *cpu_string = NULL; 127 int cpu_has_vme = 0; 128 int has_iocache = 0; 129 130 vaddr_t dumppage; 131 132 static void identifycpu __P((void)); 133 static void initcpu __P((void)); 134 135 /* 136 * Console initialization: called early on from main, 137 * before vm init or cpu_startup. This system is able 138 * to use the console for output immediately (via PROM) 139 * but can not use it for input until after this point. 140 */ 141 void 142 consinit() 143 { 144 145 /* 146 * Switch from the PROM console (output only) 147 * to our own console driver. 148 */ 149 cninit(); 150 151 #if NKSYMS || defined(DDB) || defined(LKM) 152 { 153 extern int nsym; 154 extern char *ssym, *esym; 155 156 ksyms_init(nsym, ssym, esym); 157 } 158 #endif /* DDB */ 159 160 /* 161 * Now that the console can do input as well as 162 * output, consider stopping for a debugger. 163 */ 164 if (boothowto & RB_KDB) { 165 #ifdef KGDB 166 /* XXX - Ask on console for kgdb_dev? */ 167 /* Note: this will just return if kgdb_dev==NODEV */ 168 kgdb_connect(1); 169 #else /* KGDB */ 170 /* Either DDB or no debugger (just PROM). */ 171 Debugger(); 172 #endif /* KGDB */ 173 } 174 } 175 176 /* 177 * cpu_startup: allocate memory for variable-sized tables, 178 * initialize cpu, and do autoconfiguration. 179 * 180 * This is called early in init_main.c:main(), after the 181 * kernel memory allocator is ready for use, but before 182 * the creation of processes 1,2, and mountroot, etc. 183 */ 184 void 185 cpu_startup() 186 { 187 caddr_t v; 188 vsize_t size; 189 int sz, i, base, residual; 190 vaddr_t minaddr, maxaddr; 191 char pbuf[9]; 192 193 if (fputype != FPU_NONE) 194 m68k_make_fpu_idle_frame(); 195 196 /* 197 * Initialize message buffer (for kernel printf). 198 * This is put in physical page zero so it will 199 * always be in the same place after a reboot. 200 * Its mapping was prepared in pmap_bootstrap(). 201 * Also, offset some to avoid PROM scribbles. 202 */ 203 v = (caddr_t) KERNBASE; 204 msgbufaddr = (caddr_t)(v + MSGBUFOFF); 205 initmsgbuf(msgbufaddr, MSGBUFSIZE); 206 207 /* 208 * Good {morning,afternoon,evening,night}. 209 */ 210 printf(version); 211 identifycpu(); 212 initfpu(); /* also prints FPU type */ 213 214 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 215 printf("total memory = %s\n", pbuf); 216 217 /* 218 * Get scratch page for dumpsys(). 219 */ 220 if ((dumppage = uvm_km_alloc(kernel_map, PAGE_SIZE)) == 0) 221 panic("startup: alloc dumppage"); 222 223 /* 224 * Find out how much space we need, allocate it, 225 * and then give everything true virtual addresses. 226 */ 227 sz = (u_int)allocsys(NULL, NULL); 228 if ((v = (caddr_t)uvm_km_alloc(kernel_map, round_page(sz))) == 0) 229 panic("startup: no room for tables"); 230 if (allocsys(v, NULL) - v != sz) 231 panic("startup: table size inconsistency"); 232 233 /* 234 * Now allocate buffers proper. They are different than the above 235 * in that they usually occupy more virtual memory than physical. 236 */ 237 size = MAXBSIZE * nbuf; 238 if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size), 239 NULL, UVM_UNKNOWN_OFFSET, 0, 240 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 241 UVM_ADV_NORMAL, 0)) != 0) 242 panic("startup: cannot allocate VM for buffers"); 243 minaddr = (vaddr_t)buffers; 244 if ((bufpages / nbuf) >= btoc(MAXBSIZE)) { 245 /* don't want to alloc more physical mem than needed */ 246 bufpages = btoc(MAXBSIZE) * nbuf; 247 } 248 base = bufpages / nbuf; 249 residual = bufpages % nbuf; 250 for (i = 0; i < nbuf; i++) { 251 vsize_t curbufsize; 252 vaddr_t curbuf; 253 struct vm_page *pg; 254 255 /* 256 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 257 * that MAXBSIZE space, we allocate and map (base+1) pages 258 * for the first "residual" buffers, and then we allocate 259 * "base" pages for the rest. 260 */ 261 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 262 curbufsize = PAGE_SIZE * ((i < residual) ? (base+1) : base); 263 264 while (curbufsize) { 265 pg = uvm_pagealloc(NULL, 0, NULL, 0); 266 if (pg == NULL) 267 panic("cpu_startup: not enough memory for " 268 "buffer cache"); 269 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 270 VM_PROT_READ|VM_PROT_WRITE); 271 curbuf += PAGE_SIZE; 272 curbufsize -= PAGE_SIZE; 273 } 274 } 275 pmap_update(pmap_kernel()); 276 277 /* 278 * Allocate a submap for exec arguments. This map effectively 279 * limits the number of processes exec'ing at any time. 280 */ 281 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 282 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 283 284 /* 285 * Allocate a submap for physio 286 */ 287 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 288 VM_PHYS_SIZE, 0, FALSE, NULL); 289 290 /* 291 * Finally, allocate mbuf cluster submap. 292 */ 293 mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 294 nmbclusters * mclbytes, VM_MAP_INTRSAFE, 295 FALSE, NULL); 296 297 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 298 printf("avail memory = %s\n", pbuf); 299 format_bytes(pbuf, sizeof(pbuf), bufpages * PAGE_SIZE); 300 printf("using %u buffers containing %s of memory\n", nbuf, pbuf); 301 302 /* 303 * Allocate a virtual page (for use by /dev/mem) 304 * This page is handed to pmap_enter() therefore 305 * it has to be in the normal kernel VA range. 306 */ 307 vmmap = uvm_km_valloc_wait(kernel_map, PAGE_SIZE); 308 309 /* 310 * Create the DVMA maps. 311 */ 312 dvma_init(); 313 314 /* 315 * Set up CPU-specific registers, cache, etc. 316 */ 317 initcpu(); 318 319 /* 320 * Set up buffers, so they can be used to read disk labels. 321 */ 322 bufinit(); 323 } 324 325 /* 326 * Set registers on exec. 327 */ 328 void 329 setregs(l, pack, stack) 330 struct lwp *l; 331 struct exec_package *pack; 332 u_long stack; 333 { 334 struct trapframe *tf = (struct trapframe *)l->l_md.md_regs; 335 336 tf->tf_sr = PSL_USERSET; 337 tf->tf_pc = pack->ep_entry & ~1; 338 tf->tf_regs[D0] = 0; 339 tf->tf_regs[D1] = 0; 340 tf->tf_regs[D2] = 0; 341 tf->tf_regs[D3] = 0; 342 tf->tf_regs[D4] = 0; 343 tf->tf_regs[D5] = 0; 344 tf->tf_regs[D6] = 0; 345 tf->tf_regs[D7] = 0; 346 tf->tf_regs[A0] = 0; 347 tf->tf_regs[A1] = 0; 348 tf->tf_regs[A2] = (int)l->l_proc->p_psstr; 349 tf->tf_regs[A3] = 0; 350 tf->tf_regs[A4] = 0; 351 tf->tf_regs[A5] = 0; 352 tf->tf_regs[A6] = 0; 353 tf->tf_regs[SP] = stack; 354 355 /* restore a null state frame */ 356 l->l_addr->u_pcb.pcb_fpregs.fpf_null = 0; 357 if (fputype) 358 m68881_restore(&l->l_addr->u_pcb.pcb_fpregs); 359 360 l->l_md.md_flags = 0; 361 } 362 363 /* 364 * Info for CTL_HW 365 */ 366 char machine[16] = MACHINE; /* from <machine/param.h> */ 367 char kernel_arch[16] = "sun3x"; /* XXX needs a sysctl node */ 368 char cpu_model[120]; 369 370 /* 371 * XXX - Should empirically estimate the divisor... 372 * Note that the value of delay_divisor is roughly 373 * 2048 / cpuclock (where cpuclock is in MHz). 374 */ 375 int delay_divisor = 62; /* assume the fastest (33 MHz) */ 376 377 void 378 identifycpu() 379 { 380 u_char machtype; 381 382 machtype = identity_prom.idp_machtype; 383 if ((machtype & IDM_ARCH_MASK) != IDM_ARCH_SUN3X) { 384 printf("Bad IDPROM arch!\n"); 385 sunmon_abort(); 386 } 387 388 cpu_machine_id = machtype; 389 switch (cpu_machine_id) { 390 391 case SUN3X_MACH_80: 392 cpu_string = "80"; /* Hydra */ 393 delay_divisor = 102; /* 20 MHz */ 394 cpu_has_vme = FALSE; 395 break; 396 397 case SUN3X_MACH_470: 398 cpu_string = "470"; /* Pegasus */ 399 delay_divisor = 62; /* 33 MHz */ 400 cpu_has_vme = TRUE; 401 break; 402 403 default: 404 printf("unknown sun3x model\n"); 405 sunmon_abort(); 406 } 407 408 /* Other stuff? (VAC, mc6888x version, etc.) */ 409 /* Note: miniroot cares about the kernel_arch part. */ 410 sprintf(cpu_model, "%s %s", kernel_arch, cpu_string); 411 412 printf("Model: %s\n", cpu_model); 413 } 414 415 /* 416 * machine dependent system variables. 417 */ 418 int 419 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 420 int *name; 421 u_int namelen; 422 void *oldp; 423 size_t *oldlenp; 424 void *newp; 425 size_t newlen; 426 struct proc *p; 427 { 428 int error; 429 dev_t consdev; 430 431 /* all sysctl names at this level are terminal */ 432 if (namelen != 1) 433 return (ENOTDIR); /* overloaded */ 434 435 switch (name[0]) { 436 case CPU_CONSDEV: 437 if (cn_tab != NULL) 438 consdev = cn_tab->cn_dev; 439 else 440 consdev = NODEV; 441 error = sysctl_rdstruct(oldp, oldlenp, newp, 442 &consdev, sizeof consdev); 443 break; 444 445 #if 0 /* XXX - Not yet... */ 446 case CPU_ROOT_DEVICE: 447 error = sysctl_rdstring(oldp, oldlenp, newp, root_device); 448 break; 449 450 case CPU_BOOTED_KERNEL: 451 error = sysctl_rdstring(oldp, oldlenp, newp, booted_kernel); 452 break; 453 #endif 454 455 default: 456 error = EOPNOTSUPP; 457 } 458 return (error); 459 } 460 461 /* See: sig_machdep.c */ 462 463 /* 464 * Do a sync in preparation for a reboot. 465 * XXX - This could probably be common code. 466 * XXX - And now, most of it is in vfs_shutdown() 467 * XXX - Put waittime checks in there too? 468 */ 469 int waittime = -1; /* XXX - Who else looks at this? -gwr */ 470 static void 471 reboot_sync __P((void)) 472 { 473 474 /* Check waittime here to localize its use to this function. */ 475 if (waittime >= 0) 476 return; 477 waittime = 0; 478 vfs_shutdown(); 479 } 480 481 /* 482 * Common part of the BSD and SunOS reboot system calls. 483 */ 484 __dead void 485 cpu_reboot(howto, user_boot_string) 486 int howto; 487 char *user_boot_string; 488 { 489 /* Note: this string MUST be static! */ 490 static char bootstr[128]; 491 char *p; 492 493 /* If system is cold, just halt. (early panic?) */ 494 if (cold) 495 goto haltsys; 496 497 /* Un-blank the screen if appropriate. */ 498 cnpollc(1); 499 500 if ((howto & RB_NOSYNC) == 0) { 501 reboot_sync(); 502 /* 503 * If we've been adjusting the clock, the todr 504 * will be out of synch; adjust it now. 505 * 506 * XXX - However, if the kernel has been sitting in ddb, 507 * the time will be way off, so don't set the HW clock! 508 * XXX - Should do sanity check against HW clock. -gwr 509 */ 510 /* resettodr(); */ 511 } 512 513 /* Disable interrupts. */ 514 splhigh(); 515 516 /* Write out a crash dump if asked. */ 517 if (howto & RB_DUMP) 518 dumpsys(); 519 520 /* run any shutdown hooks */ 521 doshutdownhooks(); 522 523 if (howto & RB_HALT) { 524 haltsys: 525 printf("halted.\n"); 526 sunmon_halt(); 527 } 528 529 /* 530 * Automatic reboot. 531 */ 532 if (user_boot_string) 533 strncpy(bootstr, user_boot_string, sizeof(bootstr)); 534 else { 535 /* 536 * Build our own boot string with an empty 537 * boot device/file and (maybe) some flags. 538 * The PROM will supply the device/file name. 539 */ 540 p = bootstr; 541 *p = '\0'; 542 if (howto & (RB_KDB|RB_ASKNAME|RB_SINGLE)) { 543 /* Append the boot flags. */ 544 *p++ = ' '; 545 *p++ = '-'; 546 if (howto & RB_KDB) 547 *p++ = 'd'; 548 if (howto & RB_ASKNAME) 549 *p++ = 'a'; 550 if (howto & RB_SINGLE) 551 *p++ = 's'; 552 *p = '\0'; 553 } 554 } 555 printf("rebooting...\n"); 556 sunmon_reboot(bootstr); 557 for (;;) ; 558 /*NOTREACHED*/ 559 } 560 561 /* 562 * These variables are needed by /sbin/savecore 563 */ 564 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 565 int dumpsize = 0; /* pages */ 566 long dumplo = 0; /* blocks */ 567 568 #define DUMP_EXTRA 1 /* CPU-dependent extra pages */ 569 570 /* 571 * This is called by main to set dumplo, dumpsize. 572 * Dumps always skip the first PAGE_SIZE of disk space 573 * in case there might be a disk label stored there. 574 * If there is extra space, put dump at the end to 575 * reduce the chance that swapping trashes it. 576 */ 577 void 578 cpu_dumpconf() 579 { 580 const struct bdevsw *bdev; 581 int devblks; /* size of dump device in blocks */ 582 int dumpblks; /* size of dump image in blocks */ 583 int (*getsize)__P((dev_t)); 584 585 if (dumpdev == NODEV) 586 return; 587 588 bdev = bdevsw_lookup(dumpdev); 589 if (bdev == NULL) 590 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 591 getsize = bdev->d_psize; 592 if (getsize == NULL) 593 return; 594 devblks = (*getsize)(dumpdev); 595 if (devblks <= ctod(1)) 596 return; 597 devblks &= ~(ctod(1) - 1); 598 599 /* 600 * Note: savecore expects dumpsize to be the 601 * number of pages AFTER the dump header. 602 */ 603 dumpsize = physmem; /* pages */ 604 605 /* Position dump image near end of space, page aligned. */ 606 dumpblks = ctod(physmem + DUMP_EXTRA); 607 dumplo = devblks - dumpblks; 608 609 /* If it does not fit, truncate it by moving dumplo. */ 610 /* Note: Must force signed comparison. */ 611 if (dumplo < ((long)ctod(1))) { 612 dumplo = ctod(1); 613 dumpsize = dtoc(devblks - dumplo) - DUMP_EXTRA; 614 } 615 } 616 617 /* Note: gdb looks for "dumppcb" in a kernel crash dump. */ 618 struct pcb dumppcb; 619 620 /* 621 * Write a crash dump. The format while in swap is: 622 * kcore_seg_t cpu_hdr; 623 * cpu_kcore_hdr_t cpu_data; 624 * padding (PAGE_SIZE-sizeof(kcore_seg_t)) 625 * pagemap (2*PAGE_SIZE) 626 * physical memory... 627 */ 628 void 629 dumpsys() 630 { 631 const struct bdevsw *dsw; 632 kcore_seg_t *kseg_p; 633 cpu_kcore_hdr_t *chdr_p; 634 struct sun3x_kcore_hdr *sh; 635 phys_ram_seg_t *crs_p; 636 char *vaddr; 637 paddr_t paddr; 638 int psize, todo, seg, segsz; 639 daddr_t blkno; 640 int error = 0; 641 642 if (dumpdev == NODEV) 643 return; 644 dsw = bdevsw_lookup(dumpdev); 645 if (dsw == NULL || dsw->d_psize == NULL) 646 return; 647 648 /* 649 * For dumps during autoconfiguration, 650 * if dump device has already configured... 651 */ 652 if (dumpsize == 0) 653 cpu_dumpconf(); 654 if (dumplo <= 0) { 655 printf("\ndump to dev %u,%u not possible\n", major(dumpdev), 656 minor(dumpdev)); 657 return; 658 } 659 savectx(&dumppcb); 660 661 psize = (*(dsw->d_psize))(dumpdev); 662 if (psize == -1) { 663 printf("dump area unavailable\n"); 664 return; 665 } 666 667 printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), 668 minor(dumpdev), dumplo); 669 670 /* 671 * Prepare the dump header 672 */ 673 blkno = dumplo; 674 todo = dumpsize; /* pages */ 675 vaddr = (char *)dumppage; 676 memset(vaddr, 0, PAGE_SIZE); 677 678 /* Set pointers to all three parts. */ 679 kseg_p = (kcore_seg_t *)vaddr; 680 chdr_p = (cpu_kcore_hdr_t *)(kseg_p + 1); 681 sh = &chdr_p->un._sun3x; 682 683 /* Fill in kcore_seg_t part. */ 684 CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 685 kseg_p->c_size = (ctob(DUMP_EXTRA) - sizeof(*kseg_p)); 686 687 /* Fill in cpu_kcore_hdr_t part. */ 688 strncpy(chdr_p->name, kernel_arch, sizeof(chdr_p->name)); 689 chdr_p->page_size = PAGE_SIZE; 690 chdr_p->kernbase = KERNBASE; 691 692 /* Fill in the sun3x_kcore_hdr part. */ 693 pmap_kcore_hdr(sh); 694 695 /* Write out the dump header. */ 696 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); 697 if (error) 698 goto fail; 699 blkno += btodb(PAGE_SIZE); 700 701 /* 702 * Now dump physical memory. Note that physical memory 703 * might NOT be congiguous, so do it by segments. 704 */ 705 706 vaddr = (char *)vmmap; /* Borrow /dev/mem VA */ 707 708 for (seg = 0; seg < SUN3X_NPHYS_RAM_SEGS; seg++) { 709 crs_p = &sh->ram_segs[seg]; 710 paddr = crs_p->start; 711 segsz = crs_p->size; 712 713 while (todo && (segsz > 0)) { 714 715 /* Print pages left after every 16. */ 716 if ((todo & 0xf) == 0) 717 printf("\r%4d", todo); 718 719 /* Make a temporary mapping for the page. */ 720 pmap_kenter_pa(vmmap, paddr | PMAP_NC, VM_PROT_READ); 721 pmap_update(pmap_kernel()); 722 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, 723 PAGE_SIZE); 724 pmap_kremove(vmmap, PAGE_SIZE); 725 pmap_update(pmap_kernel()); 726 if (error) 727 goto fail; 728 paddr += PAGE_SIZE; 729 segsz -= PAGE_SIZE; 730 blkno += btodb(PAGE_SIZE); 731 todo--; 732 } 733 } 734 printf("\rdump succeeded\n"); 735 return; 736 fail: 737 printf(" dump error=%d\n", error); 738 } 739 740 static void 741 initcpu() 742 { 743 /* XXX: Enable RAM parity/ECC checking? */ 744 /* XXX: parityenable(); */ 745 746 #ifdef HAVECACHE 747 cache_enable(); 748 #endif 749 } 750 751 /* straptrap() in trap.c */ 752 753 /* from hp300: badaddr() */ 754 /* peek_byte(), peek_word() moved to bus_subr.c */ 755 756 /* XXX: parityenable() ? */ 757 /* regdump() moved to regdump.c */ 758 759 /* 760 * cpu_exec_aout_makecmds(): 761 * cpu-dependent a.out format hook for execve(). 762 * 763 * Determine if the given exec package refers to something which we 764 * understand and, if so, set up the vmcmds for it. 765 */ 766 int 767 cpu_exec_aout_makecmds(p, epp) 768 struct proc *p; 769 struct exec_package *epp; 770 { 771 return ENOEXEC; 772 } 773