1 /* $NetBSD: m68k_machdep.c,v 1.24 2026/05/03 19:10:41 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 2026 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Copyright (c) 1988 University of Utah. 31 * Copyright (c) 1982, 1986, 1990, 1993 32 * The Regents of the University of California. All rights reserved. 33 * 34 * This code is derived from software contributed to Berkeley by 35 * the Systems Programming Group of the University of Utah Computer 36 * Science Department. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. Neither the name of the University nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * 62 * from: Utah $Hdr: machdep.c 1.74 92/12/20$ 63 * 64 * @(#)machdep.c 8.10 (Berkeley) 4/20/94 65 */ 66 67 #include <sys/cdefs.h> 68 __KERNEL_RCSID(0, "$NetBSD: m68k_machdep.c,v 1.24 2026/05/03 19:10:41 thorpej Exp $"); 69 70 #include "opt_compat_netbsd.h" 71 #include "opt_compat_sunos.h" 72 #include "opt_execfmt.h" 73 #include "opt_m68k_arch.h" 74 75 #include <sys/param.h> 76 #include <sys/cpu.h> 77 #include <sys/exec.h> 78 #include <sys/lwp.h> 79 #include <sys/proc.h> 80 #include <sys/msgbuf.h> 81 #include <sys/reboot.h> 82 #include <sys/device.h> 83 #include <sys/vnode.h> 84 #include <sys/kernel.h> 85 #include <sys/kcore.h> 86 87 #include <dev/cons.h> 88 89 #ifdef EXEC_AOUT 90 #include <sys/exec_aout.h> /* for cpu_exec_aout_makecmds() prototype */ 91 #endif 92 93 #include <uvm/uvm_extern.h> 94 95 #include <m68k/m68k.h> 96 #include <m68k/kcore.h> 97 #include <m68k/frame.h> 98 #include <m68k/pcb.h> 99 #include <m68k/reg.h> 100 #ifdef M68060 101 #include <m68k/pcr.h> 102 #endif 103 #include <m68k/seglist.h> 104 105 /* the following is used externally (sysctl_hw) */ 106 char machine[] = MACHINE; /* from <machine/param.h> */ 107 char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */ 108 109 /* Our exported CPU info; we can have only one. */ 110 struct cpu_info cpu_info_store; 111 112 /* cpu speed in kHz */ 113 int cpuspeed_khz; 114 115 #if defined(M68020) || defined(M68030) 116 /* fpu speed in kHz */ 117 int fpuspeed_khz; 118 #endif 119 120 #ifdef M68K_EC 121 /* external cache size in bytes */ 122 int ecsize; 123 #endif 124 125 /* 126 * Physical memory segments. These segments are included in kernel 127 * crash dumps, and the available ranges of the segments are loaded 128 * into the VM system as managed pages. 129 */ 130 phys_seg_list_t phys_seg_list[VM_PHYSSEG_MAX]; 131 132 /* 133 * __HAVE_M68K_PRIVATE_MSGSBUF is a hook for the Sun platforms that 134 * are re-using PROM mappings of memory for the messsage buffer that 135 * are not guaranteed to be physically contiguous. 136 * 137 * How we act on this: We don't care about the PA of the message buffer 138 * at all, and we assume that the message buffer has already been mapped 139 * as part of the VM bootstrap. 140 */ 141 #ifndef __HAVE_M68K_PRIVATE_MSGSBUF 142 paddr_t msgbufpa = (paddr_t)-1; /* PA of message buffer */ 143 #endif 144 void *msgbufaddr; 145 146 vaddr_t m68k_usrstack; 147 148 /* 149 * Common tasks for machine_init(). 150 */ 151 void 152 machine_init_common(paddr_t nextpa) 153 { 154 extern paddr_t avail_start, avail_end; 155 int i; 156 #ifndef __HAVE_M68K_PRIVATE_MSGSBUF 157 int end_seg = 0; 158 #endif 159 160 /* 161 * Compute the boundaries of available memory. 162 */ 163 avail_start = UINT_MAX; 164 avail_end = 0; 165 for (i = 0; i < VM_PHYSSEG_MAX; i++) { 166 /* 167 * Make sure the memory segment begins/ends on 168 * page boundaries. 169 * 170 * If ps_avail_start and ps_avail_end have not already 171 * been initialized, go ahead and validate those. 172 */ 173 phys_seg_list[i].ps_start = 174 m68k_round_page(phys_seg_list[i].ps_start); 175 phys_seg_list[i].ps_end = 176 m68k_trunc_page(phys_seg_list[i].ps_end); 177 178 if (phys_seg_list[i].ps_avail_start == 0 && 179 phys_seg_list[i].ps_avail_end == 0) { 180 phys_seg_list[i].ps_avail_start = 181 phys_seg_list[i].ps_start; 182 phys_seg_list[i].ps_avail_end = 183 phys_seg_list[i].ps_end; 184 } 185 186 if (phys_seg_list[i].ps_start == phys_seg_list[i].ps_end) { 187 /* Empty segment. */ 188 continue; 189 } 190 191 /* 192 * nextpa represents the next available page after 193 * the pages already consumed by the bootstrap 194 * process. If it falls within this physical segment, 195 * just the available range as necessary. 196 */ 197 if (nextpa >= phys_seg_list[i].ps_start && 198 /* this <= is intentional */ 199 nextpa <= phys_seg_list[i].ps_end && 200 nextpa > phys_seg_list[i].ps_avail_start) { 201 phys_seg_list[i].ps_avail_start = nextpa; 202 } 203 204 if (phys_seg_list[i].ps_avail_start == 205 phys_seg_list[i].ps_avail_end) { 206 /* Segment has been completely gobbled up. */ 207 continue; 208 } 209 210 if (phys_seg_list[i].ps_avail_start < avail_start) { 211 avail_start = phys_seg_list[i].ps_avail_start; 212 } 213 if (phys_seg_list[i].ps_avail_end > avail_end) { 214 avail_end = phys_seg_list[i].ps_avail_end; 215 #ifndef __HAVE_M68K_PRIVATE_MSGSBUF 216 end_seg = i; 217 #endif 218 } 219 } 220 221 #ifndef __HAVE_M68K_PRIVATE_MSGSBUF 222 /* 223 * If the message buffer has not already been allocated, 224 * allocate it from the end of physical memory. 225 */ 226 if (msgbufpa == (paddr_t)-1) { 227 KASSERT((phys_seg_list[end_seg].ps_avail_end 228 - phys_seg_list[end_seg].ps_avail_start) 229 >= round_page(MSGBUFSIZE)); 230 phys_seg_list[end_seg].ps_avail_end -= round_page(MSGBUFSIZE); 231 msgbufpa = phys_seg_list[end_seg].ps_avail_end; 232 } 233 #endif 234 235 #ifndef VM_PHYS_SEG_TO_FREELIST 236 #define VM_PHYS_SEG_TO_FREELIST(s) VM_FREELIST_DEFAULT 237 #endif 238 239 /* 240 * Now load the pages into the VM system. 241 */ 242 for (i = 0; i < VM_PHYSSEG_MAX; i++) { 243 if (phys_seg_list[i].ps_avail_start == 244 phys_seg_list[i].ps_avail_end) { 245 /* Segment has been completely gobbled up. */ 246 continue; 247 } 248 uvm_page_physload(atop(phys_seg_list[i].ps_avail_start), 249 atop(phys_seg_list[i].ps_avail_end), 250 atop(phys_seg_list[i].ps_avail_start), 251 atop(phys_seg_list[i].ps_avail_end), 252 VM_PHYS_SEG_TO_FREELIST(i)); 253 } 254 255 /* 256 * Initialize the kernel message buffer. 257 */ 258 #ifndef __HAVE_M68K_PRIVATE_MSGSBUF 259 for (i = 0; i < btoc(round_page(MSGBUFSIZE)); i++) { 260 pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE, 261 msgbufpa + i * PAGE_SIZE, 262 VM_PROT_READ|VM_PROT_WRITE, 0); 263 } 264 pmap_update(pmap_kernel()); 265 #endif 266 initmsgbuf(msgbufaddr, round_page(MSGBUFSIZE)); 267 } 268 269 /* 270 * Common tasks for cpu_startup(). 271 */ 272 void 273 cpu_startup_common(void) 274 { 275 vaddr_t minaddr, maxaddr; 276 char pbuf[9]; 277 278 /* 279 * For the benefit of modules that need USRSTACK (such 280 * as compat exec modules). Initialized here because 281 * USRSTACK may not be a compile-time constant. 282 */ 283 m68k_usrstack = USRSTACK; 284 285 /* Initialize the FPU, if present. */ 286 fpu_init(); 287 288 /* Set the model info. */ 289 machine_set_model(); 290 291 /* 292 * Good {morning,afternoon,evening,night}. 293 * XXX Should augment banner() and then switch to using it. 294 */ 295 printf("%s%s", copyright, version); 296 #ifdef __HAVE_CPU_STARTUP_PRINT_MACHINE_MODEL 297 cpu_startup_print_machine_model(printf); 298 #endif 299 #ifdef __HAVE_CPU_STARTUP_PRINT_TOTAL_MEMORY 300 cpu_startup_print_total_memory(printf); 301 #else 302 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 303 printf("total memory = %s\n", pbuf); 304 #endif 305 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false))); 306 printf("avail memory = %s\n", pbuf); 307 308 /* 309 * Allocate a submap for physio 310 */ 311 minaddr = 0; 312 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 313 VM_PHYS_SIZE, 0, false, NULL); 314 } 315 __weak_alias(cpu_startup, cpu_startup_common); 316 317 static const char * 318 mhz_string_from_khz(int speed_khz, char *buf, size_t bufsize) 319 { 320 int whole_mhz = speed_khz / 1000; 321 int frac_mhz = (speed_khz % 1000) / 10; 322 if ((frac_mhz % 10) == 0) { 323 frac_mhz /= 10; 324 } 325 if (frac_mhz == 0) { 326 snprintf(buf, bufsize, " @ %dMHz", whole_mhz); 327 } else { 328 snprintf(buf, bufsize, " @ %d.%dMHz", whole_mhz, frac_mhz); 329 } 330 return buf; 331 } 332 333 void 334 cpu_startup_print_machine_model(void (*pr)(const char *, ...) 335 __printflike(1, 2)) 336 { 337 char speed_str[sizeof("@ xxx.xxxMHz")] = { 0 }; 338 339 /* 340 * Caller should have set the system model already. We 341 * will print the CPU information after, like so: 342 * 343 * MODEL 344 * CPU MMU FPU CACHE 345 * 346 * Examples: 347 348 Qemu 10.1.2 Virt platform 349 MC68040+MMU+FPU, 4k+4k on-chip I/D caches 350 351 Motorola MVME-147 352 MC68030 CPU+MMU @ 25MHz, MC68882 FPU 353 354 HP 9000/433s 355 MC68040 CPU+MMU+FPU @ 33MHz, 4K+4K on-chip I/D caches 356 357 HP 9000/320 358 MC68020 CPU @ 16.67MHz, HP MMU, MC68881 FPU 359 External 16K virtual-address cache 360 361 HP 9000/350 362 MC68020 CPU @ 25MHz, HP MMU, MC68881 FPU @ 20MHz 363 External 32K virtual-address cache 364 365 * ^^^ Yes, there's at least one HP system where the FPU 366 * has a different clock than the CPU. 367 * 368 * There is a hook that allows machine-specific code to print 369 * a more informative model banner, such as: 370 371 Model: sun3x 80 372 MC68030 CPU+MMU @ 20MHz, MC68882 FPU 373 374 Model: sun3 160 375 MC68020 CPU @ 16.67MHz, Sun MMU, MC68881 FPU 376 377 Model: sun2 {120,170} 378 MC68010 CPU @ 10MHz, Sun MMU 379 380 SONY NET WORK STATION, Model NWS-1710, Machine ID #123456 381 MC68030 CPU+MMU @ 25MHz, MC68882 FPU 382 383 * (In this last example, cpu_model() returns "NWS-1710".) 384 * In the Sun examples, for historical reasons, the model 385 * string is formatted a certain way for use by the installer 386 * miniroot. 387 * 388 * This is a departure from how it has been on some NetBSD 389 * systems historically, but this is intended to bring some 390 * consistency to the platforms while maintaining a reasonable 391 * aesthetic. 392 */ 393 #ifdef __HAVE_M68K_MACHINE_PRINT_MODEL 394 machine_print_model(pr); 395 #else 396 (*pr)("%s\n", cpu_getmodel()); 397 #endif 398 399 switch (cputype) { 400 #ifdef M68010 401 case CPU_68010: 402 (*pr)("MC68010 CPU"); 403 break; 404 #endif 405 #ifdef M68020 406 case CPU_68020: 407 (*pr)("MC68020 CPU"); 408 break; 409 #endif 410 #ifdef M68030 411 case CPU_68030: 412 (*pr)("MC68030 CPU+MMU"); 413 break; 414 #endif 415 #ifdef M68040 416 case CPU_68040: 417 (*pr)("MC68040 CPU+MMU"); 418 break; 419 #endif 420 #ifdef M68060 421 case CPU_68060: { 422 u_int pcr = get_pcr(); 423 (*pr)("MC68%s060 rev.%d CPU+MMU", 424 (PCR_ID(pcr) & 1) ? "LC" : "", 425 (int)PCR_REVISION(pcr)); 426 if (pcr & PCR_DFP) { 427 (*pr)("+FPU(disabled)"); 428 } 429 break; 430 } 431 #endif 432 default: 433 (*pr)("unknown CPU type\n"); 434 panic("startup"); 435 } 436 437 #if defined(M68040) || defined(M68060) 438 switch (fputype) { 439 case FPU_68040: 440 case FPU_68060: 441 (*pr)("+FPU"); 442 break; 443 default: 444 break; 445 } 446 #endif 447 448 if (cpuspeed_khz) { 449 (*pr)("%s", 450 mhz_string_from_khz(cpuspeed_khz, 451 speed_str, sizeof(speed_str))); 452 } 453 454 switch (mmutype) { 455 #ifdef M68K_MMU_68851 456 case MMU_68851: 457 (*pr)(", MC68851 MMU"); 458 break; 459 #endif 460 #ifdef M68K_MMU_HP 461 case MMU_HP: 462 (*pr)(", HP MMU"); 463 break; 464 #endif 465 #ifdef M68K_MMU_SUN 466 case MMU_SUN: 467 (*pr)(", Sun MMU"); 468 break; 469 #endif 470 #ifdef M68K_MMU_CUSTOM 471 case MMU_CUSTOM: 472 (*pr)(", custom MMU"); 473 break; 474 #endif 475 default: 476 break; 477 } 478 479 switch (fputype) { 480 #ifdef FPU_EMULATE 481 case FPU_NONE: 482 (*pr)(", emulated FPU"); 483 break; 484 #endif 485 #if defined(M68020) || defined(M68030) 486 case FPU_68881: 487 (*pr)(", MC68881 FPU"); 488 break; 489 490 case FPU_68882: 491 (*pr)(", MC68882 FPU"); 492 break; 493 #endif 494 default: 495 break; 496 } 497 498 #if defined(M68020) || defined(M68030) 499 if (fpuspeed_khz != 0 && fpuspeed_khz != cpuspeed_khz) { 500 (*pr)("%s", 501 mhz_string_from_khz(fpuspeed_khz, 502 speed_str, sizeof(speed_str))); 503 } 504 #endif 505 506 switch (cputype) { 507 #if defined(M68040) || defined(M68060) 508 case CPU_68040: 509 case CPU_68060: 510 (*pr)(", %dK+%dK on-chip I/D caches", 511 cputype == CPU_68040 ? 4 : 8, 512 cputype == CPU_68040 ? 4 : 8); 513 break; 514 #endif 515 default: 516 #ifdef M68K_EC 517 if (ectype != EC_NONE) { 518 (*pr)("\nExternal "); 519 if (ecsize >= 1024) { 520 (*pr)("%dK ", ecsize / 1024); 521 } 522 (*pr)("%s-address cache", 523 ectype == EC_PHYS ? "physical" : "virtual"); 524 } 525 #endif 526 break; 527 } 528 (*pr)("\n"); 529 } 530 531 int 532 mm_md_physacc_regular(paddr_t pa, vm_prot_t prot) 533 { 534 int i; 535 536 for (i = 0; i < VM_PHYSSEG_MAX; i++) { 537 if (phys_seg_list[i].ps_start == phys_seg_list[i].ps_end) { 538 continue; 539 } 540 if (pa < phys_seg_list[i].ps_start) { 541 continue; 542 } 543 if (pa >= phys_seg_list[i].ps_end) { 544 continue; 545 } 546 return 0; 547 } 548 return EFAULT; 549 } 550 551 int 552 cpu_reboot_poll_console(bool wait) 553 { 554 int rv; 555 556 cnpollc(true); 557 /* If there is no console input device, cngetc() returns 0. */ 558 while ((rv = cngetc()) == 0 && wait) { 559 delay(100000); 560 } 561 cnpollc(false); 562 563 return rv; 564 } 565 566 void 567 machine_powerdown_default(void) 568 { 569 /* zip, nada, nothing */ 570 } 571 __weak_alias(machine_powerdown,machine_powerdown_default); 572 573 void 574 machine_halt_default(void) 575 { 576 printf("Please press any key to reboot.\n"); 577 578 cpu_reboot_poll_console(true); 579 } 580 __weak_alias(machine_halt,machine_halt_default); 581 582 int waittime = -1; 583 584 void 585 bootsync(void) 586 { 587 if (waittime < 0) { 588 waittime = 0; 589 vfs_shutdown(); 590 } 591 } 592 593 void 594 cpu_reboot_common(int howto, char *bootstr) 595 { 596 struct pcb *pcb = lwp_getpcb(curlwp); 597 598 /* take a snap shot before clobbering any registers */ 599 if (pcb != NULL) { 600 savectx(pcb); 601 } 602 603 /* If system is hold, just halt. */ 604 if (cold) { 605 howto |= RB_HALT; 606 goto haltsys; 607 } 608 609 /* Un-blank the screen if appropriate. */ 610 cnpollc(true); 611 612 boothowto = howto; 613 if ((howto & RB_NOSYNC) == 0) { 614 bootsync(); 615 } 616 617 /* Disable interrupts. */ 618 splhigh(); 619 620 /* If rebooting and a dump is requested, do it. */ 621 if (howto & RB_DUMP) { 622 dumpsys(); 623 } 624 625 haltsys: 626 /* Run any shutdown hooks. */ 627 doshutdownhooks(); 628 629 pmf_system_shutdown(boothowto); 630 631 #if defined(PANICWAIT) && !defined(DDB) 632 if ((howto & RB_HALT) == 0 && panicstr) { 633 printf("hit any key to reboot...\n"); 634 cpu_reboot_poll_console(false); 635 printf("\n"); 636 } 637 #endif 638 639 /* Finally, halt/reboot the system. */ 640 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 641 machine_powerdown(); 642 } 643 if (howto & RB_HALT) { 644 printf("The operating system has halted.\n"); 645 machine_halt(); 646 } 647 648 printf("rebooting...\n"); 649 delay(1000000); 650 machine_reboot(howto, bootstr); 651 printf("WARNING: system reboot failed, holding here.\n\n"); 652 for (;;) { 653 /* spin forever. */ 654 } 655 } 656 __weak_alias(cpu_reboot,cpu_reboot_common); 657 658 /* 659 * mm_md_physacc_common is the standard implementation for all 660 * m68k platforms, and covers regular physical memory. If a 661 * platform wants to include other ranges, it can simply 662 * define its own mm_md_physacc(), call mm_md_physacc_common() 663 * first, and then check its own ranges if mm_md_physacc_common() 664 * does not return 0. 665 */ 666 __weak_alias(mm_md_physacc, mm_md_physacc_regular); 667 668 /* 669 * Set registers on exec. 670 */ 671 void 672 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 673 { 674 struct trapframe *tf = (struct trapframe *)l->l_md.md_regs; 675 struct pcb *pcb = lwp_getpcb(l); 676 677 memset(tf, 0, sizeof(*tf)); 678 679 tf->tf_sr = PSL_USERSET; 680 tf->tf_pc = pack->ep_entry & ~1; 681 tf->tf_regs[D0] = 0; 682 tf->tf_regs[D1] = 0; 683 tf->tf_regs[D2] = 0; 684 tf->tf_regs[D3] = 0; 685 tf->tf_regs[D4] = 0; 686 tf->tf_regs[D5] = 0; 687 tf->tf_regs[D6] = 0; 688 tf->tf_regs[D7] = 0; 689 tf->tf_regs[A0] = 0; 690 tf->tf_regs[A1] = 0; 691 tf->tf_regs[A2] = l->l_proc->p_psstrp; 692 tf->tf_regs[A3] = 0; 693 tf->tf_regs[A4] = 0; 694 tf->tf_regs[A5] = 0; 695 tf->tf_regs[A6] = 0; 696 tf->tf_regs[SP] = stack; 697 698 /* restore a null state frame */ 699 pcb->pcb_fpregs.fpf_null = 0; 700 #if !defined(__mc68010__) 701 if (fputype) 702 m68881_restore(&pcb->pcb_fpregs); 703 #endif 704 705 #ifdef COMPAT_SUNOS 706 /* see m68k/sunos_syscall.c */ 707 l->l_md.md_flags = 0; 708 #endif 709 } 710 711 #ifdef EXEC_AOUT 712 /* 713 * cpu_exec_aout_makecmds(): 714 * cpu-dependent a.out format hook for execve(). 715 * 716 * Determine of the given exec package refers to something which we 717 * understand and, if so, set up the vmcmds for it. 718 * 719 * XXX what are the special cases for the hp300? 720 * XXX why is this COMPAT_NOMID? was something generating 721 * hp300 binaries with an a_mid of 0? i thought that was only 722 * done on little-endian machines... -- cgd 723 * XXX perhaps this whole thing should be relegated to a smoking crater? 724 */ 725 int 726 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 727 { 728 #ifdef __mc68010__ 729 /* There were never native a.out binaries for NetBSD on 68010. */ 730 return ENOEXEC; 731 #elif defined(COMPAT_NOMID) || defined(COMPAT_44) 732 struct exec *execp = epp->ep_hdr; 733 u_long midmag, magic; 734 u_short mid; 735 int error; 736 737 midmag = ntohl(execp->a_midmag); 738 mid = (midmag >> 16) & 0xffff; 739 magic = midmag & 0xffff; 740 741 midmag = mid << 16 | magic; 742 743 switch (midmag) { 744 #ifdef COMPAT_NOMID 745 case (MID_ZERO << 16) | ZMAGIC: 746 error = exec_aout_prep_oldzmagic(l, epp); 747 break; 748 #endif 749 #ifdef COMPAT_44 750 case (MID_HP300 << 16) | ZMAGIC: 751 error = exec_aout_prep_oldzmagic(l, epp); 752 break; 753 #endif 754 default: 755 error = ENOEXEC; 756 } 757 return error; 758 #else /* COMPAT_NOMID || COMPAT_44 */ 759 return ENOEXEC; 760 #endif 761 } 762 #endif /* EXEC_AOUT */ 763