1 /* $NetBSD: machdep.c,v 1.168 2010/10/16 17:10:42 tsutsui Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 5 * 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.63 91/04/24$ 36 * 37 * @(#)machdep.c 7.16 (Berkeley) 6/3/91 38 */ 39 /* 40 * Copyright (c) 1988 University of Utah. 41 * 42 * This code is derived from software contributed to Berkeley by 43 * the Systems Programming Group of the University of Utah Computer 44 * Science Department. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by the University of 57 * California, Berkeley and its contributors. 58 * 4. Neither the name of the University nor the names of its contributors 59 * may be used to endorse or promote products derived from this software 60 * without specific prior written permission. 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 72 * SUCH DAMAGE. 73 * 74 * from: Utah $Hdr: machdep.c 1.63 91/04/24$ 75 * 76 * @(#)machdep.c 7.16 (Berkeley) 6/3/91 77 */ 78 79 #include <sys/cdefs.h> 80 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.168 2010/10/16 17:10:42 tsutsui Exp $"); 81 82 #include "opt_ddb.h" 83 #include "opt_compat_netbsd.h" 84 #include "opt_mbtype.h" 85 #include "opt_modular.h" 86 #include "opt_panicbutton.h" 87 88 #include <sys/param.h> 89 #include <sys/systm.h> 90 #include <sys/signalvar.h> 91 #include <sys/kernel.h> 92 #include <sys/proc.h> 93 #include <sys/buf.h> 94 #include <sys/reboot.h> 95 #include <sys/conf.h> 96 #include <sys/file.h> 97 #include <sys/device.h> 98 #include <sys/malloc.h> 99 #include <sys/mbuf.h> 100 #include <sys/msgbuf.h> 101 #include <sys/vnode.h> 102 #include <sys/queue.h> 103 #include <sys/mount.h> 104 #include <sys/syscallargs.h> 105 #include <sys/ksyms.h> 106 #include <sys/module.h> 107 #include <sys/intr.h> 108 #include <sys/exec.h> 109 #include <sys/exec_aout.h> 110 #include <sys/cpu.h> 111 #if defined(DDB) && defined(__ELF__) 112 #include <sys/exec_elf.h> 113 #endif 114 115 #undef PS /* XXX netccitt/pk.h conflict with machine/reg.h? */ 116 117 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 118 #include <uvm/uvm_extern.h> 119 120 #include <sys/sysctl.h> 121 122 #include <machine/db_machdep.h> 123 #include <ddb/db_sym.h> 124 #include <ddb/db_extern.h> 125 126 #include <machine/reg.h> 127 #include <machine/psl.h> 128 #include <machine/pte.h> 129 130 #include <dev/cons.h> 131 132 #include "ksyms.h" 133 134 static void bootsync(void); 135 static void call_sicallbacks(void); 136 static void identifycpu(void); 137 void straymfpint(int, u_short); 138 void straytrap(int, u_short); 139 140 #ifdef _MILANHW_ 141 void nmihandler(void); 142 #endif 143 144 struct vm_map *phys_map = NULL; 145 146 void * msgbufaddr; 147 vaddr_t msgbufpa; 148 149 int physmem = MAXMEM; /* max supported memory, changes to actual */ 150 /* 151 * safepri is a safe priority for sleep to set for a spin-wait 152 * during autoconfiguration or after a panic. 153 */ 154 int safepri = PSL_LOWIPL; 155 extern int freebufspace; 156 extern u_int lowram; 157 158 /* 159 * For the fpu emulation and the fpu driver 160 */ 161 int fputype = 0; 162 163 /* the following is used externally (sysctl_hw) */ 164 char machine[] = MACHINE; /* from <machine/param.h> */ 165 166 /* Our exported CPU info; we can have only one. */ 167 struct cpu_info cpu_info_store; 168 169 /* 170 * Console initialization: called early on from main, 171 * before vm init or startup. Do enough configuration 172 * to choose and initialize a console. 173 */ 174 void 175 consinit(void) 176 { 177 int i; 178 179 /* 180 * Initialize error message buffer. pmap_bootstrap() has 181 * positioned this at the end of kernel memory segment - map 182 * and initialize it now. 183 */ 184 for (i = 0; i < btoc(MSGBUFSIZE); i++) 185 pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE, 186 msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 0); 187 pmap_update(pmap_kernel()); 188 initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); 189 190 /* 191 * Initialize hardware that support various console types like 192 * the grf and PCI busses. 193 */ 194 config_console(); 195 196 /* 197 * Now pick the best console candidate. 198 */ 199 cninit(); 200 201 #if NKSYMS || defined(DDB) || defined(MODULAR) 202 { 203 extern int end; 204 extern int *esym; 205 206 #ifndef __ELF__ 207 ksyms_addsyms_elf(*(int *)&end, ((int *)&end) + 1, esym); 208 #else 209 ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr), 210 (void *)&end, esym); 211 #endif 212 } 213 #endif 214 #if defined (DDB) 215 if (boothowto & RB_KDB) 216 Debugger(); 217 #endif 218 } 219 220 /* 221 * cpu_startup: allocate memory for variable-sized tables, 222 * initialize CPU, and do autoconfiguration. 223 */ 224 void 225 cpu_startup(void) 226 { 227 extern int iomem_malloc_safe; 228 char pbuf[9]; 229 #ifdef DEBUG 230 extern int pmapdebug; 231 int opmapdebug = pmapdebug; 232 #endif 233 vaddr_t minaddr, maxaddr; 234 extern vsize_t mem_size; /* from pmap.c */ 235 236 #ifdef DEBUG 237 pmapdebug = 0; 238 #endif 239 240 if (fputype != FPU_NONE) 241 m68k_make_fpu_idle_frame(); 242 243 /* 244 * Good {morning,afternoon,evening,night}. 245 */ 246 printf("%s%s", copyright, version); 247 identifycpu(); 248 249 format_bytes(pbuf, sizeof(pbuf), mem_size); 250 printf("total memory = %s\n", pbuf); 251 252 minaddr = 0; 253 254 /* 255 * Allocate a submap for physio 256 */ 257 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 258 VM_PHYS_SIZE, 0, false, NULL); 259 260 #ifdef DEBUG 261 pmapdebug = opmapdebug; 262 #endif 263 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 264 printf("avail memory = %s\n", pbuf); 265 266 /* 267 * Alloc extent allocation to use malloc 268 */ 269 iomem_malloc_safe = 1; 270 } 271 272 /* 273 * Set registers on exec. 274 */ 275 void 276 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 277 { 278 struct frame *frame = (struct frame *)l->l_md.md_regs; 279 struct pcb *pcb = lwp_getpcb(l); 280 281 frame->f_sr = PSL_USERSET; 282 frame->f_pc = pack->ep_entry & ~1; 283 frame->f_regs[D0] = 0; 284 frame->f_regs[D1] = 0; 285 frame->f_regs[D2] = 0; 286 frame->f_regs[D3] = 0; 287 frame->f_regs[D4] = 0; 288 frame->f_regs[D5] = 0; 289 frame->f_regs[D6] = 0; 290 frame->f_regs[D7] = 0; 291 frame->f_regs[A0] = 0; 292 frame->f_regs[A1] = 0; 293 frame->f_regs[A2] = (int)l->l_proc->p_psstr; 294 frame->f_regs[A3] = 0; 295 frame->f_regs[A4] = 0; 296 frame->f_regs[A5] = 0; 297 frame->f_regs[A6] = 0; 298 frame->f_regs[SP] = stack; 299 300 /* restore a null state frame */ 301 pcb->pcb_fpregs.fpf_null = 0; 302 if (fputype) 303 m68881_restore(&pcb->pcb_fpregs); 304 } 305 306 /* 307 * Info for CTL_HW 308 */ 309 char cpu_model[120]; 310 311 static void 312 identifycpu(void) 313 { 314 const char *mach, *mmu, *fpu, *cpu; 315 316 switch (machineid & ATARI_ANYMACH) { 317 case ATARI_TT: 318 mach = "Atari TT"; 319 break; 320 case ATARI_FALCON: 321 mach = "Atari Falcon"; 322 break; 323 case ATARI_HADES: 324 mach = "Atari Hades"; 325 break; 326 case ATARI_MILAN: 327 mach = "Atari Milan"; 328 break; 329 default: 330 mach = "Atari UNKNOWN"; 331 break; 332 } 333 334 cpu = "m68k"; 335 fputype = fpu_probe(); 336 fpu = fpu_describe(fputype); 337 338 switch (cputype) { 339 340 case CPU_68060: 341 { 342 uint32_t pcr; 343 char cputxt[30]; 344 345 __asm(".word 0x4e7a,0x0808;" 346 "movl %%d0,%0" : "=d"(pcr) : : "d0"); 347 sprintf(cputxt, "68%s060 rev.%d", 348 pcr & 0x10000 ? "LC/EC" : "", (pcr >> 8) & 0xff); 349 cpu = cputxt; 350 mmu = "/MMU"; 351 } 352 break; 353 case CPU_68040: 354 cpu = "m68040"; 355 mmu = "/MMU"; 356 break; 357 case CPU_68030: 358 cpu = "m68030"; 359 mmu = "/MMU"; 360 break; 361 default: /* XXX */ 362 cpu = "m68020"; 363 mmu = " m68851 MMU"; 364 } 365 sprintf(cpu_model, "%s (%s CPU%s%sFPU)", mach, cpu, mmu, fpu); 366 printf("%s\n", cpu_model); 367 } 368 369 /* 370 * machine dependent system variables. 371 */ 372 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 373 { 374 375 sysctl_createv(clog, 0, NULL, NULL, 376 CTLFLAG_PERMANENT, 377 CTLTYPE_NODE, "machdep", NULL, 378 NULL, 0, NULL, 0, 379 CTL_MACHDEP, CTL_EOL); 380 381 sysctl_createv(clog, 0, NULL, NULL, 382 CTLFLAG_PERMANENT, 383 CTLTYPE_STRUCT, "console_device", NULL, 384 sysctl_consdev, 0, NULL, sizeof(dev_t), 385 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 386 } 387 388 static int waittime = -1; 389 390 static void 391 bootsync(void) 392 { 393 394 if (waittime < 0) { 395 waittime = 0; 396 397 vfs_shutdown(); 398 399 /* 400 * If we've been adjusting the clock, the todr 401 * will be out of synch; adjust it now. 402 */ 403 resettodr(); 404 } 405 } 406 407 void 408 cpu_reboot(int howto, char *bootstr) 409 { 410 struct pcb *pcb = lwp_getpcb(curlwp); 411 412 /* take a snap shot before clobbering any registers */ 413 if (pcb != NULL) 414 savectx(pcb); 415 416 boothowto = howto; 417 if ((howto & RB_NOSYNC) == 0) 418 bootsync(); 419 420 /* 421 * Call shutdown hooks. Do this _before_ anything might be 422 * asked to the user in case nobody is there.... 423 */ 424 doshutdownhooks(); 425 426 pmf_system_shutdown(boothowto); 427 428 splhigh(); /* extreme priority */ 429 if (howto & RB_HALT) { 430 printf("halted\n\n"); 431 __asm(" stop #0x2700"); 432 } else { 433 if (howto & RB_DUMP) 434 dumpsys(); 435 436 doboot(); 437 /*NOTREACHED*/ 438 } 439 panic("Boot() should never come here"); 440 /*NOTREACHED*/ 441 } 442 443 #define BYTES_PER_DUMP PAGE_SIZE /* Must be a multiple of PAGE_SIZE */ 444 static vaddr_t dumpspace; /* Virt. space to map dumppages */ 445 446 /* 447 * Reserve _virtual_ memory to map in the page to be dumped 448 */ 449 vaddr_t 450 reserve_dumppages(vaddr_t p) 451 { 452 453 dumpspace = p; 454 return p + BYTES_PER_DUMP; 455 } 456 457 uint32_t dumpmag = 0x8fca0101; /* magic number for savecore */ 458 int dumpsize = 0; /* also for savecore (pages) */ 459 long dumplo = 0; /* (disk blocks) */ 460 461 void 462 cpu_dumpconf(void) 463 { 464 const struct bdevsw *bdev; 465 int nblks, i; 466 467 for (i = dumpsize = 0; i < NMEM_SEGS; i++) { 468 if (boot_segs[i].start == boot_segs[i].end) 469 break; 470 dumpsize += boot_segs[i].end - boot_segs[i].start; 471 } 472 dumpsize = btoc(dumpsize); 473 474 if (dumpdev != NODEV) { 475 bdev = bdevsw_lookup(dumpdev); 476 if (bdev == NULL) { 477 dumpdev = NODEV; 478 return; 479 } 480 if (bdev->d_psize != NULL) { 481 nblks = (*bdev->d_psize)(dumpdev); 482 if (dumpsize > btoc(dbtob(nblks - dumplo))) 483 dumpsize = btoc(dbtob(nblks - dumplo)); 484 else if (dumplo == 0) 485 dumplo = nblks - btodb(ctob(dumpsize)); 486 } 487 } 488 dumplo -= cpu_dumpsize(); 489 490 /* 491 * Don't dump on the first PAGE_SIZE (why PAGE_SIZE?) 492 * in case the dump device includes a disk label. 493 */ 494 if (dumplo < btodb(PAGE_SIZE)) 495 dumplo = btodb(PAGE_SIZE); 496 } 497 498 /* 499 * Doadump comes here after turning off memory management and 500 * getting on the dump stack, either when called above, or by 501 * the auto-restart code. 502 */ 503 void 504 dumpsys(void) 505 { 506 const struct bdevsw *bdev; 507 daddr_t blkno; /* Current block to write */ 508 int (*dump)(dev_t, daddr_t, void *, size_t); 509 /* Dumping function */ 510 u_long maddr; /* PA being dumped */ 511 int segbytes; /* Number of bytes in this seg. */ 512 int segnum; /* Segment we are dumping */ 513 int nbytes; /* Bytes left to dump */ 514 int i, n, error; 515 516 error = segnum = 0; 517 if (dumpdev == NODEV) 518 return; 519 bdev = bdevsw_lookup(dumpdev); 520 if (bdev == NULL) 521 return; 522 /* 523 * For dumps during autoconfiguration, 524 * if dump device has already configured... 525 */ 526 if (dumpsize == 0) 527 cpu_dumpconf(); 528 if (dumplo <= 0) { 529 printf("\ndump to dev %u,%u not possible\n", 530 major(dumpdev), minor(dumpdev)); 531 return; 532 } 533 printf("\ndumping to dev %u,%u offset %ld\n", 534 major(dumpdev), minor(dumpdev), dumplo); 535 536 #if defined(DDB) || defined(PANICWAIT) 537 printf("Do you want to dump memory? [y]"); 538 cnputc(i = cngetc()); 539 switch (i) { 540 case 'n': 541 case 'N': 542 return; 543 case '\n': 544 break; 545 default : 546 cnputc('\n'); 547 } 548 #endif /* defined(DDB) || defined(PANICWAIT) */ 549 550 maddr = 0; 551 segbytes = boot_segs[0].end; 552 blkno = dumplo; 553 dump = bdev->d_dump; 554 nbytes = dumpsize * PAGE_SIZE; 555 556 printf("dump "); 557 558 error = cpu_dump(dump, &blkno); 559 if (!error) { 560 for (i = 0; i < nbytes; i += n, segbytes -= n) { 561 /* 562 * Skip the hole 563 */ 564 if (segbytes == 0) { 565 segnum++; 566 maddr = boot_segs[segnum].start; 567 segbytes = boot_segs[segnum].end - 568 boot_segs[segnum].start; 569 } 570 /* 571 * Print Mb's to go 572 */ 573 n = nbytes - i; 574 if (n && (n % (1024 * 1024)) == 0) 575 printf_nolog("%d ", n / (1024 * 1024)); 576 577 /* 578 * Limit transfer to BYTES_PER_DUMP 579 */ 580 if (n > BYTES_PER_DUMP) 581 n = BYTES_PER_DUMP; 582 583 /* 584 * Map to a VA and write it 585 */ 586 if (maddr != 0) { /* XXX kvtop chokes on this */ 587 (void)pmap_map(dumpspace, maddr, maddr + n, 588 VM_PROT_READ); 589 error = (*dump)(dumpdev, blkno, 590 (void *)dumpspace, n); 591 if (error) 592 break; 593 } 594 595 maddr += n; 596 blkno += btodb(n); 597 } 598 } 599 switch (error) { 600 601 case ENXIO: 602 printf("device bad\n"); 603 break; 604 605 case EFAULT: 606 printf("device not ready\n"); 607 break; 608 609 case EINVAL: 610 printf("area improper\n"); 611 break; 612 613 case EIO: 614 printf("i/o error\n"); 615 break; 616 617 default: 618 printf("succeeded\n"); 619 break; 620 } 621 printf("\n\n"); 622 delay(5000000); /* 5 seconds */ 623 } 624 625 void 626 straytrap(int pc, u_short evec) 627 { 628 static int prev_evec; 629 630 printf("unexpected trap (vector offset 0x%x) from 0x%x\n", 631 evec & 0xFFF, pc); 632 633 if (prev_evec == evec) { 634 delay(1000000); 635 prev_evec = 0; 636 } else 637 prev_evec = evec; 638 } 639 640 void 641 straymfpint(int pc, u_short evec) 642 { 643 644 printf("unexpected mfp-interrupt (vector offset 0x%x) from 0x%x\n", 645 evec & 0xFFF, pc); 646 } 647 648 int *nofault; 649 650 int 651 badbaddr(void *addr, int size) 652 { 653 register int i; 654 label_t faultbuf; 655 656 #ifdef lint 657 i = *addr; if (i) return(0); 658 #endif 659 nofault = (int *) &faultbuf; 660 if (setjmp((label_t *)nofault)) { 661 nofault = (int *) 0; 662 return 1; 663 } 664 switch (size) { 665 case 1: 666 i = *(volatile uint8_t *)addr; 667 break; 668 case 2: 669 i = *(volatile uint16_t *)addr; 670 break; 671 case 4: 672 i = *(volatile uint32_t *)addr; 673 break; 674 default: 675 panic("badbaddr: unknown size"); 676 } 677 nofault = (int *)0; 678 return 0; 679 } 680 681 /* 682 * this is a handy package to have asynchronously executed 683 * function calls executed at very low interrupt priority. 684 * Example for use is keyboard repeat, where the repeat 685 * handler running at splclock() triggers such a (hardware 686 * aided) software interrupt. 687 * Note: the installed functions are currently called in a 688 * LIFO fashion, might want to change this to FIFO 689 * later. 690 * 691 * XXX: Some of functions which use this callback should be rewritten 692 * XXX: to use MI softintr(9) directly. 693 */ 694 struct si_callback { 695 struct si_callback *next; 696 void (*function)(void *rock1, void *rock2); 697 void *rock1, *rock2; 698 }; 699 static void *si_callback_cookie; 700 static struct si_callback *si_callbacks; 701 static struct si_callback *si_free; 702 #ifdef DIAGNOSTIC 703 static int ncbd; /* number of callback blocks dynamically allocated */ 704 #endif 705 706 void 707 init_sicallback(void) 708 { 709 710 si_callback_cookie = softint_establish(SOFTINT_NET, 711 (void (*)(void *))call_sicallbacks, NULL); 712 } 713 714 void 715 add_sicallback(void (*function)(void *, void *), void *rock1, void *rock2) 716 { 717 struct si_callback *si; 718 int s; 719 720 /* 721 * this function may be called from high-priority interrupt handlers. 722 * We may NOT block for memory-allocation in here!. 723 */ 724 s = splhigh(); 725 if ((si = si_free) != NULL) 726 si_free = si->next; 727 splx(s); 728 729 if (si == NULL) { 730 si = malloc(sizeof(*si), M_TEMP, M_NOWAIT); 731 #ifdef DIAGNOSTIC 732 if (si) 733 ++ncbd; /* count # dynamically allocated */ 734 #endif 735 if (si == NULL) 736 return; 737 } 738 739 si->function = function; 740 si->rock1 = rock1; 741 si->rock2 = rock2; 742 743 s = splhigh(); 744 si->next = si_callbacks; 745 si_callbacks = si; 746 splx(s); 747 748 /* 749 * and cause a software interrupt (spl1). This interrupt might 750 * happen immediately, or after returning to a safe enough level. 751 * 752 * XXX: 753 * According to <machine/scu.h> and lev1intr() hander in locore.s, 754 * at least _ATARIHW_ machines (ATARITT and HADES?) seem to have 755 * some hardware support which can initiate real hardware interrupt 756 * at ipl 1 for software interrupt. But as per <machine/mtpr.h>, 757 * this feature was not used at all on setsoft*() calls and 758 * traditional hp300 derived ssir (simulated software interrupt 759 * request) on VAX REI emulation in locore.s is used. 760 */ 761 softint_schedule(si_callback_cookie); 762 } 763 764 void 765 rem_sicallback(void (*function)(void *rock1, void *rock2)) 766 { 767 struct si_callback *si, *psi, *nsi; 768 int s; 769 770 s = splhigh(); 771 for (psi = 0, si = si_callbacks; si; ) { 772 nsi = si->next; 773 774 if (si->function != function) 775 psi = si; 776 else { 777 si->next = si_free; 778 si_free = si; 779 if (psi != NULL) 780 psi->next = nsi; 781 else 782 si_callbacks = nsi; 783 } 784 si = nsi; 785 } 786 splx(s); 787 } 788 789 /* purge the list */ 790 static void 791 call_sicallbacks(void) 792 { 793 struct si_callback *si; 794 int s; 795 void *rock1, *rock2; 796 void (*function)(void *, void *); 797 798 do { 799 s = splhigh(); 800 if ((si = si_callbacks) != NULL) 801 si_callbacks = si->next; 802 splx(s); 803 804 if (si != NULL) { 805 function = si->function; 806 rock1 = si->rock1; 807 rock2 = si->rock2; 808 s = splhigh(); 809 if (si_callbacks) 810 softint_schedule(si_callback_cookie); 811 si->next = si_free; 812 si_free = si; 813 splx(s); 814 815 /* 816 * Raise spl for BASEPRI() checks to see 817 * nested interrupts in some drivers using callbacks 818 * since modern MI softint(9) doesn't seem to do it 819 * in !__HAVE_FAST_SOFTINTS case. 820 * 821 * XXX: This is just a workaround hack. 822 * Each driver should raise spl in its handler 823 * to avoid nested interrupts if necessary. 824 */ 825 s = splsoftnet(); /* XXX */ 826 function(rock1, rock2); 827 splx(s); 828 } 829 } while (si != NULL); 830 #ifdef DIAGNOSTIC 831 if (ncbd) { 832 #ifdef DEBUG 833 printf("call_sicallback: %d more dynamic structures\n", ncbd); 834 #endif 835 ncbd = 0; 836 } 837 #endif 838 } 839 840 #if defined(DEBUG) && !defined(PANICBUTTON) 841 #define PANICBUTTON 842 #endif 843 844 #ifdef PANICBUTTON 845 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 846 int crashandburn = 0; 847 int candbdelay = 50; /* give em half a second */ 848 849 void candbtimer(void); 850 851 void 852 candbtimer(void) 853 { 854 855 crashandburn = 0; 856 } 857 #endif 858 859 /* 860 * should only get here, if no standard executable. This can currently 861 * only mean, we're reading an old ZMAGIC file without MID, but since Atari 862 * ZMAGIC always worked the `right' way (;-)) just ignore the missing 863 * MID and proceed to new zmagic code ;-) 864 */ 865 int 866 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 867 { 868 int error = ENOEXEC; 869 #ifdef COMPAT_NOMID 870 struct exec *execp = epp->ep_hdr; 871 #endif 872 873 #ifdef COMPAT_NOMID 874 if (!((execp->a_midmag >> 16) & 0x0fff) 875 && execp->a_midmag == ZMAGIC) 876 return exec_aout_prep_zmagic(l->l_proc, epp); 877 #endif 878 return error; 879 } 880 881 #ifdef MODULAR 882 /* 883 * Push any modules loaded by the bootloader etc. 884 */ 885 void 886 module_init_md(void) 887 { 888 } 889 #endif 890 891 #ifdef _MILANHW_ 892 893 /* 894 * Currently the only source of NMI interrupts on the Milan is the PLX9080. 895 * On access errors to the PCI bus, an NMI is generated. This NMI is shorted 896 * in locore in case of a PCI config cycle to a non-existing address to allow 897 * for probes. On other occaisions, it ShouldNotHappen(TM). 898 * Note: The handler in locore clears the errors, to make further PCI access 899 * possible. 900 */ 901 void 902 nmihandler(void) 903 { 904 extern unsigned long plx_status; 905 906 printf("nmihandler: plx_status = 0x%08lx\n", plx_status); 907 } 908 #endif 909