1 /* $NetBSD: machdep.c,v 1.370 2024/09/14 21:02:46 nat Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1982, 1990 The Regents of the University of California. 6 * 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. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 /*- 38 * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, 39 * Michael L. Finch, Bradley A. Grantham, and 40 * Lawrence A. Kesteloot 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by the Alice Group. 54 * 4. The names of the Alice Group or any of its members may not be used 55 * to endorse or promote products derived from this software without 56 * specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR 59 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 60 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61 * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, 62 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 63 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 64 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 65 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 67 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 * 69 */ 70 /* 71 * from: Utah $Hdr: machdep.c 1.63 91/04/24$ 72 * 73 * @(#)machdep.c 7.16 (Berkeley) 6/3/91 74 */ 75 76 #include <sys/cdefs.h> 77 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.370 2024/09/14 21:02:46 nat Exp $"); 78 79 #include "opt_adb.h" 80 #include "opt_compat_netbsd.h" 81 #include "opt_copy_symtab.h" 82 #include "opt_ddb.h" 83 #include "opt_ddbparam.h" 84 #include "opt_kgdb.h" 85 #include "opt_mac68k.h" 86 #include "opt_modular.h" 87 88 #include "akbd.h" 89 #include "genfb.h" 90 #include "macfb.h" 91 #include "zsc.h" 92 93 #include <sys/param.h> 94 #include <sys/systm.h> 95 #include <sys/buf.h> 96 #include <sys/conf.h> 97 #include <sys/core.h> 98 #include <sys/exec.h> 99 #include <sys/exec_aout.h> /* for MID_* */ 100 #include <sys/extent.h> 101 #include <sys/file.h> 102 #include <sys/kcore.h> 103 #include <sys/kernel.h> 104 #include <sys/malloc.h> 105 #include <sys/mbuf.h> 106 #include <sys/mount.h> 107 #include <sys/msgbuf.h> 108 #include <sys/pool.h> 109 #include <sys/proc.h> 110 #include <sys/queue.h> 111 #include <sys/reboot.h> 112 #include <sys/signalvar.h> 113 #include <sys/syscallargs.h> 114 #include <sys/vnode.h> 115 #include <sys/ksyms.h> 116 #include <sys/module.h> 117 #ifdef KGDB 118 #include <sys/kgdb.h> 119 #endif 120 #include <sys/exec_elf.h> 121 #include <sys/device.h> 122 #include <sys/cpu.h> 123 124 #include <m68k/cacheops.h> 125 #include <m68k/mmu_40.h> 126 127 #include <machine/db_machdep.h> 128 #include <ddb/db_sym.h> 129 #include <ddb/db_extern.h> 130 131 #include <machine/autoconf.h> 132 #include <machine/cpu.h> 133 #include <machine/reg.h> 134 #include <machine/pcb.h> 135 #include <machine/psl.h> 136 #include <machine/pte.h> 137 #include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */ 138 #include <machine/video.h> 139 140 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 141 #include <uvm/uvm_extern.h> 142 143 #include <sys/sysctl.h> 144 145 #include <dev/cons.h> 146 #include <dev/mm.h> 147 148 #include <machine/iopreg.h> 149 #include <machine/psc.h> 150 #include <machine/viareg.h> 151 #include <mac68k/mac68k/macrom.h> 152 #include <mac68k/dev/adbvar.h> 153 #if NAKBD > 0 154 #include <mac68k/dev/akbdvar.h> 155 #endif 156 #if NMACFB > 0 157 #include <mac68k/dev/macfbvar.h> 158 #endif 159 #include <mac68k/dev/pm_direct.h> 160 #include <mac68k/dev/zs_cons.h> 161 162 #include "ksyms.h" 163 164 int symsize, end, *ssym, *esym; 165 166 /* The following is used externally (sysctl_hw) */ 167 char machine[] = MACHINE; /* from <machine/param.h> */ 168 169 struct mac68k_machine_S mac68k_machine; 170 171 volatile u_char *Via1Base, *Via2Base, *PSCBase = NULL; 172 u_long NuBusBase = NBBASE; 173 u_long IOBase; 174 175 vaddr_t SCSIBase; 176 177 /* These are used to map kernel space: */ 178 extern int numranges; 179 extern u_long low[8]; 180 extern u_long high[8]; 181 extern int machineid; 182 183 /* These are used to map NuBus space: */ 184 #define NBMAXRANGES 16 185 int nbnumranges; /* = 0 == don't use the ranges */ 186 u_long nbphys[NBMAXRANGES]; /* Start physical addr of this range */ 187 u_long nblog[NBMAXRANGES]; /* Start logical addr of this range */ 188 long nblen[NBMAXRANGES]; /* Length of this range If the length is */ 189 /* negative, all phys addrs are the same. */ 190 191 /* Definitions for the variables defined in machine/video.h */ 192 struct mac68k_video mac68k_video; 193 194 /* Callback and cookie to run bell */ 195 int (*mac68k_bell_callback)(void *, int, int, int); 196 void * mac68k_bell_cookie; 197 198 struct vm_map *phys_map = NULL; 199 200 int maxmem; /* max memory per process */ 201 202 /* 203 * Extent maps to manage all memory space, including I/O ranges. Allocate 204 * storage for 8 regions in each, initially. Later, iomem_malloc_safe 205 * will indicate that it's safe to use malloc() to dynamically allocate 206 * region descriptors. 207 * 208 * The extent maps are not static! Machine-dependent NuBus and on-board 209 * I/O routines need access to them for bus address space allocation. 210 */ 211 static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 212 struct extent *iomem_ex; 213 int iomem_malloc_safe; 214 215 /* Our exported CPU info; we can have only one. */ 216 struct cpu_info cpu_info_store; 217 218 static void identifycpu(void); 219 static u_long get_physical(u_int, u_long *); 220 221 void initcpu(void); 222 int cpu_dumpsize(void); 223 int cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *); 224 void cpu_init_kcore_hdr(void); 225 226 void getenvvars(u_long, char *); 227 static long getenv(const char *); 228 229 /* functions called from locore.s */ 230 void dumpsys(void); 231 void mac68k_init(void); 232 void straytrap(int, int); 233 void nmihand(struct frame); 234 235 /* 236 * Machine-dependent crash dump header info. 237 */ 238 cpu_kcore_hdr_t cpu_kcore_hdr; 239 240 /* 241 * XXX: For zs serial driver. We always initialize the base address 242 * to avoid a bunch of #ifdefs. 243 */ 244 volatile unsigned char *sccA = 0; 245 246 /* 247 * Early initialization, before main() is called. 248 */ 249 void 250 mac68k_init(void) 251 { 252 int i; 253 extern vaddr_t avail_start; 254 255 /* 256 * Tell the VM system about available physical memory. 257 * Notice that we don't need to worry about avail_end here 258 * since it's equal to high[numranges-1]. 259 */ 260 for (i = 0; i < numranges; i++) { 261 if (low[i] <= avail_start && avail_start < high[i]) 262 uvm_page_physload(atop(avail_start), atop(high[i]), 263 atop(avail_start), atop(high[i]), 264 VM_FREELIST_DEFAULT); 265 else 266 uvm_page_physload(atop(low[i]), atop(high[i]), 267 atop(low[i]), atop(high[i]), 268 VM_FREELIST_DEFAULT); 269 } 270 271 /* 272 * Initialize the I/O mem extent map. 273 * Note: we don't have to check the return value since 274 * creation of a fixed extent map will never fail (since 275 * descriptor storage has already been allocated). 276 * 277 * N.B. The iomem extent manages _all_ physical addresses 278 * on the machine. When the amount of RAM is found, all 279 * extents of RAM are allocated from the map. 280 */ 281 iomem_ex = extent_create("iomem", 0x0, 0xffffffff, 282 (void *)iomem_ex_storage, sizeof(iomem_ex_storage), 283 EX_NOCOALESCE|EX_NOWAIT); 284 285 /* Initialize the interrupt handlers. */ 286 intr_init(); 287 288 /* Initialize the IOPs (if present) */ 289 iop_init(1); 290 291 /* 292 * Initialize error message buffer (at end of core). 293 * high[numranges-1] was decremented in pmap_bootstrap. 294 */ 295 for (i = 0; i < btoc(MSGBUFSIZE); i++) 296 pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE, 297 high[numranges - 1] + i * PAGE_SIZE, 298 VM_PROT_READ|VM_PROT_WRITE, 299 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); 300 initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); 301 pmap_update(pmap_kernel()); 302 } 303 304 /* 305 * Console initialization: called early on from main, 306 * before vm init or startup. Do enough configuration 307 * to choose and initialize a console. 308 */ 309 void 310 consinit(void) 311 { 312 /* 313 * Generic console: sys/dev/cons.c 314 * Initializes either ite or ser as console. 315 * Can be called from locore.s and init_main.c. (Ugh.) 316 */ 317 static int init; /* = 0 */ 318 319 if (!init) { 320 cninit(); 321 init = 1; 322 } else { 323 #if NAKBD > 0 && (NMACFB + NGENFB) > 0 324 /* 325 * XXX This is an evil hack on top of an evil hack! 326 * 327 * With the graybar stuff, we've got a catch-22: we need 328 * to do at least some console setup really early on, even 329 * before we're running with the mappings we need. On 330 * the other hand, we're not nearly ready to do anything 331 * with wscons or the ADB driver at that point. 332 * 333 * To get around this, maccninit() ignores the first call 334 * it gets (from cninit(), if not on a serial console). 335 * Once we're here, we call maccninit() again, which sets 336 * up the console devices and does the appropriate wscons 337 * initialization. 338 */ 339 if (mac68k_machine.serial_console == 0) { 340 void maccninit(struct consdev *); 341 maccninit(NULL); 342 } 343 #endif 344 345 mac68k_calibrate_delay(); 346 347 #if NZSC > 0 && defined(KGDB) 348 zs_kgdb_init(); 349 #endif 350 #if NKSYMS || defined(DDB) || defined(MODULAR) 351 /* 352 * Initialize kernel debugger, if compiled in. 353 */ 354 355 ksyms_addsyms_elf(symsize, ssym, esym); 356 #endif 357 358 if (boothowto & RB_KDB) { 359 #ifdef KGDB 360 /* XXX - Ask on console for kgdb_dev? */ 361 /* Note: this will just return if kgdb_dev==NODEV */ 362 kgdb_connect(1); 363 #else /* KGDB */ 364 #ifdef DDB 365 /* Enter DDB. We don't have a monitor PROM. */ 366 Debugger(); 367 #endif /* DDB */ 368 #endif /* KGDB */ 369 } 370 } 371 } 372 373 #define CURRENTBOOTERVER 111 374 375 /* 376 * cpu_startup: allocate memory for variable-sized tables, make 377 * (most of) kernel text read-only, and other miscellaneous bits 378 */ 379 void 380 cpu_startup(void) 381 { 382 int vers; 383 vaddr_t minaddr, maxaddr; 384 int xdelay; 385 char pbuf[9]; 386 387 /* 388 * Initialize the kernel crash dump header. 389 */ 390 cpu_init_kcore_hdr(); 391 392 /* 393 * Good {morning,afternoon,evening,night}. 394 */ 395 printf("%s%s", copyright, version); 396 identifycpu(); 397 398 vers = mac68k_machine.booter_version; 399 if (vers < CURRENTBOOTERVER) { 400 /* fix older booters with indices, not versions */ 401 if (vers < 100) 402 vers += 99; 403 404 printf("\nYou booted with booter version %d.%d.\n", 405 vers / 100, vers % 100); 406 printf("Booter version %d.%d is necessary to fully support\n", 407 CURRENTBOOTERVER / 100, CURRENTBOOTERVER % 100); 408 printf("this kernel.\n\n"); 409 for (xdelay = 0; xdelay < 1000000; xdelay++); 410 } 411 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 412 printf("total memory = %s\n", pbuf); 413 414 minaddr = 0; 415 /* 416 * Allocate a submap for physio 417 */ 418 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 419 VM_PHYS_SIZE, 0, false, NULL); 420 421 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false))); 422 printf("avail memory = %s\n", pbuf); 423 424 /* 425 * Set up CPU-specific registers, cache, etc. 426 */ 427 initcpu(); 428 429 /* Safe for extent allocation to use malloc now. */ 430 iomem_malloc_safe = 1; 431 } 432 433 void 434 initcpu(void) 435 { 436 /* Invalidate supervisor mode data cache. */ 437 DCIS(); 438 } 439 440 void doboot(void) __attribute__((__noreturn__)); 441 442 int waittime = -1; 443 struct pcb dumppcb; 444 445 void 446 cpu_reboot(int howto, char *bootstr) 447 { 448 struct pcb *pcb = lwp_getpcb(curlwp); 449 extern u_long maxaddr; 450 451 /* take a snap shot before clobbering any registers */ 452 if (pcb != NULL) 453 savectx(pcb); 454 455 /* If system is cold, just halt. */ 456 if (cold) { 457 howto |= RB_HALT; 458 goto haltsys; 459 } 460 461 boothowto = howto; 462 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 463 waittime = 0; 464 vfs_shutdown(); 465 # ifdef DIAGNOSTIC 466 printf("NetBSD/mac68k does not trust itself to update the " 467 "RTC on shutdown.\n"); 468 # endif 469 } 470 471 /* Disable interrupts. */ 472 splhigh(); 473 474 /* If rebooting and a dump is requested, do it. */ 475 if (howto & RB_DUMP) 476 dumpsys(); 477 478 haltsys: 479 /* Run any shutdown hooks. */ 480 doshutdownhooks(); 481 482 pmf_system_shutdown(boothowto); 483 484 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 485 /* First try to power down under VIA control. */ 486 via_powerdown(); 487 488 #ifndef MRG_ADB 489 /* 490 * Shut down machines whose power functions are accessed 491 * via modified ADB calls. adb_poweroff() is available 492 * only when the MRG ADB is not being used. 493 */ 494 adb_poweroff(); 495 #endif 496 /* 497 * Try to shutdown via the power manager (PowerBooks mainly). 498 */ 499 pm_poweroff(); 500 501 /* 502 * RB_POWERDOWN implies RB_HALT... fall into it... 503 */ 504 } 505 506 if (howto & RB_HALT) { 507 printf("\n"); 508 printf("The operating system has halted.\n"); 509 printf("Please press any key to reboot.\n\n"); 510 cnpollc(1); 511 (void)cngetc(); 512 cnpollc(0); 513 } 514 515 /* Map the last physical page VA = PA for doboot() */ 516 pmap_enter(pmap_kernel(), (vaddr_t)maxaddr, (vaddr_t)maxaddr, 517 VM_PROT_ALL, VM_PROT_ALL|PMAP_WIRED); 518 pmap_update(pmap_kernel()); 519 520 printf("rebooting...\n"); 521 DELAY(1000000); 522 doboot(); 523 /* NOTREACHED */ 524 } 525 526 /* 527 * Initialize the kernel crash dump header. 528 */ 529 void 530 cpu_init_kcore_hdr(void) 531 { 532 extern int end; 533 cpu_kcore_hdr_t *h = &cpu_kcore_hdr; 534 struct m68k_kcore_hdr *m = &h->un._m68k; 535 int i; 536 537 memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr)); 538 539 /* 540 * Initialize the `dispatcher' portion of the header. 541 */ 542 strcpy(h->name, machine); 543 h->page_size = PAGE_SIZE; 544 h->kernbase = KERNBASE; 545 546 /* 547 * Fill in information about our MMU configuration. 548 */ 549 m->mmutype = mmutype; 550 m->sg_v = SG_V; 551 m->sg_frame = SG_FRAME; 552 m->sg_ishift = SG_ISHIFT; 553 m->sg_pmask = SG_PMASK; 554 m->sg40_shift1 = SG4_SHIFT1; 555 m->sg40_mask2 = SG4_MASK2; 556 m->sg40_shift2 = SG4_SHIFT2; 557 m->sg40_mask3 = SG4_MASK3; 558 m->sg40_shift3 = SG4_SHIFT3; 559 m->sg40_addr1 = SG4_ADDR1; 560 m->sg40_addr2 = SG4_ADDR2; 561 m->pg_v = PG_V; 562 m->pg_frame = PG_FRAME; 563 564 /* 565 * Initialize pointer to kernel segment table. 566 */ 567 m->sysseg_pa = (u_int32_t)(pmap_kernel()->pm_stpa); 568 569 /* 570 * Initialize relocation value such that: 571 * 572 * pa = (va - KERNBASE) + reloc 573 */ 574 m->reloc = load_addr; 575 576 /* 577 * Define the end of the relocatable range. 578 */ 579 m->relocend = (u_int32_t)&end; 580 581 /* 582 * mac68k has multiple RAM segments on some models. 583 */ 584 for (i = 0; i < numranges; i++) { 585 m->ram_segs[i].start = low[i]; 586 m->ram_segs[i].size = high[i] - low[i]; 587 } 588 } 589 590 /* 591 * Compute the size of the machine-dependent crash dump header. 592 * Returns size in disk blocks. 593 */ 594 595 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t))) 596 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1)) 597 598 int 599 cpu_dumpsize(void) 600 { 601 602 return btodb(MDHDRSIZE); 603 } 604 605 /* 606 * Called by dumpsys() to dump the machine-dependent header. 607 */ 608 int 609 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop) 610 { 611 int buf[MDHDRSIZE / sizeof(int)]; 612 cpu_kcore_hdr_t *chdr; 613 kcore_seg_t *kseg; 614 int error; 615 616 kseg = (kcore_seg_t *)buf; 617 chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) / 618 sizeof(int)]; 619 620 /* Create the segment header. */ 621 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 622 kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t)); 623 624 memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t)); 625 error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf)); 626 *blknop += btodb(sizeof(buf)); 627 return (error); 628 } 629 630 /* 631 * These variables are needed by /sbin/savecore 632 */ 633 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 634 int dumpsize = 0; /* pages */ 635 long dumplo = 0; /* blocks */ 636 637 /* 638 * This is called by main to set dumplo and dumpsize. 639 * Dumps always skip the first PAGE_SIZE of disk space in 640 * case there might be a disk label stored there. If there 641 * is extra space, put dump at the end to reduce the chance 642 * that swapping trashes it. 643 */ 644 void 645 cpu_dumpconf(void) 646 { 647 cpu_kcore_hdr_t *h = &cpu_kcore_hdr; 648 struct m68k_kcore_hdr *m = &h->un._m68k; 649 int chdrsize; /* size of dump header */ 650 int nblks; /* size of dump area */ 651 int i; 652 653 if (dumpdev == NODEV) 654 return; 655 656 nblks = bdev_size(dumpdev); 657 chdrsize = cpu_dumpsize(); 658 659 dumpsize = 0; 660 for (i = 0; i < M68K_NPHYS_RAM_SEGS && m->ram_segs[i].size; i++) 661 dumpsize += btoc(m->ram_segs[i].size); 662 663 /* 664 * Check to see if we will fit. Note we always skip the 665 * first PAGE_SIZE in case there is a disk label there. 666 */ 667 if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) { 668 dumpsize = 0; 669 dumplo = -1; 670 return; 671 } 672 673 /* 674 * Put dump at the end of the partition. 675 */ 676 dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize; 677 } 678 679 void 680 dumpsys(void) 681 { 682 cpu_kcore_hdr_t *h = &cpu_kcore_hdr; 683 struct m68k_kcore_hdr *m = &h->un._m68k; 684 const struct bdevsw *bdev; 685 daddr_t blkno; /* current block to write */ 686 /* dump routine */ 687 int (*dump)(dev_t, daddr_t, void *, size_t); 688 int pg; /* page being dumped */ 689 paddr_t maddr; /* PA being dumped */ 690 int seg; /* RAM segment being dumped */ 691 int error; /* error code from (*dump)() */ 692 693 /* XXX initialized here because of gcc lossage */ 694 seg = 0; 695 maddr = m->ram_segs[seg].start; 696 pg = 0; 697 698 /* Make sure dump device is valid. */ 699 if (dumpdev == NODEV) 700 return; 701 bdev = bdevsw_lookup(dumpdev); 702 if (bdev == NULL) 703 return; 704 if (dumpsize == 0) { 705 cpu_dumpconf(); 706 if (dumpsize == 0) 707 return; 708 } 709 if (dumplo <= 0) { 710 printf("\ndump to dev %u,%u not possible\n", 711 major(dumpdev), minor(dumpdev)); 712 return; 713 } 714 dump = bdev->d_dump; 715 blkno = dumplo; 716 717 printf("\ndumping to dev %u,%u offset %ld\n", 718 major(dumpdev), minor(dumpdev), dumplo); 719 720 printf("dump "); 721 722 /* Write the dump header. */ 723 error = cpu_dump(dump, &blkno); 724 if (error) 725 goto bad; 726 727 for (pg = 0; pg < dumpsize; pg++) { 728 #define NPGMB (1024*1024/PAGE_SIZE) 729 /* print out how many MBs we have dumped */ 730 if (pg && (pg % NPGMB) == 0) 731 printf("%d ", pg / NPGMB); 732 #undef NPGMB 733 while (maddr >= 734 (m->ram_segs[seg].start + m->ram_segs[seg].size)) { 735 if (++seg >= M68K_NPHYS_RAM_SEGS || 736 m->ram_segs[seg].size == 0) { 737 error = EINVAL; /* XXX ?? */ 738 goto bad; 739 } 740 maddr = m->ram_segs[seg].start; 741 } 742 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr, 743 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 744 pmap_update(pmap_kernel()); 745 746 error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE); 747 bad: 748 switch (error) { 749 case 0: 750 maddr += PAGE_SIZE; 751 blkno += btodb(PAGE_SIZE); 752 break; 753 754 case ENXIO: 755 printf("device bad\n"); 756 return; 757 758 case EFAULT: 759 printf("device not ready\n"); 760 return; 761 762 case EINVAL: 763 printf("area improper\n"); 764 return; 765 766 case EIO: 767 printf("i/o error\n"); 768 return; 769 770 case EINTR: 771 printf("aborted from console\n"); 772 return; 773 774 default: 775 printf("error %d\n", error); 776 return; 777 } 778 } 779 printf("succeeded\n"); 780 } 781 782 void straytrap(int, int); 783 784 void 785 straytrap(int pc, int evec) 786 { 787 printf("unexpected trap; vector offset 0x%x from 0x%x.\n", 788 (int)(evec & 0xfff), pc); 789 #ifdef DDB 790 Debugger(); 791 #endif 792 } 793 794 /* 795 * Level 7 interrupts can be caused by the keyboard or parity errors. 796 */ 797 void nmihand(struct frame); 798 799 void 800 nmihand(struct frame frame) 801 { 802 static int nmihanddeep = 0; 803 804 if (nmihanddeep++) 805 return; 806 /* regdump((struct trapframe *)&frame, 128); 807 dumptrace(); */ 808 #ifdef DDB 809 printf("Panic switch: PC is 0x%x.\n", frame.f_pc); 810 Debugger(); 811 #endif 812 nmihanddeep = 0; 813 } 814 815 /* 816 * It should be possible to probe for the top of RAM, but Apple has 817 * memory structured so that in at least some cases, it's possible 818 * for RAM to be aliased across all memory--or for it to appear that 819 * there is more RAM than there really is. 820 */ 821 int get_top_of_ram(void); 822 823 int 824 get_top_of_ram(void) 825 { 826 return ((mac68k_machine.mach_memsize * (1024 * 1024)) - PAGE_SIZE); 827 } 828 829 /* 830 * machine dependent system variables. 831 */ 832 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 833 { 834 835 sysctl_createv(clog, 0, NULL, NULL, 836 CTLFLAG_PERMANENT, 837 CTLTYPE_NODE, "machdep", NULL, 838 NULL, 0, NULL, 0, 839 CTL_MACHDEP, CTL_EOL); 840 841 sysctl_createv(clog, 0, NULL, NULL, 842 CTLFLAG_PERMANENT, 843 CTLTYPE_STRUCT, "console_device", NULL, 844 sysctl_consdev, 0, NULL, sizeof(dev_t), 845 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 846 } 847 848 int 849 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 850 { 851 int error = ENOEXEC; 852 853 #ifdef COMPAT_NOMID 854 /* Check to see if MID == 0. */ 855 if (((struct exec *)epp->ep_hdr)->a_midmag == ZMAGIC) 856 return exec_aout_prep_oldzmagic(l, epp); 857 #endif 858 859 return error; 860 } 861 862 #ifdef MODULAR 863 /* 864 * Push any modules loaded by the bootloader etc. 865 */ 866 void 867 module_init_md(void) 868 { 869 } 870 #endif 871 872 static char *envbuf = NULL; 873 874 /* 875 * getenvvars: Grab a few useful variables 876 */ 877 878 void 879 getenvvars(u_long flag, char *buf) 880 { 881 extern u_long bootdev; 882 extern u_long macos_boottime, MacOSROMBase; 883 extern long macos_gmtbias; 884 int root_scsi_id; 885 u_long root_ata_dev; 886 int i; 887 Elf_Ehdr *ehdr; 888 Elf_Shdr *shp; 889 vaddr_t minsym; 890 891 /* 892 * If flag & 0x80000000 == 0, then we're booting with the old booter 893 * and we should freak out. 894 */ 895 if ((flag & 0x80000000) == 0) { 896 /* Freak out; print something if that becomes available */ 897 } else 898 envbuf = buf; 899 900 /* These next two should give us mapped video & serial */ 901 /* We need these for pre-mapping graybars & echo, but probably */ 902 /* only on MacII or LC. -- XXX */ 903 /* mac68k_video.mv_kvaddr = getenv("MACOS_VIDEO"); */ 904 905 mac68k_video.mv_kvaddr = getenv("VIDEO_ADDR"); 906 mac68k_video.mv_stride = getenv("ROW_BYTES"); 907 mac68k_video.mv_depth = getenv("SCREEN_DEPTH"); 908 mac68k_video.mv_width = getenv("DIMENSIONS") & 0xffff; 909 mac68k_video.mv_height = (getenv("DIMENSIONS") >> 16) & 0xffff; 910 911 /* 912 * More misc stuff from booter. 913 */ 914 mac68k_machine.machineid = machineid = getenv("MACHINEID"); 915 mac68k_machine.mach_processor = getenv("PROCESSOR"); 916 #ifndef MAC68K_MEMSIZE 917 mac68k_machine.mach_memsize = getenv("MEMSIZE"); 918 #else 919 mac68k_machine.mach_memsize = MAC68K_MEMSIZE; 920 #endif 921 mac68k_machine.do_graybars = getenv("GRAYBARS"); 922 mac68k_machine.serial_boot_echo = getenv("SERIALECHO"); 923 mac68k_machine.serial_console = getenv("SERIALCONSOLE"); 924 925 mac68k_machine.modem_flags = getenv("SERIAL_MODEM_FLAGS"); 926 mac68k_machine.modem_cts_clk = getenv("SERIAL_MODEM_HSKICLK"); 927 mac68k_machine.modem_dcd_clk = getenv("SERIAL_MODEM_GPICLK"); 928 mac68k_machine.modem_d_speed = getenv("SERIAL_MODEM_DSPEED"); 929 mac68k_machine.print_flags = getenv("SERIAL_PRINT_FLAGS"); 930 mac68k_machine.print_cts_clk = getenv("SERIAL_PRINT_HSKICLK"); 931 mac68k_machine.print_dcd_clk = getenv("SERIAL_PRINT_GPICLK"); 932 mac68k_machine.print_d_speed = getenv("SERIAL_PRINT_DSPEED"); 933 mac68k_machine.booter_version = getenv("BOOTERVER"); 934 935 /* 936 * For now, we assume that the boot device is off the first controller. 937 * Booter versions 1.11.0 and later set a flag to tell us to construct 938 * bootdev using the SCSI ID passed in via the environment. 939 */ 940 root_scsi_id = getenv("ROOT_SCSI_ID"); 941 root_ata_dev = getenv("ROOT_ATA_DEV"); 942 if (((mac68k_machine.booter_version < CURRENTBOOTERVER) || 943 (flag & 0x40000)) && bootdev == 0) { 944 if (root_ata_dev) { 945 /* 946 * Consider only internal IDE drive. 947 * Buses(=channel) will be always 0. 948 * Because 68k Mac has only single channel. 949 */ 950 switch (root_ata_dev) { 951 default: /* fall through */ 952 case 0xffffffe0: /* buses,drive = 0,0 */ 953 case 0x20: /* buses,drive = 1,0 */ 954 case 0x21: /* buses,drive = 1,1 */ 955 bootdev = MAKEBOOTDEV(22, 0, 0, 0, 0); 956 break; 957 case 0xffffffe1: /* buses,drive = 0,1 */ 958 bootdev = MAKEBOOTDEV(22, 0, 0, 1, 0); 959 break; 960 } 961 } else { 962 bootdev = MAKEBOOTDEV(4, 0, 0, root_scsi_id, 0); 963 } 964 } 965 966 /* 967 * Booter 1.11.3 and later pass a BOOTHOWTO variable with the 968 * appropriate bits set. 969 */ 970 boothowto = getenv("BOOTHOWTO"); 971 if (boothowto == 0) 972 boothowto = getenv("SINGLE_USER"); 973 974 /* 975 * Get end of symbols for kernel debugging 976 */ 977 esym = (int *)getenv("END_SYM"); 978 #ifndef makeoptions_COPY_SYMTAB 979 if (esym == (int *)0) 980 #endif 981 esym = (int *)&end; 982 983 /* Get MacOS time */ 984 macos_boottime = getenv("BOOTTIME"); 985 986 /* Save GMT BIAS saved in Booter parameters dialog box */ 987 macos_gmtbias = getenv("GMTBIAS"); 988 989 /* 990 * Save globals stolen from MacOS 991 */ 992 993 ROMBase = (void *)getenv("ROMBASE"); 994 if (ROMBase == (void *)0) { 995 ROMBase = (void *)ROMBASE; 996 } 997 MacOSROMBase = (unsigned long)ROMBase; 998 TimeDBRA = getenv("TIMEDBRA"); 999 ADBDelay = (u_short)getenv("ADBDELAY"); 1000 HwCfgFlags = getenv("HWCFGFLAGS"); 1001 HwCfgFlags2 = getenv("HWCFGFLAG2"); 1002 HwCfgFlags3 = getenv("HWCFGFLAG3"); 1003 ADBReInit_JTBL = getenv("ADBREINIT_JTBL"); 1004 mrg_ADBIntrPtr = (void *)getenv("ADBINTERRUPT"); 1005 1006 /* 1007 * Check the ELF headers. 1008 */ 1009 1010 ehdr = (void *)getenv("MARK_SYM"); 1011 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 || 1012 ehdr->e_ident[EI_CLASS] != ELFCLASS32) { 1013 return; 1014 } 1015 1016 /* 1017 * Find the end of the symbols and strings. 1018 */ 1019 1020 minsym = ~0; 1021 shp = (Elf_Shdr *)(end + ehdr->e_shoff); 1022 for (i = 0; i < ehdr->e_shnum; i++) { 1023 if (shp[i].sh_type != SHT_SYMTAB && 1024 shp[i].sh_type != SHT_STRTAB) { 1025 continue; 1026 } 1027 minsym = MIN(minsym, (vaddr_t)end + shp[i].sh_offset); 1028 } 1029 1030 symsize = 1; 1031 ssym = (int *)ehdr; 1032 } 1033 1034 static long 1035 getenv(const char *str) 1036 { 1037 /* 1038 * Returns the value of the environment variable "str". 1039 * 1040 * Format of the buffer is "var=val\0var=val\0...\0var=val\0\0". 1041 * 1042 * Returns 0 if the variable is not there, and 1 if the variable is 1043 * there without an "=val". 1044 */ 1045 1046 char *s; 1047 const char *s1; 1048 int val, base; 1049 1050 s = envbuf; 1051 while (1) { 1052 for (s1 = str; *s1 && *s && *s != '='; s1++, s++) { 1053 if (toupper(*s1) != toupper(*s)) { 1054 break; 1055 } 1056 } 1057 if (*s1) { /* No match */ 1058 while (*s) { 1059 s++; 1060 } 1061 s++; 1062 if (*s == '\0') { /* Not found */ 1063 /* Boolean flags are false (0) if not there */ 1064 return 0; 1065 } 1066 continue; 1067 } 1068 if (*s == '=') {/* Has a value */ 1069 s++; 1070 val = 0; 1071 base = 10; 1072 if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) { 1073 base = 16; 1074 s += 2; 1075 } else 1076 if (*s == '0') { 1077 base = 8; 1078 } 1079 while (*s) { 1080 if (toupper(*s) >= 'A' && toupper(*s) <= 'F') { 1081 val = val * base + toupper(*s) - 'A' + 10; 1082 } else { 1083 val = val * base + (*s - '0'); 1084 } 1085 s++; 1086 } 1087 return val; 1088 } else { /* TRUE (1) */ 1089 return 1; 1090 } 1091 } 1092 } 1093 1094 /* 1095 * ROM Vector information for calling drivers in ROMs 1096 * 1097 * According to information published on the Web by Apple, there have 1098 * been 9 different ROM families used in the Mac since the introduction 1099 * of the Lisa/XL through the latest PowerMacs (May 96). Each family 1100 * has zero or more version variants and in some cases a version variant 1101 * may exist in one than one length format. Generally any one specific 1102 * Mac will use a common set of routines within the ROM and a model-specific 1103 * set also in the ROM. Luckily most of the routines used by NetBSD fall 1104 * into the common set and can therefore be defined in the ROM Family. 1105 * The offset addresses (address minus the ROM Base) of these common routines 1106 * is the same for all machines which use that ROM. The offset addresses of 1107 * the machine-specific routines is generally different for each machine. 1108 * The machine-specific routines currently used by NetBSD/mac68k include: 1109 * ADB_interrupt, PM_interrupt, ADBBase+130_interrupt, 1110 * PMgrOp, jClkNoMem, Egret, InitEgret, and ADBReInit_JTBL 1111 * 1112 * It is possible that the routine at "jClkNoMem" is a common routine, but 1113 * some variation in addresses has been seen. Also, execept for the very 1114 * earliest machines which used Egret, the machine-specific value of the 1115 * Egret routine may be unimportant as the machine-specific InitEgret code 1116 * seems to always set the OS Trap vector for Egret. 1117 * 1118 * Only three of the nine different ROMs are important to NetBSD/mac68k. 1119 * All other ROMs are used in early model Macs which are unable to run 1120 * NetBSD due to other hardware limitations such as 68000 CPU, no MMU 1121 * capability, or used only in PowerMacs. The three that we are interested 1122 * in are: 1123 * 1124 * ROM Family $0178 - used in the II, IIx, IIcx, and SE/30 1125 * All machines which use this ROM are now supported by NetBSD. 1126 * There are no machine-dependent routines in these ROMs used by 1127 * NetBSD/mac68k. This ROM is always 256K in length. 1128 * 1129 * ROM Family $067c - used in Classic, Color Classic, Color Classic II, 1130 * IIci, IIsi, IIvi, IIvx, IIfx, LC, LC II, LC III, 1131 * LC III+, LC475, LC520, LC550, LC575, LC580, LC630, 1132 * MacTV, P200, P250, P275, P400/405/410/430, P450, 1133 * P460/466/467, P475/476, P520, P550/560, P575/577/578, 1134 * P580/588, P600, P630/631/635/636/637/638/640, Q605, 1135 * Q610, C610, Q630, C650, Q650, Q700, Q800, Q900, Q950, 1136 * PB140, PB145/145B, PB150, PB160, PB165, PB165c, PB170, 1137 * PB180, PB180c, Duo 210, Duo 230, Duo 250, Duo 270c, 1138 * Duo280, Duo 280c, PB 520/520c/540/540c/550 1139 * This is the so-called "Universal" ROM used in almost all 68K 1140 * machines. There are machine-dependent and machine-independent 1141 * routines used by NetBSD/mac68k in this ROM, and except for the 1142 * PowerBooks and the Duos, this ROM seems to be fairly well 1143 * known by NetBSD/mac68k. Desktop machines listed here that are 1144 * not yet running NetBSD probably only lack the necessary 1145 * addresses for the machine-dependent routines, or are waiting 1146 * for IDE disk support. This ROM is generally 1Meg in length, 1147 * however when used in the IIci, IIfx, IIsi, LC, Classic II, and 1148 * P400/405/410/430 it is 512K in length, and when used in the 1149 * PB 520/520c/540/540c/550 it is 2Meg in length. 1150 * 1151 * ROM Family - $077d - used in C660AV/Q660AV, Q840AV 1152 * The "Universal" ROM used on the PowerMacs and used in the 1153 * 68K line for the AV Macs only. When used in the 68K AV 1154 * machines the ROM is 2Meg in length; all uses in the PowerMac 1155 * use a length of 4Meg. 1156 * 1157 * Bob Nestor - <rnestor@metronet.com> 1158 */ 1159 static romvec_t romvecs[] = 1160 { 1161 /* Vectors verified for II, IIx, IIcx, SE/30 */ 1162 { /* 0 */ 1163 "Mac II class ROMs", 1164 (void *)0x40807002, /* where does ADB interrupt */ 1165 (void *)0x0, /* PM interrupt (?) */ 1166 (void *)0x4080a4d8, /* ADBBase + 130 interrupt; whatzit? */ 1167 (void *)0x40807778, /* CountADBs */ 1168 (void *)0x40807792, /* GetIndADB */ 1169 (void *)0x408077be, /* GetADBInfo */ 1170 (void *)0x408077c4, /* SetADBInfo */ 1171 (void *)0x40807704, /* ADBReInit */ 1172 (void *)0x408072fa, /* ADBOp */ 1173 (void *)0x0, /* PMgrOp */ 1174 (void *)0x4080d6d0, /* WriteParam */ 1175 (void *)0x4080d6fa, /* SetDateTime */ 1176 (void *)0x4080dbe8, /* InitUtil */ 1177 (void *)0x4080dd78, /* ReadXPRam */ 1178 (void *)0x4080dd82, /* WriteXPRam */ 1179 (void *)0x4080ddd6, /* jClkNoMem */ 1180 (void *)0x0, /* ADBAlternateInit */ 1181 (void *)0x0, /* Egret */ 1182 (void *)0x0, /* InitEgret */ 1183 (void *)0x0, /* ADBReInit_JTBL */ 1184 (void *)0x0, /* ROMResourceMap List Head */ 1185 (void *)0x40814c58, /* FixDiv */ 1186 (void *)0x40814b64, /* FixMul */ 1187 }, 1188 /* 1189 * Vectors verified for PB 140, PB 145, PB 170 1190 * (PB 100?) 1191 */ 1192 { /* 1 */ 1193 "Powerbook class ROMs", 1194 (void *)0x4088ae5e, /* ADB interrupt */ 1195 (void *)0x408885ec, /* PB ADB interrupt */ 1196 (void *)0x4088ae0e, /* ADBBase + 130 interrupt; whatzit? */ 1197 (void *)0x4080a360, /* CountADBs */ 1198 (void *)0x4080a37a, /* GetIndADB */ 1199 (void *)0x4080a3a6, /* GetADBInfo */ 1200 (void *)0x4080a3ac, /* SetADBInfo */ 1201 (void *)0x4080a752, /* ADBReInit */ 1202 (void *)0x4080a3dc, /* ADBOp */ 1203 (void *)0x408888ec, /* PMgrOp */ 1204 (void *)0x4080c05c, /* WriteParam */ 1205 (void *)0x4080c086, /* SetDateTime */ 1206 (void *)0x4080c5cc, /* InitUtil */ 1207 (void *)0x4080b186, /* ReadXPRam */ 1208 (void *)0x4080b190, /* WriteXPRam */ 1209 (void *)0x4080b1e4, /* jClkNoMem */ 1210 (void *)0x4080a818, /* ADBAlternateInit */ 1211 (void *)0x40814800, /* Egret */ 1212 (void *)0x408147c4, /* InitEgret */ 1213 (void *)0x0, /* ADBReInit_JTBL */ 1214 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1215 (void *)0x4081c406, /* FixDiv */ 1216 (void *)0x4081c312, /* FixMul */ 1217 }, 1218 /* 1219 * Vectors verified for IIsi, IIvx, IIvi 1220 */ 1221 { /* 2 */ 1222 "Mac IIsi class ROMs", 1223 (void *)0x40814912, /* ADB interrupt */ 1224 (void *)0x0, /* PM ADB interrupt */ 1225 (void *)0x408150f0, /* ADBBase + 130 interrupt; whatzit? */ 1226 (void *)0x4080a360, /* CountADBs */ 1227 (void *)0x4080a37a, /* GetIndADB */ 1228 (void *)0x4080a3a6, /* GetADBInfo */ 1229 (void *)0x4080a3ac, /* SetADBInfo */ 1230 (void *)0x4080a752, /* ADBReInit */ 1231 (void *)0x4080a3dc, /* ADBOp */ 1232 (void *)0x0, /* PMgrOp */ 1233 (void *)0x4080c05c, /* WriteParam */ 1234 (void *)0x4080c086, /* SetDateTime */ 1235 (void *)0x4080c5cc, /* InitUtil */ 1236 (void *)0x4080b186, /* ReadXPRam */ 1237 (void *)0x4080b190, /* WriteXPRam */ 1238 (void *)0x4080b1e4, /* jClkNoMem */ 1239 (void *)0x4080a818, /* ADBAlternateInit */ 1240 (void *)0x40814800, /* Egret */ 1241 (void *)0x408147c4, /* InitEgret */ 1242 (void *)0x0, /* ADBReInit_JTBL */ 1243 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1244 (void *)0x4081c406, /* FixDiv */ 1245 (void *)0x4081c312, /* FixMul */ 1246 }, 1247 /* 1248 * Vectors verified for Mac Classic II and LC II 1249 * (Other LC's? 680x0 Performas?) 1250 */ 1251 { /* 3 */ 1252 "Mac Classic II ROMs", 1253 (void *)0x40a14912, /* ADB interrupt */ 1254 (void *)0x0, /* PM ADB interrupt */ 1255 (void *)0x40a150f0, /* ADBBase + 130 interrupt; whatzit? */ 1256 (void *)0x40a0a360, /* CountADBs */ 1257 (void *)0x40a0a37a, /* GetIndADB */ 1258 (void *)0x40a0a3a6, /* GetADBInfo */ 1259 (void *)0x40a0a3ac, /* SetADBInfo */ 1260 (void *)0x40a0a752, /* ADBReInit */ 1261 (void *)0x40a0a3dc, /* ADBOp */ 1262 (void *)0x0, /* PMgrOp */ 1263 (void *)0x40a0c05c, /* WriteParam */ 1264 (void *)0x40a0c086, /* SetDateTime */ 1265 (void *)0x40a0c5cc, /* InitUtil */ 1266 (void *)0x40a0b186, /* ReadXPRam */ 1267 (void *)0x40a0b190, /* WriteXPRam */ 1268 (void *)0x40a0b1e4, /* jClkNoMem */ 1269 (void *)0x40a0a818, /* ADBAlternateInit */ 1270 (void *)0x40a14800, /* Egret */ 1271 (void *)0x40a147c4, /* InitEgret */ 1272 (void *)0x40a03ba6, /* ADBReInit_JTBL */ 1273 (void *)0x40a7eb90, /* ROMResourceMap List Head */ 1274 (void *)0x40a1c406, /* FixDiv, wild guess */ 1275 (void *)0x40a1c312, /* FixMul, wild guess */ 1276 }, 1277 /* 1278 * Vectors verified for IIci, Q700 1279 */ 1280 { /* 4 */ 1281 "Mac IIci/Q700 ROMs", 1282 (void *)0x4080a700, /* ADB interrupt */ 1283 (void *)0x0, /* PM ADB interrupt */ 1284 (void *)0x4080a5aa, /* ADBBase + 130 interrupt; whatzit? */ 1285 (void *)0x4080a360, /* CountADBs */ 1286 (void *)0x4080a37a, /* GetIndADB */ 1287 (void *)0x4080a3a6, /* GetADBInfo */ 1288 (void *)0x4080a3ac, /* SetADBInfo */ 1289 (void *)0x4080a752, /* ADBReInit */ 1290 (void *)0x4080a3dc, /* ADBOp */ 1291 (void *)0x0, /* PMgrOp */ 1292 (void *)0x4080c05c, /* WriteParam */ 1293 (void *)0x4080c086, /* SetDateTime */ 1294 (void *)0x4080c5cc, /* InitUtil */ 1295 (void *)0x4080b186, /* ReadXPRam */ 1296 (void *)0x4080b190, /* WriteXPRam */ 1297 (void *)0x4080b1e4, /* jClkNoMem */ 1298 (void *)0x4080a818, /* ADBAlternateInit */ 1299 (void *)0x0, /* Egret */ 1300 (void *)0x408147c4, /* InitEgret */ 1301 (void *)0x0, /* ADBReInit_JTBL */ 1302 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1303 (void *)0x4081c406, /* FixDiv */ 1304 (void *)0x4081c312, /* FixMul */ 1305 }, 1306 /* 1307 * Vectors verified for Duo 230, PB 180, PB 160, PB 165/165C 1308 * (Duo 210? Duo 250? Duo 270?) 1309 */ 1310 { /* 5 */ 1311 "2nd Powerbook class ROMs", 1312 (void *)0x408b2eec, /* ADB interrupt */ 1313 (void *)0x408885ec, /* PB ADB interrupt */ 1314 (void *)0x408b2e76, /* ADBBase + 130 interrupt; whatzit? */ 1315 (void *)0x4080a360, /* CountADBs */ 1316 (void *)0x4080a37a, /* GetIndADB */ 1317 (void *)0x4080a3a6, /* GetADBInfo */ 1318 (void *)0x4080a3ac, /* SetADBInfo */ 1319 (void *)0x4080a752, /* ADBReInit */ 1320 (void *)0x4080a3dc, /* ADBOp */ 1321 (void *)0x408888ec, /* PMgrOp */ 1322 (void *)0x4080c05c, /* WriteParam */ 1323 (void *)0x4080c086, /* SetDateTime */ 1324 (void *)0x4080c5cc, /* InitUtil */ 1325 (void *)0x4080b186, /* ReadXPRam */ 1326 (void *)0x4080b190, /* WriteXPRam */ 1327 (void *)0x408b39b2, /* jClkNoMem */ /* From PB180 */ 1328 (void *)0x4080a818, /* ADBAlternateInit */ 1329 (void *)0x40814800, /* Egret */ 1330 (void *)0x40888400, /* InitPwrMgr */ /* From PB180 */ 1331 (void *)0x408cce28, /* ADBReInit_JTBL -- from PB160*/ 1332 (void *)0x4087eb90, /* ROMRsrcMap List Head -- from PB160*/ 1333 (void *)0x4081c406, /* FixDiv, wild guess */ 1334 (void *)0x4081c312, /* FixMul, wild guess */ 1335 }, 1336 /* 1337 * Vectors verified for the Quadra, Centris 650 1338 * (610, Q800?) 1339 */ 1340 { /* 6 */ 1341 "Quadra/Centris ROMs", 1342 (void *)0x408b2dea, /* ADB int */ 1343 (void *)0x0, /* PM intr */ 1344 (void *)0x408b2c72, /* ADBBase + 130 */ 1345 (void *)0x4080a360, /* CountADBs */ 1346 (void *)0x4080a37a, /* GetIndADB */ 1347 (void *)0x4080a3a6, /* GetADBInfo */ 1348 (void *)0x4080a3ac, /* SetADBInfo */ 1349 (void *)0x4080a752, /* ADBReInit */ 1350 (void *)0x4080a3dc, /* ADBOp */ 1351 (void *)0x40809ae6, /* PMgrOp */ 1352 (void *)0x4080c05c, /* WriteParam */ 1353 (void *)0x4080c086, /* SetDateTime */ 1354 (void *)0x4080c5cc, /* InitUtil */ 1355 (void *)0x4080b186, /* ReadXPRam */ 1356 (void *)0x4080b190, /* WriteXPRam */ 1357 (void *)0x408b39b6, /* jClkNoMem */ 1358 (void *)0x4080a818, /* ADBAlternateInit */ 1359 (void *)0x40814800, /* Egret */ 1360 (void *)0x408147c4, /* InitEgret */ 1361 (void *)0x408d2b64, /* ADBReInit_JTBL */ 1362 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1363 (void *)0x4081c406, /* FixDiv, wild guess */ 1364 (void *)0x4081c312, /* FixMul, wild guess */ 1365 }, 1366 /* 1367 * Vectors verified for the Quadra 660AV 1368 * (Quadra 840AV?) 1369 */ 1370 { /* 7 */ 1371 "Quadra AV ROMs", 1372 (void *)0x4080cac6, /* ADB int */ 1373 (void *)0x0, /* PM int */ 1374 (void *)0x40805cd4, /* ADBBase + 130 */ 1375 (void *)0x40839600, /* CountADBs */ 1376 (void *)0x4083961a, /* GetIndADB */ 1377 (void *)0x40839646, /* GetADBInfo */ 1378 (void *)0x4083964c, /* SetADBInfo */ 1379 (void *)0x408397b8, /* ADBReInit */ 1380 (void *)0x4083967c, /* ADBOp */ 1381 (void *)0x0, /* PMgrOp */ 1382 (void *)0x4081141c, /* WriteParam */ 1383 (void *)0x4081144e, /* SetDateTime */ 1384 (void *)0x40811930, /* InitUtil */ 1385 (void *)0x4080b624, /* ReadXPRam */ 1386 (void *)0x4080b62e, /* WriteXPRam */ 1387 (void *)0x40806884, /* jClkNoMem */ 1388 (void *)0x408398c2, /* ADBAlternateInit */ 1389 (void *)0x4080cada, /* Egret */ 1390 (void *)0x4080de14, /* InitEgret */ 1391 (void *)0x408143b8, /* ADBReInit_JTBL */ 1392 (void *)0x409bdb60, /* ROMResourceMap List Head */ 1393 (void *)0x4083b3d8, /* FixDiv */ 1394 (void *)0x4083b2e4, /* FixMul */ 1395 }, 1396 /* 1397 * PB 540, PB 550 1398 * (PB 520? Duo 280?) 1399 */ 1400 { /* 8 */ 1401 "68040 PowerBook ROMs", 1402 (void *)0x400b2efc, /* ADB int */ 1403 (void *)0x400d8e66, /* PM int */ 1404 (void *)0x400b2e86, /* ADBBase + 130 */ 1405 (void *)0x4000a360, /* CountADBs */ 1406 (void *)0x4000a37a, /* GetIndADB */ 1407 (void *)0x4000a3a6, /* GetADBInfo */ 1408 (void *)0x4000a3ac, /* SetADBInfo */ 1409 (void *)0x4000a752, /* ADBReInit */ 1410 (void *)0x4000a3dc, /* ADBOp */ 1411 (void *)0x400d9302, /* PmgrOp */ 1412 (void *)0x4000c05c, /* WriteParam */ 1413 (void *)0x4000c086, /* SetDateTime */ 1414 (void *)0x4000c5cc, /* InitUtil */ 1415 (void *)0x4000b186, /* ReadXPRam */ 1416 (void *)0x4000b190, /* WriteXPRam */ 1417 (void *)0x400b3c08, /* jClkNoMem */ 1418 (void *)0x4000a818, /* ADBAlternateInit */ 1419 (void *)0x40009ae6, /* Egret */ /* From PB520 */ 1420 (void *)0x400147c4, /* InitEgret */ 1421 (void *)0x400a7a5c, /* ADBReInit_JTBL */ 1422 (void *)0x4007eb90, /* ROMResourceMap List Head */ 1423 (void *)0x4001c406, /* FixDiv, wild guess */ 1424 (void *)0x4001c312, /* FixMul, wild guess */ 1425 }, 1426 /* 1427 * Verified for the Q605 1428 */ 1429 { /* 9 */ 1430 "Quadra/Centris 605 ROMs", 1431 (void *)0x408a9b56, /* ADB int */ 1432 (void *)0x0, /* PM int */ 1433 (void *)0x408b2f94, /* ADBBase + 130 */ 1434 (void *)0x4080a360, /* CountADBs */ 1435 (void *)0x4080a37a, /* GetIndADB */ 1436 (void *)0x4080a3a6, /* GetADBInfo */ 1437 (void *)0x4080a3ac, /* SetADBInfo */ 1438 (void *)0x4080a752, /* ADBReInit */ 1439 (void *)0x4080a3dc, /* ADBOp */ 1440 (void *)0x0, /* PmgrOp */ 1441 (void *)0x4080c05c, /* WriteParam */ 1442 (void *)0x4080c086, /* SetDateTime */ 1443 (void *)0x4080c5cc, /* InitUtil */ 1444 (void *)0x4080b186, /* ReadXPRam */ 1445 (void *)0x4080b190, /* WriteXPRam */ 1446 (void *)0x408b3bf8, /* jClkNoMem */ 1447 (void *)0x4080a818, /* ADBAlternateInit */ 1448 (void *)0x408a99c0, /* Egret */ 1449 (void *)0x408147c4, /* InitEgret */ 1450 (void *)0x408a82c0, /* ADBReInit_JTBL */ 1451 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1452 (void *)0x4081c406, /* FixDiv */ 1453 (void *)0x4081c312, /* FixMul */ 1454 }, 1455 /* 1456 * Vectors verified for Duo 270c, PB150 1457 */ 1458 { /* 10 */ 1459 "Duo 270C ROMs", 1460 (void *)0x408b2efc, /* ADB interrupt */ 1461 (void *)0x408885ec, /* PB ADB interrupt */ 1462 (void *)0x408b2e86, /* ADBBase + 130 interrupt; whatzit? */ 1463 (void *)0x4080a360, /* CountADBs */ 1464 (void *)0x4080a37a, /* GetIndADB */ 1465 (void *)0x4080a3a6, /* GetADBInfo */ 1466 (void *)0x4080a3ac, /* SetADBInfo */ 1467 (void *)0x4080a752, /* ADBReInit */ 1468 (void *)0x4080a3dc, /* ADBOp */ 1469 (void *)0x408888ec, /* PMgrOp */ 1470 (void *)0x4080c05c, /* WriteParam */ 1471 (void *)0x4080c086, /* SetDateTime */ 1472 (void *)0x4080c5cc, /* InitUtil */ 1473 (void *)0x4080b186, /* ReadXPRam */ 1474 (void *)0x4080b190, /* WriteXPRam */ 1475 (void *)0x408b3bf8, /* jClkNoMem */ /* from PB 150 */ 1476 (void *)0x4080a818, /* ADBAlternateInit */ 1477 (void *)0x40814800, /* Egret */ 1478 (void *)0x408147c4, /* InitEgret */ 1479 (void *)0x0, /* ADBReInit_JTBL */ 1480 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1481 (void *)0x4081c406, /* FixDiv, wild guess */ 1482 (void *)0x4081c312, /* FixMul, wild guess */ 1483 }, 1484 /* 1485 * Vectors verified for Performa/LC 550 1486 */ 1487 { /* 11 */ 1488 "P/LC 550 ROMs", 1489 (void *)0x408d16d6, /* ADB interrupt */ 1490 (void *)0x0, /* PB ADB interrupt */ 1491 (void *)0x408b2f84, /* ADBBase + 130 interrupt; whatzit? */ 1492 (void *)0x4080a360, /* CountADBs */ 1493 (void *)0x4080a37a, /* GetIndADB */ 1494 (void *)0x4080a3a6, /* GetADBInfo */ 1495 (void *)0x4080a3ac, /* SetADBInfo */ 1496 (void *)0x4080a752, /* ADBReInit */ 1497 (void *)0x4080a3dc, /* ADBOp */ 1498 (void *)0x0, /* PMgrOp */ 1499 (void *)0x4080c05c, /* WriteParam */ 1500 (void *)0x4080c086, /* SetDateTime */ 1501 (void *)0x4080c5cc, /* InitUtil */ 1502 (void *)0x4080b186, /* ReadXPRam */ 1503 (void *)0x4080b190, /* WriteXPRam */ 1504 (void *)0x408b3c04, /* jClkNoMem */ 1505 (void *)0x4080a818, /* ADBAlternateInit */ 1506 (void *)0x408d1450, /* Egret */ 1507 (void *)0x408147c4, /* InitEgret */ 1508 (void *)0x408d24a4, /* ADBReInit_JTBL */ 1509 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1510 (void *)0x4081c406, /* FixDiv for P550 */ 1511 (void *)0x4081c312, /* FixMul for P550 */ 1512 }, 1513 /* 1514 * Vectors verified for the MacTV 1515 */ 1516 { /* 12 */ 1517 "MacTV ROMs", 1518 (void *)0x40acfed6, /* ADB interrupt */ 1519 (void *)0x0, /* PB ADB interrupt */ 1520 (void *)0x40ab2f84, /* ADBBase + 130 interrupt; whatzit? */ 1521 (void *)0x40a0a360, /* CountADBs */ 1522 (void *)0x40a0a37a, /* GetIndADB */ 1523 (void *)0x40a0a3a6, /* GetADBInfo */ 1524 (void *)0x40a0a3ac, /* SetADBInfo */ 1525 (void *)0x40a0a752, /* ADBReInit */ 1526 (void *)0x40a0a3dc, /* ADBOp */ 1527 (void *)0x0, /* PMgrOp */ 1528 (void *)0x40a0c05c, /* WriteParam */ 1529 (void *)0x40a0c086, /* SetDateTime */ 1530 (void *)0x40a0c5cc, /* InitUtil */ 1531 (void *)0x40a0b186, /* ReadXPRam */ 1532 (void *)0x40a0b190, /* WriteXPRam */ 1533 (void *)0x40ab3bf4, /* jClkNoMem */ 1534 (void *)0x40a0a818, /* ADBAlternateInit */ 1535 (void *)0x40acfd40, /* Egret */ 1536 (void *)0x40a147c4, /* InitEgret */ 1537 (void *)0x40a038a0, /* ADBReInit_JTBL */ 1538 (void *)0x40a7eb90, /* ROMResourceMap List Head */ 1539 (void *)0x40a1c406, /* FixDiv */ 1540 (void *)0x40a1c312, /* FixMul */ 1541 }, 1542 /* 1543 * Vectors verified for the Quadra630 1544 */ 1545 { /* 13 */ 1546 "Quadra630 ROMs", 1547 (void *)0x408a9bd2, /* ADB int */ 1548 (void *)0x0, /* PM intr */ 1549 (void *)0x408b2f94, /* ADBBase + 130 */ 1550 (void *)0x4080a360, /* CountADBs */ 1551 (void *)0x4080a37a, /* GetIndADB */ 1552 (void *)0x4080a3a6, /* GetADBInfo */ 1553 (void *)0x4080a3ac, /* SetADBInfo */ 1554 (void *)0x4080a752, /* ADBReInit */ 1555 (void *)0x4080a3dc, /* ADBOp */ 1556 (void *)0, /* PMgrOp */ 1557 (void *)0x4080c05c, /* WriteParam */ 1558 (void *)0x4080c086, /* SetDateTime */ 1559 (void *)0x4080c5cc, /* InitUtil */ 1560 (void *)0x4080b186, /* Wild guess at ReadXPRam */ 1561 (void *)0x4080b190, /* Wild guess at WriteXPRam */ 1562 (void *)0x408b39f4, /* jClkNoMem */ 1563 (void *)0x4080a818, /* ADBAlternateInit */ 1564 (void *)0x408a99c0, /* Egret */ 1565 (void *)0x408147c8, /* InitEgret */ 1566 (void *)0x408a7ef8, /* ADBReInit_JTBL */ 1567 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1568 (void *)0x4081c406, /* FixDiv */ 1569 (void *)0x4081c312, /* FixMul */ 1570 }, 1571 /* 1572 * Vectors verified for LC III 1573 */ 1574 { /* 14 */ 1575 "LC III ROMs", 1576 (void *)0x40814912, /* ADB interrupt */ 1577 (void *)0x0, /* PM ADB interrupt */ 1578 (void *)0x408b2f94, /* ADBBase + 130 interrupt */ 1579 (void *)0x4080a360, /* CountADBs */ 1580 (void *)0x4080a37a, /* GetIndADB */ 1581 (void *)0x4080a3a6, /* GetADBInfo */ 1582 (void *)0x4080a3ac, /* SetADBInfo */ 1583 (void *)0x4080a752, /* ADBReInit */ 1584 (void *)0x4080a3dc, /* ADBOp */ 1585 (void *)0x0, /* PMgrOp */ 1586 (void *)0x4080c05c, /* WriteParam */ 1587 (void *)0x4080c086, /* SetDateTime */ 1588 (void *)0x4080c5cc, /* InitUtil */ 1589 (void *)0x4080b186, /* ReadXPRam */ 1590 (void *)0x4080b190, /* WriteXPRam */ 1591 (void *)0x408b39b6, /* jClkNoMem */ 1592 (void *)0x4080a818, /* ADBAlternateInit */ 1593 (void *)0x40814800, /* Egret */ 1594 (void *)0x408147c4, /* InitEgret */ 1595 (void *)0x408d2918, /* ADBReInit_JTBL */ 1596 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1597 (void *)0x4081c406, /* FixDiv */ 1598 (void *)0x4081c312, /* FixMul */ 1599 }, 1600 /* 1601 * Vectors verified for the LC520 1602 */ 1603 { /* 15 */ 1604 "MacLC520 ROMs", 1605 (void *)0x408d16d6, /* ADB interrupt */ 1606 (void *)0x0, /* PB ADB interrupt */ 1607 (void *)0x408b2f84, /* ADBBase + 130 interrupt; whatzit? */ 1608 (void *)0x4080a360, /* CountADBs */ 1609 (void *)0x4080a37a, /* GetIndADB */ 1610 (void *)0x4080a3a6, /* GetADBInfo */ 1611 (void *)0x4080a3ac, /* SetADBInfo */ 1612 (void *)0x4080a752, /* ADBReInit */ 1613 (void *)0x4080a3dc, /* ADBOp */ 1614 (void *)0x0, /* PMgrOp */ 1615 (void *)0x4080c05c, /* WriteParam */ 1616 (void *)0x4080c086, /* SetDateTime */ 1617 (void *)0x4080c5cc, /* InitUtil */ 1618 (void *)0x4080b186, /* ReadXPRam */ 1619 (void *)0x4080b190, /* WriteXPRam */ 1620 (void *)0x408b3c04, /* jClkNoMem */ 1621 (void *)0x4080a818, /* ADBAlternateInit */ 1622 (void *)0x408d1450, /* Egret */ 1623 (void *)0x408147c4, /* InitEgret */ 1624 (void *)0x408d2460, /* ADBReInit_JTBL */ 1625 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1626 (void *)0x4081c406, /* FixDiv for P520 */ 1627 (void *)0x4081c312, /* FixMul for P520 */ 1628 }, 1629 /* 1630 * Vectors verified for the LC 575/577/578 1631 */ 1632 { /* 16 */ 1633 "MacLC575 ROMs", 1634 (void *)0x408a9b56, /* ADB interrupt */ 1635 (void *)0x0, /* PB ADB interrupt */ 1636 (void *)0x408b2f94, /* ADBBase + 130 interrupt; whatzit? */ 1637 (void *)0x4080a360, /* CountADBs */ 1638 (void *)0x4080a37a, /* GetIndADB */ 1639 (void *)0x4080a3a6, /* GetADBInfo */ 1640 (void *)0x4080a3ac, /* SetADBInfo */ 1641 (void *)0x4080a752, /* ADBReInit */ 1642 (void *)0x4080a3dc, /* ADBOp */ 1643 (void *)0x0, /* PMgrOp */ 1644 (void *)0x4080c05c, /* WriteParam */ 1645 (void *)0x4080c086, /* SetDateTime */ 1646 (void *)0x4080c5cc, /* InitUtil */ 1647 (void *)0x4080b186, /* ReadXPRam */ 1648 (void *)0x4080b190, /* WriteXPRam */ 1649 (void *)0x408b3bf8, /* jClkNoMem */ 1650 (void *)0x4080a818, /* ADBAlternateInit */ 1651 (void *)0x408a99c0, /* Egret */ 1652 (void *)0x408147c4, /* InitEgret */ 1653 (void *)0x408a81a0, /* ADBReInit_JTBL */ 1654 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1655 (void *)0x4081c406, /* FixDiv for P520 */ 1656 (void *)0x4081c312, /* FixMul for P520 */ 1657 }, 1658 /* 1659 * Vectors verified for the Quadra 950 1660 */ 1661 { /* 17 */ 1662 "Quadra950 class ROMs", 1663 (void *)0x40814912, /* ADB interrupt */ 1664 (void *)0x0, /* PM ADB interrupt */ 1665 (void *)0x4080a4d8, /* ADBBase + 130 interrupt; whatzit? */ 1666 (void *)0x4080a360, /* CountADBs */ 1667 (void *)0x4080a37a, /* GetIndADB */ 1668 (void *)0x4080a3a6, /* GetADBInfo */ 1669 (void *)0x4080a3ac, /* SetADBInfo */ 1670 (void *)0x4080a752, /* ADBReInit */ 1671 (void *)0x4080a3dc, /* ADBOp */ 1672 (void *)0x0, /* PMgrOp */ 1673 (void *)0x4080c05c, /* WriteParam */ 1674 (void *)0x4080c086, /* SetDateTime */ 1675 (void *)0x4080c5cc, /* InitUtil */ 1676 (void *)0x4080b186, /* ReadXPRam */ 1677 (void *)0x4080b190, /* WriteXPRam */ 1678 (void *)0x4080b1e4, /* jClkNoMem */ 1679 (void *)0x4080a818, /* ADBAlternateInit */ 1680 (void *)0x40814800, /* Egret */ 1681 (void *)0x408147c4, /* InitEgret */ 1682 (void *)0x408038bc, /* ADBReInit_JTBL */ 1683 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1684 (void *)0x4081c406, /* FixDiv */ 1685 (void *)0x4081c312, /* FixMul */ 1686 }, 1687 /* 1688 * Vectors verified for the Mac IIfx 1689 */ 1690 { /* 18 */ 1691 "Mac IIfx ROMs", 1692 (void *)0x40809f4a, /* ADB interrupt */ 1693 (void *)0x0, /* PM ADB interrupt */ 1694 (void *)0x4080a4d8, /* ADBBase + 130 interrupt */ 1695 (void *)0x4080a360, /* CountADBs */ 1696 (void *)0x4080a37a, /* GetIndADB */ 1697 (void *)0x4080a3a6, /* GetADBInfo */ 1698 (void *)0x4080a3ac, /* SetADBInfo */ 1699 (void *)0x4080a752, /* ADBReInit */ 1700 (void *)0x4080a3dc, /* ADBOp */ 1701 (void *)0x0, /* PMgrOp */ 1702 (void *)0x4080c05c, /* WriteParam */ 1703 (void *)0x4080c086, /* SetDateTime */ 1704 (void *)0x4080c5cc, /* InitUtil */ 1705 (void *)0x4080b186, /* ReadXPRam */ 1706 (void *)0x4080b190, /* WriteXPRam */ 1707 (void *)0x4080b1e4, /* jClkNoMem */ 1708 (void *)0x4080a818, /* ADBAlternateInit */ 1709 (void *)0x0, /* Egret */ 1710 (void *)0x0, /* InitEgret */ 1711 (void *)0x408037c0, /* ADBReInit_JTBL */ 1712 (void *)0x4087eb90, /* ROMResourceMap List Head */ 1713 (void *)0x4081c406, /* FixDiv */ 1714 (void *)0x4081c312, /* FixMul */ 1715 }, 1716 /* 1717 * Vectors verified for the Performa 588 (and 580?) 1718 */ 1719 { /* 19 */ 1720 "Performa 580 ROMs", 1721 (void *) 0x4089a8be, /* ADB interrupt */ 1722 (void *) 0x0, /* PM ADB interrupt */ 1723 (void *) 0x408b2f94, /* ADBBase + 130 interrupt */ 1724 (void *) 0x4080a360, /* CountADBs */ 1725 (void *) 0x4080a37a, /* GetIndADB */ 1726 (void *) 0x4080a3a6, /* GetADBInfo */ 1727 (void *) 0x4080a3ac, /* SetADBInfo */ 1728 (void *) 0x4080a752, /* ADBReInit */ 1729 (void *) 0x4080a3dc, /* ADBOp */ 1730 (void *) 0x0, /* PMgrOp */ 1731 (void *) 0x4080c05c, /* WriteParam */ 1732 (void *) 0x4080c086, /* SetDateTime */ 1733 (void *) 0x4080c5cc, /* InitUtil */ 1734 (void *) 0x4080b186, /* ReadXPRam */ 1735 (void *) 0x4080b190, /* WriteXPRam */ 1736 (void *) 0x408b3bf4, /* jClkNoMem */ 1737 (void *) 0x4080a818, /* ADBAlternateInit */ 1738 (void *) 0x408a99c0, /* Egret */ 1739 (void *) 0x408147c8, /* InitEgret */ 1740 (void *) 0x408a7f74, /* ADBReInit_JTBL */ 1741 (void *) 0x4087eb90, /* ROMResourceMap List Head */ 1742 (void *) 0x4081c406, /* FixDiv */ 1743 (void *) 0x4081c312, /* FixMul */ 1744 }, 1745 /* Please fill these in! -BG */ 1746 }; 1747 1748 1749 struct cpu_model_info cpu_models[] = { 1750 1751 /* The first four. */ 1752 {MACH_MACII, "II ", "", MACH_CLASSII, &romvecs[0]}, 1753 {MACH_MACIIX, "IIx ", "", MACH_CLASSII, &romvecs[0]}, 1754 {MACH_MACIICX, "IIcx ", "", MACH_CLASSII, &romvecs[0]}, 1755 {MACH_MACSE30, "SE/30 ", "", MACH_CLASSII, &romvecs[0]}, 1756 1757 /* The rest of the II series... */ 1758 {MACH_MACIICI, "IIci ", "", MACH_CLASSIIci, &romvecs[4]}, 1759 {MACH_MACIISI, "IIsi ", "", MACH_CLASSIIsi, &romvecs[2]}, 1760 {MACH_MACIIVI, "IIvi ", "", MACH_CLASSIIvx, &romvecs[2]}, 1761 {MACH_MACIIVX, "IIvx ", "", MACH_CLASSIIvx, &romvecs[2]}, 1762 {MACH_MACIIFX, "IIfx ", "", MACH_CLASSIIfx, &romvecs[18]}, 1763 1764 /* The Centris/Quadra series. */ 1765 {MACH_MACQ700, "Quadra", " 700 ", MACH_CLASSQ, &romvecs[4]}, 1766 {MACH_MACQ900, "Quadra", " 900 ", MACH_CLASSQ, &romvecs[6]}, 1767 {MACH_MACQ950, "Quadra", " 950 ", MACH_CLASSQ, &romvecs[17]}, 1768 {MACH_MACQ800, "Quadra", " 800 ", MACH_CLASSQ, &romvecs[6]}, 1769 {MACH_MACQ650, "Quadra", " 650 ", MACH_CLASSQ, &romvecs[6]}, 1770 {MACH_MACC650, "Centris", " 650 ", MACH_CLASSQ, &romvecs[6]}, 1771 {MACH_MACQ605, "Quadra", " 605 ", MACH_CLASSQ, &romvecs[9]}, 1772 {MACH_MACQ605_33, "Quadra", " 605/33 ", MACH_CLASSQ, &romvecs[9]}, 1773 {MACH_MACC610, "Centris", " 610 ", MACH_CLASSQ, &romvecs[6]}, 1774 {MACH_MACQ610, "Quadra", " 610 ", MACH_CLASSQ, &romvecs[6]}, 1775 {MACH_MACQ630, "Quadra", " 630 ", MACH_CLASSQ2, &romvecs[13]}, 1776 {MACH_MACC660AV, "Centris", " 660AV ", MACH_CLASSAV, &romvecs[7]}, 1777 {MACH_MACQ840AV, "Quadra", " 840AV ", MACH_CLASSAV, &romvecs[7]}, 1778 1779 /* The Powerbooks/Duos... */ 1780 {MACH_MACPB100, "PowerBook", " 100 ", MACH_CLASSPB, &romvecs[1]}, 1781 /* PB 100 has no MMU! */ 1782 {MACH_MACPB140, "PowerBook", " 140 ", MACH_CLASSPB, &romvecs[1]}, 1783 {MACH_MACPB145, "PowerBook", " 145 ", MACH_CLASSPB, &romvecs[1]}, 1784 {MACH_MACPB150, "PowerBook", " 150 ", MACH_CLASSDUO, &romvecs[10]}, 1785 {MACH_MACPB160, "PowerBook", " 160 ", MACH_CLASSPB, &romvecs[5]}, 1786 {MACH_MACPB165, "PowerBook", " 165 ", MACH_CLASSPB, &romvecs[5]}, 1787 {MACH_MACPB165C, "PowerBook", " 165c ", MACH_CLASSPB, &romvecs[5]}, 1788 {MACH_MACPB170, "PowerBook", " 170 ", MACH_CLASSPB, &romvecs[1]}, 1789 {MACH_MACPB180, "PowerBook", " 180 ", MACH_CLASSPB, &romvecs[5]}, 1790 {MACH_MACPB180C, "PowerBook", " 180c ", MACH_CLASSPB, &romvecs[5]}, 1791 {MACH_MACPB190, "PowerBook", " 190 ", MACH_CLASSPB, &romvecs[8]}, 1792 {MACH_MACPB190CS, "PowerBook", " 190cs ", MACH_CLASSPB, &romvecs[8]}, 1793 {MACH_MACPB500, "PowerBook", " 500 ", MACH_CLASSPB, &romvecs[8]}, 1794 1795 /* The Duos */ 1796 {MACH_MACPB210, "PowerBook Duo", " 210 ", MACH_CLASSDUO, &romvecs[5]}, 1797 {MACH_MACPB230, "PowerBook Duo", " 230 ", MACH_CLASSDUO, &romvecs[5]}, 1798 {MACH_MACPB250, "PowerBook Duo", " 250 ", MACH_CLASSDUO, &romvecs[5]}, 1799 {MACH_MACPB270, "PowerBook Duo", " 270C ", MACH_CLASSDUO, &romvecs[5]}, 1800 {MACH_MACPB280, "PowerBook Duo", " 280 ", MACH_CLASSDUO, &romvecs[5]}, 1801 {MACH_MACPB280C, "PowerBook Duo", " 280C ", MACH_CLASSDUO, &romvecs[5]}, 1802 1803 /* The Performas... */ 1804 {MACH_MACP600, "Performa", " 600 ", MACH_CLASSIIvx, &romvecs[2]}, 1805 {MACH_MACP460, "Performa", " 460 ", MACH_CLASSLC, &romvecs[14]}, 1806 {MACH_MACP550, "Performa", " 550 ", MACH_CLASSLC, &romvecs[11]}, 1807 {MACH_MACP580, "Performa", " 580 ", MACH_CLASSQ2, &romvecs[19]}, 1808 {MACH_MACTV, "TV ", "", MACH_CLASSLC, &romvecs[12]}, 1809 1810 /* The LCs... */ 1811 {MACH_MACLCII, "LC", " II ", MACH_CLASSLC, &romvecs[3]}, 1812 {MACH_MACLCIII, "LC", " III ", MACH_CLASSLC, &romvecs[14]}, 1813 {MACH_MACLC475, "LC", " 475 ", MACH_CLASSQ, &romvecs[9]}, 1814 {MACH_MACLC475_33, "LC", " 475/33 ", MACH_CLASSQ, &romvecs[9]}, 1815 {MACH_MACLC520, "LC", " 520 ", MACH_CLASSLC, &romvecs[15]}, 1816 {MACH_MACLC575, "LC", " 575 ", MACH_CLASSQ2, &romvecs[16]}, 1817 {MACH_MACCCLASSIC, "Color Classic ", "", MACH_CLASSLC, &romvecs[3]}, 1818 {MACH_MACCCLASSICII, "Color Classic"," II ", MACH_CLASSLC, &romvecs[3]}, 1819 /* Does this belong here? */ 1820 {MACH_MACCLASSICII, "Classic", " II ", MACH_CLASSLC, &romvecs[3]}, 1821 1822 /* The unknown one and the end... */ 1823 {0, "Unknown", "", MACH_CLASSII, NULL}, 1824 {0, NULL, NULL, 0, NULL}, 1825 }; /* End of cpu_models[] initialization. */ 1826 1827 struct intvid_info_t { 1828 int machineid; 1829 u_long fbbase; 1830 u_long fbmask; 1831 u_long fblen; 1832 } intvid_info[] = { 1833 { MACH_MACCLASSICII, 0x009f9a80, 0x0, 21888 }, 1834 { MACH_MACPB140, 0xfee08000, 0x0, 32 * 1024 }, 1835 { MACH_MACPB145, 0xfee08000, 0x0, 32 * 1024 }, 1836 { MACH_MACPB170, 0xfee08000, 0x0, 32 * 1024 }, 1837 { MACH_MACPB150, 0x60000000, 0x0, 128 * 1024 }, 1838 { MACH_MACPB160, 0x60000000, 0x0ffe0000, 128 * 1024 }, 1839 { MACH_MACPB165, 0x60000000, 0x0ffe0000, 128 * 1024 }, 1840 { MACH_MACPB180, 0x60000000, 0x0ffe0000, 128 * 1024 }, 1841 { MACH_MACPB210, 0x60000000, 0x0, 128 * 1024 }, 1842 { MACH_MACPB230, 0x60000000, 0x0, 128 * 1024 }, 1843 { MACH_MACPB250, 0x60000000, 0x0, 128 * 1024 }, 1844 { MACH_MACPB270, 0x60000000, 0x0, 128 * 1024 }, 1845 { MACH_MACPB280, 0x60000000, 0x0, 128 * 1024 }, 1846 { MACH_MACPB280C, 0x60000000, 0x0, 128 * 1024 }, 1847 { MACH_MACIICI, 0x0, 0x0, 320 * 1024 }, 1848 { MACH_MACIISI, 0x0, 0x0, 320 * 1024 }, 1849 { MACH_MACCCLASSIC, 0x50f40000, 0x0, 512 * 1024 }, 1850 /*??*/ { MACH_MACLCII, 0x50f40000, 0x0, 512 * 1024 }, 1851 { MACH_MACPB165C, 0xfc040000, 0x0, 512 * 1024 }, 1852 { MACH_MACPB180C, 0xfc040000, 0x0, 512 * 1024 }, 1853 { MACH_MACPB190, 0x60000000, 0x0, 512 * 1024 }, 1854 { MACH_MACPB190CS, 0x60000000, 0x0, 512 * 1024 }, 1855 { MACH_MACPB500, 0x60000000, 0x0, 512 * 1024 }, 1856 { MACH_MACLCIII, 0x60b00000, 0x0, 768 * 1024 }, 1857 { MACH_MACLC520, 0x60000000, 0x0, 1024 * 1024 }, 1858 { MACH_MACP550, 0x60000000, 0x0, 1024 * 1024 }, 1859 { MACH_MACTV, 0x60000000, 0x0, 1024 * 1024 }, 1860 { MACH_MACLC475, 0xf9000000, 0x0, 1024 * 1024 }, 1861 { MACH_MACLC475_33, 0xf9000000, 0x0, 1024 * 1024 }, 1862 { MACH_MACLC575, 0xf9000000, 0x0, 1024 * 1024 }, 1863 { MACH_MACC610, 0xf9000000, 0x0, 1024 * 1024 }, 1864 { MACH_MACC650, 0xf9000000, 0x0, 1024 * 1024 }, 1865 { MACH_MACP580, 0xf9000000, 0x0, 1024 * 1024 }, 1866 { MACH_MACQ605, 0xf9000000, 0x0, 1024 * 1024 }, 1867 { MACH_MACQ605_33, 0xf9000000, 0x0, 1024 * 1024 }, 1868 { MACH_MACQ610, 0xf9000000, 0x0, 1024 * 1024 }, 1869 { MACH_MACQ630, 0xf9000000, 0x0, 1024 * 1024 }, 1870 { MACH_MACQ650, 0xf9000000, 0x0, 1024 * 1024 }, 1871 { MACH_MACC660AV, 0x50100000, 0x0, 1024 * 1024 }, 1872 { MACH_MACQ700, 0xf9000000, 0x0, 1024 * 1024 }, 1873 { MACH_MACQ800, 0xf9000000, 0x0, 1024 * 1024 }, 1874 { MACH_MACQ900, 0xf9000000, 0x0, 1024 * 1024 }, 1875 { MACH_MACQ950, 0xf9000000, 0x0, 1024 * 1024 }, 1876 { MACH_MACQ840AV, 0x50100000, 0x0, 2048 * 1024 }, 1877 { 0, 0x0, 0x0, 0 }, 1878 }; /* End of intvid_info[] initialization. */ 1879 1880 /* 1881 * Missing Mac Models: 1882 * PowerMac 6100 1883 * PowerMac 7100 1884 * PowerMac 8100 1885 * PowerBook 540 1886 * PowerBook 520 1887 * PowerBook 150 1888 * Duo 280 1889 * Performa 6000s 1890 * ...? 1891 */ 1892 1893 int mach_cputype(void); 1894 1895 int 1896 mach_cputype(void) 1897 { 1898 return (mac68k_machine.mach_processor); 1899 } 1900 1901 static void 1902 identifycpu(void) 1903 { 1904 extern u_int delay_factor; 1905 const char *mpu; 1906 1907 switch (cputype) { 1908 case CPU_68020: 1909 mpu = ("(68020)"); 1910 break; 1911 case CPU_68030: 1912 mpu = ("(68030)"); 1913 break; 1914 case CPU_68040: 1915 mpu = ("(68040)"); 1916 break; 1917 default: 1918 mpu = ("(unknown processor)"); 1919 break; 1920 } 1921 cpu_setmodel("Apple Macintosh %s%s %s", 1922 cpu_models[mac68k_machine.cpu_model_index].model_major, 1923 cpu_models[mac68k_machine.cpu_model_index].model_minor, 1924 mpu); 1925 printf("%s\n", cpu_getmodel()); 1926 printf("cpu: delay factor %d\n", delay_factor); 1927 initfpu(); 1928 } 1929 1930 static void get_machine_info(void); 1931 1932 static void 1933 get_machine_info(void) 1934 { 1935 int i; 1936 1937 for (i = 0; cpu_models[i].model_major; i++) 1938 if (mac68k_machine.machineid == cpu_models[i].machineid) 1939 break; 1940 1941 if (cpu_models[i].model_major == NULL) 1942 i--; 1943 1944 mac68k_machine.cpu_model_index = i; 1945 } 1946 1947 struct cpu_model_info *current_mac_model; 1948 romvec_t *mrg_MacOSROMVectors = 0; 1949 1950 /* 1951 * Sets a bunch of machine-specific variables 1952 */ 1953 void setmachdep(void); 1954 1955 void 1956 setmachdep(void) 1957 { 1958 struct cpu_model_info *cpui; 1959 1960 /* 1961 * First, set things that need to be set on the first pass only 1962 * Ideally, we'd only call this once, but for some reason, the 1963 * VIAs need interrupts turned off twice !? 1964 */ 1965 get_machine_info(); 1966 1967 load_addr = 0; 1968 cpui = &(cpu_models[mac68k_machine.cpu_model_index]); 1969 current_mac_model = cpui; 1970 1971 mac68k_machine.via1_ipl = 1; 1972 mac68k_machine.via2_ipl = 2; 1973 mac68k_machine.aux_interrupts = 0; 1974 1975 /* 1976 * Set up any machine specific stuff that we have to before 1977 * ANYTHING else happens 1978 */ 1979 switch (cpui->class) { /* Base this on class of machine... */ 1980 case MACH_CLASSII: 1981 VIA2 = VIA2OFF; 1982 IOBase = 0x50f00000; 1983 Via1Base = (volatile u_char *)IOBase; 1984 mac68k_machine.scsi80 = 1; 1985 mac68k_machine.zs_chip = 0; 1986 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 1987 via_reg(VIA2, vIER) = 0x7f; /* disable VIA2 int */ 1988 break; 1989 case MACH_CLASSPB: 1990 VIA2 = VIA2OFF; 1991 IOBase = 0x50f00000; 1992 Via1Base = (volatile u_char *)IOBase; 1993 mac68k_machine.scsi80 = 1; 1994 mac68k_machine.zs_chip = 0; 1995 /* Disable everything but PM; we need it. */ 1996 via_reg(VIA1, vIER) = 0x6f; /* disable VIA1 int */ 1997 /* Are we disabling something important? */ 1998 via_reg(VIA2, vIER) = 0x7f; /* disable VIA2 int */ 1999 if (cputype == CPU_68040) 2000 mac68k_machine.sonic = 1; 2001 break; 2002 case MACH_CLASSDUO: 2003 /* 2004 * The Duo definitely does not use a VIA2, but it looks 2005 * like the VIA2 functions might be on the MSC at the RBV 2006 * locations. The rest is copied from the Powerbooks. 2007 */ 2008 VIA2 = RBVOFF; 2009 IOBase = 0x50f00000; 2010 Via1Base = (volatile u_char *)IOBase; 2011 mac68k_machine.scsi80 = 1; 2012 mac68k_machine.zs_chip = 0; 2013 /* Disable everything but PM; we need it. */ 2014 via_reg(VIA1, vIER) = 0x6f; /* disable VIA1 int */ 2015 /* Are we disabling something important? */ 2016 via_reg(VIA2, rIER) = 0x7f; /* disable VIA2 int */ 2017 break; 2018 case MACH_CLASSQ: 2019 case MACH_CLASSQ2: 2020 VIA2 = VIA2OFF; 2021 IOBase = 0x50f00000; 2022 Via1Base = (volatile u_char *)IOBase; 2023 mac68k_machine.sonic = 1; 2024 mac68k_machine.scsi96 = 1; 2025 mac68k_machine.zs_chip = 0; 2026 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2027 via_reg(VIA2, vIER) = 0x7f; /* disable VIA2 int */ 2028 2029 #if 1 2030 switch (current_mac_model->machineid) { 2031 default: 2032 /* case MACH_MACQ900: These three, at least, support the 2033 case MACH_MACQ950: A/UX interrupts. What Quadras don't? 2034 case MACH_MACQ700: */ 2035 /* Enable A/UX interrupt scheme */ 2036 mac68k_machine.aux_interrupts = 1; 2037 2038 via_reg(VIA1, vBufB) &= (0xff ^ DB1O_AuxIntEnb); 2039 via_reg(VIA1, vDirB) |= DB1O_AuxIntEnb; 2040 mac68k_machine.via1_ipl = 6; 2041 mac68k_machine.via2_ipl = 2; 2042 break; 2043 } 2044 #endif 2045 2046 break; 2047 case MACH_CLASSAV: 2048 case MACH_CLASSP580: 2049 VIA2 = VIA2OFF; 2050 IOBase = 0x50f00000; 2051 Via1Base = (volatile u_char *)IOBase; 2052 mac68k_machine.scsi96 = 1; 2053 mac68k_machine.zs_chip = 0; 2054 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2055 via_reg(VIA2, vIER) = 0x7f; /* disable VIA2 int */ 2056 break; 2057 case MACH_CLASSIIci: 2058 VIA2 = RBVOFF; 2059 IOBase = 0x50f00000; 2060 Via1Base = (volatile u_char *)IOBase; 2061 mac68k_machine.scsi80 = 1; 2062 mac68k_machine.zs_chip = 0; 2063 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2064 via_reg(VIA2, rIER) = 0x7f; /* disable RBV int */ 2065 break; 2066 case MACH_CLASSIIsi: 2067 VIA2 = RBVOFF; 2068 IOBase = 0x50f00000; 2069 Via1Base = (volatile u_char *)IOBase; 2070 mac68k_machine.scsi80 = 1; 2071 mac68k_machine.zs_chip = 0; 2072 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2073 via_reg(VIA2, rIER) = 0x7f; /* disable RBV int */ 2074 break; 2075 case MACH_CLASSIIvx: 2076 VIA2 = RBVOFF; 2077 IOBase = 0x50f00000; 2078 Via1Base = (volatile u_char *)IOBase; 2079 mac68k_machine.scsi80 = 1; 2080 mac68k_machine.zs_chip = 0; 2081 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2082 via_reg(VIA2, rIER) = 0x7f; /* disable RBV int */ 2083 break; 2084 case MACH_CLASSLC: 2085 VIA2 = RBVOFF; 2086 IOBase = 0x50f00000; 2087 Via1Base = (volatile u_char *)IOBase; 2088 mac68k_machine.scsi80 = 1; 2089 mac68k_machine.zs_chip = 0; 2090 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2091 via_reg(VIA2, rIER) = 0x7f; /* disable RBV int */ 2092 break; 2093 case MACH_CLASSIIfx: 2094 VIA2 = OSSOFF; 2095 IOBase = 0x50f00000; 2096 Via1Base = (volatile u_char *)IOBase; 2097 mac68k_machine.scsi80 = 1; 2098 mac68k_machine.zs_chip = 0; 2099 via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */ 2100 break; 2101 default: 2102 case MACH_CLASSH: 2103 break; 2104 } 2105 2106 /* 2107 * Set up current ROM Glue vectors. Actually now all we do 2108 * is save the address of the ROM Glue Vector table. This gets 2109 * used later when we re-map the vectors from MacOS Address 2110 * Space to NetBSD Address Space. 2111 */ 2112 mrg_MacOSROMVectors = cpui->rom_vectors; 2113 } 2114 2115 /* 2116 * Set IO offsets. 2117 */ 2118 void 2119 mac68k_set_io_offsets(vaddr_t base) 2120 { 2121 2122 Via1Base = (volatile u_char *)base; 2123 Via2Base = Via1Base + 0x2000 * VIA2; 2124 switch (current_mac_model->class) { 2125 case MACH_CLASSQ: 2126 switch (current_mac_model->machineid) { 2127 case MACH_MACQ900: 2128 case MACH_MACQ950: 2129 sccA = (volatile u_char *)base + 0xc020; 2130 SCSIBase = base + 0xf000; 2131 mac68k_machine.scsi96_2 = 1; 2132 iop_init(0); /* For console */ 2133 break; 2134 case MACH_MACQ800: 2135 /* 2136 * The H/W partially decode address for sccA; it is 2137 * available at offsets 0xc000, 0xc020, .... Here, 2138 * we choose 0xc020, where Mac toolbox ROM uses. 2139 */ 2140 sccA = (volatile u_char *)base + 0xc020; 2141 SCSIBase = base + 0x10000; 2142 break; 2143 case MACH_MACQ700: 2144 sccA = (volatile u_char *)base + 0xc000; 2145 SCSIBase = base + 0xf000; 2146 break; 2147 default: 2148 sccA = (volatile u_char *)base + 0xc000; 2149 SCSIBase = base + 0x10000; 2150 break; 2151 } 2152 break; 2153 case MACH_CLASSQ2: 2154 /* 2155 * Note the different offset for sccA for this class of 2156 * machines. This seems to be common on many of the 2157 * Quadra-type machines. 2158 */ 2159 sccA = (volatile u_char *)base + 0xc020; 2160 SCSIBase = base + 0x10000; 2161 break; 2162 case MACH_CLASSP580: 2163 /* 2164 * Here's a queer bird... it seems to be a cross between 2165 * the two different Quadra classes. 2166 */ 2167 sccA = (volatile u_char *)base + 0xc020; 2168 SCSIBase = base; 2169 break; 2170 case MACH_CLASSAV: 2171 sccA = (volatile u_char *)base + 0x4000; 2172 SCSIBase = base + 0x18000; 2173 PSCBase = (volatile u_char *)base + 0x31000; 2174 break; 2175 case MACH_CLASSII: 2176 case MACH_CLASSPB: 2177 case MACH_CLASSDUO: 2178 case MACH_CLASSIIci: 2179 case MACH_CLASSIIsi: 2180 case MACH_CLASSIIvx: 2181 case MACH_CLASSLC: 2182 sccA = (volatile u_char *)base + 0x4000; 2183 SCSIBase = base; 2184 break; 2185 case MACH_CLASSIIfx: 2186 /* 2187 * Note that sccA base address is based on having 2188 * the serial port in `compatible' mode (set in 2189 * the Serial Switch control panel before booting). 2190 */ 2191 sccA = (volatile u_char *)base + 0x4020; 2192 SCSIBase = base; 2193 iop_init(0); /* For console */ 2194 break; 2195 default: 2196 case MACH_CLASSH: 2197 panic("Unknown/unsupported machine class (%d).", 2198 current_mac_model->class); 2199 break; 2200 } 2201 } 2202 2203 #if GRAYBARS 2204 static u_long gray_nextaddr = 0; 2205 2206 void 2207 gray_bar(void) 2208 { 2209 static int i = 0; 2210 static int flag = 0; 2211 2212 /* MF basic premise as I see it: 2213 1) Save the scratch regs as they are not saved by the compilier. 2214 2) Check to see if we want gray bars, if so, 2215 display some lines of gray, 2216 a couple of lines of white(about 8), 2217 and loop to slow this down. 2218 3) restore regs 2219 */ 2220 2221 __asm volatile ( 2222 " movl %a0,%sp@-;" 2223 " movl %a1,%sp@-;" 2224 " movl %d0,%sp@-;" 2225 " movl %d1,%sp@-"); 2226 2227 /* check to see if gray bars are turned off */ 2228 if (mac68k_machine.do_graybars) { 2229 /* MF the 10*stride/4 is done lots, but we want this to be 2230 * slow */ 2231 for (i = 0; i < 10 * mac68k_video.mv_stride / 4; i++) 2232 ((u_long *)mac68k_video.mv_kvaddr) 2233 [gray_nextaddr++] = 0xaaaaaaaa; 2234 for (i = 0; i < 2 * mac68k_video.mv_stride / 4; i++) 2235 ((u_long *)mac68k_video.mv_kvaddr) 2236 [gray_nextaddr++] = 0x00000000; 2237 } 2238 2239 __asm volatile ( 2240 " movl %sp@+,%d1;" 2241 " movl %sp@+,%d0;" 2242 " movl %sp@+,%a1;" 2243 " movl %sp@+,%a0"); 2244 } 2245 #endif 2246 2247 /* in locore */ 2248 extern u_long ptest040(void *, u_int); 2249 extern int get_pte(u_int, u_long *, u_short *); 2250 2251 /* 2252 * LAK (7/24/94): given a logical address, puts the physical address 2253 * in *phys and return 1, or returns 0 on failure. This is intended 2254 * to look through MacOS page tables. 2255 */ 2256 2257 static u_long 2258 get_physical(u_int addr, u_long * phys) 2259 { 2260 extern u_int macos_tc; 2261 u_long pte[2], ph, mask; 2262 u_short psr; 2263 int i, numbits; 2264 2265 if (mmutype == MMU_68040) { 2266 ph = ptest040((void *)addr, FC_SUPERD); 2267 if ((ph & MMUSR40_R) == 0) { 2268 ph = ptest040((void *)addr, FC_USERD); 2269 if ((ph & MMUSR40_R) == 0) 2270 return 0; 2271 } 2272 if ((ph & MMUSR40_T) != 0) 2273 ph = addr; 2274 2275 mask = (macos_tc & TCR40_P) ? 0x00001fff : 0x00000fff; 2276 ph &= (~mask); 2277 } else { 2278 switch (get_pte(addr, pte, &psr)) { 2279 case (-1): 2280 return 0; 2281 case 0: 2282 ph = pte[0] & 0xFFFFFF00; 2283 break; 2284 case 1: 2285 ph = pte[1] & 0xFFFFFF00; 2286 break; 2287 default: 2288 panic("get_physical(): bad get_pte()"); 2289 } 2290 2291 /* 2292 * We must now figure out how many levels down we went and 2293 * mask the bits appropriately -- the returned value may only 2294 * be the upper n bits, and we have to take the rest from addr. 2295 */ 2296 numbits = 0; 2297 psr &= 0x0007; /* Number of levels we went */ 2298 for (i = 0; i < psr; i++) 2299 numbits += (macos_tc >> (12 - i * 4)) & 0x0f; 2300 2301 /* 2302 * We have to take the most significant "numbits" from 2303 * the returned value "ph", and the rest from our addr. 2304 * Assume that numbits != 0. 2305 */ 2306 mask = (1 << (32 - numbits)) - 1; 2307 } 2308 *phys = ph + (addr & mask); 2309 2310 return 1; 2311 } 2312 2313 static void check_video(const char *, u_long, u_long); 2314 2315 static void 2316 check_video(const char *id, u_long limit, u_long maxm) 2317 { 2318 u_long addr, phys; 2319 2320 if (!get_physical(mac68k_video.mv_kvaddr, &phys)) { 2321 if (mac68k_machine.do_graybars) 2322 printf("get_mapping(): %s. False start.\n", id); 2323 } else { 2324 mac68k_video.mv_log = mac68k_video.mv_kvaddr; 2325 mac68k_video.mv_phys = phys; 2326 mac68k_video.mv_len = 32768; 2327 addr = mac68k_video.mv_kvaddr + 32768; 2328 while (get_physical(addr, &phys)) { 2329 if ((phys - mac68k_video.mv_phys) 2330 != mac68k_video.mv_len) 2331 break; 2332 if (mac68k_video.mv_len + 32768 > limit) { 2333 if (mac68k_machine.do_graybars) { 2334 printf("mapping: %s. Does it never end?\n", 2335 id); 2336 printf(" Forcing VRAM size "); 2337 printf("to a conservative %ldK.\n", 2338 maxm/1024); 2339 } 2340 mac68k_video.mv_len = maxm; 2341 break; 2342 } 2343 mac68k_video.mv_len += 32768; 2344 addr += 32768; 2345 } 2346 if (mac68k_machine.do_graybars) { 2347 printf(" %s internal video at addr %p (phys %p), ", 2348 id, (void *)mac68k_video.mv_log, 2349 (void *)mac68k_video.mv_phys); 2350 printf("len 0x%x.\n", mac68k_video.mv_len); 2351 } 2352 } 2353 } 2354 2355 /* 2356 * Find out how MacOS has mapped itself so we can do the same thing. 2357 * Returns the address of logical 0 so that locore can map the kernel 2358 * properly. 2359 */ 2360 u_int 2361 get_mapping(void) 2362 { 2363 struct intvid_info_t *iip; 2364 u_long addr, lastpage, phys, len, limit; 2365 int i, last, same; 2366 2367 numranges = 0; 2368 for (i = 0; i < 8; i++) { 2369 low[i] = 0; 2370 high[i] = 0; 2371 } 2372 2373 lastpage = get_top_of_ram(); 2374 2375 get_physical(0, &load_addr); 2376 2377 if (mac68k_machine.do_graybars) 2378 printf("Loaded at 0x%0lx\n", load_addr); 2379 2380 last = 0; 2381 for (addr = 0; addr <= lastpage && get_physical(addr, &phys); 2382 addr += PAGE_SIZE) { 2383 if (numranges > 0 && phys != high[last]) { 2384 /* 2385 * Attempt to find if this page is already 2386 * accounted for in an existing physical segment. 2387 */ 2388 for (i = 0; i < numranges; i++) { 2389 if (low[i] <= phys && phys <= high[i]) { 2390 last = i; 2391 break; 2392 } 2393 } 2394 if (i >= numranges) 2395 last = numranges - 1; 2396 2397 if (low[last] <= phys && phys < high[last]) 2398 continue; /* Skip pages we've seen. */ 2399 } 2400 2401 if (numranges > 0 && phys == high[last]) { 2402 /* Common case: extend existing segment on high end */ 2403 high[last] += PAGE_SIZE; 2404 } else { 2405 /* This is a new physical segment. */ 2406 for (last = 0; last < numranges; last++) 2407 if (phys < low[last]) 2408 break; 2409 2410 /* Create space for segment, if necessary */ 2411 if (last < numranges && phys < low[last]) { 2412 for (i = numranges; i > last; i--) { 2413 low[i] = low[i - 1]; 2414 high[i] = high[i - 1]; 2415 } 2416 } 2417 2418 numranges++; 2419 low[last] = phys; 2420 high[last] = phys + PAGE_SIZE; 2421 } 2422 2423 /* Coalesce adjoining segments as appropriate */ 2424 if (last < (numranges - 1) && high[last] == low[last + 1] && 2425 low[last + 1] != load_addr) { 2426 high[last] = high[last + 1]; 2427 for (i = last + 1; i < numranges; i++) { 2428 low[i] = low[i + 1]; 2429 high[i] = high[i + 1]; 2430 } 2431 --numranges; 2432 } 2433 } 2434 if (mac68k_machine.do_graybars) { 2435 printf("System RAM: %ld bytes in %ld pages.\n", 2436 addr, addr / PAGE_SIZE); 2437 for (i = 0; i < numranges; i++) { 2438 printf(" Low = 0x%lx, high = 0x%lx\n", 2439 low[i], high[i]); 2440 } 2441 } 2442 2443 /* 2444 * If we can't figure out the PA of the frame buffer by groveling 2445 * the page tables, assume that we already have the correct 2446 * address. This is the case on several of the PowerBook 1xx 2447 * series, in particular. 2448 */ 2449 if (!get_physical(mac68k_video.mv_kvaddr, &phys)) 2450 phys = mac68k_video.mv_kvaddr; 2451 2452 /* 2453 * Find on-board video, if we have an idea of where to look 2454 * on this system. 2455 */ 2456 for (iip = intvid_info; iip->machineid; iip++) 2457 if (mac68k_machine.machineid == iip->machineid) 2458 break; 2459 2460 if (mac68k_machine.machineid == iip->machineid && 2461 (phys & ~iip->fbmask) >= iip->fbbase && 2462 (phys & ~iip->fbmask) < (iip->fbbase + iip->fblen)) { 2463 mac68k_video.mv_phys = phys & ~iip->fbmask; 2464 mac68k_video.mv_len = 32768 - (phys & 0x7fff); 2465 2466 limit = iip->fbbase + iip->fblen - mac68k_video.mv_phys; 2467 if (mac68k_video.mv_len > limit) { 2468 mac68k_video.mv_len = limit; 2469 } else { 2470 addr = mac68k_video.mv_kvaddr + mac68k_video.mv_len; 2471 while (get_physical(addr, &phys)) { 2472 phys &= ~iip->fbmask; 2473 if ((phys - mac68k_video.mv_phys) != 2474 mac68k_video.mv_len) 2475 break; 2476 if ((mac68k_video.mv_phys + 32768) > limit) { 2477 mac68k_video.mv_len = limit; 2478 break; 2479 } 2480 mac68k_video.mv_len += 32768; 2481 addr += 32768; 2482 } 2483 } 2484 } 2485 2486 if (mac68k_video.mv_len > 0) { 2487 /* 2488 * We've already figured out where internal video is. 2489 * Tell the user what we know. 2490 */ 2491 if (mac68k_machine.do_graybars) 2492 printf("On-board video at addr %p (phys %p), " 2493 "len 0x%x.\n", 2494 (void *)mac68k_video.mv_kvaddr, 2495 (void *)mac68k_video.mv_phys, 2496 mac68k_video.mv_len); 2497 } else { 2498 /* 2499 * We should now look through all of NuBus space to find where 2500 * the internal video is being mapped. Just to be sure we 2501 * handle all the cases, we simply map our NuBus space exactly 2502 * how MacOS did it. As above, we find a bunch of ranges that 2503 * are contiguously mapped. Since there are a lot of pages 2504 * that are all mapped to 0, we handle that as a special case 2505 * where the length is negative. We search in increments of 2506 * 32768 because that's the page size that MacOS uses. 2507 */ 2508 nbnumranges = 0; 2509 for (i = 0; i < NBMAXRANGES; i++) { 2510 nbphys[i] = 0; 2511 nblog[i] = 0; 2512 nblen[i] = 0; 2513 } 2514 2515 same = 0; 2516 for (addr = 0xF9000000; addr < 0xFF000000; addr += 32768) { 2517 if (!get_physical(addr, &phys)) { 2518 continue; 2519 } 2520 len = nbnumranges == 0 ? 0 : nblen[nbnumranges - 1]; 2521 2522 #ifdef __debug_mondo_verbose__ 2523 if (mac68k_machine.do_graybars) 2524 printf ("0x%lx --> 0x%lx\n", addr, phys); 2525 #endif 2526 2527 if (nbnumranges > 0 2528 && addr == nblog[nbnumranges - 1] + len 2529 && phys == nbphys[nbnumranges - 1]) { 2530 /* Same as last one */ 2531 nblen[nbnumranges - 1] += 32768; 2532 same = 1; 2533 } else { 2534 if ((nbnumranges > 0) 2535 && !same 2536 && (addr == nblog[nbnumranges - 1] + len) 2537 && (phys == nbphys[nbnumranges - 1] + len)) 2538 nblen[nbnumranges - 1] += 32768; 2539 else { 2540 if (same) { 2541 nblen[nbnumranges - 1] = -len; 2542 same = 0; 2543 } 2544 if (nbnumranges == NBMAXRANGES) { 2545 if (mac68k_machine.do_graybars) 2546 printf("get_mapping(): Too many NuBus ranges.\n"); 2547 break; 2548 } 2549 nbnumranges++; 2550 nblog[nbnumranges - 1] = addr; 2551 nbphys[nbnumranges - 1] = phys; 2552 nblen[nbnumranges - 1] = 32768; 2553 } 2554 } 2555 } 2556 if (same) { 2557 nblen[nbnumranges - 1] = -nblen[nbnumranges - 1]; 2558 same = 0; 2559 } 2560 if (mac68k_machine.do_graybars) { 2561 printf("Non-system RAM (nubus, etc.):\n"); 2562 for (i = 0; i < nbnumranges; i++) { 2563 printf(" Log = 0x%lx, Phys = 0x%lx, Len = 0x%lx (%lu)\n", 2564 nblog[i], nbphys[i], nblen[i], nblen[i]); 2565 } 2566 } 2567 2568 /* 2569 * We must now find the logical address of internal video in the 2570 * ranges we made above. Internal video is at physical 0, but 2571 * a lot of pages map there. Instead, we look for the logical 2572 * page that maps to 32768 and go back one page. 2573 */ 2574 for (i = 0; i < nbnumranges; i++) { 2575 if (nblen[i] > 0 2576 && nbphys[i] <= 32768 2577 && 32768 <= nbphys[i] + nblen[i]) { 2578 mac68k_video.mv_log = nblog[i] - nbphys[i]; 2579 mac68k_video.mv_len = nblen[i] + nbphys[i]; 2580 mac68k_video.mv_phys = 0; 2581 break; 2582 } 2583 } 2584 if (i == nbnumranges) { 2585 if (0x60000000 <= mac68k_video.mv_kvaddr 2586 && mac68k_video.mv_kvaddr < 0x70000000) { 2587 if (mac68k_machine.do_graybars) 2588 printf("Checking for Internal Video "); 2589 /* 2590 * Kludge for IIvx internal video (60b0 0000). 2591 * PB 520 (6000 0000) 2592 */ 2593 check_video("PB/IIvx (0x60?00000)", 2594 1 * 1024 * 1024, 1 * 1024 * 1024); 2595 } else if (0x50F40000 <= mac68k_video.mv_kvaddr 2596 && mac68k_video.mv_kvaddr < 0x50FBFFFF) { 2597 /* 2598 * Kludge for LC internal video 2599 */ 2600 check_video("LC video (0x50f40000)", 2601 512 * 1024, 512 * 1024); 2602 } else if (0x50100100 <= mac68k_video.mv_kvaddr 2603 && mac68k_video.mv_kvaddr < 0x50400000) { 2604 /* 2605 * Kludge for AV internal video 2606 */ 2607 check_video("AV video (0x50100100)", 2608 1 * 1024 * 1024, 1 * 1024 * 1024); 2609 } else { 2610 if (mac68k_machine.do_graybars) 2611 printf(" no internal video at " 2612 "address 0 -- " 2613 "mac68k_video.mv_kvaddr is " 2614 "0x%lx.\n", 2615 mac68k_video.mv_kvaddr); 2616 } 2617 } else if (mac68k_machine.do_graybars) { 2618 printf(" Video address = %p\n", 2619 (void *)mac68k_video.mv_kvaddr); 2620 printf(" Int video starts at %p\n", 2621 (void *)mac68k_video.mv_log); 2622 printf(" Length = 0x%x (%d) bytes\n", 2623 mac68k_video.mv_len, mac68k_video.mv_len); 2624 } 2625 } 2626 /* mv_len sanity check */ 2627 int reqsize = mac68k_video.mv_height * mac68k_video.mv_stride; 2628 if (mac68k_video.mv_len < reqsize) 2629 mac68k_video.mv_len = reqsize; 2630 2631 return load_addr; /* Return physical address of logical 0 */ 2632 } 2633 2634 /* 2635 * Debugging code for locore page-traversal routine. 2636 */ 2637 void printstar(void); 2638 void 2639 printstar(void) 2640 { 2641 /* 2642 * Be careful as we assume that no registers are clobbered 2643 * when we call this from assembly. 2644 */ 2645 __asm volatile ( 2646 " movl %a0,%sp@-;" 2647 " movl %a1,%sp@-;" 2648 " movl %d0,%sp@-;" 2649 " movl %d1,%sp@-"); 2650 2651 /* printf("*"); */ 2652 2653 __asm volatile ( 2654 " movl %sp@+,%d1;" 2655 " movl %sp@+,%d0;" 2656 " movl %sp@+,%a1;" 2657 " movl %sp@+,%a0"); 2658 } 2659 2660 /* 2661 * Console bell callback; modularizes the console terminal emulator 2662 * and the audio system, so neither requires direct knowledge of the 2663 * other. 2664 */ 2665 2666 void 2667 mac68k_set_bell_callback(int (*callback)(void *, int, int, int), void *cookie) 2668 { 2669 mac68k_bell_callback = callback; 2670 mac68k_bell_cookie = (void *)cookie; 2671 } 2672 2673 int 2674 mac68k_ring_bell(int freq, int length, int volume) 2675 { 2676 if (mac68k_bell_callback) 2677 return ((*mac68k_bell_callback)(mac68k_bell_cookie, 2678 freq, length, volume)); 2679 else 2680 return (ENXIO); 2681 } 2682 2683 int 2684 mm_md_physacc(paddr_t pa, vm_prot_t prot) 2685 { 2686 extern u_long maxaddr; 2687 2688 return (pa < maxaddr) ? 0 : EFAULT; 2689 } 2690