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