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 
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 EXPORT_SYMBOL(nubus_get_rsrc_mem);
192 
nubus_get_rsrc_str(void * dest,const struct nubus_dirent * dirent,int len)193 void 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 }
206 EXPORT_SYMBOL(nubus_get_rsrc_str);
207 
nubus_get_root_dir(const struct nubus_board * board,struct nubus_dir * dir)208 int 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 }
216 EXPORT_SYMBOL(nubus_get_root_dir);
217 
218 /* This is a slyly renamed version of the above */
nubus_get_func_dir(const struct nubus_dev * dev,struct nubus_dir * dir)219 int 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 }
227 EXPORT_SYMBOL(nubus_get_func_dir);
228 
nubus_get_board_dir(const struct nubus_board * board,struct nubus_dir * dir)229 int 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 }
246 EXPORT_SYMBOL(nubus_get_board_dir);
247 
nubus_get_subdir(const struct nubus_dirent * ent,struct nubus_dir * dir)248 int 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 }
256 EXPORT_SYMBOL(nubus_get_subdir);
257 
nubus_readdir(struct nubus_dir * nd,struct nubus_dirent * ent)258 int 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 }
285 EXPORT_SYMBOL(nubus_readdir);
286 
nubus_rewinddir(struct nubus_dir * dir)287 int nubus_rewinddir(struct nubus_dir* dir)
288 {
289 	dir->ptr = dir->base;
290 	return 0;
291 }
292 EXPORT_SYMBOL(nubus_rewinddir);
293 
294 /* Driver interface functions, more or less like in pci.c */
295 
296 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)297 nubus_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 }
316 EXPORT_SYMBOL(nubus_find_device);
317 
318 struct nubus_dev*
nubus_find_type(unsigned short category,unsigned short type,const struct nubus_dev * from)319 nubus_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 }
334 EXPORT_SYMBOL(nubus_find_type);
335 
336 struct nubus_dev*
nubus_find_slot(unsigned int slot,const struct nubus_dev * from)337 nubus_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 }
350 EXPORT_SYMBOL(nubus_find_slot);
351 
352 int
nubus_find_rsrc(struct nubus_dir * dir,unsigned char rsrc_type,struct nubus_dirent * ent)353 nubus_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 }
362 EXPORT_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 
nubus_show_display_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)373 static 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 
nubus_show_network_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)391 static 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 
nubus_show_cpu_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)415 static 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 
nubus_show_private_resource(struct nubus_dev * dev,const struct nubus_dirent * ent)442 static 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 
462 static struct nubus_dev* __init
nubus_get_functional_resource(struct nubus_board * board,int slot,const struct nubus_dirent * parent)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. */
nubus_get_vidnames(struct nubus_board * board,const struct nubus_dirent * parent)557 static 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. */
nubus_get_icon(struct nubus_board * board,const struct nubus_dirent * ent)597 static 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 
nubus_get_vendorinfo(struct nubus_board * board,const struct nubus_dirent * parent)624 static 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 
nubus_get_board_resource(struct nubus_board * board,int slot,const struct nubus_dirent * parent)652 static 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 */
nubus_find_rom_dir(struct nubus_board * board)725 static 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 */
nubus_add_board(int slot,int bytelanes)801 static 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 
nubus_probe_slot(int slot)916 void __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 
sprint_nubus_board(struct nubus_board * board,char * ptr,int len)962 static 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 
nubus_read_proc(char * page,char ** start,off_t off,int count,int * eof,void * data)973 static 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 
nubus_scan_bus(void)1008 void __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 
nubus_init(void)1021 static 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 
1053 subsys_initcall(nubus_init);
1054