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