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