1 /* $NetBSD: machdep.c,v 1.7 2002/05/14 02:58:35 matt 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 * 42 * @(#)machdep.c 8.10 (Berkeley) 4/20/94 43 */ 44 45 #include "opt_bufcache.h" 46 #include "opt_ddb.h" 47 #include "opt_kgdb.h" 48 #include "opt_compat_hpux.h" 49 #include "opt_compat_netbsd.h" 50 #include "opt_sysv.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/buf.h> 55 #include <sys/callout.h> 56 #include <sys/clist.h> 57 #include <sys/conf.h> 58 #include <sys/exec.h> 59 #include <sys/file.h> 60 #include <sys/ioctl.h> 61 #include <sys/kernel.h> 62 #include <sys/malloc.h> 63 #include <sys/map.h> 64 #include <sys/mbuf.h> 65 #include <sys/mount.h> 66 #include <sys/msgbuf.h> 67 #include <sys/proc.h> 68 #include <sys/reboot.h> 69 #include <sys/signalvar.h> 70 #include <sys/syscallargs.h> 71 #include <sys/tty.h> 72 #include <sys/user.h> 73 #include <sys/vnode.h> 74 #ifdef SYSVMSG 75 #include <sys/msg.h> 76 #endif 77 #ifdef SYSVSEM 78 #include <sys/sem.h> 79 #endif 80 #ifdef SYSVSHM 81 #include <sys/shm.h> 82 #endif 83 #include <sys/kgdb.h> 84 85 #include <machine/db_machdep.h> 86 #include <ddb/db_sym.h> 87 #include <ddb/db_extern.h> 88 89 #include <machine/autoconf.h> 90 #include <machine/cpu.h> 91 #include <machine/reg.h> 92 #include <machine/psl.h> 93 #include <machine/pte.h> 94 95 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 96 97 #include <uvm/uvm_extern.h> 98 99 #include <sys/sysctl.h> 100 #include <sys/device.h> 101 #include <dev/cons.h> 102 #include <dev/ic/z8530reg.h> 103 #include <machine/z8530var.h> 104 #include <cesfic/dev/zsvar.h> 105 106 107 /* the following is used externally (sysctl_hw) */ 108 char machine[] = MACHINE; /* cpu "architecture" */ 109 110 /* Our exported CPU info; we can have only one. */ 111 struct cpu_info cpu_info_store; 112 113 struct vm_map *exec_map = NULL; 114 struct vm_map *mb_map = NULL; 115 struct vm_map *phys_map = NULL; 116 117 extern vaddr_t virtual_avail; 118 119 /* 120 * Declare these as initialized data so we can patch them. 121 */ 122 caddr_t msgbufaddr; 123 /*int maxmem;*/ /* max memory per process */ 124 int physmem = MAXMEM; /* max supported memory, changes to actual */ 125 /* 126 * safepri is a safe priority for sleep to set for a spin-wait 127 * during autoconfiguration or after a panic. 128 */ 129 int safepri = PSL_LOWIPL; 130 131 extern u_int lowram; 132 133 void fic_init __P((void)); 134 135 /* prototypes for local functions */ 136 void identifycpu __P((void)); 137 void dumpmem __P((int *, int, int)); 138 char *hexstr __P((int, int)); 139 140 /* functions called from locore.s */ 141 void dumpsys __P((void)); 142 void straytrap __P((int, u_short)); 143 void nmihand __P((struct frame)); 144 145 int delay_divisor; /* delay constant */ 146 147 extern void sicinit __P((void*)); 148 149 void fic_init() 150 { 151 int i; 152 153 extern paddr_t avail_start, avail_end; 154 155 boothowto = RB_SINGLE; /* XXX for now */ 156 boothowto |= RB_KDB; /* XXX for now */ 157 158 delay_divisor = 30; /* XXX */ 159 160 /* 161 * Tell the VM system about available physical memory. The 162 * fic uses one segment. 163 */ 164 uvm_page_physload(atop(avail_start), atop(avail_end), 165 atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT); 166 167 /* 168 * map and init interrupt controller 169 */ 170 physaccess((void*)virtual_avail, (void*)0x44000000, NBPG, PG_RW|PG_CI); 171 sicinit((void*)virtual_avail); 172 virtual_avail += NBPG; 173 174 /* 175 * Initialize error message buffer (at end of core). 176 * avail_end was pre-decremented in pmap_bootstrap to compensate. 177 */ 178 for (i = 0; i < btoc(MSGBUFSIZE); i++) 179 pmap_enter(pmap_kernel(), (vm_offset_t)msgbufaddr + i * NBPG, 180 avail_end + i * NBPG, VM_PROT_READ|VM_PROT_WRITE, 181 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); 182 initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); 183 } 184 185 int 186 zs_check_kgdb(cs, dev) 187 struct zs_chanstate *cs; 188 int dev; 189 { 190 191 if((boothowto & RB_KDB) && (dev == makedev(10, 0))) 192 return (1); 193 return (0); 194 } 195 196 void zs_kgdb_cnputc __P((dev_t, int)); 197 void zs_kgdb_cnputc(dev, c) 198 dev_t dev; 199 int c; 200 { 201 zscnputc(dev, c); 202 } 203 int zs_kgdb_cngetc __P((dev_t)); 204 int zs_kgdb_cngetc(dev) 205 dev_t dev; 206 { 207 return (zscngetc(dev)); 208 } 209 210 /* 211 * Console initialization: called early on from main, 212 * before vm init or startup. Do enough configuration 213 * to choose and initialize a console. 214 */ 215 extern void sic_enable_int __P((int, int, int, int, int)); 216 void 217 consinit() 218 { 219 220 /* 221 * Initialize the console before we print anything out. 222 */ 223 physaccess((void*)virtual_avail, (void*)0x58000000, NBPG, PG_RW|PG_CI); 224 zs_cnattach((void*)virtual_avail); 225 virtual_avail += NBPG; 226 227 #ifdef KGDB 228 kgdb_dev = 1; 229 kgdb_attach((void*)zscngetc, (void*)zscnputc, (void *)0); 230 231 if (boothowto & RB_KDB) { 232 kgdb_connect(1); 233 zscons.cn_putc = zs_kgdb_cnputc; 234 zscons.cn_getc = zs_kgdb_cngetc; 235 } 236 #endif 237 #ifdef DDB 238 ddb_init(0, 0, 0); 239 if (boothowto & RB_KDB) 240 Debugger(); 241 #endif 242 sic_enable_int(39, 2, 1, 7, 0); /* NMI */ 243 } 244 245 /* 246 * cpu_startup: allocate memory for variable-sized tables, 247 * initialize cpu, and do autoconfiguration. 248 */ 249 void 250 cpu_startup() 251 { 252 extern char *etext; 253 unsigned i; 254 caddr_t v; 255 int base, residual; 256 vaddr_t minaddr, maxaddr; 257 vsize_t size; 258 #ifdef DEBUG 259 extern int pmapdebug; 260 int opmapdebug = pmapdebug; 261 262 pmapdebug = 0; 263 #endif 264 265 /* 266 * Good {morning,afternoon,evening,night}. 267 */ 268 printf(version); 269 identifycpu(); 270 printf("real mem = %d\n", ctob(physmem)); 271 272 /* 273 * Find out how much space we need, allocate it, 274 * and the give everything true virtual addresses. 275 */ 276 size = (vm_size_t)allocsys(NULL, NULL); 277 if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(size))) == 0) 278 panic("startup: no room for tables"); 279 if ((allocsys(v, NULL) - v) != size) 280 panic("startup: talbe 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 if (uvm_map(kernel_map, (vm_offset_t *) &buffers, round_page(size), 288 NULL, UVM_UNKNOWN_OFFSET, 0, 289 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 290 UVM_ADV_NORMAL, 0)) != 0) 291 panic("startup: cannot allocate VM for buffers"); 292 minaddr = (vm_offset_t)buffers; 293 base = bufpages / nbuf; 294 residual = bufpages % nbuf; 295 for (i = 0; i < nbuf; i++) { 296 vm_size_t curbufsize; 297 vm_offset_t curbuf; 298 struct vm_page *pg; 299 300 /* 301 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 302 * that MAXBSIZE space, we allocate and map (base+1) pages 303 * for the first "residual" buffers, and then we allocate 304 * "base" pages for the rest. 305 */ 306 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 307 curbufsize = NBPG * ((i < residual) ? (base+1) : base); 308 309 while (curbufsize) { 310 pg = uvm_pagealloc(NULL, 0, NULL, 0); 311 if (pg == NULL) 312 panic("cpu_startup: not enough memory for " 313 "buffer cache"); 314 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 315 VM_PROT_READ|VM_PROT_WRITE); 316 curbuf += PAGE_SIZE; 317 curbufsize -= PAGE_SIZE; 318 } 319 } 320 321 /* 322 * Allocate a submap for exec arguments. This map effectively 323 * limits the number of processes exec'ing at any time. 324 */ 325 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 326 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 327 328 /* 329 * Allocate a submap for physio 330 */ 331 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 332 VM_PHYS_SIZE, 0, FALSE, NULL); 333 334 /* 335 * Finally, allocate mbuf cluster submap. 336 */ 337 mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 338 nmbclusters * mclbytes, VM_MAP_INTRSAFE, 339 FALSE, NULL); 340 341 #ifdef DEBUG 342 pmapdebug = opmapdebug; 343 #endif 344 printf("avail mem = %ld\n", ptoa(uvmexp.free)); 345 printf("using %d buffers containing %d bytes of memory\n", 346 nbuf, bufpages * NBPG); 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 (uvm_map_protect(kernel_map, KERNBASE, m68k_round_page(&etext), 353 UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) 354 panic("can't protect kernel text"); 355 356 /* 357 * Set up buffers, so they can be used to read disk labels. 358 */ 359 bufinit(); 360 } 361 362 /* 363 * Set registers on exec. 364 * XXX Should clear registers except sp, pc, 365 * but would break init; should be fixed soon. 366 */ 367 void 368 setregs(p, pack, stack) 369 struct proc *p; 370 struct exec_package *pack; 371 u_long stack; 372 { 373 struct frame *frame = (struct frame *)p->p_md.md_regs; 374 375 frame->f_sr = PSL_USERSET; 376 frame->f_pc = pack->ep_entry & ~1; 377 frame->f_regs[D0] = 0; 378 frame->f_regs[D1] = 0; 379 frame->f_regs[D2] = 0; 380 frame->f_regs[D3] = 0; 381 frame->f_regs[D4] = 0; 382 frame->f_regs[D5] = 0; 383 frame->f_regs[D6] = 0; 384 frame->f_regs[D7] = 0; 385 frame->f_regs[A0] = 0; 386 frame->f_regs[A1] = 0; 387 frame->f_regs[A2] = (int)p->p_psstr; 388 frame->f_regs[A3] = 0; 389 frame->f_regs[A4] = 0; 390 frame->f_regs[A5] = 0; 391 frame->f_regs[A6] = 0; 392 frame->f_regs[SP] = stack; 393 394 /* restore a null state frame */ 395 p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0; 396 if (fputype) 397 m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); 398 } 399 400 /* 401 * Info for CTL_HW 402 */ 403 char cpu_model[] = "FIC8234"; 404 405 void 406 identifycpu() 407 { 408 printf("%s\n", cpu_model); 409 printf("delay constant: %d\n", delay_divisor); 410 } 411 412 /* 413 * machine dependent system variables. 414 */ 415 int 416 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 417 int *name; 418 u_int namelen; 419 void *oldp; 420 size_t *oldlenp; 421 void *newp; 422 size_t newlen; 423 struct proc *p; 424 { 425 dev_t consdev; 426 427 /* all sysctl names at this level are terminal */ 428 if (namelen != 1) 429 return (ENOTDIR); /* overloaded */ 430 431 switch (name[0]) { 432 case CPU_CONSDEV: 433 if (cn_tab != NULL) 434 consdev = cn_tab->cn_dev; 435 else 436 consdev = NODEV; 437 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 438 sizeof consdev)); 439 default: 440 return (EOPNOTSUPP); 441 } 442 /* NOTREACHED */ 443 } 444 445 446 #define SS_RTEFRAME 1 447 #define SS_FPSTATE 2 448 #define SS_USERREGS 4 449 450 struct sigstate { 451 int ss_flags; /* which of the following are valid */ 452 struct frame ss_frame; /* original exception frame */ 453 struct fpframe ss_fpstate; /* 68881/68882 state info */ 454 }; 455 456 int waittime = -1; 457 458 void 459 cpu_reboot(howto, bootstr) 460 int howto; 461 char *bootstr; 462 { 463 464 #if __GNUC__ /* XXX work around lame compiler problem (gcc 2.7.2) */ 465 (void)&howto; 466 #endif 467 /* take a snap shot before clobbering any registers */ 468 if (curproc && curproc->p_addr) 469 savectx(&curproc->p_addr->u_pcb); 470 471 /* If system is cold, just halt. */ 472 if (cold) { 473 howto |= RB_HALT; 474 goto haltsys; 475 } 476 477 boothowto = howto; 478 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 479 waittime = 0; 480 vfs_shutdown(); 481 /* 482 * If we've been adjusting the clock, the todr 483 * will be out of synch; adjust it now. 484 */ 485 resettodr(); 486 } 487 488 /* Disable interrupts. */ 489 splhigh(); 490 491 /* If rebooting and a dump is requested do it. */ 492 if (howto & RB_DUMP) 493 dumpsys(); 494 495 haltsys: 496 /* Run any shutdown hooks. */ 497 doshutdownhooks(); 498 499 #if defined(PANICWAIT) && !defined(DDB) 500 if ((howto & RB_HALT) == 0 && panicstr) { 501 printf("hit any key to reboot...\n"); 502 (void)cngetc(); 503 printf("\n"); 504 } 505 #endif 506 507 /* Finally, halt/reboot the system. */ 508 if (howto & RB_HALT) { 509 printf("System halted. Hit any key to reboot.\n\n"); 510 (void)cngetc(); 511 } 512 513 printf("rebooting...\n"); 514 DELAY(1000000); 515 doboot(); 516 /*NOTREACHED*/ 517 } 518 519 /* 520 * These variables are needed by /sbin/savecore 521 */ 522 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 523 int dumpsize = 0; /* pages */ 524 long dumplo = 0; /* blocks */ 525 526 /* 527 * This is called by main to set dumplo and dumpsize. 528 * Dumps always skip the first CLBYTES of disk space 529 * in case there might be a disk label stored there. 530 * If there is extra space, put dump at the end to 531 * reduce the chance that swapping trashes it. 532 */ 533 void 534 cpu_dumpconf() 535 { 536 int nblks; /* size of dump area */ 537 int maj; 538 539 if (dumpdev == NODEV) 540 return; 541 maj = major(dumpdev); 542 if (maj < 0 || maj >= nblkdev) 543 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 544 if (bdevsw[maj].d_psize == NULL) 545 return; 546 nblks = (*bdevsw[maj].d_psize)(dumpdev); 547 if (nblks <= ctod(1)) 548 return; 549 550 /* 551 * XXX include the final RAM page which is not included in physmem. 552 */ 553 dumpsize = physmem + 1; 554 555 /* Always skip the first CLBYTES, in case there is a label there. */ 556 if (dumplo < ctod(1)) 557 dumplo = ctod(1); 558 559 /* Put dump at end of partition, and make it fit. */ 560 if (dumpsize > dtoc(nblks - dumplo)) 561 dumpsize = dtoc(nblks - dumplo); 562 if (dumplo < nblks - ctod(dumpsize)) 563 dumplo = nblks - ctod(dumpsize); 564 } 565 566 /* 567 * Dump physical memory onto the dump device. Called by doadump() 568 * in locore.s or by cpu_reboot() here in machdep.c 569 */ 570 void 571 dumpsys() 572 { 573 daddr_t blkno; /* current block to write */ 574 /* dump routine */ 575 int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); 576 int pg; /* page being dumped */ 577 vm_offset_t maddr; /* PA being dumped */ 578 int error; /* error code from (*dump)() */ 579 580 /* Don't put dump messages in msgbuf. */ 581 msgbufmapped = 0; 582 583 /* Make sure dump device is valid. */ 584 if (dumpdev == NODEV) 585 return; 586 if (dumpsize == 0) { 587 cpu_dumpconf(); 588 if (dumpsize == 0) 589 return; 590 } 591 if (dumplo < 0) 592 return; 593 dump = bdevsw[major(dumpdev)].d_dump; 594 blkno = dumplo; 595 596 printf("\ndumping to dev 0x%x, offset %ld\n", dumpdev, dumplo); 597 598 printf("dump "); 599 maddr = lowram; 600 for (pg = 0; pg < dumpsize; pg++) { 601 #define NPGMB (1024*1024/NBPG) 602 /* print out how many MBs we have dumped */ 603 if (pg && (pg % NPGMB) == 0) 604 printf("%d ", pg / NPGMB); 605 #undef NPGMB 606 pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr, 607 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 608 609 error = (*dump)(dumpdev, blkno, vmmap, NBPG); 610 switch (error) { 611 case 0: 612 maddr += NBPG; 613 blkno += btodb(NBPG); 614 break; 615 616 case ENXIO: 617 printf("device bad\n"); 618 return; 619 620 case EFAULT: 621 printf("device not ready\n"); 622 return; 623 624 case EINVAL: 625 printf("area improper\n"); 626 return; 627 628 case EIO: 629 printf("i/o error\n"); 630 return; 631 632 case EINTR: 633 printf("aborted from console\n"); 634 return; 635 636 default: 637 printf("error %d\n", error); 638 return; 639 } 640 } 641 printf("succeeded\n"); 642 } 643 644 void 645 straytrap(pc, evec) 646 int pc; 647 u_short evec; 648 { 649 printf("unexpected trap (vector offset %x) from %x\n", 650 evec & 0xFFF, pc); 651 } 652 653 /* XXX should change the interface, and make one badaddr() function */ 654 655 int *nofault; 656 657 int 658 badaddr(addr) 659 caddr_t addr; 660 { 661 int i; 662 label_t faultbuf; 663 664 nofault = (int *) &faultbuf; 665 if (setjmp((label_t *)nofault)) { 666 nofault = (int *) 0; 667 return (1); 668 } 669 i = *(volatile short *)addr; 670 nofault = (int *) 0; 671 return (0); 672 } 673 674 int 675 badbaddr(addr) 676 caddr_t addr; 677 { 678 int i; 679 label_t faultbuf; 680 681 nofault = (int *) &faultbuf; 682 if (setjmp((label_t *)nofault)) { 683 nofault = (int *) 0; 684 return (1); 685 } 686 i = *(volatile char *)addr; 687 nofault = (int *) 0; 688 return (0); 689 } 690 691 #ifdef PANICBUTTON 692 /* 693 * Declare these so they can be patched. 694 */ 695 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 696 int candbdiv = 2; /* give em half a second (hz / candbdiv) */ 697 698 void candbtimer __P((void *)); 699 700 int crashandburn; 701 702 void 703 candbtimer(arg) 704 void *arg; 705 { 706 707 crashandburn = 0; 708 } 709 #endif /* PANICBUTTON */ 710 711 static int innmihand; /* simple mutex */ 712 713 /* 714 * Level 7 interrupts can be caused by the keyboard or parity errors. 715 */ 716 void 717 nmihand(frame) 718 struct frame frame; 719 { 720 721 /* Prevent unwanted recursion. */ 722 if (innmihand) 723 return; 724 innmihand = 1; 725 726 printf("NMI\n"); 727 #if defined(DDB) || defined(KGDB) 728 Debugger(); 729 #endif 730 731 innmihand = 0; 732 } 733 734 735 /* 736 * cpu_exec_aout_makecmds(): 737 * cpu-dependent a.out format hook for execve(). 738 * 739 * Determine of the given exec package refers to something which we 740 * understand and, if so, set up the vmcmds for it. 741 * 742 * XXX what are the special cases for the hp300? 743 * XXX why is this COMPAT_NOMID? was something generating 744 * hp300 binaries with an a_mid of 0? i thought that was only 745 * done on little-endian machines... -- cgd 746 */ 747 int 748 cpu_exec_aout_makecmds(p, epp) 749 struct proc *p; 750 struct exec_package *epp; 751 { 752 #if defined(COMPAT_NOMID) || defined(COMPAT_44) 753 u_long midmag, magic; 754 u_short mid; 755 int error; 756 struct exec *execp = epp->ep_hdr; 757 758 midmag = ntohl(execp->a_midmag); 759 mid = (midmag >> 16) & 0xffff; 760 magic = midmag & 0xffff; 761 762 midmag = mid << 16 | magic; 763 764 switch (midmag) { 765 #ifdef COMPAT_NOMID 766 case (MID_ZERO << 16) | ZMAGIC: 767 error = exec_aout_prep_oldzmagic(p, epp); 768 return (error); 769 #endif 770 #ifdef COMPAT_44 771 case (MID_HP300 << 16) | ZMAGIC: 772 error = exec_aout_prep_oldzmagic(p, epp); 773 return (error); 774 #endif 775 } 776 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */ 777 778 return ENOEXEC; 779 } 780