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