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
27 extern void via_nubus_init(void);
28 extern 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
49 struct nubus_dev* nubus_devices;
50 struct 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
not_useful(void * p,int map)75 static 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
nubus_get_rom(unsigned char ** ptr,int len,int map)84 static 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
nubus_rewind(unsigned char ** ptr,int len,int map)102 static 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
nubus_advance(unsigned char ** ptr,int len,int map)121 static 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
nubus_move(unsigned char ** ptr,int len,int map)136 static 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
nubus_expand32(long foo)151 static inline long nubus_expand32(long foo)
152 {
153 if(foo & 0x00800000) /* 24bit negative */
154 foo |= 0xFF000000;
155 return foo;
156 }
157
nubus_rom_addr(int slot)158 static 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
nubus_dirptr(const struct nubus_dirent * nd)167 static 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
nubus_get_rsrc_mem(void * dest,const struct nubus_dirent * dirent,int len)180 void 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
nubus_get_rsrc_str(void * dest,const struct nubus_dirent * dirent,int len)192 void 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
nubus_get_root_dir(const struct nubus_board * board,struct nubus_dir * dir)206 int 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 */
nubus_get_func_dir(const struct nubus_dev * dev,struct nubus_dir * dir)216 int 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
nubus_get_board_dir(const struct nubus_board * board,struct nubus_dir * dir)225 int 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
nubus_get_subdir(const struct nubus_dirent * ent,struct nubus_dir * dir)243 int 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
nubus_readdir(struct nubus_dir * nd,struct nubus_dirent * ent)252 int 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
nubus_rewinddir(struct nubus_dir * dir)280 int 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
288 struct nubus_dev*
nubus_find_device(unsigned short category,unsigned short type,unsigned short dr_hw,unsigned short dr_sw,const struct nubus_dev * from)289 nubus_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
309 struct nubus_dev*
nubus_find_type(unsigned short category,unsigned short type,const struct nubus_dev * from)310 nubus_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
326 struct nubus_dev*
nubus_find_slot(unsigned int slot,const struct nubus_dev * from)327 nubus_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
341 int
nubus_find_rsrc(struct nubus_dir * dir,unsigned char rsrc_type,struct nubus_dirent * ent)342 nubus_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 /* FIXME: A lot of this stuff will eventually be useful after
357 initializaton, for intelligently probing Ethernet and video chips,
358 among other things. The rest of it should go in the /proc code.
359 For now, we just use it to give verbose boot logs. */
360
nubus_show_display_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)361 static int __init nubus_show_display_resource(struct nubus_dev* dev,
362 const struct nubus_dirent* ent)
363 {
364 switch (ent->type) {
365 case NUBUS_RESID_GAMMADIR:
366 printk(KERN_INFO " gamma directory offset: 0x%06x\n", ent->data);
367 break;
368 case 0x0080 ... 0x0085:
369 printk(KERN_INFO " mode %02X info offset: 0x%06x\n",
370 ent->type, ent->data);
371 break;
372 default:
373 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n",
374 ent->type, ent->data);
375 }
376 return 0;
377 }
378
nubus_show_network_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)379 static int __init nubus_show_network_resource(struct nubus_dev* dev,
380 const struct nubus_dirent* ent)
381 {
382 switch (ent->type) {
383 case NUBUS_RESID_MAC_ADDRESS:
384 {
385 char addr[6];
386 int i;
387
388 nubus_get_rsrc_mem(addr, ent, 6);
389 printk(KERN_INFO " MAC address: ");
390 for (i = 0; i < 6; i++)
391 printk("%02x%s", addr[i] & 0xff,
392 i == 5 ? "" : ":");
393 printk("\n");
394 break;
395 }
396 default:
397 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n",
398 ent->type, ent->data);
399 }
400 return 0;
401 }
402
nubus_show_cpu_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)403 static int __init nubus_show_cpu_resource(struct nubus_dev* dev,
404 const struct nubus_dirent* ent)
405 {
406 switch (ent->type) {
407 case NUBUS_RESID_MEMINFO:
408 {
409 unsigned long meminfo[2];
410 nubus_get_rsrc_mem(&meminfo, ent, 8);
411 printk(KERN_INFO " memory: [ 0x%08lx 0x%08lx ]\n",
412 meminfo[0], meminfo[1]);
413 break;
414 }
415 case NUBUS_RESID_ROMINFO:
416 {
417 unsigned long rominfo[2];
418 nubus_get_rsrc_mem(&rominfo, ent, 8);
419 printk(KERN_INFO " ROM: [ 0x%08lx 0x%08lx ]\n",
420 rominfo[0], rominfo[1]);
421 break;
422 }
423 default:
424 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n",
425 ent->type, ent->data);
426 }
427 return 0;
428 }
429
nubus_show_private_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)430 static int __init nubus_show_private_resource(struct nubus_dev* dev,
431 const struct nubus_dirent* ent)
432 {
433 switch (dev->category) {
434 case NUBUS_CAT_DISPLAY:
435 nubus_show_display_resource(dev, ent);
436 break;
437 case NUBUS_CAT_NETWORK:
438 nubus_show_network_resource(dev, ent);
439 break;
440 case NUBUS_CAT_CPU:
441 nubus_show_cpu_resource(dev, ent);
442 break;
443 default:
444 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n",
445 ent->type, ent->data);
446 }
447 return 0;
448 }
449
450 static struct nubus_dev* __init
nubus_get_functional_resource(struct nubus_board * board,int slot,const struct nubus_dirent * parent)451 nubus_get_functional_resource(struct nubus_board* board,
452 int slot,
453 const struct nubus_dirent* parent)
454 {
455 struct nubus_dir dir;
456 struct nubus_dirent ent;
457 struct nubus_dev* dev;
458
459 printk(KERN_INFO " Function 0x%02x:\n", parent->type);
460 nubus_get_subdir(parent, &dir);
461
462 /* Apple seems to have botched the ROM on the IIx */
463 if (slot == 0 && (unsigned long)dir.base % 2)
464 dir.base += 1;
465
466 if (console_loglevel >= 10)
467 printk(KERN_DEBUG "nubus_get_functional_resource: parent is 0x%p, dir is 0x%p\n",
468 parent->base, dir.base);
469
470 /* Actually we should probably panic if this fails */
471 if ((dev = kmalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
472 return NULL;
473 memset(dev, 0, sizeof(*dev));
474 dev->resid = parent->type;
475 dev->directory = dir.base;
476 dev->board = board;
477
478 while (nubus_readdir(&dir, &ent) != -1)
479 {
480 switch(ent.type)
481 {
482 case NUBUS_RESID_TYPE:
483 {
484 unsigned short nbtdata[4];
485 nubus_get_rsrc_mem(nbtdata, &ent, 8);
486 dev->category = nbtdata[0];
487 dev->type = nbtdata[1];
488 dev->dr_sw = nbtdata[2];
489 dev->dr_hw = nbtdata[3];
490 printk(KERN_INFO " type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
491 nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
492 break;
493 }
494 case NUBUS_RESID_NAME:
495 {
496 nubus_get_rsrc_str(dev->name, &ent, 64);
497 printk(KERN_INFO " name: %s\n", dev->name);
498 break;
499 }
500 case NUBUS_RESID_DRVRDIR:
501 {
502 /* MacOS driver. If we were NetBSD we might
503 use this :-) */
504 struct nubus_dir drvr_dir;
505 struct nubus_dirent drvr_ent;
506 nubus_get_subdir(&ent, &drvr_dir);
507 nubus_readdir(&drvr_dir, &drvr_ent);
508 dev->driver = nubus_dirptr(&drvr_ent);
509 printk(KERN_INFO " driver at: 0x%p\n",
510 dev->driver);
511 break;
512 }
513 case NUBUS_RESID_MINOR_BASEOS:
514 /* We will need this in order to support
515 multiple framebuffers. It might be handy
516 for Ethernet as well */
517 nubus_get_rsrc_mem(&dev->iobase, &ent, 4);
518 printk(KERN_INFO " memory offset: 0x%08lx\n",
519 dev->iobase);
520 break;
521 case NUBUS_RESID_MINOR_LENGTH:
522 /* Ditto */
523 nubus_get_rsrc_mem(&dev->iosize, &ent, 4);
524 printk(KERN_INFO " memory length: 0x%08lx\n",
525 dev->iosize);
526 break;
527 case NUBUS_RESID_FLAGS:
528 dev->flags = ent.data;
529 printk(KERN_INFO " flags: 0x%06x\n", dev->flags);
530 break;
531 case NUBUS_RESID_HWDEVID:
532 dev->hwdevid = ent.data;
533 printk(KERN_INFO " hwdevid: 0x%06x\n", dev->hwdevid);
534 break;
535 default:
536 /* Local/Private resources have their own
537 function */
538 nubus_show_private_resource(dev, &ent);
539 }
540 }
541
542 return dev;
543 }
544
545 /* This is cool. */
nubus_get_vidnames(struct nubus_board * board,const struct nubus_dirent * parent)546 static int __init nubus_get_vidnames(struct nubus_board* board,
547 const struct nubus_dirent* parent)
548 {
549 struct nubus_dir dir;
550 struct nubus_dirent ent;
551 /* FIXME: obviously we want to put this in a header file soon */
552 struct vidmode {
553 u32 size;
554 /* Don't know what this is yet */
555 u16 id;
556 /* Longest one I've seen so far is 26 characters */
557 char name[32];
558 };
559
560 printk(KERN_INFO " video modes supported:\n");
561 nubus_get_subdir(parent, &dir);
562 if (console_loglevel >= 10)
563 printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n",
564 parent->base, dir.base);
565
566 while(nubus_readdir(&dir, &ent) != -1)
567 {
568 struct vidmode mode;
569 u32 size;
570
571 /* First get the length */
572 nubus_get_rsrc_mem(&size, &ent, 4);
573
574 /* Now clobber the whole thing */
575 if (size > sizeof(mode) - 1)
576 size = sizeof(mode) - 1;
577 memset(&mode, 0, sizeof(mode));
578 nubus_get_rsrc_mem(&mode, &ent, size);
579 printk (KERN_INFO " %02X: (%02X) %s\n", ent.type,
580 mode.id, mode.name);
581 }
582 return 0;
583 }
584
585 /* This is *really* cool. */
nubus_get_icon(struct nubus_board * board,const struct nubus_dirent * ent)586 static int __init nubus_get_icon(struct nubus_board* board,
587 const struct nubus_dirent* ent)
588 {
589 /* Should be 32x32 if my memory serves me correctly */
590 unsigned char icon[128];
591 int x, y;
592
593 nubus_get_rsrc_mem(&icon, ent, 128);
594 printk(KERN_INFO " icon:\n");
595
596 /* We should actually plot these somewhere in the framebuffer
597 init. This is just to demonstrate that they do, in fact,
598 exist */
599 for (y = 0; y < 32; y++) {
600 printk(KERN_INFO " ");
601 for (x = 0; x < 32; x++) {
602 if (icon[y*4 + x/8]
603 & (0x80 >> (x%8)))
604 printk("*");
605 else
606 printk(" ");
607 }
608 printk("\n");
609 }
610 return 0;
611 }
612
nubus_get_vendorinfo(struct nubus_board * board,const struct nubus_dirent * parent)613 static int __init nubus_get_vendorinfo(struct nubus_board* board,
614 const struct nubus_dirent* parent)
615 {
616 struct nubus_dir dir;
617 struct nubus_dirent ent;
618 static char* vendor_fields[6] = {"ID", "serial", "revision",
619 "part", "date", "unknown field"};
620
621 printk(KERN_INFO " vendor info:\n");
622 nubus_get_subdir(parent, &dir);
623 if (console_loglevel >= 10)
624 printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n",
625 parent->base, dir.base);
626
627 while(nubus_readdir(&dir, &ent) != -1)
628 {
629 char name[64];
630
631 /* These are all strings, we think */
632 nubus_get_rsrc_str(name, &ent, 64);
633 if (ent.type > 5)
634 ent.type = 5;
635 printk(KERN_INFO " %s: %s\n",
636 vendor_fields[ent.type-1], name);
637 }
638 return 0;
639 }
640
nubus_get_board_resource(struct nubus_board * board,int slot,const struct nubus_dirent * parent)641 static int __init nubus_get_board_resource(struct nubus_board* board, int slot,
642 const struct nubus_dirent* parent)
643 {
644 struct nubus_dir dir;
645 struct nubus_dirent ent;
646
647 nubus_get_subdir(parent, &dir);
648 if (console_loglevel >= 10)
649 printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",
650 parent->base, dir.base);
651
652 while(nubus_readdir(&dir, &ent) != -1)
653 {
654 switch (ent.type) {
655 case NUBUS_RESID_TYPE:
656 {
657 unsigned short nbtdata[4];
658 /* This type is always the same, and is not
659 useful except insofar as it tells us that
660 we really are looking at a board resource. */
661 nubus_get_rsrc_mem(nbtdata, &ent, 8);
662 printk(KERN_INFO " type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
663 nbtdata[0], nbtdata[1], nbtdata[2],
664 nbtdata[3]);
665 if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
666 nbtdata[2] != 0 || nbtdata[3] != 0)
667 printk(KERN_ERR "this sResource is not a board resource!\n");
668 break;
669 }
670 case NUBUS_RESID_NAME:
671 nubus_get_rsrc_str(board->name, &ent, 64);
672 printk(KERN_INFO " name: %s\n", board->name);
673 break;
674 case NUBUS_RESID_ICON:
675 nubus_get_icon(board, &ent);
676 break;
677 case NUBUS_RESID_BOARDID:
678 printk(KERN_INFO " board id: 0x%x\n", ent.data);
679 break;
680 case NUBUS_RESID_PRIMARYINIT:
681 printk(KERN_INFO " primary init offset: 0x%06x\n", ent.data);
682 break;
683 case NUBUS_RESID_VENDORINFO:
684 nubus_get_vendorinfo(board, &ent);
685 break;
686 case NUBUS_RESID_FLAGS:
687 printk(KERN_INFO " flags: 0x%06x\n", ent.data);
688 break;
689 case NUBUS_RESID_HWDEVID:
690 printk(KERN_INFO " hwdevid: 0x%06x\n", ent.data);
691 break;
692 case NUBUS_RESID_SECONDINIT:
693 printk(KERN_INFO " secondary init offset: 0x%06x\n", ent.data);
694 break;
695 /* WTF isn't this in the functional resources? */
696 case NUBUS_RESID_VIDNAMES:
697 nubus_get_vidnames(board, &ent);
698 break;
699 /* Same goes for this */
700 case NUBUS_RESID_VIDMODES:
701 printk(KERN_INFO " video mode parameter directory offset: 0x%06x\n",
702 ent.data);
703 break;
704 default:
705 printk(KERN_INFO " unknown resource %02X, data 0x%06x\n",
706 ent.type, ent.data);
707 }
708 }
709 return 0;
710 }
711
712 /* Attempt to bypass the somewhat non-obvious arrangement of
713 sResources in the motherboard ROM */
nubus_find_rom_dir(struct nubus_board * board)714 static void __init nubus_find_rom_dir(struct nubus_board* board)
715 {
716 unsigned char* rp;
717 unsigned char* romdir;
718 struct nubus_dir dir;
719 struct nubus_dirent ent;
720
721 /* Check for the extra directory just under the format block */
722 rp = board->fblock;
723 nubus_rewind(&rp, 4, board->lanes);
724 if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) {
725 /* OK, the ROM was telling the truth */
726 board->directory = board->fblock;
727 nubus_move(&board->directory,
728 nubus_expand32(board->doffset),
729 board->lanes);
730 return;
731 }
732
733 /* On "slot zero", you have to walk down a few more
734 directories to get to the equivalent of a real card's root
735 directory. We don't know what they were smoking when they
736 came up with this. */
737 romdir = nubus_rom_addr(board->slot);
738 nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes);
739 dir.base = dir.ptr = romdir;
740 dir.done = 0;
741 dir.mask = board->lanes;
742
743 /* This one points to an "Unknown Macintosh" directory */
744 if (nubus_readdir(&dir, &ent) == -1)
745 goto badrom;
746
747 if (console_loglevel >= 10)
748 printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
749 /* This one takes us to where we want to go. */
750 if (nubus_readdir(&dir, &ent) == -1)
751 goto badrom;
752 if (console_loglevel >= 10)
753 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
754 nubus_get_subdir(&ent, &dir);
755
756 /* Resource ID 01, also an "Unknown Macintosh" */
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 /* FIXME: the first one is *not* always the right one. We
763 suspect this has something to do with the ROM revision.
764 "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR
765 Continues" (Q630) uses 0x7b. The DAFB Macs evidently use
766 something else. Please run "Slots" on your Mac (see
767 include/linux/nubus.h for where to get this program) and
768 tell us where the 'SiDirPtr' for Slot 0 is. If you feel
769 brave, you should also use MacsBug to walk down the ROM
770 directories like this function does and try to find the
771 path to that address... */
772 if (nubus_readdir(&dir, &ent) == -1)
773 goto badrom;
774 if (console_loglevel >= 10)
775 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
776
777 /* Bwahahahaha... */
778 nubus_get_subdir(&ent, &dir);
779 board->directory = dir.base;
780 return;
781
782 /* Even more evil laughter... */
783 badrom:
784 board->directory = board->fblock;
785 nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes);
786 printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness! Notify the developers...\n");
787 }
788
789 /* Add a board (might be many devices) to the list */
nubus_add_board(int slot,int bytelanes)790 static struct nubus_board* __init nubus_add_board(int slot, int bytelanes)
791 {
792 struct nubus_board* board;
793 struct nubus_board** boardp;
794
795 unsigned char *rp;
796 unsigned long dpat;
797 struct nubus_dir dir;
798 struct nubus_dirent ent;
799
800 /* Move to the start of the format block */
801 rp = nubus_rom_addr(slot);
802 nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
803
804 /* Actually we should probably panic if this fails */
805 if ((board = kmalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
806 return NULL;
807 memset(board, 0, sizeof(*board));
808 board->fblock = rp;
809
810 /* Dump the format block for debugging purposes */
811 if (console_loglevel >= 10) {
812 int i;
813 printk(KERN_DEBUG "Slot %X, format block at 0x%p\n",
814 slot, rp);
815 printk(KERN_DEBUG "Format block: ");
816 for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) {
817 unsigned short foo, bar;
818 foo = nubus_get_rom(&rp, 2, bytelanes);
819 bar = nubus_get_rom(&rp, 2, bytelanes);
820 printk("%04x %04x ", foo, bar);
821 }
822 printk("\n");
823 rp = board->fblock;
824 }
825
826 board->slot = slot;
827 board->slot_addr = (unsigned long) nubus_slot_addr(slot);
828 board->doffset = nubus_get_rom(&rp, 4, bytelanes);
829 /* rom_length is *supposed* to be the total length of the
830 * ROM. In practice it is the "amount of ROM used to compute
831 * the CRC." So some jokers decide to set it to zero and
832 * set the crc to zero so they don't have to do any math.
833 * See the Performa 460 ROM, for example. Those Apple "engineers".
834 */
835 board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
836 board->crc = nubus_get_rom(&rp, 4, bytelanes);
837 board->rev = nubus_get_rom(&rp, 1, bytelanes);
838 board->format = nubus_get_rom(&rp,1, bytelanes);
839 board->lanes = bytelanes;
840
841 /* Directory offset should be small and negative... */
842 if(!(board->doffset & 0x00FF0000))
843 printk(KERN_WARNING "Dodgy doffset!\n");
844 dpat = nubus_get_rom(&rp, 4, bytelanes);
845 if(dpat != NUBUS_TEST_PATTERN)
846 printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat);
847
848 /*
849 * I wonder how the CRC is meant to work -
850 * any takers ?
851 * CSA: According to MAC docs, not all cards pass the CRC anyway,
852 * since the initial Macintosh ROM releases skipped the check.
853 */
854
855 /* Attempt to work around slot zero weirdness */
856 nubus_find_rom_dir(board);
857 nubus_get_root_dir(board, &dir);
858
859 /* We're ready to rock */
860 printk(KERN_INFO "Slot %X:\n", slot);
861
862 /* Each slot should have one board resource and any number of
863 functional resources. So we'll fill in some fields in the
864 struct nubus_board from the board resource, then walk down
865 the list of functional resources, spinning out a nubus_dev
866 for each of them. */
867 if (nubus_readdir(&dir, &ent) == -1) {
868 /* We can't have this! */
869 printk(KERN_ERR "Board resource not found!\n");
870 return NULL;
871 } else {
872 printk(KERN_INFO " Board resource:\n");
873 nubus_get_board_resource(board, slot, &ent);
874 }
875
876 /* Aaaarrrrgghh! The LC III motherboard has *two* board
877 resources. I have no idea WTF to do about this. */
878
879 while (nubus_readdir(&dir, &ent) != -1) {
880 struct nubus_dev* dev;
881 struct nubus_dev** devp;
882 dev = nubus_get_functional_resource(board, slot, &ent);
883 if (dev == NULL)
884 continue;
885
886 /* We zeroed this out above */
887 if (board->first_dev == NULL)
888 board->first_dev = dev;
889
890 /* Put it on the global NuBus device chain. Keep entries in order. */
891 for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next))
892 /* spin */;
893 *devp = dev;
894 dev->next = NULL;
895 }
896
897 /* Put it on the global NuBus board chain. Keep entries in order. */
898 for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next))
899 /* spin */;
900 *boardp = board;
901 board->next = NULL;
902
903 return board;
904 }
905
nubus_probe_slot(int slot)906 void __init nubus_probe_slot(int slot)
907 {
908 unsigned char dp;
909 unsigned char* rp;
910 int i;
911
912 rp = nubus_rom_addr(slot);
913 for(i = 4; i; i--)
914 {
915 unsigned long flags;
916 int card_present;
917
918 rp--;
919 save_flags(flags);
920 cli();
921 card_present = hwreg_present(rp);
922 restore_flags(flags);
923
924 if (!card_present)
925 continue;
926
927 printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp);
928 dp = *rp;
929 if(dp == 0)
930 continue;
931
932 /* The last byte of the format block consists of two
933 nybbles which are "mirror images" of each other.
934 These show us the valid bytelanes */
935 if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)
936 continue;
937 /* Check that this value is actually *on* one of the
938 bytelanes it claims are valid! */
939 if ((dp & 0x0F) >= (1<<i))
940 continue;
941
942 /* Looks promising. Let's put it on the list. */
943 nubus_add_board(slot, dp);
944
945 return;
946 }
947 }
948
949 #if defined(CONFIG_PROC_FS)
950
951 /* /proc/nubus stuff */
952
sprint_nubus_board(struct nubus_board * board,char * ptr,int len)953 static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len)
954 {
955 if(len < 100)
956 return -1;
957
958 sprintf(ptr, "Slot %X: %s\n",
959 board->slot, board->name);
960
961 return strlen(ptr);
962 }
963
nubus_read_proc(char * page,char ** start,off_t off,int count,int * eof,void * data)964 static int nubus_read_proc(char *page, char **start, off_t off,
965 int count, int *eof, void *data)
966 {
967 int nprinted, len, begin = 0;
968 int size = PAGE_SIZE;
969 struct nubus_board* board;
970
971 len = sprintf(page, "Nubus devices found:\n");
972 /* Walk the list of NuBus boards */
973 for (board = nubus_boards; board != NULL; board = board->next)
974 {
975 nprinted = sprint_nubus_board(board, page + len, size - len);
976 if (nprinted < 0)
977 break;
978 len += nprinted;
979 if (len+begin < off) {
980 begin += len;
981 len = 0;
982 }
983 if (len+begin >= off+count)
984 break;
985 }
986 if (len+begin < off)
987 *eof = 1;
988 off -= begin;
989 *start = page + off;
990 len -= off;
991 if (len>count)
992 len = count;
993 if (len<0)
994 len = 0;
995 return len;
996 }
997 #endif
998
nubus_scan_bus(void)999 void __init nubus_scan_bus(void)
1000 {
1001 int slot;
1002 /* This might not work on your machine */
1003 #ifdef I_WANT_TO_PROBE_SLOT_ZERO
1004 nubus_probe_slot(0);
1005 #endif
1006 for(slot = 9; slot < 15; slot++)
1007 {
1008 nubus_probe_slot(slot);
1009 }
1010 }
1011
nubus_init(void)1012 void __init nubus_init(void)
1013 {
1014 if (!MACH_IS_MAC)
1015 return;
1016
1017 /* Initialize the NuBus interrupts */
1018 if (oss_present) {
1019 oss_nubus_init();
1020 } else {
1021 via_nubus_init();
1022 }
1023
1024 #ifdef TRY_TO_DODGE_WSOD
1025 /* Rogue Ethernet interrupts can kill the machine if we don't
1026 do this. Obviously this is bogus. Hopefully the local VIA
1027 gurus can fix the real cause of the problem. */
1028 mdelay(1000);
1029 #endif
1030
1031 /* And probe */
1032 printk("NuBus: Scanning NuBus slots.\n");
1033 nubus_devices = NULL;
1034 nubus_boards = NULL;
1035 nubus_scan_bus();
1036
1037 #ifdef CONFIG_PROC_FS
1038 create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
1039 nubus_proc_init();
1040 #endif
1041 }
1042