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