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