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