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