Home | History | Annotate | Line # | Download | only in nubus
nubus.c revision 1.9
      1 /*	$NetBSD: nubus.c,v 1.9 1995/04/12 14:57:40 briggs Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
      5  *			Michael L. Finch, Bradley A. Grantham, and
      6  *			Lawrence A. Kesteloot
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *	This product includes software developed by the Alice Group.
     20  * 4. The names of the Alice Group or any of its members may not be used
     21  *    to endorse or promote products derived from this software without
     22  *    specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
     25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27  * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
     28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <machine/cpu.h>
     39 
     40 #include <sys/device.h>
     41 #include "nubus.h"
     42 
     43 
     44 /* TODO:
     45 	be able to do "memcpy"s from the board, then i won't
     46 	have to fill in structures by hand.
     47 
     48 	get rid of extra crap calls that are useless
     49 
     50 	I think the directory stuff is bogus, I need to find
     51         that other magic resource that tells me fancy stuff,
     52         I could be wrong.
     53 
     54 
     55 */
     56 
     57 
     58 struct dir *getRsrcByNum(struct slot *Slot,struct dir *p,int num,struct dir *out,int max);
     59 int print_rsrcinfo(struct slot *Slot,struct dir *p);
     60 char *GetStringInfo(struct slot *Slot,unsigned char *data1,char *space,int len);
     61 int printTree(struct slot *Slot,struct dir *root);
     62 long GetLongInfo(struct slot *,unsigned char *data);
     63 int FindMagic(unsigned long *data);
     64 int GetHeader(struct slot *Slot,unsigned long pos);
     65 unsigned char *IncPtr(struct slot *Slot,unsigned char *p,int size);
     66 char GetByteInfo(struct slot *Slot,unsigned char *data);
     67 int GetRsrcs(struct slot *Slot,unsigned char *p,struct dir *Dir,int maxdir);
     68 unsigned char *getDataAtRsrc(struct slot *Slot,struct dir *p,int num);
     69 short GetShortInfo(struct slot *Slot,unsigned char *data);
     70 
     71 /* this is the main I used in macos to get stuff out */
     72 #if 0
     73 main()
     74 {
     75 
     76 	unsigned long *rawImage;
     77 	struct imagedata image;
     78 	struct dir *Dir;
     79 	struct dir dirSpace[15];
     80 	struct dir dirSpace2[10];
     81 	unsigned long length;
     82 	unsigned long offset;
     83 	unsigned long nextoffset;
     84 	int pos,i;
     85 	unsigned char *data;
     86 	struct slot Slot;
     87 
     88 //	firstHeader=(char *)0xbfffff-40;
     89 
     90 	data=(char *)SLOTADDR-100;
     91 
     92 	for(i=0;i<100;i++)
     93 		if (Slot.size=FindMagic( (long *)(data+i) ) )
     94 		{
     95 			/* printf("magic found at i=%d\n",i); */
     96 			GetHeader(&Slot,SLOTADDR-100+i);
     97 			break;
     98 		}
     99 
    100 
    101 
    102 
    103 	printf("main directory\n");
    104 	print_rsrcinfo(&Slot,Slot.mainDir );
    105 
    106 	Dir=getRsrcByNum(&Slot,Slot.mainDir,128,dirSpace,15);
    107 
    108 	printf("image directory\n");
    109 	print_rsrcinfo(&Slot,Dir);
    110 
    111 	printTree(&Slot,Slot.mainDir);
    112 
    113 // get image param stuff
    114 	Dir=getRsrcByNum(&Slot,Dir,128,dirSpace2,10);
    115 
    116 	/* hopefully video mode params */
    117 	rawImage=getDataAtRsrc(&Slot,Dir,1);
    118 
    119 	image.whatTheHellIsThis=GetLongInfo(&Slot,rawImage);
    120 	rawImage=IncPtr(&Slot,rawImage,4);
    121 
    122 	image.offset=GetLongInfo(&Slot,rawImage);
    123 	rawImage=IncPtr(&Slot,rawImage,4);
    124 
    125 	image.rowbytes=GetShortInfo(&Slot,rawImage);
    126 	rawImage=IncPtr(&Slot,rawImage,2);
    127 
    128 	image.top=GetShortInfo(&Slot,rawImage);
    129 	rawImage=IncPtr(&Slot,rawImage,2);
    130 
    131 	image.left=GetShortInfo(&Slot,rawImage);
    132 	rawImage=IncPtr(&Slot,rawImage,2);
    133 
    134 	image.bottom=GetShortInfo(&Slot,rawImage);
    135 	rawImage=IncPtr(&Slot,rawImage,2);
    136 
    137 	image.right=GetShortInfo(&Slot,rawImage);
    138 	rawImage=IncPtr(&Slot,rawImage,2);
    139 
    140 	image.version=GetShortInfo(&Slot,rawImage);
    141 	rawImage=IncPtr(&Slot,rawImage,2);
    142 
    143 	image.packType=GetShortInfo(&Slot,rawImage);
    144 	rawImage=IncPtr(&Slot,rawImage,2);
    145 
    146 	image.packSize=GetShortInfo(&Slot,rawImage);
    147 	rawImage=IncPtr(&Slot,rawImage,2);
    148 
    149 	image.hRes=GetLongInfo(&Slot,rawImage);
    150 	rawImage=IncPtr(&Slot,rawImage,4);
    151 
    152 	image.vRes=GetLongInfo(&Slot,rawImage);
    153 	rawImage=IncPtr(&Slot,rawImage,4);
    154 
    155 	image.pixelType=GetShortInfo(&Slot,rawImage);
    156 	rawImage=IncPtr(&Slot,rawImage,2);
    157 
    158 	image.pixelSize=GetShortInfo(&Slot,rawImage);
    159 	rawImage=IncPtr(&Slot,rawImage,2);
    160 
    161 
    162 }
    163 #endif /* main */
    164 
    165 int GetHeader(struct slot *Slot,unsigned long pos)
    166 {
    167 	/* the pos passed in is the pos that the magic testvalue was found at */
    168 	unsigned char *p;
    169 	unsigned char *dirBase;
    170 
    171 	switch (Slot->size)
    172 	{
    173 		case 1:	/* char */
    174 			pos-=14;
    175 			break;
    176 		case 2:
    177 			pos-=28;
    178 			break;
    179 		case 4:
    180 			pos-=56;
    181 			break;
    182 	}
    183 
    184 	p=(unsigned char *)pos;
    185 
    186 	Slot->head.offset=(0xff000000 | (unsigned long) GetLongInfo(Slot,p));
    187 	p=IncPtr(Slot,p,4);
    188 
    189 	Slot->head.length=GetLongInfo(Slot,p);
    190 	p=IncPtr(Slot,p,4);
    191 
    192 	Slot->head.crc=GetLongInfo(Slot,p);
    193 	p=IncPtr(Slot,p,4);
    194 
    195 	Slot->head.romrev=GetByteInfo(Slot,p);
    196 	p=IncPtr(Slot,p,1);
    197 
    198 	Slot->head.format=GetByteInfo(Slot,p);
    199 	p=IncPtr(Slot,p,1);
    200 
    201 	Slot->head.tst=GetLongInfo(Slot,p);
    202 	p=IncPtr(Slot,p,4);
    203 
    204 	Slot->head.reserved=GetByteInfo(Slot,p);
    205 	p=IncPtr(Slot,p,1);
    206 
    207 /* byte lanes should be used instead of size, this hasn't bitten me yet */
    208 	Slot->head.bytelane=GetByteInfo(Slot,p);
    209 	p=IncPtr(Slot,p,1);
    210 
    211 	dirBase=(unsigned char *)(pos+Slot->head.offset*Slot->size);
    212 	GetRsrcs(Slot,dirBase,Slot->mainDir,15);
    213 	return 0;
    214 }
    215 
    216 
    217 printTree(struct slot *Slot,struct dir *root)
    218 {
    219 	struct dir *b;
    220 	unsigned char *c;
    221 	struct dir *d;
    222 	unsigned char *e;
    223 	struct dir *f;
    224 	unsigned char *g;
    225 	struct dir *h;
    226 	unsigned char *i;
    227 	unsigned char *j;
    228 	unsigned char *k;
    229 	struct dir bSpace[15];
    230 	struct dir cSpace[15];
    231 	struct dir dSpace[15];
    232 	struct dir fSpace[15];
    233 	struct dir hSpace[15];
    234 	char space[40];
    235 /* to get a good idea of what is happening here you should get the
    236 "slots" program from apple dts, it is so cool.  Its the next
    237 best thing to actual docs, which i didn't have...
    238 */
    239 
    240 	b=getRsrcByNum(Slot,root,1,bSpace,15);
    241 	c=getDataAtRsrc(Slot,b,2);
    242 	d=getRsrcByNum(Slot,b,0x24,dSpace,15);
    243 
    244 	e=getDataAtRsrc(Slot,d,1);
    245 
    246 	f=getRsrcByNum(Slot,root,0x80,fSpace,15);
    247 	g=getDataAtRsrc(Slot,f,2);
    248 	j=getDataAtRsrc(Slot,f,0x0a);
    249 	k=getDataAtRsrc(Slot,f,0x0b);
    250 
    251 	h=getRsrcByNum(Slot,root,0xa0,hSpace,15);
    252 	i=getDataAtRsrc(Slot,h,2);
    253 
    254 	printf("A\n");
    255 	print_rsrcinfo(Slot,root);
    256 
    257 	printf("B\n");
    258 	print_rsrcinfo(Slot,b);
    259 
    260 	printf("C\n");
    261 	printf("%s\n",GetStringInfo(Slot,c,space,40));
    262 
    263 	printf("D\n");
    264 	print_rsrcinfo(Slot,d);
    265 
    266 	printf("E\n");
    267 	printf("%s\n",GetStringInfo(Slot,e,space,40));
    268 
    269 	printf("F\n");
    270 	print_rsrcinfo(Slot,f);
    271 
    272 
    273 	printf("g\n");
    274 	printf("%s\n",GetStringInfo(Slot,g,space,40));
    275 	printf("Video RAM Base %lx\n", GetLongInfo(Slot,j) );
    276 	printf("Video RAM Length %lx\n", GetLongInfo(Slot,k) );
    277 
    278 	printf("H\n");
    279 	print_rsrcinfo(Slot,h);
    280 
    281 	printf("I\n");
    282 	printf("%s\n",GetStringInfo(Slot,i,space,40));
    283 
    284 }
    285 
    286 
    287 print_rsrcinfo(struct slot *Slot,struct dir *p)
    288 {
    289 	int i=0;
    290 	int failsafe=20;
    291 
    292 	if (p==NULL) return 1;
    293 	while(failsafe--)
    294 	{
    295 		printf("RSRC %02x :%06lx\n",p[i].rsrc,p[i].offset);
    296 		if (p[i].rsrc == 0xff) break;
    297 		i++;
    298 	}
    299 
    300 }
    301 
    302 struct dir *getRsrcByNum(struct slot *Slot,struct dir *p,int num,struct dir *out,int max)
    303 {
    304 	int i=0;
    305 	int failsafe=20;
    306 	long nextoffset=0;
    307 	unsigned char *base;
    308 
    309 	if (p==NULL) return NULL;
    310 
    311 
    312 	base=getDataAtRsrc(Slot,p,num);
    313 
    314 	if (NULL==base) return NULL;
    315 
    316 	GetRsrcs(Slot,base,out,max);
    317 
    318 	return out;
    319 }
    320 
    321 char *GetStringInfo(struct slot *Slot,unsigned char *data,char *space,int len)
    322 {
    323 	int i;
    324 	char *p=space;
    325 
    326 	if (NULL==data) return "";
    327 
    328 	for(i=0;(i<len) && *data;i++,p++)
    329 	{
    330 		*p=GetByteInfo(Slot,data);
    331 		data=IncPtr(Slot,data,1);
    332 	}
    333 	*p='\0';
    334 	return space;
    335 }
    336 
    337 long GetLongInfo(struct slot *Slot,unsigned char *data)
    338 {
    339 	long ret=0;
    340 
    341 	switch (Slot->size)
    342 	{
    343 		case 1:
    344 			ret= (unsigned long)data[0]<<24  | (unsigned long)data[1]<<16 | (unsigned long)data[2]<<8 |data[3] ;
    345 			break;
    346 		case 2:
    347 			ret= (unsigned long)data[0]<<24  | (unsigned long)data[2]<<16 | (unsigned long)data[4]<<8 |data[6] ;
    348 			break;
    349 		case 4:
    350 			ret= (unsigned long)data[0]<<24  | (unsigned long)data[4]<<16 | (unsigned long)data[8]<<8 |data[12] ;
    351 			break;
    352 	}
    353 
    354 	return ret;
    355 }
    356 
    357 short GetShortInfo(struct slot *Slot,unsigned char *data)
    358 {
    359 	short ret;
    360 
    361 	switch (Slot->size)
    362 	{
    363 		case 1:
    364 			ret=  (unsigned long)data[0]<<8 |data[1] ;
    365 			break;
    366 		case 2:
    367 			ret=  (unsigned long)data[0]<<8 |data[2] ;
    368 			break;
    369 		case 4:
    370 			ret=  (unsigned long)data[0]<<8 |data[4] ;
    371 			break;
    372 	}
    373 
    374 	return ret;
    375 }
    376 
    377 char GetByteInfo(struct slot *Slot,unsigned char *data)
    378 {
    379 	/* boring  .... */
    380 	return data[0];
    381 }
    382 
    383 
    384 int FindMagic(unsigned long data[])
    385 {
    386 	unsigned short *data2=(unsigned short *)data;
    387 	unsigned char *data3=(unsigned char *)data;
    388 
    389 
    390 	/* char data */
    391 	if (((data3[0] )== 0x5a) &&
    392 		((data3[1] )== 0x93) &&
    393 		((data3[2] )== 0x2b) &&
    394 		((data3[3] )== 0xc7) )
    395 		return 1;
    396 
    397 	/* short data */
    398 
    399 	if (((data3[0] )== 0x5a) &&
    400 		((data3[2] )== 0x93) &&
    401 		((data3[4] )== 0x2b) &&
    402 		((data3[6] )== 0xc7) )
    403 		return 2;
    404 
    405 	/* long data */
    406 	if (((data3[0] )== 0x5a) &&
    407 		((data3[4] )== 0x93) &&
    408 		((data3[8] )== 0x2b) &&
    409 		((data3[12] )== 0xc7) )
    410 		return 4;
    411 
    412 
    413 	return 0;
    414 }
    415 
    416 unsigned char *IncPtr(struct slot *Slot,unsigned char *p,int size)
    417 {
    418 /* MF make this a macro someday */
    419 
    420 	unsigned char *tmp=p;
    421 
    422 	tmp=tmp+size*Slot->size;
    423 
    424 	return tmp;
    425 
    426 }
    427 
    428 int GetRsrcs(struct slot *Slot,unsigned char *p,struct dir *Dir,int maxdir)
    429 {
    430 	int i=0;
    431 /* MF if you alias memory here you will be fucked. */
    432 
    433 	if (p==NULL) return 1;
    434 
    435 	while(maxdir--)
    436 	{
    437 		long entry;
    438 
    439 		entry=GetLongInfo(Slot,p);
    440 
    441 		Dir[i].rsrc=(entry 	& 0xff000000) >> 24;
    442 		Dir[i].offset=entry & 0x00ffffff;
    443 		Dir[i].base=(unsigned long)p;
    444 		p=IncPtr(Slot,p,4);
    445 		if (Dir[i].rsrc==0xff)
    446 			break;
    447 		i++;
    448 	}
    449 
    450 	return 0;
    451 }
    452 
    453 unsigned char *getDataAtRsrc(struct slot *Slot,struct dir *p,int num)
    454 {
    455 	int i=0;
    456 	int failsafe=num;
    457 	long nextoffset=0;
    458 	unsigned char *base;
    459 
    460 	if (p==NULL) return NULL;
    461 
    462 	while(failsafe--)
    463 	{
    464 		if (p[i].rsrc==num)
    465 		{
    466 			base= (unsigned char *)( (unsigned long)Slot->size*p[i].offset+
    467 				(unsigned long)p[i].base );
    468 			return base;
    469 		}
    470 		if (p[i].rsrc==0xff) return NULL;
    471 		i++;
    472 	}
    473 
    474 
    475 
    476 	return NULL;
    477 }
    478 
    479 
    480 int InitNubusSlot(unsigned long slotaddr,struct slot *newSlot)
    481 {
    482 	int i=0;
    483 	struct slot Slot;
    484 	struct dir *b;
    485 	struct dir bSpace[5];
    486 	struct dir *d;
    487 	struct dir dSpace[5];
    488 	struct dir *f;
    489 	struct dir fSpace[5];
    490 	unsigned char *c;
    491 	unsigned char *e;
    492 	unsigned char *g;
    493 
    494 	unsigned long slotend;
    495 
    496 
    497 
    498 	slotend=slotaddr+NBMEMSIZE-1;
    499 
    500 	for(i=5;i<100;i++)
    501 	{
    502 /* lets be quite clear here, if magic is not on the card, then
    503    we will quite likely bus error, because we will read a long
    504    word when there are only 3 bytes left on the card, unless
    505    there is a card in the next slot that has readable memory starting
    506    at 0, so more than likely we crash, ohh well.
    507 
    508    The other day I heard (read) that the directory and the rest of
    509    the card can be in different formats, to this I say FUCK!  So
    510    for the time being I will just assume the whole card is in the
    511    same format, and let it crash most heiniously on bizzare cards
    512    from hell, which I hear has lots of luke warm fresca on tap.
    513 */
    514 		if (Slot.size=FindMagic( (unsigned long *)(slotend-i) ) )
    515 		{
    516 			GetHeader(&Slot,slotend-i);
    517 			break;
    518 		}
    519 	}
    520 
    521 /* ohh ohh Mexico, i've never really been, but I'd sure like to go */
    522 	if (Slot.size)
    523 	{
    524 		b=getRsrcByNum(&Slot,Slot.mainDir,1,bSpace,5);
    525 		c=getDataAtRsrc(&Slot,b,2);
    526 		d=getRsrcByNum(&Slot,b,0x24,dSpace,5);
    527 		e=getDataAtRsrc(&Slot,d,1);
    528 		f=getRsrcByNum(&Slot,Slot.mainDir,0x80,fSpace,5);
    529 		g=getDataAtRsrc(&Slot,f,1);
    530 		GetStringInfo(&Slot,c,Slot.name,40);
    531 /* printf("card is %s, ",Slot.name); */
    532 		GetStringInfo(&Slot,e,Slot.manufacturer,40);
    533 /* printf("%s\n",Slot.manufacturer); */
    534 /* info here is two long words (cat,type,drvrsw,drvrhw) */
    535 		Slot.type=(GetLongInfo(&Slot,g) & 0xffff0000) >> 16;
    536 /* printf("type is %x\n",Slot.type); */
    537 
    538 /* sounds so simple with the sun sinking low */
    539 
    540 	}
    541 	else
    542 		return 1;
    543 /* this comment intentionally left meaningless */
    544 
    545 	*newSlot=Slot;
    546 	return 0;
    547 }
    548 
    549 struct imagedata *NUBUS_GetImageData(struct slot *Slot,
    550 			struct imagedata *Rimage)
    551 {
    552 	struct imagedata image;
    553 	struct dir *Dir;
    554 	struct dir dirSpace[10];
    555 	struct dir dirSpace2[10];
    556 	unsigned char *rawImage;
    557 
    558 
    559 	Dir=getRsrcByNum(Slot,Slot->mainDir,128,dirSpace,10);
    560 	Dir=getRsrcByNum(Slot,Dir,128,dirSpace2,10);
    561 
    562 	rawImage=getDataAtRsrc(Slot,Dir,1);
    563 
    564 /* this is self documenting code, WHAT THE HELL IS THIS? */
    565 	image.whatTheHellIsThis=GetLongInfo(Slot,rawImage);
    566 	rawImage=IncPtr(Slot,rawImage,4);
    567 
    568 	image.offset=GetLongInfo(Slot,rawImage);
    569 	rawImage=IncPtr(Slot,rawImage,4);
    570 
    571 	image.rowbytes=GetShortInfo(Slot,rawImage);
    572 	rawImage=IncPtr(Slot,rawImage,2);
    573 
    574 	image.top=GetShortInfo(Slot,rawImage);
    575 	rawImage=IncPtr(Slot,rawImage,2);
    576 
    577 	image.left=GetShortInfo(Slot,rawImage);
    578 	rawImage=IncPtr(Slot,rawImage,2);
    579 
    580 	image.bottom=GetShortInfo(Slot,rawImage);
    581 	rawImage=IncPtr(Slot,rawImage,2);
    582 
    583 	image.right=GetShortInfo(Slot,rawImage);
    584 	rawImage=IncPtr(Slot,rawImage,2);
    585 
    586 	image.version=GetShortInfo(Slot,rawImage);
    587 	rawImage=IncPtr(Slot,rawImage,2);
    588 
    589 	image.packType=GetShortInfo(Slot,rawImage);
    590 	rawImage=IncPtr(Slot,rawImage,2);
    591 
    592 	image.packSize=GetShortInfo(Slot,rawImage);
    593 	rawImage=IncPtr(Slot,rawImage,2);
    594 
    595 	image.hRes=GetLongInfo(Slot,rawImage);
    596 	rawImage=IncPtr(Slot,rawImage,4);
    597 
    598 	image.vRes=GetLongInfo(Slot,rawImage);
    599 	rawImage=IncPtr(Slot,rawImage,4);
    600 
    601 	image.pixelType=GetShortInfo(Slot,rawImage);
    602 	rawImage=IncPtr(Slot,rawImage,2);
    603 
    604 	image.pixelSize=GetShortInfo(Slot,rawImage);
    605 	rawImage=IncPtr(Slot,rawImage,2);
    606 
    607 	*Rimage=image;
    608 
    609 	return Rimage;
    610 }
    611 
    612 struct	nubus_hw nubus_table[NUBUS_MAXSLOTS];
    613 
    614 extern int
    615 nubus_addr_to_slot(caddr_t addr)
    616 {
    617 	int nubus_num;
    618 
    619 	for (nubus_num = 0 ; nubus_num < NUBUS_MAXSLOTS ; nubus_num++)
    620 		if (nubus_table[nubus_num].addr == addr)
    621 			return nubus_num;
    622 	return -1;
    623 }
    624 
    625 static void
    626 find_nubus(void)
    627 {
    628    /* This functions sets up the array "nubus_table" which contains the
    629    basic information about each card in the Nubus slot.  When device
    630    drivers are initialized later, they can look through this array to
    631    see if their hardware is present and claim it. */
    632 
    633    extern unsigned long	NuBusBase;
    634    register struct nubus_hw *nu;
    635    int nubus_num;
    636 
    637    for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++)
    638      nubus_table[nubus_num].found = 0; /* Empty */
    639 
    640    /* LAK: For now we can only check 9..F because that's all we map
    641    in locore.s.  Eventually (i.e. near future) we should put THIS
    642    function in locore.s before enabling the MMU and only map the
    643    slots that have a card in them.  Also, the next loop should go from
    644    1 to 0xF inclusive (0 is "reserved") to cover all possible hardware.
    645    Even if the MacII only has 9..F, it won't hurt us to probe 1..8 also. */
    646    for (nubus_num = 0; nubus_num < 6; nubus_num++)
    647    {
    648       nu = nubus_table + nubus_num + 9;
    649       nu->addr = (caddr_t)(NuBusBase + nubus_num * NBMEMSIZE);
    650       nu->rom = nu->addr + NBROMOFFSET;
    651 
    652       if(!badbaddr(nu->addr+NBMEMSIZE-1))
    653       {
    654 	 InitNubusSlot((unsigned long) nu->addr, &(nu->Slot));
    655 
    656          nu->found = 1;
    657          nu->claimed = 0; /* No driver has claimed this slot yet */
    658 
    659       }
    660    }
    661 }
    662 
    663 static int
    664 nubus_print(aux, name)
    665 	void	*aux;
    666 	char	*name;
    667 {
    668 	struct nubus_hw	*nu = (struct nubus_hw *) aux;
    669       	int		i;
    670 
    671 	if (name) {
    672 		i = nu - nubus_table;
    673 		printf ("%s: s:%d t:%d \"",
    674 			 name, i, nu->Slot.type);
    675 		printf ("%s, ",nu->Slot.name);
    676 		printf ("%s\"",nu->Slot.manufacturer);
    677 	}
    678 	return(UNCONF);
    679 }
    680 
    681 static void
    682 nubus_attach(parent, self, aux)
    683 	struct device	*parent, *self;
    684 	void		*aux;
    685 {
    686 	register struct nubus_hw *nu;
    687 	int			 i;
    688 
    689 	printf("\n");
    690 
    691 	find_nubus();
    692 
    693 	for (i = 0; i < 6; i++) {
    694 		nu = nubus_table + i + 9;
    695 
    696 		if (!nu->found)
    697 			continue;
    698 
    699 		if (config_found(self, nu, nubus_print))
    700 			nu->claimed = 1;
    701 	}
    702 }
    703 
    704 extern int matchbyname();
    705 
    706 struct cfdriver nubuscd =
    707       { NULL, "nubus", matchbyname, nubus_attach,
    708 	DV_DULL, sizeof(struct device), 1, 0 };
    709