1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: machdep.c 1.74 92/12/20$ 13 * 14 * @(#)machdep.c 7.36 (Berkeley) 02/10/93 15 */ 16 17 #include <sys/param.h> 18 #include <sys/systm.h> 19 #include <sys/signalvar.h> 20 #include <sys/kernel.h> 21 #include <sys/map.h> 22 #include <sys/proc.h> 23 #include <sys/buf.h> 24 #include <sys/reboot.h> 25 #include <sys/conf.h> 26 #include <sys/file.h> 27 #include <sys/clist.h> 28 #include <sys/callout.h> 29 #include <sys/malloc.h> 30 #include <sys/mbuf.h> 31 #include <sys/msgbuf.h> 32 #include <sys/mount.h> 33 #include <sys/user.h> 34 #include <sys/exec.h> 35 #ifdef SYSVSHM 36 #include <sys/shm.h> 37 #endif 38 #ifdef HPUXCOMPAT 39 #include <hp/hpux/hpux.h> 40 #endif 41 42 #include <machine/cpu.h> 43 #include <machine/reg.h> 44 #include <machine/psl.h> 45 #include <hp300/hp300/isr.h> 46 #include <hp300/hp300/pte.h> 47 #include <net/netisr.h> 48 49 #define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */ 50 #include <vm/vm_kern.h> 51 52 /* the following is used externally (sysctl_hw) */ 53 char machine[] = "hp300"; /* cpu "architecture" */ 54 55 vm_map_t buffer_map; 56 extern vm_offset_t avail_end; 57 58 /* 59 * Declare these as initialized data so we can patch them. 60 */ 61 int nswbuf = 0; 62 #ifdef NBUF 63 int nbuf = NBUF; 64 #else 65 int nbuf = 0; 66 #endif 67 #ifdef BUFPAGES 68 int bufpages = BUFPAGES; 69 #else 70 int bufpages = 0; 71 #endif 72 int msgbufmapped; /* set when safe to use msgbuf */ 73 int maxmem; /* max memory per process */ 74 int physmem = MAXMEM; /* max supported memory, changes to actual */ 75 /* 76 * safepri is a safe priority for sleep to set for a spin-wait 77 * during autoconfiguration or after a panic. 78 */ 79 int safepri = PSL_LOWIPL; 80 81 extern u_int lowram; 82 extern short exframesize[]; 83 84 /* 85 * Console initialization: called early on from main, 86 * before vm init or startup. Do enough configuration 87 * to choose and initialize a console. 88 */ 89 consinit() 90 { 91 92 /* 93 * Set cpuspeed immediately since cninit() called routines 94 * might use delay. Note that we only set it if a custom value 95 * has not already been specified. 96 */ 97 if (cpuspeed == 0) { 98 switch (machineid) { 99 case HP_320: 100 case HP_330: 101 case HP_340: 102 cpuspeed = MHZ_16; 103 break; 104 case HP_350: 105 case HP_360: 106 case HP_380: 107 cpuspeed = MHZ_25; 108 break; 109 case HP_370: 110 case HP_433: 111 cpuspeed = MHZ_33; 112 break; 113 case HP_375: 114 cpuspeed = MHZ_50; 115 break; 116 default: /* assume the fastest */ 117 cpuspeed = MHZ_50; 118 break; 119 } 120 if (mmutype == MMU_68040) 121 cpuspeed *= 2; /* XXX */ 122 } 123 /* 124 * Find what hardware is attached to this machine. 125 */ 126 find_devs(); 127 128 /* 129 * Initialize the console before we print anything out. 130 */ 131 cninit(); 132 } 133 134 /* 135 * cpu_startup: allocate memory for variable-sized tables, 136 * initialize cpu, and do autoconfiguration. 137 */ 138 cpu_startup() 139 { 140 register unsigned i; 141 register caddr_t v, firstaddr; 142 int base, residual; 143 vm_offset_t minaddr, maxaddr; 144 vm_size_t size; 145 #ifdef DEBUG 146 extern int pmapdebug; 147 int opmapdebug = pmapdebug; 148 149 pmapdebug = 0; 150 #endif 151 152 /* 153 * Initialize error message buffer (at end of core). 154 * avail_end was pre-decremented in pmap_bootstrap to compensate. 155 */ 156 for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) 157 pmap_enter(kernel_pmap, (vm_offset_t)msgbufp, 158 avail_end + i * NBPG, VM_PROT_ALL, TRUE); 159 msgbufmapped = 1; 160 161 /* 162 * Good {morning,afternoon,evening,night}. 163 */ 164 printf(version); 165 identifycpu(); 166 printf("real mem = %d\n", ctob(physmem)); 167 168 /* 169 * Allocate space for system data structures. 170 * The first available real memory address is in "firstaddr". 171 * The first available kernel virtual address is in "v". 172 * As pages of kernel virtual memory are allocated, "v" is incremented. 173 * As pages of memory are allocated and cleared, 174 * "firstaddr" is incremented. 175 * An index into the kernel page table corresponding to the 176 * virtual memory address maintained in "v" is kept in "mapaddr". 177 */ 178 /* 179 * Make two passes. The first pass calculates how much memory is 180 * needed and allocates it. The second pass assigns virtual 181 * addresses to the various data structures. 182 */ 183 firstaddr = 0; 184 again: 185 v = (caddr_t)firstaddr; 186 187 #define valloc(name, type, num) \ 188 (name) = (type *)v; v = (caddr_t)((name)+(num)) 189 #define valloclim(name, type, num, lim) \ 190 (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) 191 valloc(cfree, struct cblock, nclist); 192 valloc(callout, struct callout, ncallout); 193 valloc(swapmap, struct map, nswapmap = maxproc * 2); 194 #ifdef SYSVSHM 195 valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 196 #endif 197 198 /* 199 * Determine how many buffers to allocate. 200 * Since HPs tend to be long on memory and short on disk speed, 201 * we allocate more buffer space than the BSD standard of 202 * use 10% of memory for the first 2 Meg, 5% of remaining. 203 * We just allocate a flat 10%. Insure a minimum of 16 buffers. 204 * We allocate 1/2 as many swap buffer headers as file i/o buffers. 205 */ 206 if (bufpages == 0) 207 bufpages = physmem / 10 / CLSIZE; 208 if (nbuf == 0) { 209 nbuf = bufpages; 210 if (nbuf < 16) 211 nbuf = 16; 212 } 213 if (nswbuf == 0) { 214 nswbuf = (nbuf / 2) &~ 1; /* force even */ 215 if (nswbuf > 256) 216 nswbuf = 256; /* sanity */ 217 } 218 valloc(swbuf, struct buf, nswbuf); 219 valloc(buf, struct buf, nbuf); 220 /* 221 * End of first pass, size has been calculated so allocate memory 222 */ 223 if (firstaddr == 0) { 224 size = (vm_size_t)(v - firstaddr); 225 firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size)); 226 if (firstaddr == 0) 227 panic("startup: no room for tables"); 228 goto again; 229 } 230 /* 231 * End of second pass, addresses have been assigned 232 */ 233 if ((vm_size_t)(v - firstaddr) != size) 234 panic("startup: table size inconsistency"); 235 /* 236 * Now allocate buffers proper. They are different than the above 237 * in that they usually occupy more virtual memory than physical. 238 */ 239 size = MAXBSIZE * nbuf; 240 buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers, 241 &maxaddr, size, FALSE); 242 minaddr = (vm_offset_t)buffers; 243 if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0, 244 &minaddr, size, FALSE) != KERN_SUCCESS) 245 panic("startup: cannot allocate buffers"); 246 base = bufpages / nbuf; 247 residual = bufpages % nbuf; 248 for (i = 0; i < nbuf; i++) { 249 vm_size_t curbufsize; 250 vm_offset_t curbuf; 251 252 /* 253 * First <residual> buffers get (base+1) physical pages 254 * allocated for them. The rest get (base) physical pages. 255 * 256 * The rest of each buffer occupies virtual space, 257 * but has no physical memory allocated for it. 258 */ 259 curbuf = (vm_offset_t)buffers + i * MAXBSIZE; 260 curbufsize = CLBYTES * (i < residual ? base+1 : base); 261 vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE); 262 vm_map_simplify(buffer_map, curbuf); 263 } 264 /* 265 * Allocate a submap for exec arguments. This map effectively 266 * limits the number of processes exec'ing at any time. 267 */ 268 exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 269 16*NCARGS, TRUE); 270 /* 271 * Allocate a submap for physio 272 */ 273 phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 274 VM_PHYS_SIZE, TRUE); 275 276 /* 277 * Finally, allocate mbuf pool. Since mclrefcnt is an off-size 278 * we use the more space efficient malloc in place of kmem_alloc. 279 */ 280 mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, 281 M_MBUF, M_NOWAIT); 282 bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); 283 mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, 284 VM_MBUF_SIZE, FALSE); 285 /* 286 * Initialize callouts 287 */ 288 callfree = callout; 289 for (i = 1; i < ncallout; i++) 290 callout[i-1].c_next = &callout[i]; 291 callout[i-1].c_next = NULL; 292 293 #ifdef DEBUG 294 pmapdebug = opmapdebug; 295 #endif 296 printf("avail mem = %d\n", ptoa(cnt.v_free_count)); 297 printf("using %d buffers containing %d bytes of memory\n", 298 nbuf, bufpages * CLBYTES); 299 /* 300 * Set up CPU-specific registers, cache, etc. 301 */ 302 initcpu(); 303 304 /* 305 * Set up buffers, so they can be used to read disk labels. 306 */ 307 bufinit(); 308 309 /* 310 * Configure the system. 311 */ 312 configure(); 313 } 314 315 /* 316 * Set registers on exec. 317 * XXX Should clear registers except sp, pc, 318 * but would break init; should be fixed soon. 319 */ 320 setregs(p, entry, retval) 321 register struct proc *p; 322 u_long entry; 323 int retval[2]; 324 { 325 struct frame *frame = (struct frame *)p->p_md.md_regs; 326 327 frame->f_pc = entry & ~1; 328 #ifdef FPCOPROC 329 /* restore a null state frame */ 330 p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0; 331 m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); 332 #endif 333 #ifdef HPUXCOMPAT 334 if (p->p_md.md_flags & MDP_HPUX) { 335 336 frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */ 337 retval[0] = 0; /* no float card */ 338 #ifdef FPCOPROC 339 retval[1] = 1; /* yes 68881 */ 340 #else 341 retval[1] = 0; /* no 68881 */ 342 #endif 343 } 344 /* 345 * XXX This doesn't have much to do with setting registers but 346 * I didn't want to muck up kern_exec.c with this code, so I 347 * stuck it here. 348 * 349 * Ensure we perform the right action on traps type 1 and 2: 350 * If our parent is an HPUX process and we are being traced, turn 351 * on HPUX style interpretation. Else if we were using the HPUX 352 * style interpretation, revert to the BSD interpretation. 353 * 354 * Note that we do this by changing the trap instruction in the 355 * global "sigcode" array which then gets copied out to the user's 356 * sigcode in the stack. Since we are changing it in the global 357 * array we must always reset it, even for non-HPUX processes. 358 * 359 * Note also that implementing it in this way creates a potential 360 * race where we could have tweaked it for process A which then 361 * blocks in the copyout to the stack and process B comes along 362 * and untweaks it causing A to wind up with the wrong setting 363 * when the copyout continues. However, since we have already 364 * copied something out to this user stack page (thereby faulting 365 * it in), this scenerio is extremely unlikely. 366 */ 367 { 368 extern short sigcodetrap[]; 369 370 if ((p->p_pptr->p_md.md_flags & MDP_HPUX) && 371 (p->p_flag & STRC)) { 372 p->p_md.md_flags |= MDP_HPUXTRACE; 373 *sigcodetrap = 0x4E42; 374 } else { 375 p->p_md.md_flags &= ~MDP_HPUXTRACE; 376 *sigcodetrap = 0x4E41; 377 } 378 } 379 #endif 380 } 381 382 extern char machine[]; 383 char cpu_model[120]; 384 extern char ostype[], osrelease[], version[]; 385 386 identifycpu() 387 { 388 char *t, *mc; 389 int len; 390 391 switch (machineid) { 392 case HP_320: 393 t = "320 (16.67MHz"; 394 break; 395 case HP_330: 396 t = "318/319/330 (16.67MHz"; 397 break; 398 case HP_340: 399 t = "340 (16.67MHz"; 400 break; 401 case HP_350: 402 t = "350 (25MHz"; 403 break; 404 case HP_360: 405 t = "360 (25MHz"; 406 break; 407 case HP_370: 408 t = "370 (33.33MHz"; 409 break; 410 case HP_375: 411 t = "345/375 (50MHz"; 412 break; 413 case HP_380: 414 t = "380/425 (25MHz"; 415 break; 416 case HP_433: 417 t = "433 (33MHz"; 418 break; 419 default: 420 printf("\nunknown machine type %d\n", machineid); 421 panic("startup"); 422 } 423 mc = (mmutype == MMU_68040 ? "40" : 424 (mmutype == MMU_68030 ? "30" : "20")); 425 sprintf(cpu_model, "HP9000/%s MC680%s CPU", t, mc); 426 switch (mmutype) { 427 case MMU_68040: 428 case MMU_68030: 429 strcat(cpu_model, "+MMU"); 430 break; 431 case MMU_68851: 432 strcat(cpu_model, ", MC68851 MMU"); 433 break; 434 case MMU_HP: 435 strcat(cpu_model, ", HP MMU"); 436 break; 437 default: 438 printf("%s\nunknown MMU type %d\n", cpu_model, mmutype); 439 panic("startup"); 440 } 441 len = strlen(cpu_model); 442 if (mmutype == MMU_68040) 443 len += sprintf(cpu_model + len, 444 "+FPU, 4k on-chip physical I/D caches"); 445 else if (mmutype == MMU_68030) 446 len += sprintf(cpu_model + len, ", %sMHz MC68882 FPU", 447 machineid == HP_340 ? "16.67" : 448 (machineid == HP_360 ? "25" : 449 (machineid == HP_370 ? "33.33" : "50"))); 450 else 451 len += sprintf(cpu_model + len, ", %sMHz MC68881 FPU", 452 machineid == HP_350 ? "20" : "16.67"); 453 switch (ectype) { 454 case EC_VIRT: 455 sprintf(cpu_model + len, ", %dK virtual-address cache", 456 machineid == HP_320 ? 16 : 32); 457 break; 458 case EC_PHYS: 459 sprintf(cpu_model + len, ", %dK physical-address cache", 460 machineid == HP_370 ? 64 : 32); 461 break; 462 } 463 strcat(cpu_model, ")"); 464 printf("%s\n", cpu_model); 465 /* 466 * Now that we have told the user what they have, 467 * let them know if that machine type isn't configured. 468 */ 469 switch (machineid) { 470 case -1: /* keep compilers happy */ 471 #if !defined(HP320) && !defined(HP350) 472 case HP_320: 473 case HP_350: 474 #endif 475 #ifndef HP330 476 case HP_330: 477 #endif 478 #if !defined(HP360) && !defined(HP370) 479 case HP_340: 480 case HP_360: 481 case HP_370: 482 #endif 483 #if !defined(HP380) 484 case HP_380: 485 case HP_433: 486 #endif 487 panic("CPU type not configured"); 488 default: 489 break; 490 } 491 } 492 493 #ifdef USELEDS 494 #include <hp300/hp300/led.h> 495 496 int inledcontrol = 0; /* 1 if we are in ledcontrol already, cheap mutex */ 497 char *ledaddr; 498 499 /* 500 * Map the LED page and setup the KVA to access it. 501 */ 502 ledinit() 503 { 504 extern caddr_t ledbase; 505 506 pmap_enter(kernel_pmap, (vm_offset_t)ledbase, (vm_offset_t)LED_ADDR, 507 VM_PROT_READ|VM_PROT_WRITE, TRUE); 508 ledaddr = (char *) ((int)ledbase | (LED_ADDR & PGOFSET)); 509 } 510 511 /* 512 * Do lights: 513 * `ons' is a mask of LEDs to turn on, 514 * `offs' is a mask of LEDs to turn off, 515 * `togs' is a mask of LEDs to toggle. 516 * Note we don't use splclock/splx for mutual exclusion. 517 * They are expensive and we really don't need to be that precise. 518 * Besides we would like to be able to profile this routine. 519 */ 520 ledcontrol(ons, offs, togs) 521 register int ons, offs, togs; 522 { 523 static char currentleds; 524 register char leds; 525 526 inledcontrol = 1; 527 leds = currentleds; 528 if (ons) 529 leds |= ons; 530 if (offs) 531 leds &= ~offs; 532 if (togs) 533 leds ^= togs; 534 currentleds = leds; 535 *ledaddr = ~leds; 536 inledcontrol = 0; 537 } 538 #endif 539 540 #define SS_RTEFRAME 1 541 #define SS_FPSTATE 2 542 #define SS_USERREGS 4 543 544 struct sigstate { 545 int ss_flags; /* which of the following are valid */ 546 struct frame ss_frame; /* original exception frame */ 547 struct fpframe ss_fpstate; /* 68881/68882 state info */ 548 }; 549 550 /* 551 * WARNING: code in locore.s assumes the layout shown for sf_signum 552 * thru sf_handler so... don't screw with them! 553 */ 554 struct sigframe { 555 int sf_signum; /* signo for handler */ 556 int sf_code; /* additional info for handler */ 557 struct sigcontext *sf_scp; /* context ptr for handler */ 558 sig_t sf_handler; /* handler addr for u_sigc */ 559 struct sigstate sf_state; /* state of the hardware */ 560 struct sigcontext sf_sc; /* actual context */ 561 }; 562 563 #ifdef HPUXCOMPAT 564 struct hpuxsigcontext { 565 int hsc_syscall; 566 char hsc_action; 567 char hsc_pad1; 568 char hsc_pad2; 569 char hsc_onstack; 570 int hsc_mask; 571 int hsc_sp; 572 short hsc_ps; 573 int hsc_pc; 574 /* the rest aren't part of the context but are included for our convenience */ 575 short hsc_pad; 576 u_int hsc_magic; /* XXX sigreturn: cookie */ 577 struct sigcontext *hsc_realsc; /* XXX sigreturn: ptr to BSD context */ 578 }; 579 580 /* 581 * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe. 582 * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it. 583 */ 584 struct hpuxsigframe { 585 int hsf_signum; 586 int hsf_code; 587 struct sigcontext *hsf_scp; 588 struct hpuxsigcontext hsf_sc; 589 int hsf_regs[15]; 590 }; 591 #endif 592 593 #ifdef DEBUG 594 int sigdebug = 0; 595 int sigpid = 0; 596 #define SDB_FOLLOW 0x01 597 #define SDB_KSTACK 0x02 598 #define SDB_FPSTATE 0x04 599 #endif 600 601 /* 602 * Send an interrupt to process. 603 */ 604 void 605 sendsig(catcher, sig, mask, code) 606 sig_t catcher; 607 int sig, mask; 608 unsigned code; 609 { 610 register struct proc *p = curproc; 611 register struct sigframe *fp, *kfp; 612 register struct frame *frame; 613 register struct sigacts *psp = p->p_sigacts; 614 register short ft; 615 int oonstack, fsize; 616 extern char sigcode[], esigcode[]; 617 618 frame = (struct frame *)p->p_md.md_regs; 619 ft = frame->f_format; 620 oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK; 621 /* 622 * Allocate and validate space for the signal handler 623 * context. Note that if the stack is in P0 space, the 624 * call to grow() is a nop, and the useracc() check 625 * will fail if the process has not already allocated 626 * the space with a `brk'. 627 */ 628 #ifdef HPUXCOMPAT 629 if (p->p_md.md_flags & MDP_HPUX) 630 fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe); 631 else 632 #endif 633 fsize = sizeof(struct sigframe); 634 if ((psp->ps_flags & SAS_ALTSTACK) && 635 (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 && 636 (psp->ps_sigonstack & sigmask(sig))) { 637 fp = (struct sigframe *)(psp->ps_sigstk.ss_base + 638 psp->ps_sigstk.ss_size - fsize); 639 psp->ps_sigstk.ss_flags |= SA_ONSTACK; 640 } else 641 fp = (struct sigframe *)(frame->f_regs[SP] - fsize); 642 if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 643 (void)grow(p, (unsigned)fp); 644 #ifdef DEBUG 645 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 646 printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n", 647 p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft); 648 #endif 649 if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) { 650 #ifdef DEBUG 651 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 652 printf("sendsig(%d): useracc failed on sig %d\n", 653 p->p_pid, sig); 654 #endif 655 /* 656 * Process has trashed its stack; give it an illegal 657 * instruction to halt it in its tracks. 658 */ 659 SIGACTION(p, SIGILL) = SIG_DFL; 660 sig = sigmask(SIGILL); 661 p->p_sigignore &= ~sig; 662 p->p_sigcatch &= ~sig; 663 p->p_sigmask &= ~sig; 664 psignal(p, SIGILL); 665 return; 666 } 667 kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK); 668 /* 669 * Build the argument list for the signal handler. 670 */ 671 kfp->sf_signum = sig; 672 kfp->sf_code = code; 673 kfp->sf_scp = &fp->sf_sc; 674 kfp->sf_handler = catcher; 675 /* 676 * Save necessary hardware state. Currently this includes: 677 * - general registers 678 * - original exception frame (if not a "normal" frame) 679 * - FP coprocessor state 680 */ 681 kfp->sf_state.ss_flags = SS_USERREGS; 682 bcopy((caddr_t)frame->f_regs, 683 (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs); 684 if (ft >= FMT7) { 685 #ifdef DEBUG 686 if (ft > 15 || exframesize[ft] < 0) 687 panic("sendsig: bogus frame type"); 688 #endif 689 kfp->sf_state.ss_flags |= SS_RTEFRAME; 690 kfp->sf_state.ss_frame.f_format = frame->f_format; 691 kfp->sf_state.ss_frame.f_vector = frame->f_vector; 692 bcopy((caddr_t)&frame->F_u, 693 (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]); 694 /* 695 * Leave an indicator that we need to clean up the kernel 696 * stack. We do this by setting the "pad word" above the 697 * hardware stack frame to the amount the stack must be 698 * adjusted by. 699 * 700 * N.B. we increment rather than just set f_stackadj in 701 * case we are called from syscall when processing a 702 * sigreturn. In that case, f_stackadj may be non-zero. 703 */ 704 frame->f_stackadj += exframesize[ft]; 705 frame->f_format = frame->f_vector = 0; 706 #ifdef DEBUG 707 if (sigdebug & SDB_FOLLOW) 708 printf("sendsig(%d): copy out %d of frame %d\n", 709 p->p_pid, exframesize[ft], ft); 710 #endif 711 } 712 #ifdef FPCOPROC 713 kfp->sf_state.ss_flags |= SS_FPSTATE; 714 m68881_save(&kfp->sf_state.ss_fpstate); 715 #ifdef DEBUG 716 if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate) 717 printf("sendsig(%d): copy out FP state (%x) to %x\n", 718 p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate, 719 &kfp->sf_state.ss_fpstate); 720 #endif 721 #endif 722 /* 723 * Build the signal context to be used by sigreturn. 724 */ 725 kfp->sf_sc.sc_onstack = oonstack; 726 kfp->sf_sc.sc_mask = mask; 727 kfp->sf_sc.sc_sp = frame->f_regs[SP]; 728 kfp->sf_sc.sc_fp = frame->f_regs[A6]; 729 kfp->sf_sc.sc_ap = (int)&fp->sf_state; 730 kfp->sf_sc.sc_pc = frame->f_pc; 731 kfp->sf_sc.sc_ps = frame->f_sr; 732 #ifdef HPUXCOMPAT 733 /* 734 * Create an HP-UX style sigcontext structure and associated goo 735 */ 736 if (p->p_md.md_flags & MDP_HPUX) { 737 register struct hpuxsigframe *hkfp; 738 739 hkfp = (struct hpuxsigframe *)&kfp[1]; 740 hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum); 741 hkfp->hsf_code = kfp->sf_code; 742 hkfp->hsf_scp = (struct sigcontext *) 743 &((struct hpuxsigframe *)(&fp[1]))->hsf_sc; 744 hkfp->hsf_sc.hsc_syscall = 0; /* XXX */ 745 hkfp->hsf_sc.hsc_action = 0; /* XXX */ 746 hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0; 747 hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack; 748 hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask; 749 hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp; 750 hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps; 751 hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc; 752 hkfp->hsf_sc.hsc_pad = 0; 753 hkfp->hsf_sc.hsc_magic = 0xdeadbeef; 754 hkfp->hsf_sc.hsc_realsc = kfp->sf_scp; 755 bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs, 756 sizeof (hkfp->hsf_regs)); 757 758 kfp->sf_signum = hkfp->hsf_signum; 759 kfp->sf_scp = hkfp->hsf_scp; 760 } 761 #endif 762 (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize); 763 frame->f_regs[SP] = (int)fp; 764 #ifdef DEBUG 765 if (sigdebug & SDB_FOLLOW) 766 printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n", 767 p->p_pid, sig, kfp->sf_scp, fp, 768 kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap); 769 #endif 770 /* 771 * Signal trampoline code is at base of user stack. 772 */ 773 frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode); 774 #ifdef DEBUG 775 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 776 printf("sendsig(%d): sig %d returns\n", 777 p->p_pid, sig); 778 #endif 779 free((caddr_t)kfp, M_TEMP); 780 } 781 782 /* 783 * System call to cleanup state after a signal 784 * has been taken. Reset signal mask and 785 * stack state from context left by sendsig (above). 786 * Return to previous pc and psl as specified by 787 * context left by sendsig. Check carefully to 788 * make sure that the user has not modified the 789 * psl to gain improper priviledges or to cause 790 * a machine fault. 791 */ 792 struct sigreturn_args { 793 struct sigcontext *sigcntxp; 794 }; 795 /* ARGSUSED */ 796 sigreturn(p, uap, retval) 797 struct proc *p; 798 struct sigreturn_args *uap; 799 int *retval; 800 { 801 register struct sigcontext *scp; 802 register struct frame *frame; 803 register int rf; 804 struct sigcontext tsigc; 805 struct sigstate tstate; 806 int flags; 807 808 scp = uap->sigcntxp; 809 #ifdef DEBUG 810 if (sigdebug & SDB_FOLLOW) 811 printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp); 812 #endif 813 if ((int)scp & 1) 814 return (EINVAL); 815 #ifdef HPUXCOMPAT 816 /* 817 * Grab context as an HP-UX style context and determine if it 818 * was one that we contructed in sendsig. 819 */ 820 if (p->p_md.md_flags & MDP_HPUX) { 821 struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp; 822 struct hpuxsigcontext htsigc; 823 824 if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 || 825 copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc)) 826 return (EINVAL); 827 /* 828 * If not generated by sendsig or we cannot restore the 829 * BSD-style sigcontext, just restore what we can -- state 830 * will be lost, but them's the breaks. 831 */ 832 hscp = &htsigc; 833 if (hscp->hsc_magic != 0xdeadbeef || 834 (scp = hscp->hsc_realsc) == 0 || 835 useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || 836 copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) { 837 if (hscp->hsc_onstack & 01) 838 p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; 839 else 840 p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; 841 p->p_sigmask = hscp->hsc_mask &~ sigcantmask; 842 frame = (struct frame *) p->p_md.md_regs; 843 frame->f_regs[SP] = hscp->hsc_sp; 844 frame->f_pc = hscp->hsc_pc; 845 frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR; 846 return (EJUSTRETURN); 847 } 848 /* 849 * Otherwise, overlay BSD context with possibly modified 850 * HP-UX values. 851 */ 852 tsigc.sc_onstack = hscp->hsc_onstack; 853 tsigc.sc_mask = hscp->hsc_mask; 854 tsigc.sc_sp = hscp->hsc_sp; 855 tsigc.sc_ps = hscp->hsc_ps; 856 tsigc.sc_pc = hscp->hsc_pc; 857 } else 858 #endif 859 /* 860 * Test and fetch the context structure. 861 * We grab it all at once for speed. 862 */ 863 if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || 864 copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) 865 return (EINVAL); 866 scp = &tsigc; 867 if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0) 868 return (EINVAL); 869 /* 870 * Restore the user supplied information 871 */ 872 if (scp->sc_onstack & 01) 873 p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; 874 else 875 p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; 876 p->p_sigmask = scp->sc_mask &~ sigcantmask; 877 frame = (struct frame *) p->p_md.md_regs; 878 frame->f_regs[SP] = scp->sc_sp; 879 frame->f_regs[A6] = scp->sc_fp; 880 frame->f_pc = scp->sc_pc; 881 frame->f_sr = scp->sc_ps; 882 /* 883 * Grab pointer to hardware state information. 884 * If zero, the user is probably doing a longjmp. 885 */ 886 if ((rf = scp->sc_ap) == 0) 887 return (EJUSTRETURN); 888 /* 889 * See if there is anything to do before we go to the 890 * expense of copying in close to 1/2K of data 891 */ 892 flags = fuword((caddr_t)rf); 893 #ifdef DEBUG 894 if (sigdebug & SDB_FOLLOW) 895 printf("sigreturn(%d): sc_ap %x flags %x\n", 896 p->p_pid, rf, flags); 897 #endif 898 /* 899 * fuword failed (bogus sc_ap value). 900 */ 901 if (flags == -1) 902 return (EINVAL); 903 if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate)) 904 return (EJUSTRETURN); 905 #ifdef DEBUG 906 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 907 printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n", 908 p->p_pid, &flags, scp->sc_sp, uap->sigcntxp, 909 (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1); 910 #endif 911 /* 912 * Restore most of the users registers except for A6 and SP 913 * which were handled above. 914 */ 915 if (flags & SS_USERREGS) 916 bcopy((caddr_t)tstate.ss_frame.f_regs, 917 (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW); 918 /* 919 * Restore long stack frames. Note that we do not copy 920 * back the saved SR or PC, they were picked up above from 921 * the sigcontext structure. 922 */ 923 if (flags & SS_RTEFRAME) { 924 register int sz; 925 926 /* grab frame type and validate */ 927 sz = tstate.ss_frame.f_format; 928 if (sz > 15 || (sz = exframesize[sz]) < 0) 929 return (EINVAL); 930 frame->f_stackadj -= sz; 931 frame->f_format = tstate.ss_frame.f_format; 932 frame->f_vector = tstate.ss_frame.f_vector; 933 bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz); 934 #ifdef DEBUG 935 if (sigdebug & SDB_FOLLOW) 936 printf("sigreturn(%d): copy in %d of frame type %d\n", 937 p->p_pid, sz, tstate.ss_frame.f_format); 938 #endif 939 } 940 #ifdef FPCOPROC 941 /* 942 * Finally we restore the original FP context 943 */ 944 if (flags & SS_FPSTATE) 945 m68881_restore(&tstate.ss_fpstate); 946 #ifdef DEBUG 947 if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate) 948 printf("sigreturn(%d): copied in FP state (%x) at %x\n", 949 p->p_pid, *(u_int *)&tstate.ss_fpstate, 950 &tstate.ss_fpstate); 951 #endif 952 #endif 953 #ifdef DEBUG 954 if ((sigdebug & SDB_FOLLOW) || 955 ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) 956 printf("sigreturn(%d): returns\n", p->p_pid); 957 #endif 958 return (EJUSTRETURN); 959 } 960 961 int waittime = -1; 962 963 boot(howto) 964 register int howto; 965 { 966 /* take a snap shot before clobbering any registers */ 967 if (curproc) 968 savectx(curproc->p_addr, 0); 969 970 boothowto = howto; 971 if ((howto&RB_NOSYNC) == 0 && waittime < 0) { 972 register struct buf *bp; 973 int iter, nbusy; 974 975 waittime = 0; 976 (void) spl0(); 977 printf("syncing disks... "); 978 /* 979 * Release vnodes held by texts before sync. 980 */ 981 if (panicstr == 0) 982 vnode_pager_umount(NULL); 983 #ifdef notdef 984 #include "fd.h" 985 #if NFD > 0 986 fdshutdown(); 987 #endif 988 #endif 989 sync(&proc0, (void *)NULL, (int *)NULL); 990 991 for (iter = 0; iter < 20; iter++) { 992 nbusy = 0; 993 for (bp = &buf[nbuf]; --bp >= buf; ) 994 if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) 995 nbusy++; 996 if (nbusy == 0) 997 break; 998 printf("%d ", nbusy); 999 DELAY(40000 * iter); 1000 } 1001 if (nbusy) 1002 printf("giving up\n"); 1003 else 1004 printf("done\n"); 1005 /* 1006 * If we've been adjusting the clock, the todr 1007 * will be out of synch; adjust it now. 1008 */ 1009 resettodr(); 1010 } 1011 splhigh(); /* extreme priority */ 1012 if (howto&RB_HALT) { 1013 printf("halted\n\n"); 1014 asm(" stop #0x2700"); 1015 } else { 1016 if (howto & RB_DUMP) 1017 dumpsys(); 1018 doboot(); 1019 /*NOTREACHED*/ 1020 } 1021 /*NOTREACHED*/ 1022 } 1023 1024 int dumpmag = 0x8fca0101; /* magic number for savecore */ 1025 int dumpsize = 0; /* also for savecore */ 1026 long dumplo = 0; 1027 1028 dumpconf() 1029 { 1030 int nblks; 1031 1032 dumpsize = physmem; 1033 if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) { 1034 nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 1035 if (dumpsize > btoc(dbtob(nblks - dumplo))) 1036 dumpsize = btoc(dbtob(nblks - dumplo)); 1037 else if (dumplo == 0) 1038 dumplo = nblks - btodb(ctob(physmem)); 1039 } 1040 /* 1041 * Don't dump on the first CLBYTES (why CLBYTES?) 1042 * in case the dump device includes a disk label. 1043 */ 1044 if (dumplo < btodb(CLBYTES)) 1045 dumplo = btodb(CLBYTES); 1046 } 1047 1048 /* 1049 * Doadump comes here after turning off memory management and 1050 * getting on the dump stack, either when called above, or by 1051 * the auto-restart code. 1052 */ 1053 dumpsys() 1054 { 1055 1056 msgbufmapped = 0; 1057 if (dumpdev == NODEV) 1058 return; 1059 /* 1060 * For dumps during autoconfiguration, 1061 * if dump device has already configured... 1062 */ 1063 if (dumpsize == 0) 1064 dumpconf(); 1065 if (dumplo < 0) 1066 return; 1067 printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); 1068 printf("dump "); 1069 switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { 1070 1071 case ENXIO: 1072 printf("device bad\n"); 1073 break; 1074 1075 case EFAULT: 1076 printf("device not ready\n"); 1077 break; 1078 1079 case EINVAL: 1080 printf("area improper\n"); 1081 break; 1082 1083 case EIO: 1084 printf("i/o error\n"); 1085 break; 1086 1087 default: 1088 printf("succeeded\n"); 1089 break; 1090 } 1091 } 1092 1093 initcpu() 1094 { 1095 parityenable(); 1096 #ifdef USELEDS 1097 ledinit(); 1098 #endif 1099 } 1100 1101 straytrap(pc, evec) 1102 int pc; 1103 u_short evec; 1104 { 1105 printf("unexpected trap (vector offset %x) from %x\n", 1106 evec & 0xFFF, pc); 1107 } 1108 1109 int *nofault; 1110 1111 badaddr(addr) 1112 register caddr_t addr; 1113 { 1114 register int i; 1115 label_t faultbuf; 1116 1117 #ifdef lint 1118 i = *addr; if (i) return(0); 1119 #endif 1120 nofault = (int *) &faultbuf; 1121 if (setjmp((label_t *)nofault)) { 1122 nofault = (int *) 0; 1123 return(1); 1124 } 1125 i = *(volatile short *)addr; 1126 nofault = (int *) 0; 1127 return(0); 1128 } 1129 1130 badbaddr(addr) 1131 register caddr_t addr; 1132 { 1133 register int i; 1134 label_t faultbuf; 1135 1136 #ifdef lint 1137 i = *addr; if (i) return(0); 1138 #endif 1139 nofault = (int *) &faultbuf; 1140 if (setjmp((label_t *)nofault)) { 1141 nofault = (int *) 0; 1142 return(1); 1143 } 1144 i = *(volatile char *)addr; 1145 nofault = (int *) 0; 1146 return(0); 1147 } 1148 1149 netintr() 1150 { 1151 #ifdef INET 1152 if (netisr & (1 << NETISR_ARP)) { 1153 netisr &= ~(1 << NETISR_ARP); 1154 arpintr(); 1155 } 1156 if (netisr & (1 << NETISR_IP)) { 1157 netisr &= ~(1 << NETISR_IP); 1158 ipintr(); 1159 } 1160 #endif 1161 #ifdef NS 1162 if (netisr & (1 << NETISR_NS)) { 1163 netisr &= ~(1 << NETISR_NS); 1164 nsintr(); 1165 } 1166 #endif 1167 #ifdef ISO 1168 if (netisr & (1 << NETISR_ISO)) { 1169 netisr &= ~(1 << NETISR_ISO); 1170 clnlintr(); 1171 } 1172 #endif 1173 #ifdef CCITT 1174 if (netisr & (1 << NETISR_CCITT)) { 1175 netisr &= ~(1 << NETISR_CCITT); 1176 ccittintr(); 1177 } 1178 #endif 1179 } 1180 1181 intrhand(sr) 1182 int sr; 1183 { 1184 register struct isr *isr; 1185 register int found = 0; 1186 register int ipl; 1187 extern struct isr isrqueue[]; 1188 1189 ipl = (sr >> 8) & 7; 1190 switch (ipl) { 1191 1192 case 3: 1193 case 4: 1194 case 5: 1195 ipl = ISRIPL(ipl); 1196 isr = isrqueue[ipl].isr_forw; 1197 for (; isr != &isrqueue[ipl]; isr = isr->isr_forw) { 1198 if ((isr->isr_intr)(isr->isr_arg)) { 1199 found++; 1200 break; 1201 } 1202 } 1203 if (found == 0) 1204 printf("stray interrupt, sr 0x%x\n", sr); 1205 break; 1206 1207 case 0: 1208 case 1: 1209 case 2: 1210 case 6: 1211 case 7: 1212 printf("intrhand: unexpected sr 0x%x\n", sr); 1213 break; 1214 } 1215 } 1216 1217 #if defined(DEBUG) && !defined(PANICBUTTON) 1218 #define PANICBUTTON 1219 #endif 1220 1221 #ifdef PANICBUTTON 1222 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 1223 int crashandburn = 0; 1224 int candbdelay = 50; /* give em half a second */ 1225 1226 void 1227 candbtimer(arg) 1228 void *arg; 1229 { 1230 1231 crashandburn = 0; 1232 } 1233 #endif 1234 1235 /* 1236 * Level 7 interrupts can be caused by the keyboard or parity errors. 1237 */ 1238 nmihand(frame) 1239 struct frame frame; 1240 { 1241 if (kbdnmi()) { 1242 #ifdef PANICBUTTON 1243 static int innmihand = 0; 1244 1245 /* 1246 * Attempt to reduce the window of vulnerability for recursive 1247 * NMIs (e.g. someone holding down the keyboard reset button). 1248 */ 1249 if (innmihand == 0) { 1250 innmihand = 1; 1251 printf("Got a keyboard NMI\n"); 1252 innmihand = 0; 1253 } 1254 if (panicbutton) { 1255 if (crashandburn) { 1256 crashandburn = 0; 1257 panic(panicstr ? 1258 "forced crash, nosync" : "forced crash"); 1259 } 1260 crashandburn++; 1261 timeout(candbtimer, (void *)0, candbdelay); 1262 } 1263 #endif 1264 return; 1265 } 1266 if (parityerror(&frame)) 1267 return; 1268 /* panic?? */ 1269 printf("unexpected level 7 interrupt ignored\n"); 1270 } 1271 1272 /* 1273 * Parity error section. Contains magic. 1274 */ 1275 #define PARREG ((volatile short *)IIOV(0x5B0000)) 1276 static int gotparmem = 0; 1277 #ifdef DEBUG 1278 int ignorekperr = 0; /* ignore kernel parity errors */ 1279 #endif 1280 1281 /* 1282 * Enable parity detection 1283 */ 1284 parityenable() 1285 { 1286 label_t faultbuf; 1287 1288 nofault = (int *) &faultbuf; 1289 if (setjmp((label_t *)nofault)) { 1290 nofault = (int *) 0; 1291 #ifdef DEBUG 1292 printf("No parity memory\n"); 1293 #endif 1294 return; 1295 } 1296 *PARREG = 1; 1297 nofault = (int *) 0; 1298 gotparmem = 1; 1299 #ifdef DEBUG 1300 printf("Parity detection enabled\n"); 1301 #endif 1302 } 1303 1304 /* 1305 * Determine if level 7 interrupt was caused by a parity error 1306 * and deal with it if it was. Returns 1 if it was a parity error. 1307 */ 1308 parityerror(fp) 1309 struct frame *fp; 1310 { 1311 if (!gotparmem) 1312 return(0); 1313 *PARREG = 0; 1314 DELAY(10); 1315 *PARREG = 1; 1316 if (panicstr) { 1317 printf("parity error after panic ignored\n"); 1318 return(1); 1319 } 1320 if (!findparerror()) 1321 printf("WARNING: transient parity error ignored\n"); 1322 else if (USERMODE(fp->f_sr)) { 1323 printf("pid %d: parity error\n", curproc->p_pid); 1324 uprintf("sorry, pid %d killed due to memory parity error\n", 1325 curproc->p_pid); 1326 psignal(curproc, SIGKILL); 1327 #ifdef DEBUG 1328 } else if (ignorekperr) { 1329 printf("WARNING: kernel parity error ignored\n"); 1330 #endif 1331 } else { 1332 regdump(fp, 128); 1333 panic("kernel parity error"); 1334 } 1335 return(1); 1336 } 1337 1338 /* 1339 * Yuk! There has got to be a better way to do this! 1340 * Searching all of memory with interrupts blocked can lead to disaster. 1341 */ 1342 findparerror() 1343 { 1344 static label_t parcatch; 1345 static int looking = 0; 1346 volatile struct pte opte; 1347 volatile int pg, o, s; 1348 register volatile int *ip; 1349 register int i; 1350 int found; 1351 1352 #ifdef lint 1353 ip = &found; 1354 i = o = pg = 0; if (i) return(0); 1355 #endif 1356 /* 1357 * If looking is true we are searching for a known parity error 1358 * and it has just occured. All we do is return to the higher 1359 * level invocation. 1360 */ 1361 if (looking) 1362 longjmp(&parcatch); 1363 s = splhigh(); 1364 /* 1365 * If setjmp returns true, the parity error we were searching 1366 * for has just occured (longjmp above) at the current pg+o 1367 */ 1368 if (setjmp(&parcatch)) { 1369 printf("Parity error at 0x%x\n", ctob(pg)|o); 1370 found = 1; 1371 goto done; 1372 } 1373 /* 1374 * If we get here, a parity error has occured for the first time 1375 * and we need to find it. We turn off any external caches and 1376 * loop thru memory, testing every longword til a fault occurs and 1377 * we regain control at setjmp above. Note that because of the 1378 * setjmp, pg and o need to be volatile or their values will be lost. 1379 */ 1380 looking = 1; 1381 ecacheoff(); 1382 for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) { 1383 pmap_enter(kernel_pmap, (vm_offset_t)vmmap, ctob(pg), 1384 VM_PROT_READ, TRUE); 1385 for (o = 0; o < NBPG; o += sizeof(int)) 1386 i = *(int *)(&vmmap[o]); 1387 } 1388 /* 1389 * Getting here implies no fault was found. Should never happen. 1390 */ 1391 printf("Couldn't locate parity error\n"); 1392 found = 0; 1393 done: 1394 looking = 0; 1395 pmap_remove(kernel_pmap, (vm_offset_t)vmmap, 1396 (vm_offset_t)&vmmap[NBPG]); 1397 ecacheon(); 1398 splx(s); 1399 return(found); 1400 } 1401 1402 regdump(fp, sbytes) 1403 struct frame *fp; /* must not be register */ 1404 int sbytes; 1405 { 1406 static int doingdump = 0; 1407 register int i; 1408 int s; 1409 extern char *hexstr(); 1410 1411 if (doingdump) 1412 return; 1413 s = splhigh(); 1414 doingdump = 1; 1415 printf("pid = %d, pc = %s, ", 1416 curproc ? curproc->p_pid : -1, hexstr(fp->f_pc, 8)); 1417 printf("ps = %s, ", hexstr(fp->f_sr, 4)); 1418 printf("sfc = %s, ", hexstr(getsfc(), 4)); 1419 printf("dfc = %s\n", hexstr(getdfc(), 4)); 1420 printf("Registers:\n "); 1421 for (i = 0; i < 8; i++) 1422 printf(" %d", i); 1423 printf("\ndreg:"); 1424 for (i = 0; i < 8; i++) 1425 printf(" %s", hexstr(fp->f_regs[i], 8)); 1426 printf("\nareg:"); 1427 for (i = 0; i < 8; i++) 1428 printf(" %s", hexstr(fp->f_regs[i+8], 8)); 1429 if (sbytes > 0) { 1430 if (fp->f_sr & PSL_S) { 1431 printf("\n\nKernel stack (%s):", 1432 hexstr((int)(((int *)&fp)-1), 8)); 1433 dumpmem(((int *)&fp)-1, sbytes, 0); 1434 } else { 1435 printf("\n\nUser stack (%s):", hexstr(fp->f_regs[SP], 8)); 1436 dumpmem((int *)fp->f_regs[SP], sbytes, 1); 1437 } 1438 } 1439 doingdump = 0; 1440 splx(s); 1441 } 1442 1443 extern char kstack[]; 1444 #define KSADDR ((int *)&(kstack[(UPAGES-1)*NBPG])) 1445 1446 dumpmem(ptr, sz, ustack) 1447 register int *ptr; 1448 int sz; 1449 { 1450 register int i, val; 1451 extern char *hexstr(); 1452 1453 for (i = 0; i < sz; i++) { 1454 if ((i & 7) == 0) 1455 printf("\n%s: ", hexstr((int)ptr, 6)); 1456 else 1457 printf(" "); 1458 if (ustack == 1) { 1459 if ((val = fuword(ptr++)) == -1) 1460 break; 1461 } else { 1462 if (ustack == 0 && 1463 (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1))) 1464 break; 1465 val = *ptr++; 1466 } 1467 printf("%s", hexstr(val, 8)); 1468 } 1469 printf("\n"); 1470 } 1471 1472 char * 1473 hexstr(val, len) 1474 register int val; 1475 { 1476 static char nbuf[9]; 1477 register int x, i; 1478 1479 if (len > 8) 1480 return(""); 1481 nbuf[len] = '\0'; 1482 for (i = len-1; i >= 0; --i) { 1483 x = val & 0xF; 1484 if (x > 9) 1485 nbuf[i] = x - 10 + 'A'; 1486 else 1487 nbuf[i] = x + '0'; 1488 val >>= 4; 1489 } 1490 return(nbuf); 1491 } 1492 1493 #ifdef DEBUG 1494 char oflowmsg[] = "k-stack overflow"; 1495 char uflowmsg[] = "k-stack underflow"; 1496 1497 badkstack(oflow, fr) 1498 int oflow; 1499 struct frame fr; 1500 { 1501 extern char kstackatbase[]; 1502 1503 printf("%s: sp should be %x\n", 1504 oflow ? oflowmsg : uflowmsg, 1505 kstackatbase - (exframesize[fr.f_format] + 8)); 1506 regdump(&fr, 0); 1507 panic(oflow ? oflowmsg : uflowmsg); 1508 } 1509 #endif 1510