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