machdep.c revision 1.27
1/* $NetBSD: machdep.c,v 1.27 1997/12/04 15:33:49 tv 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 <sys/param.h> 45#include <sys/systm.h> 46#include <sys/kernel.h> 47#include <sys/map.h> 48#include <sys/proc.h> 49#include <sys/buf.h> 50#include <sys/reboot.h> 51#include <sys/conf.h> 52#include <sys/file.h> 53#include <sys/clist.h> 54#include <sys/callout.h> 55#include <sys/malloc.h> 56#include <sys/mbuf.h> 57#include <sys/msgbuf.h> 58#include <sys/ioctl.h> 59#include <sys/tty.h> 60#include <sys/mount.h> 61#include <sys/user.h> 62#include <sys/exec.h> 63#include <sys/core.h> 64#include <sys/kcore.h> 65#include <sys/vnode.h> 66#include <sys/syscallargs.h> 67#ifdef SYSVMSG 68#include <sys/msg.h> 69#endif 70#ifdef SYSVSEM 71#include <sys/sem.h> 72#endif 73#ifdef SYSVSHM 74#include <sys/shm.h> 75#endif 76#ifdef KGDB 77#include <sys/kgdb.h> 78#endif 79 80#include <vm/vm.h> 81#include <vm/vm_map.h> 82#include <vm/vm_kern.h> 83#include <vm/vm_page.h> 84 85#include <sys/sysctl.h> 86 87#include <dev/cons.h> 88 89#include <machine/cpu.h> 90#include <machine/reg.h> 91#include <machine/psl.h> 92#include <machine/pte.h> 93#include <machine/dvma.h> 94#include <machine/kcore.h> 95#include <machine/db_machdep.h> 96#include <machine/idprom.h> 97#include <machine/machdep.h> 98 99extern char version[]; 100 101/* Defined in locore.s */ 102extern char kernel_text[]; 103/* Defined by the linker */ 104extern char etext[]; 105 106int physmem; 107int fputype; 108 109caddr_t msgbufaddr; 110 111vm_offset_t vmmap; 112 113/* 114 * safepri is a safe priority for sleep to set for a spin-wait 115 * during autoconfiguration or after a panic. 116 */ 117int safepri = PSL_LOWIPL; 118 119/* 120 * Declare these as initialized data so we can patch them. 121 */ 122int nswbuf = 0; 123#ifdef NBUF 124int nbuf = NBUF; 125#else 126int nbuf = 0; 127#endif 128#ifdef BUFPAGES 129int bufpages = BUFPAGES; 130#else 131int bufpages = 0; 132#endif 133 134unsigned char cpu_machine_id = 0; 135char *cpu_string = NULL; 136int cpu_has_vme = 0; 137int has_iocache = 0; 138 139static void identifycpu __P((void)); 140static void initcpu __P((void)); 141 142/* 143 * Console initialization: called early on from main, 144 * before vm init or cpu_startup. This system is able 145 * to setup the console much earlier than here (thanks 146 * to some help from the PROM monitor) so all that is 147 * left to do here is the debugger stuff. 148 */ 149void 150consinit() 151{ 152 /* Note: cninit() done earlier. (See _startup.c) */ 153 154#ifdef KGDB 155 /* XXX - Ask on console for kgdb_dev? */ 156 /* Note: this will just return if kgdb_dev<0 */ 157 if (boothowto & RB_KDB) 158 kgdb_connect(1); 159#endif 160#ifdef DDB 161 /* Now that we have a console, we can stop in DDB. */ 162 db_machine_init(); 163 ddb_init(); 164 if (boothowto & RB_KDB) 165 Debugger(); 166#endif DDB 167} 168 169/* 170 * allocsys() - Private routine used by cpu_startup() below. 171 * 172 * Allocate space for system data structures. We are given 173 * a starting virtual address and we return a final virtual 174 * address; along the way we set each data structure pointer. 175 * 176 * We call allocsys() with 0 to find out how much space we want, 177 * allocate that much and fill it with zeroes, and then call 178 * allocsys() again with the correct base virtual address. 179 */ 180#define valloc(name, type, num) \ 181 v = (caddr_t)(((name) = (type *)v) + (num)) 182static caddr_t allocsys __P((caddr_t)); 183static caddr_t 184allocsys(v) 185 register caddr_t v; 186{ 187 188#ifdef REAL_CLISTS 189 valloc(cfree, struct cblock, nclist); 190#endif 191 valloc(callout, struct callout, ncallout); 192#ifdef SYSVSHM 193 valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 194#endif 195#ifdef SYSVSEM 196 valloc(sema, struct semid_ds, seminfo.semmni); 197 valloc(sem, struct sem, seminfo.semmns); 198 /* This is pretty disgusting! */ 199 valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); 200#endif 201#ifdef SYSVMSG 202 valloc(msgpool, char, msginfo.msgmax); 203 valloc(msgmaps, struct msgmap, msginfo.msgseg); 204 valloc(msghdrs, struct msg, msginfo.msgtql); 205 valloc(msqids, struct msqid_ds, msginfo.msgmni); 206#endif 207 208 /* 209 * Determine how many buffers to allocate. We allocate 210 * the BSD standard of use 10% of memory for the first 2 Meg, 211 * 5% of remaining. Insure a minimum of 16 buffers. 212 * Allocate 1/2 as many swap buffer headers as file i/o buffers. 213 */ 214 if (bufpages == 0) { 215 /* We always have more than 2MB of memory. */ 216 bufpages = ((btoc(2 * 1024 * 1024) + physmem) / 217 (20 * CLSIZE)); 218 } 219 if (nbuf == 0) { 220 nbuf = bufpages; 221 if (nbuf < 16) 222 nbuf = 16; 223 } 224 if (nswbuf == 0) { 225 nswbuf = (nbuf / 2) &~ 1; /* force even */ 226 if (nswbuf > 256) 227 nswbuf = 256; /* sanity */ 228 } 229 valloc(swbuf, struct buf, nswbuf); 230 valloc(buf, struct buf, nbuf); 231 return v; 232} 233#undef valloc 234 235/* 236 * cpu_startup: allocate memory for variable-sized tables, 237 * initialize cpu, and do autoconfiguration. 238 * 239 * This is called early in init_main.c:main(), after the 240 * kernel memory allocator is ready for use, but before 241 * the creation of processes 1,2, and mountroot, etc. 242 */ 243void 244cpu_startup() 245{ 246 caddr_t v; 247 int sz, i; 248 vm_size_t size; 249 int base, residual; 250 vm_offset_t minaddr, maxaddr; 251 252 /* 253 * Initialize message buffer (for kernel printf). 254 * This is put in physical page zero so it will 255 * always be in the same place after a reboot. 256 * Its mapping was prepared in pmap_bootstrap(). 257 * Also, offset some to avoid PROM scribbles. 258 */ 259 v = (caddr_t) KERNBASE; 260 msgbufaddr = (caddr_t)(v + MSGBUFOFF); 261 initmsgbuf(msgbufaddr, MSGBUFSIZE); 262 263 /* 264 * Good {morning,afternoon,evening,night}. 265 */ 266 printf(version); 267 identifycpu(); 268 initfpu(); /* also prints FPU type */ 269 270 printf("real mem = %d\n", ctob(physmem)); 271 272 /* 273 * Find out how much space we need, allocate it, 274 * and then give everything true virtual addresses. 275 */ 276 sz = (int)allocsys((caddr_t)0); 277 if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0) 278 panic("startup: no room for tables"); 279 if (allocsys(v) - v != sz) 280 panic("startup: table size inconsistency"); 281 282 /* 283 * Now allocate buffers proper. They are different than the above 284 * in that they usually occupy more virtual memory than physical. 285 */ 286 size = MAXBSIZE * nbuf; 287 buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers, 288 &maxaddr, size, TRUE); 289 minaddr = (vm_offset_t)buffers; 290 if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0, 291 &minaddr, size, FALSE) != KERN_SUCCESS) 292 panic("startup: cannot allocate buffers"); 293 if ((bufpages / nbuf) >= btoc(MAXBSIZE)) { 294 /* don't want to alloc more physical mem than needed */ 295 bufpages = btoc(MAXBSIZE) * nbuf; 296 } 297 base = bufpages / nbuf; 298 residual = bufpages % nbuf; 299 for (i = 0; i < nbuf; i++) { 300 vm_size_t curbufsize; 301 vm_offset_t curbuf; 302 303 /* 304 * First <residual> buffers get (base+1) physical pages 305 * allocated for them. The rest get (base) physical pages. 306 * 307 * The rest of each buffer occupies virtual space, 308 * but has no physical memory allocated for it. 309 */ 310 curbuf = (vm_offset_t)buffers + i * MAXBSIZE; 311 curbufsize = CLBYTES * (i < residual ? base+1 : base); 312 vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE); 313 vm_map_simplify(buffer_map, curbuf); 314 } 315 316 /* 317 * Allocate a submap for exec arguments. This map effectively 318 * limits the number of processes exec'ing at any time. 319 */ 320 exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 321 16*NCARGS, TRUE); 322 323 /* 324 * We don't use a submap for physio, and use a separate map 325 * for DVMA allocations. Our vmapbuf just maps pages into 326 * the kernel map (any kernel mapping is OK) and then the 327 * device drivers clone the kernel mappings into DVMA space. 328 */ 329 330 /* 331 * Finally, allocate mbuf cluster submap. 332 */ 333 mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, 334 VM_MBUF_SIZE, FALSE); 335 336 /* 337 * Initialize callouts 338 */ 339 callfree = callout; 340 for (i = 1; i < ncallout; i++) 341 callout[i-1].c_next = &callout[i]; 342 callout[i-1].c_next = NULL; 343 344 printf("avail mem = %d\n", (int) ptoa(cnt.v_free_count)); 345 printf("using %d buffers containing %d bytes of memory\n", 346 nbuf, bufpages * CLBYTES); 347 348 /* 349 * Tell the VM system that writing to kernel text isn't allowed. 350 * If we don't, we might end up COW'ing the text segment! 351 */ 352 if (vm_map_protect(kernel_map, (vm_offset_t) kernel_text, 353 trunc_page((vm_offset_t) etext), 354 VM_PROT_READ|VM_PROT_EXECUTE, TRUE) 355 != KERN_SUCCESS) 356 panic("can't protect kernel text"); 357 358 /* 359 * Allocate a virtual page (for use by /dev/mem) 360 * This page is handed to pmap_enter() therefore 361 * it has to be in the normal kernel VA range. 362 */ 363 vmmap = kmem_alloc_wait(kernel_map, NBPG); 364 365 /* 366 * Create the DVMA maps. 367 */ 368 dvma_init(); 369 370 /* 371 * Set up CPU-specific registers, cache, etc. 372 */ 373 initcpu(); 374 375 /* 376 * Set up buffers, so they can be used to read disk labels. 377 */ 378 bufinit(); 379 380 /* 381 * Configure the system. 382 */ 383 configure(); 384} 385 386/* 387 * Set registers on exec. 388 */ 389void 390setregs(p, pack, stack) 391 register struct proc *p; 392 struct exec_package *pack; 393 u_long stack; 394{ 395 struct trapframe *tf = (struct trapframe *)p->p_md.md_regs; 396 397 tf->tf_sr = PSL_USERSET; 398 tf->tf_pc = pack->ep_entry & ~1; 399 tf->tf_regs[D0] = 0; 400 tf->tf_regs[D1] = 0; 401 tf->tf_regs[D2] = 0; 402 tf->tf_regs[D3] = 0; 403 tf->tf_regs[D4] = 0; 404 tf->tf_regs[D5] = 0; 405 tf->tf_regs[D6] = 0; 406 tf->tf_regs[D7] = 0; 407 tf->tf_regs[A0] = 0; 408 tf->tf_regs[A1] = 0; 409 tf->tf_regs[A2] = (int)PS_STRINGS; 410 tf->tf_regs[A3] = 0; 411 tf->tf_regs[A4] = 0; 412 tf->tf_regs[A5] = 0; 413 tf->tf_regs[A6] = 0; 414 tf->tf_regs[SP] = stack; 415 416 /* restore a null state frame */ 417 p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0; 418 if (fputype) 419 m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); 420 421 p->p_md.md_flags = 0; 422} 423 424/* 425 * Info for CTL_HW 426 */ 427char machine[16] = MACHINE; /* from <machine/param.h> */ 428char cpu_model[120]; 429 430/* 431 * XXX - Should empirically estimate the divisor... 432 * Note that the value of delay_divisor is roughly 433 * 2048 / cpuclock (where cpuclock is in MHz). 434 */ 435int delay_divisor = 62; /* assume the fastest (33 MHz) */ 436 437void 438identifycpu() 439{ 440 unsigned char machtype; 441 442 /* Find the IDPROM and copy it to memory. */ 443 /* Note: this needs to use peek_byte(). */ 444 idprom_init(); 445 446 machtype = identity_prom.idp_machtype; 447 if ((machtype & CPU_ARCH_MASK) != SUN3X_ARCH) { 448 printf("not a sun3x?\n"); 449 sunmon_abort(); 450 } 451 452 cpu_machine_id = machtype & SUN3X_IMPL_MASK; 453 switch (cpu_machine_id) { 454 455 case SUN3X_MACH_80: 456 cpu_string = "80"; /* Hydra */ 457 delay_divisor = 102; /* 20 MHz */ 458 cpu_has_vme = FALSE; 459 break; 460 461 case SUN3X_MACH_470: 462 cpu_string = "470"; /* Pegasus */ 463 delay_divisor = 62; /* 33 MHz */ 464 cpu_has_vme = TRUE; 465 break; 466 467 default: 468 printf("unknown sun3x model\n"); 469 sunmon_abort(); 470 } 471 472 /* Other stuff? (VAC, mc6888x version, etc.) */ 473 sprintf(cpu_model, "Sun 3/%s", cpu_string); 474 475 printf("Model: %s (hostid %x)\n", cpu_model, (int) hostid); 476} 477 478/* 479 * machine dependent system variables. 480 */ 481int 482cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 483 int *name; 484 u_int namelen; 485 void *oldp; 486 size_t *oldlenp; 487 void *newp; 488 size_t newlen; 489 struct proc *p; 490{ 491 int error; 492 dev_t consdev; 493 494 /* all sysctl names at this level are terminal */ 495 if (namelen != 1) 496 return (ENOTDIR); /* overloaded */ 497 498 switch (name[0]) { 499 case CPU_CONSDEV: 500 if (cn_tab != NULL) 501 consdev = cn_tab->cn_dev; 502 else 503 consdev = NODEV; 504 error = sysctl_rdstruct(oldp, oldlenp, newp, 505 &consdev, sizeof consdev); 506 break; 507 508#if 0 /* XXX - Not yet... */ 509 case CPU_ROOT_DEVICE: 510 error = sysctl_rdstring(oldp, oldlenp, newp, root_device); 511 break; 512 513 case CPU_BOOTED_KERNEL: 514 error = sysctl_rdstring(oldp, oldlenp, newp, booted_kernel); 515 break; 516#endif 517 518 default: 519 error = EOPNOTSUPP; 520 } 521 return (error); 522} 523 524/* See: sig_machdep.c */ 525 526/* 527 * Do a sync in preparation for a reboot. 528 * XXX - This could probably be common code. 529 * XXX - And now, most of it is in vfs_shutdown() 530 * XXX - Put waittime checks in there too? 531 */ 532int waittime = -1; /* XXX - Who else looks at this? -gwr */ 533static void 534reboot_sync __P((void)) 535{ 536 537 /* Check waittime here to localize its use to this function. */ 538 if (waittime >= 0) 539 return; 540 waittime = 0; 541 vfs_shutdown(); 542} 543 544/* 545 * Common part of the BSD and SunOS reboot system calls. 546 */ 547__dead void 548cpu_reboot(howto, user_boot_string) 549 int howto; 550 char *user_boot_string; 551{ 552 /* Note: this string MUST be static! */ 553 static char bootstr[128]; 554 char *p; 555 556 /* If system is cold, just halt. (early panic?) */ 557 if (cold) 558 goto haltsys; 559 560 /* Un-blank the screen if appropriate. */ 561 cnpollc(1); 562 563 if ((howto & RB_NOSYNC) == 0) { 564 reboot_sync(); 565 /* 566 * If we've been adjusting the clock, the todr 567 * will be out of synch; adjust it now. 568 * 569 * XXX - However, if the kernel has been sitting in ddb, 570 * the time will be way off, so don't set the HW clock! 571 * XXX - Should do sanity check against HW clock. -gwr 572 */ 573 /* resettodr(); */ 574 } 575 576 /* Disable interrupts. */ 577 splhigh(); 578 579 /* Write out a crash dump if asked. */ 580 if (howto & RB_DUMP) 581 dumpsys(); 582 583 /* run any shutdown hooks */ 584 doshutdownhooks(); 585 586 if (howto & RB_HALT) { 587 haltsys: 588 printf("Kernel halted.\n"); 589#if 0 590 /* 591 * This calls the PROM monitor "exit_to_mon" function 592 * which appears to have problems... SunOS uses the 593 * "abort" function when you halt (bug work-around?) 594 * so we might as well do the same. 595 */ 596 sunmon_halt(); /* provokes PROM monitor bug */ 597#else 598 sunmon_abort(); 599#endif 600 } 601 602 /* 603 * Automatic reboot. 604 */ 605 if (user_boot_string) 606 strncpy(bootstr, user_boot_string, sizeof(bootstr)); 607 else { 608 /* 609 * Build our own boot string with an empty 610 * boot device/file and (maybe) some flags. 611 * The PROM will supply the device/file name. 612 */ 613 p = bootstr; 614 *p = '\0'; 615 if (howto & (RB_KDB|RB_ASKNAME|RB_SINGLE)) { 616 /* Append the boot flags. */ 617 *p++ = ' '; 618 *p++ = '-'; 619 if (howto & RB_KDB) 620 *p++ = 'd'; 621 if (howto & RB_ASKNAME) 622 *p++ = 'a'; 623 if (howto & RB_SINGLE) 624 *p++ = 's'; 625 *p = '\0'; 626 } 627 } 628 printf("Kernel rebooting...\n"); 629 sunmon_reboot(bootstr); 630 for (;;) ; 631 /*NOTREACHED*/ 632} 633 634/* 635 * These variables are needed by /sbin/savecore 636 */ 637u_long dumpmag = 0x8fca0101; /* magic number */ 638int dumpsize = 0; /* pages */ 639long dumplo = 0; /* blocks */ 640 641/* 642 * This is called by main to set dumplo, dumpsize. 643 * Dumps always skip the first CLBYTES of disk space 644 * in case there might be a disk label stored there. 645 * If there is extra space, put dump at the end to 646 * reduce the chance that swapping trashes it. 647 */ 648void 649cpu_dumpconf() 650{ 651 int nblks; /* size of dump area */ 652 int maj; 653 int (*getsize)__P((dev_t)); 654 655 /* Validate space in page zero for the kcore header. */ 656 if (MSGBUFOFF < (sizeof(kcore_seg_t) + sizeof(cpu_kcore_hdr_t))) 657 panic("cpu_dumpconf: MSGBUFOFF too small"); 658 659 if (dumpdev == NODEV) 660 return; 661 662 maj = major(dumpdev); 663 if (maj < 0 || maj >= nblkdev) 664 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 665 getsize = bdevsw[maj].d_psize; 666 if (getsize == NULL) 667 return; 668 nblks = (*getsize)(dumpdev); 669 if (nblks <= ctod(1)) 670 return; 671 672 /* Position dump image near end of space, page aligned. */ 673 dumpsize = physmem; /* pages */ 674 dumplo = nblks - ctod(dumpsize); 675 dumplo &= ~(ctod(1)-1); 676 677 /* If it does not fit, truncate it by moving dumplo. */ 678 /* Note: Must force signed comparison. */ 679 if (dumplo < ((long)ctod(1))) { 680 dumplo = ctod(1); 681 dumpsize = dtoc(nblks - dumplo); 682 } 683} 684 685/* Note: gdb looks for "dumppcb" in a kernel crash dump. */ 686struct pcb dumppcb; 687 688/* 689 * Write a crash dump. The format while in swap is: 690 * kcore_seg_t cpu_hdr; 691 * cpu_kcore_hdr_t cpu_data; 692 * padding (NBPG-sizeof(kcore_seg_t)) 693 * pagemap (2*NBPG) 694 * physical memory... 695 */ 696void 697dumpsys() 698{ 699 struct bdevsw *dsw; 700 kcore_seg_t *kseg_p; 701 cpu_kcore_hdr_t *chdr_p; 702 struct sun3x_kcore_hdr *sh; 703 phys_ram_seg_t *crs_p; 704 char *vaddr; 705 vm_offset_t paddr; 706 int psize, todo, seg, segsz; 707 daddr_t blkno; 708 int error = 0; 709 710 msgbufmapped = 0; 711 if (dumpdev == NODEV) 712 return; 713 714 /* 715 * For dumps during autoconfiguration, 716 * if dump device has already configured... 717 */ 718 if (dumpsize == 0) 719 cpu_dumpconf(); 720 if (dumplo <= 0) 721 return; 722 savectx(&dumppcb); 723 724 dsw = &bdevsw[major(dumpdev)]; 725 psize = (*(dsw->d_psize))(dumpdev); 726 if (psize == -1) { 727 printf("dump area unavailable\n"); 728 return; 729 } 730 731 printf("\ndumping to dev 0x%x, offset %d\n", 732 (int) dumpdev, (int) dumplo); 733 734 /* 735 * We put the dump header is in physical page zero, 736 * so there is no extra work here to write it out. 737 * All we do is initialize the header. 738 */ 739 740 /* Set pointers to all three parts. */ 741 kseg_p = (kcore_seg_t *)KERNBASE; 742 chdr_p = (cpu_kcore_hdr_t *) (kseg_p + 1); 743 sh = &chdr_p->un._sun3x; 744 745 /* Fill in kcore_seg_t part. */ 746 CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 747 kseg_p->c_size = sizeof(*chdr_p); 748 749 /* Fill in cpu_kcore_hdr_t part. */ 750 bcopy(machine, chdr_p->name, sizeof(chdr_p->name)); 751 chdr_p->page_size = NBPG; 752 chdr_p->kernbase = KERNBASE; 753 754 /* Fill in the sun3x_kcore_hdr part. */ 755 pmap_kcore_hdr(sh); 756 757 /* 758 * Now dump physical memory. Note that physical memory 759 * might NOT be congiguous, so do it by segments. 760 */ 761 762 blkno = dumplo; 763 todo = dumpsize; /* pages */ 764 vaddr = (char*)vmmap; /* Borrow /dev/mem VA */ 765 766 for (seg = 0; seg < SUN3X_NPHYS_RAM_SEGS; seg++) { 767 crs_p = &sh->ram_segs[seg]; 768 paddr = crs_p->start; 769 segsz = crs_p->size; 770 /* 771 * Our header lives in the first little bit of 772 * physical memory (not written separately), so 773 * we have to adjust the first ram segment size 774 * and start address to reflect the stolen RAM. 775 * (Nothing interesing in that RAM anyway 8^). 776 */ 777 if (seg == 0) { 778 int adj = sizeof(*kseg_p) + sizeof(*chdr_p); 779 crs_p->start += adj; 780 crs_p->size -= adj; 781 } 782 783 while (todo && (segsz > 0)) { 784 785 /* Print pages left after every 16. */ 786 if ((todo & 0xf) == 0) 787 printf("\r%4d", todo); 788 789 /* Make a temporary mapping for the page. */ 790 pmap_enter(pmap_kernel(), vmmap, paddr | PMAP_NC, 791 VM_PROT_READ, FALSE); 792 error = (*dsw->d_dump)(dumpdev, blkno, vaddr, NBPG); 793 pmap_remove(pmap_kernel(), vmmap, vmmap + NBPG); 794 if (error) 795 goto fail; 796 paddr += NBPG; 797 segsz -= NBPG; 798 blkno += btodb(NBPG); 799 todo--; 800 } 801 } 802 printf("\rdump succeeded\n"); 803 return; 804fail: 805 printf(" dump error=%d\n", error); 806} 807 808static void 809initcpu() 810{ 811 /* XXX: Enable RAM parity/ECC checking? */ 812 /* XXX: parityenable(); */ 813 814#ifdef HAVECACHE 815 cache_enable(); 816#endif 817} 818 819/* straptrap() in trap.c */ 820 821/* from hp300: badaddr() */ 822/* peek_byte(), peek_word() moved to bus_subr.c */ 823 824/* XXX: parityenable() ? */ 825/* regdump() moved to regdump.c */ 826 827/* 828 * cpu_exec_aout_makecmds(): 829 * cpu-dependent a.out format hook for execve(). 830 * 831 * Determine if the given exec package refers to something which we 832 * understand and, if so, set up the vmcmds for it. 833 */ 834int 835cpu_exec_aout_makecmds(p, epp) 836 struct proc *p; 837 struct exec_package *epp; 838{ 839 return ENOEXEC; 840} 841