1/* 2 * Macintosh Nubus Interface Code 3 * 4 * Originally by Alan Cox 5 * 6 * Mostly rewritten by David Huggins-Daines, C. Scott Ananian, 7 * and others. 8 */ 9 10#include <linux/config.h> 11#include <linux/ptrace.h> 12#include <linux/types.h> 13#include <linux/kernel.h> 14#include <linux/string.h> 15#include <linux/nubus.h> 16#include <linux/errno.h> 17#include <linux/init.h> 18#include <linux/delay.h> 19#include <asm/setup.h> 20#include <asm/system.h> 21#include <asm/page.h> 22#include <asm/hwtest.h> 23#include <linux/proc_fs.h> 24#include <asm/mac_via.h> 25#include <asm/mac_oss.h> 26 27extern void via_nubus_init(void); 28extern void oss_nubus_init(void); 29 30/* Constants */ 31 32/* This is, of course, the size in bytelanes, rather than the size in 33 actual bytes */ 34#define FORMAT_BLOCK_SIZE 20 35#define ROM_DIR_OFFSET 0x24 36 37#define NUBUS_TEST_PATTERN 0x5A932BC7 38 39/* Define this if you like to live dangerously - it is known not to 40 work on pretty much every machine except the Quadra 630 and the LC 41 III. */ 42#undef I_WANT_TO_PROBE_SLOT_ZERO 43 44/* This sometimes helps combat failure to boot */ 45#undef TRY_TO_DODGE_WSOD 46 47/* Globals */ 48 49struct nubus_dev* nubus_devices; 50struct nubus_board* nubus_boards; 51 52/* Meaning of "bytelanes": 53 54 The card ROM may appear on any or all bytes of each long word in 55 NuBus memory. The low 4 bits of the "map" value found in the 56 format block (at the top of the slot address space, as well as at 57 the top of the MacOS ROM) tells us which bytelanes, i.e. which byte 58 offsets within each longword, are valid. Thus: 59 60 A map of 0x0f, as found in the MacOS ROM, means that all bytelanes 61 are valid. 62 63 A map of 0xf0 means that no bytelanes are valid (We pray that we 64 will never encounter this, but stranger things have happened) 65 66 A map of 0xe1 means that only the MSB of each long word is actually 67 part of the card ROM. (We hope to never encounter NuBus on a 68 little-endian machine. Again, stranger things have happened) 69 70 A map of 0x78 means that only the LSB of each long word is valid. 71 72 Etcetera, etcetera. Hopefully this clears up some confusion over 73 what the following code actually does. */ 74 75static inline int not_useful(void *p, int map) 76{ 77 unsigned long pv=(unsigned long)p; 78 pv &= 3; 79 if(map & (1<<pv)) 80 return 0; 81 return 1; 82} 83 84static unsigned long nubus_get_rom(unsigned char **ptr, int len, int map) 85{ 86 /* This will hold the result */ 87 unsigned long v = 0; 88 unsigned char *p = *ptr; 89 90 while(len) 91 { 92 v <<= 8; 93 while(not_useful(p,map)) 94 p++; 95 v |= *p++; 96 len--; 97 } 98 *ptr = p; 99 return v; 100} 101 102static void nubus_rewind(unsigned char **ptr, int len, int map) 103{ 104 unsigned char *p=*ptr; 105 106 /* Sanity check */ 107 if(len > 65536) 108 printk(KERN_ERR "rewind of 0x%08x!\n", len); 109 while(len) 110 { 111 do 112 { 113 p--; 114 } 115 while(not_useful(p, map)); 116 len--; 117 } 118 *ptr=p; 119} 120 121static void nubus_advance(unsigned char **ptr, int len, int map) 122{ 123 unsigned char *p = *ptr; 124 if(len>65536) 125 printk(KERN_ERR "advance of 0x%08x!\n", len); 126 while(len) 127 { 128 while(not_useful(p,map)) 129 p++; 130 p++; 131 len--; 132 } 133 *ptr = p; 134} 135 136static void nubus_move(unsigned char **ptr, int len, int map) 137{ 138 if(len > 0) 139 nubus_advance(ptr, len, map); 140 else if(len < 0) 141 nubus_rewind(ptr, -len, map); 142} 143 144/* Now, functions to read the sResource tree */ 145 146/* Each sResource entry consists of a 1-byte ID and a 3-byte data 147 field. If that data field contains an offset, then obviously we 148 have to expand it from a 24-bit signed number to a 32-bit signed 149 number. */ 150 151static inline long nubus_expand32(long foo) 152{ 153 if(foo & 0x00800000) /* 24bit negative */ 154 foo |= 0xFF000000; 155 return foo; 156} 157 158static inline void *nubus_rom_addr(int slot) 159{ 160 /* 161 * Returns the first byte after the card. We then walk 162 * backwards to get the lane register and the config 163 */ 164 return (void *)(0xF1000000+(slot<<24)); 165} 166 167static unsigned char *nubus_dirptr(const struct nubus_dirent *nd) 168{ 169 unsigned char *p = nd->base; 170 /* Essentially, just step over the bytelanes using whatever 171 offset we might have found */ 172 nubus_move(&p, nubus_expand32(nd->data), nd->mask); 173 /* And return the value */ 174 return p; 175} 176 177/* These two are for pulling resource data blocks (i.e. stuff that's 178 pointed to with offsets) out of the card ROM. */ 179 180void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent* dirent, 181 int len) 182{ 183 unsigned char *t = (unsigned char *)dest; 184 unsigned char *p = nubus_dirptr(dirent); 185 while(len) 186 { 187 *t++ = nubus_get_rom(&p, 1, dirent->mask); 188 len--; 189 } 190} 191 192void nubus_get_rsrc_str(void *dest, const struct nubus_dirent* dirent, 193 int len) 194{ 195 unsigned char *t=(unsigned char *)dest; 196 unsigned char *p = nubus_dirptr(dirent); 197 while(len) 198 { 199 *t = nubus_get_rom(&p, 1, dirent->mask); 200 if(!*t++) 201 break; 202 len--; 203 } 204} 205 206int nubus_get_root_dir(const struct nubus_board* board, 207 struct nubus_dir* dir) 208{ 209 dir->ptr = dir->base = board->directory; 210 dir->done = 0; 211 dir->mask = board->lanes; 212 return 0; 213} 214 215/* This is a slyly renamed version of the above */ 216int nubus_get_func_dir(const struct nubus_dev* dev, 217 struct nubus_dir* dir) 218{ 219 dir->ptr = dir->base = dev->directory; 220 dir->done = 0; 221 dir->mask = dev->board->lanes; 222 return 0; 223} 224 225int nubus_get_board_dir(const struct nubus_board* board, 226 struct nubus_dir* dir) 227{ 228 struct nubus_dirent ent; 229 230 dir->ptr = dir->base = board->directory; 231 dir->done = 0; 232 dir->mask = board->lanes; 233 234 /* Now dereference it (the first directory is always the board 235 directory) */ 236 if (nubus_readdir(dir, &ent) == -1) 237 return -1; 238 if (nubus_get_subdir(&ent, dir) == -1) 239 return -1; 240 return 0; 241} 242 243int nubus_get_subdir(const struct nubus_dirent *ent, 244 struct nubus_dir *dir) 245{ 246 dir->ptr = dir->base = nubus_dirptr(ent); 247 dir->done = 0; 248 dir->mask = ent->mask; 249 return 0; 250} 251 252int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent) 253{ 254 u32 resid; 255 if (nd->done) 256 return -1; 257 258 /* Do this first, otherwise nubus_rewind & co are off by 4 */ 259 ent->base = nd->ptr; 260 261 /* This moves nd->ptr forward */ 262 resid = nubus_get_rom(&nd->ptr, 4, nd->mask); 263 264 /* EOL marker, as per the Apple docs */ 265 if((resid&0xff000000) == 0xff000000) 266 { 267 /* Mark it as done */ 268 nd->done = 1; 269 return -1; 270 } 271 272 /* First byte is the resource ID */ 273 ent->type = resid >> 24; 274 /* Low 3 bytes might contain data (or might not) */ 275 ent->data = resid & 0xffffff; 276 ent->mask = nd->mask; 277 return 0; 278} 279 280int nubus_rewinddir(struct nubus_dir* dir) 281{ 282 dir->ptr = dir->base; 283 return 0; 284} 285 286/* Driver interface functions, more or less like in pci.c */ 287 288struct nubus_dev* 289nubus_find_device(unsigned short category, 290 unsigned short type, 291 unsigned short dr_hw, 292 unsigned short dr_sw, 293 const struct nubus_dev* from) 294{ 295 struct nubus_dev* itor = 296 from ? from->next : nubus_devices; 297 298 while (itor) { 299 if (itor->category == category 300 && itor->type == type 301 && itor->dr_hw == dr_hw 302 && itor->dr_sw == dr_sw) 303 return itor; 304 itor = itor->next; 305 } 306 return NULL; 307} 308 309struct nubus_dev* 310nubus_find_type(unsigned short category, 311 unsigned short type, 312 const struct nubus_dev* from) 313{ 314 struct nubus_dev* itor = 315 from ? from->next : nubus_devices; 316 317 while (itor) { 318 if (itor->category == category 319 && itor->type == type) 320 return itor; 321 itor = itor->next; 322 } 323 return NULL; 324} 325 326struct nubus_dev* 327nubus_find_slot(unsigned int slot, 328 const struct nubus_dev* from) 329{ 330 struct nubus_dev* itor = 331 from ? from->next : nubus_devices; 332 333 while (itor) { 334 if (itor->board->slot == slot) 335 return itor; 336 itor = itor->next; 337 } 338 return NULL; 339} 340 341int 342nubus_find_rsrc(struct nubus_dir* dir, unsigned char rsrc_type, 343 struct nubus_dirent* ent) 344{ 345 while (nubus_readdir(dir, ent) != -1) { 346 if (ent->type == rsrc_type) 347 return 0; 348 } 349 return -1; 350} 351 352/* Initialization functions - decide which slots contain stuff worth 353 looking at, and print out lots and lots of information from the 354 resource blocks. */ 355 356 357static int __init nubus_show_display_resource(struct nubus_dev* dev, 358 const struct nubus_dirent* ent) 359{ 360 switch (ent->type) { 361 case NUBUS_RESID_GAMMADIR: 362 printk(KERN_INFO " gamma directory offset: 0x%06x\n", ent->data); 363 break; 364 case 0x0080 ... 0x0085: 365 printk(KERN_INFO " mode %02X info offset: 0x%06x\n", 366 ent->type, ent->data); 367 break; 368 default: 369 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n", 370 ent->type, ent->data); 371 } 372 return 0; 373} 374 375static int __init nubus_show_network_resource(struct nubus_dev* dev, 376 const struct nubus_dirent* ent) 377{ 378 switch (ent->type) { 379 case NUBUS_RESID_MAC_ADDRESS: 380 { 381 char addr[6]; 382 int i; 383 384 nubus_get_rsrc_mem(addr, ent, 6); 385 printk(KERN_INFO " MAC address: "); 386 for (i = 0; i < 6; i++) 387 printk("%02x%s", addr[i] & 0xff, 388 i == 5 ? "" : ":"); 389 printk("\n"); 390 break; 391 } 392 default: 393 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n", 394 ent->type, ent->data); 395 } 396 return 0; 397} 398 399static int __init nubus_show_cpu_resource(struct nubus_dev* dev, 400 const struct nubus_dirent* ent) 401{ 402 switch (ent->type) { 403 case NUBUS_RESID_MEMINFO: 404 { 405 unsigned long meminfo[2]; 406 nubus_get_rsrc_mem(&meminfo, ent, 8); 407 printk(KERN_INFO " memory: [ 0x%08lx 0x%08lx ]\n", 408 meminfo[0], meminfo[1]); 409 break; 410 } 411 case NUBUS_RESID_ROMINFO: 412 { 413 unsigned long rominfo[2]; 414 nubus_get_rsrc_mem(&rominfo, ent, 8); 415 printk(KERN_INFO " ROM: [ 0x%08lx 0x%08lx ]\n", 416 rominfo[0], rominfo[1]); 417 break; 418 } 419 default: 420 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n", 421 ent->type, ent->data); 422 } 423 return 0; 424} 425 426static int __init nubus_show_private_resource(struct nubus_dev* dev, 427 const struct nubus_dirent* ent) 428{ 429 switch (dev->category) { 430 case NUBUS_CAT_DISPLAY: 431 nubus_show_display_resource(dev, ent); 432 break; 433 case NUBUS_CAT_NETWORK: 434 nubus_show_network_resource(dev, ent); 435 break; 436 case NUBUS_CAT_CPU: 437 nubus_show_cpu_resource(dev, ent); 438 break; 439 default: 440 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n", 441 ent->type, ent->data); 442 } 443 return 0; 444} 445 446static struct nubus_dev* __init 447 nubus_get_functional_resource(struct nubus_board* board, 448 int slot, 449 const struct nubus_dirent* parent) 450{ 451 struct nubus_dir dir; 452 struct nubus_dirent ent; 453 struct nubus_dev* dev; 454 455 printk(KERN_INFO " Function 0x%02x:\n", parent->type); 456 nubus_get_subdir(parent, &dir); 457 458 /* Apple seems to have botched the ROM on the IIx */ 459 if (slot == 0 && (unsigned long)dir.base % 2) 460 dir.base += 1; 461 462 if (console_loglevel >= 10) 463 printk(KERN_DEBUG "nubus_get_functional_resource: parent is 0x%p, dir is 0x%p\n", 464 parent->base, dir.base); 465 466 /* Actually we should probably panic if this fails */ 467 if ((dev = kmalloc(sizeof(*dev), GFP_ATOMIC)) == NULL) 468 return NULL; 469 memset(dev, 0, sizeof(*dev)); 470 dev->resid = parent->type; 471 dev->directory = dir.base; 472 dev->board = board; 473 474 while (nubus_readdir(&dir, &ent) != -1) 475 { 476 switch(ent.type) 477 { 478 case NUBUS_RESID_TYPE: 479 { 480 unsigned short nbtdata[4]; 481 nubus_get_rsrc_mem(nbtdata, &ent, 8); 482 dev->category = nbtdata[0]; 483 dev->type = nbtdata[1]; 484 dev->dr_sw = nbtdata[2]; 485 dev->dr_hw = nbtdata[3]; 486 printk(KERN_INFO " type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n", 487 nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]); 488 break; 489 } 490 case NUBUS_RESID_NAME: 491 { 492 nubus_get_rsrc_str(dev->name, &ent, 64); 493 printk(KERN_INFO " name: %s\n", dev->name); 494 break; 495 } 496 case NUBUS_RESID_DRVRDIR: 497 { 498 /* MacOS driver. If we were NetBSD we might 499 use this :-) */ 500 struct nubus_dir drvr_dir; 501 struct nubus_dirent drvr_ent; 502 nubus_get_subdir(&ent, &drvr_dir); 503 nubus_readdir(&drvr_dir, &drvr_ent); 504 dev->driver = nubus_dirptr(&drvr_ent); 505 printk(KERN_INFO " driver at: 0x%p\n", 506 dev->driver); 507 break; 508 } 509 case NUBUS_RESID_MINOR_BASEOS: 510 /* We will need this in order to support 511 multiple framebuffers. It might be handy 512 for Ethernet as well */ 513 nubus_get_rsrc_mem(&dev->iobase, &ent, 4); 514 printk(KERN_INFO " memory offset: 0x%08lx\n", 515 dev->iobase); 516 break; 517 case NUBUS_RESID_MINOR_LENGTH: 518 /* Ditto */ 519 nubus_get_rsrc_mem(&dev->iosize, &ent, 4); 520 printk(KERN_INFO " memory length: 0x%08lx\n", 521 dev->iosize); 522 break; 523 case NUBUS_RESID_FLAGS: 524 dev->flags = ent.data; 525 printk(KERN_INFO " flags: 0x%06x\n", dev->flags); 526 break; 527 case NUBUS_RESID_HWDEVID: 528 dev->hwdevid = ent.data; 529 printk(KERN_INFO " hwdevid: 0x%06x\n", dev->hwdevid); 530 break; 531 default: 532 /* Local/Private resources have their own 533 function */ 534 nubus_show_private_resource(dev, &ent); 535 } 536 } 537 538 return dev; 539} 540 541/* This is cool. */ 542static int __init nubus_get_vidnames(struct nubus_board* board, 543 const struct nubus_dirent* parent) 544{ 545 struct nubus_dir dir; 546 struct nubus_dirent ent; 547 struct vidmode { 548 u32 size; 549 /* Don't know what this is yet */ 550 u16 id; 551 /* Longest one I've seen so far is 26 characters */ 552 char name[32]; 553 }; 554 555 printk(KERN_INFO " video modes supported:\n"); 556 nubus_get_subdir(parent, &dir); 557 if (console_loglevel >= 10) 558 printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n", 559 parent->base, dir.base); 560 561 while(nubus_readdir(&dir, &ent) != -1) 562 { 563 struct vidmode mode; 564 u32 size; 565 566 /* First get the length */ 567 nubus_get_rsrc_mem(&size, &ent, 4); 568 569 /* Now clobber the whole thing */ 570 if (size > sizeof(mode) - 1) 571 size = sizeof(mode) - 1; 572 memset(&mode, 0, sizeof(mode)); 573 nubus_get_rsrc_mem(&mode, &ent, size); 574 printk (KERN_INFO " %02X: (%02X) %s\n", ent.type, 575 mode.id, mode.name); 576 } 577 return 0; 578} 579 580/* This is *really* cool. */ 581static int __init nubus_get_icon(struct nubus_board* board, 582 const struct nubus_dirent* ent) 583{ 584 /* Should be 32x32 if my memory serves me correctly */ 585 unsigned char icon[128]; 586 int x, y; 587 588 nubus_get_rsrc_mem(&icon, ent, 128); 589 printk(KERN_INFO " icon:\n"); 590 591 /* We should actually plot these somewhere in the framebuffer 592 init. This is just to demonstrate that they do, in fact, 593 exist */ 594 for (y = 0; y < 32; y++) { 595 printk(KERN_INFO " "); 596 for (x = 0; x < 32; x++) { 597 if (icon[y*4 + x/8] 598 & (0x80 >> (x%8))) 599 printk("*"); 600 else 601 printk(" "); 602 } 603 printk("\n"); 604 } 605 return 0; 606} 607 608static int __init nubus_get_vendorinfo(struct nubus_board* board, 609 const struct nubus_dirent* parent) 610{ 611 struct nubus_dir dir; 612 struct nubus_dirent ent; 613 static char* vendor_fields[6] = {"ID", "serial", "revision", 614 "part", "date", "unknown field"}; 615 616 printk(KERN_INFO " vendor info:\n"); 617 nubus_get_subdir(parent, &dir); 618 if (console_loglevel >= 10) 619 printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n", 620 parent->base, dir.base); 621 622 while(nubus_readdir(&dir, &ent) != -1) 623 { 624 char name[64]; 625 626 /* These are all strings, we think */ 627 nubus_get_rsrc_str(name, &ent, 64); 628 if (ent.type > 5) 629 ent.type = 5; 630 printk(KERN_INFO " %s: %s\n", 631 vendor_fields[ent.type-1], name); 632 } 633 return 0; 634} 635 636static int __init nubus_get_board_resource(struct nubus_board* board, int slot, 637 const struct nubus_dirent* parent) 638{ 639 struct nubus_dir dir; 640 struct nubus_dirent ent; 641 642 nubus_get_subdir(parent, &dir); 643 if (console_loglevel >= 10) 644 printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n", 645 parent->base, dir.base); 646 647 while(nubus_readdir(&dir, &ent) != -1) 648 { 649 switch (ent.type) { 650 case NUBUS_RESID_TYPE: 651 { 652 unsigned short nbtdata[4]; 653 /* This type is always the same, and is not 654 useful except insofar as it tells us that 655 we really are looking at a board resource. */ 656 nubus_get_rsrc_mem(nbtdata, &ent, 8); 657 printk(KERN_INFO " type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n", 658 nbtdata[0], nbtdata[1], nbtdata[2], 659 nbtdata[3]); 660 if (nbtdata[0] != 1 || nbtdata[1] != 0 || 661 nbtdata[2] != 0 || nbtdata[3] != 0) 662 printk(KERN_ERR "this sResource is not a board resource!\n"); 663 break; 664 } 665 case NUBUS_RESID_NAME: 666 nubus_get_rsrc_str(board->name, &ent, 64); 667 printk(KERN_INFO " name: %s\n", board->name); 668 break; 669 case NUBUS_RESID_ICON: 670 nubus_get_icon(board, &ent); 671 break; 672 case NUBUS_RESID_BOARDID: 673 printk(KERN_INFO " board id: 0x%x\n", ent.data); 674 break; 675 case NUBUS_RESID_PRIMARYINIT: 676 printk(KERN_INFO " primary init offset: 0x%06x\n", ent.data); 677 break; 678 case NUBUS_RESID_VENDORINFO: 679 nubus_get_vendorinfo(board, &ent); 680 break; 681 case NUBUS_RESID_FLAGS: 682 printk(KERN_INFO " flags: 0x%06x\n", ent.data); 683 break; 684 case NUBUS_RESID_HWDEVID: 685 printk(KERN_INFO " hwdevid: 0x%06x\n", ent.data); 686 break; 687 case NUBUS_RESID_SECONDINIT: 688 printk(KERN_INFO " secondary init offset: 0x%06x\n", ent.data); 689 break; 690 /* WTF isn't this in the functional resources? */ 691 case NUBUS_RESID_VIDNAMES: 692 nubus_get_vidnames(board, &ent); 693 break; 694 /* Same goes for this */ 695 case NUBUS_RESID_VIDMODES: 696 printk(KERN_INFO " video mode parameter directory offset: 0x%06x\n", 697 ent.data); 698 break; 699 default: 700 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n", 701 ent.type, ent.data); 702 } 703 } 704 return 0; 705} 706 707/* Attempt to bypass the somewhat non-obvious arrangement of 708 sResources in the motherboard ROM */ 709static void __init nubus_find_rom_dir(struct nubus_board* board) 710{ 711 unsigned char* rp; 712 unsigned char* romdir; 713 struct nubus_dir dir; 714 struct nubus_dirent ent; 715 716 /* Check for the extra directory just under the format block */ 717 rp = board->fblock; 718 nubus_rewind(&rp, 4, board->lanes); 719 if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) { 720 /* OK, the ROM was telling the truth */ 721 board->directory = board->fblock; 722 nubus_move(&board->directory, 723 nubus_expand32(board->doffset), 724 board->lanes); 725 return; 726 } 727 728 /* On "slot zero", you have to walk down a few more 729 directories to get to the equivalent of a real card's root 730 directory. We don't know what they were smoking when they 731 came up with this. */ 732 romdir = nubus_rom_addr(board->slot); 733 nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes); 734 dir.base = dir.ptr = romdir; 735 dir.done = 0; 736 dir.mask = board->lanes; 737 738 /* This one points to an "Unknown Macintosh" directory */ 739 if (nubus_readdir(&dir, &ent) == -1) 740 goto badrom; 741 742 if (console_loglevel >= 10) 743 printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); 744 /* This one takes us to where we want to go. */ 745 if (nubus_readdir(&dir, &ent) == -1) 746 goto badrom; 747 if (console_loglevel >= 10) 748 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); 749 nubus_get_subdir(&ent, &dir); 750 751 /* Resource ID 01, also an "Unknown Macintosh" */ 752 if (nubus_readdir(&dir, &ent) == -1) 753 goto badrom; 754 if (console_loglevel >= 10) 755 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); 756 757 if (nubus_readdir(&dir, &ent) == -1) 758 goto badrom; 759 if (console_loglevel >= 10) 760 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); 761 762 /* Bwahahahaha... */ 763 nubus_get_subdir(&ent, &dir); 764 board->directory = dir.base; 765 return; 766 767 /* Even more evil laughter... */ 768 badrom: 769 board->directory = board->fblock; 770 nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes); 771 printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness! Notify the developers...\n"); 772} 773 774/* Add a board (might be many devices) to the list */ 775static struct nubus_board* __init nubus_add_board(int slot, int bytelanes) 776{ 777 struct nubus_board* board; 778 struct nubus_board** boardp; 779 780 unsigned char *rp; 781 unsigned long dpat; 782 struct nubus_dir dir; 783 struct nubus_dirent ent; 784 785 /* Move to the start of the format block */ 786 rp = nubus_rom_addr(slot); 787 nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes); 788 789 /* Actually we should probably panic if this fails */ 790 if ((board = kmalloc(sizeof(*board), GFP_ATOMIC)) == NULL) 791 return NULL; 792 memset(board, 0, sizeof(*board)); 793 board->fblock = rp; 794 795 /* Dump the format block for debugging purposes */ 796 if (console_loglevel >= 10) { 797 int i; 798 printk(KERN_DEBUG "Slot %X, format block at 0x%p\n", 799 slot, rp); 800 printk(KERN_DEBUG "Format block: "); 801 for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) { 802 unsigned short foo, bar; 803 foo = nubus_get_rom(&rp, 2, bytelanes); 804 bar = nubus_get_rom(&rp, 2, bytelanes); 805 printk("%04x %04x ", foo, bar); 806 } 807 printk("\n"); 808 rp = board->fblock; 809 } 810 811 board->slot = slot; 812 board->slot_addr = (unsigned long) nubus_slot_addr(slot); 813 board->doffset = nubus_get_rom(&rp, 4, bytelanes); 814 /* rom_length is *supposed* to be the total length of the 815 * ROM. In practice it is the "amount of ROM used to compute 816 * the CRC." So some jokers decide to set it to zero and 817 * set the crc to zero so they don't have to do any math. 818 * See the Performa 460 ROM, for example. Those Apple "engineers". 819 */ 820 board->rom_length = nubus_get_rom(&rp, 4, bytelanes); 821 board->crc = nubus_get_rom(&rp, 4, bytelanes); 822 board->rev = nubus_get_rom(&rp, 1, bytelanes); 823 board->format = nubus_get_rom(&rp,1, bytelanes); 824 board->lanes = bytelanes; 825 826 /* Directory offset should be small and negative... */ 827 if(!(board->doffset & 0x00FF0000)) 828 printk(KERN_WARNING "Dodgy doffset!\n"); 829 dpat = nubus_get_rom(&rp, 4, bytelanes); 830 if(dpat != NUBUS_TEST_PATTERN) 831 printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat); 832 833 /* 834 * I wonder how the CRC is meant to work - 835 * any takers ? 836 * CSA: According to MAC docs, not all cards pass the CRC anyway, 837 * since the initial Macintosh ROM releases skipped the check. 838 */ 839 840 /* Attempt to work around slot zero weirdness */ 841 nubus_find_rom_dir(board); 842 nubus_get_root_dir(board, &dir); 843 844 /* We're ready to rock */ 845 printk(KERN_INFO "Slot %X:\n", slot); 846 847 /* Each slot should have one board resource and any number of 848 functional resources. So we'll fill in some fields in the 849 struct nubus_board from the board resource, then walk down 850 the list of functional resources, spinning out a nubus_dev 851 for each of them. */ 852 if (nubus_readdir(&dir, &ent) == -1) { 853 /* We can't have this! */ 854 printk(KERN_ERR "Board resource not found!\n"); 855 return NULL; 856 } else { 857 printk(KERN_INFO " Board resource:\n"); 858 nubus_get_board_resource(board, slot, &ent); 859 } 860 861 /* Aaaarrrrgghh! The LC III motherboard has *two* board 862 resources. I have no idea WTF to do about this. */ 863 864 while (nubus_readdir(&dir, &ent) != -1) { 865 struct nubus_dev* dev; 866 struct nubus_dev** devp; 867 dev = nubus_get_functional_resource(board, slot, &ent); 868 if (dev == NULL) 869 continue; 870 871 /* We zeroed this out above */ 872 if (board->first_dev == NULL) 873 board->first_dev = dev; 874 875 /* Put it on the global NuBus device chain. Keep entries in order. */ 876 for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next)) 877 /* spin */; 878 *devp = dev; 879 dev->next = NULL; 880 } 881 882 /* Put it on the global NuBus board chain. Keep entries in order. */ 883 for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next)) 884 /* spin */; 885 *boardp = board; 886 board->next = NULL; 887 888 return board; 889} 890 891void __init nubus_probe_slot(int slot) 892{ 893 unsigned char dp; 894 unsigned char* rp; 895 int i; 896 897 rp = nubus_rom_addr(slot); 898 for(i = 4; i; i--) 899 { 900 unsigned long flags; 901 int card_present; 902 903 rp--; 904 save_flags(flags); 905 cli(); 906 card_present = hwreg_present(rp); 907 restore_flags(flags); 908 909 if (!card_present) 910 continue; 911 912 printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp); 913 dp = *rp; 914 if(dp == 0) 915 continue; 916 917 /* The last byte of the format block consists of two 918 nybbles which are "mirror images" of each other. 919 These show us the valid bytelanes */ 920 if ((((dp>>4) ^ dp) & 0x0F) != 0x0F) 921 continue; 922 /* Check that this value is actually *on* one of the 923 bytelanes it claims are valid! */ 924 if ((dp & 0x0F) >= (1<<i)) 925 continue; 926 927 /* Looks promising. Let's put it on the list. */ 928 nubus_add_board(slot, dp); 929 930 return; 931 } 932} 933 934#if defined(CONFIG_PROC_FS) 935 936/* /proc/nubus stuff */ 937 938static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len) 939{ 940 if(len < 100) 941 return -1; 942 943 sprintf(ptr, "Slot %X: %s\n", 944 board->slot, board->name); 945 946 return strlen(ptr); 947} 948 949static int nubus_read_proc(char *page, char **start, off_t off, 950 int count, int *eof, void *data) 951{ 952 int nprinted, len, begin = 0; 953 int size = PAGE_SIZE; 954 struct nubus_board* board; 955 956 len = sprintf(page, "Nubus devices found:\n"); 957 /* Walk the list of NuBus boards */ 958 for (board = nubus_boards; board != NULL; board = board->next) 959 { 960 nprinted = sprint_nubus_board(board, page + len, size - len); 961 if (nprinted < 0) 962 break; 963 len += nprinted; 964 if (len+begin < off) { 965 begin += len; 966 len = 0; 967 } 968 if (len+begin >= off+count) 969 break; 970 } 971 if (len+begin < off) 972 *eof = 1; 973 off -= begin; 974 *start = page + off; 975 len -= off; 976 if (len>count) 977 len = count; 978 if (len<0) 979 len = 0; 980 return len; 981} 982#endif 983 984void __init nubus_scan_bus(void) 985{ 986 int slot; 987 /* This might not work on your machine */ 988#ifdef I_WANT_TO_PROBE_SLOT_ZERO 989 nubus_probe_slot(0); 990#endif 991 for(slot = 9; slot < 15; slot++) 992 { 993 nubus_probe_slot(slot); 994 } 995} 996 997void __init nubus_init(void) 998{ 999 if (!MACH_IS_MAC) 1000 return; 1001 1002 /* Initialize the NuBus interrupts */ 1003 if (oss_present) { 1004 oss_nubus_init(); 1005 } else { 1006 via_nubus_init(); 1007 } 1008 1009#ifdef TRY_TO_DODGE_WSOD 1010 /* Rogue Ethernet interrupts can kill the machine if we don't 1011 do this. Obviously this is bogus. Hopefully the local VIA 1012 gurus can fix the real cause of the problem. */ 1013 mdelay(1000); 1014#endif 1015 1016 /* And probe */ 1017 printk("NuBus: Scanning NuBus slots.\n"); 1018 nubus_devices = NULL; 1019 nubus_boards = NULL; 1020 nubus_scan_bus(); 1021 1022#ifdef CONFIG_PROC_FS 1023 create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL); 1024 nubus_proc_init(); 1025#endif 1026} 1027