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