1995-04-21 06:47:35 +04:00
|
|
|
/* $NetBSD: nubus.c,v 1.10 1995/04/21 02:47:59 briggs Exp $ */
|
1994-10-26 11:45:48 +03:00
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
/*-
|
|
|
|
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
|
|
|
* Michael L. Finch, Bradley A. Grantham, and
|
|
|
|
* Lawrence A. Kesteloot
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the Alice Group.
|
|
|
|
* 4. The names of the Alice Group or any of its members may not be used
|
|
|
|
* to endorse or promote products derived from this software without
|
|
|
|
* specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
1994-01-30 04:11:36 +03:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/device.h>
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
#include <machine/cpu.h>
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
#include "nubus.h"
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static struct dir *getRsrcByNum __P((struct slot *slot, struct dir *p,
|
|
|
|
int num, struct dir *out, int max));
|
|
|
|
static int print_rsrcinfo __P((struct slot *slot, struct dir *p));
|
|
|
|
static char *GetStringInfo __P((struct slot *slot, u_char *data1,
|
|
|
|
char *space, int len));
|
|
|
|
static int printTree __P((struct slot *slot, struct dir *root));
|
|
|
|
static long GetLongInfo __P((struct slot *slot, u_char *data));
|
|
|
|
static int FindMagic __P((u_long *data));
|
|
|
|
static int GetHeader __P((struct slot *slot, u_long pos));
|
|
|
|
static u_char *IncPtr __P((struct slot *slot, u_char *p, int size));
|
|
|
|
static char GetByteInfo __P((struct slot *slot, u_char *data));
|
|
|
|
static int GetRsrcs __P((struct slot *slot, u_char *p,
|
|
|
|
struct dir *dir, int maxdir));
|
|
|
|
static u_char *getDataAtRsrc __P((struct slot *slot, struct dir *p, int num));
|
|
|
|
static short GetShortInfo __P((struct slot *slot, u_char *data));
|
|
|
|
|
|
|
|
static int
|
|
|
|
GetHeader(slot, pos)
|
|
|
|
struct slot *slot;
|
|
|
|
u_long pos;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
/* the pos passed in is the pos that the magic testvalue was found at */
|
|
|
|
u_char *p;
|
|
|
|
u_char *dirBase;
|
|
|
|
|
|
|
|
switch (slot->size) {
|
|
|
|
case 1: /* char */
|
|
|
|
pos -= 14;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
pos -= 28;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
pos -= 56;
|
|
|
|
break;
|
|
|
|
}
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
p = (u_char *) pos;
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.offset = (0xff000000 | (u_long) GetLongInfo(slot, p));
|
|
|
|
p = IncPtr(slot, p, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.length = GetLongInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.crc = GetLongInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.romrev = GetByteInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 1);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.format = GetByteInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 1);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.tst = GetLongInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.reserved = GetByteInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 1);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
/* byte lanes should be used instead of size, this hasn't bitten me yet */
|
1995-04-21 06:47:35 +04:00
|
|
|
slot->head.bytelane = GetByteInfo(slot, p);
|
|
|
|
p = IncPtr(slot, p, 1);
|
|
|
|
|
|
|
|
dirBase = (u_char *) (pos + slot->head.offset * slot->size);
|
|
|
|
GetRsrcs(slot, dirBase, slot->mainDir, 15);
|
1993-09-29 09:08:37 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static int
|
|
|
|
printTree(slot, root)
|
|
|
|
struct slot *slot;
|
|
|
|
struct dir *root;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
|
|
|
struct dir *b;
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *c;
|
1993-09-29 09:08:37 +03:00
|
|
|
struct dir *d;
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *e;
|
1993-09-29 09:08:37 +03:00
|
|
|
struct dir *f;
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *g;
|
1993-09-29 09:08:37 +03:00
|
|
|
struct dir *h;
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *i;
|
|
|
|
u_char *j;
|
|
|
|
u_char *k;
|
1993-09-29 09:08:37 +03:00
|
|
|
struct dir bSpace[15];
|
|
|
|
struct dir cSpace[15];
|
|
|
|
struct dir dSpace[15];
|
|
|
|
struct dir fSpace[15];
|
|
|
|
struct dir hSpace[15];
|
1995-04-21 06:47:35 +04:00
|
|
|
char space[40];
|
1993-09-29 09:08:37 +03:00
|
|
|
/* to get a good idea of what is happening here you should get the
|
1995-04-21 06:47:35 +04:00
|
|
|
"slots" program from apple dts, it is so cool. Its the next
|
1993-09-29 09:08:37 +03:00
|
|
|
best thing to actual docs, which i didn't have...
|
|
|
|
*/
|
1995-04-21 06:47:35 +04:00
|
|
|
|
|
|
|
b = getRsrcByNum(slot, root, 1, bSpace, 15);
|
|
|
|
c = getDataAtRsrc(slot, b, 2);
|
|
|
|
d = getRsrcByNum(slot, b, 0x24, dSpace, 15);
|
|
|
|
|
|
|
|
e = getDataAtRsrc(slot, d, 1);
|
|
|
|
|
|
|
|
f = getRsrcByNum(slot, root, 0x80, fSpace, 15);
|
|
|
|
g = getDataAtRsrc(slot, f, 2);
|
|
|
|
j = getDataAtRsrc(slot, f, 0x0a);
|
|
|
|
k = getDataAtRsrc(slot, f, 0x0b);
|
|
|
|
|
|
|
|
h = getRsrcByNum(slot, root, 0xa0, hSpace, 15);
|
|
|
|
i = getDataAtRsrc(slot, h, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
printf("A\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
print_rsrcinfo(slot, root);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
printf("B\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
print_rsrcinfo(slot, b);
|
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
printf("C\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
printf("%s\n", GetStringInfo(slot, c, space, 40));
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
printf("D\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
print_rsrcinfo(slot, d);
|
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
printf("E\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
printf("%s\n", GetStringInfo(slot, e, space, 40));
|
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
printf("F\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
print_rsrcinfo(slot, f);
|
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
printf("g\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
printf("%s\n", GetStringInfo(slot, g, space, 40));
|
|
|
|
printf("Video RAM Base %lx\n", GetLongInfo(slot, j));
|
|
|
|
printf("Video RAM Length %lx\n", GetLongInfo(slot, k));
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
printf("H\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
print_rsrcinfo(slot, h);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
printf("I\n");
|
1995-04-21 06:47:35 +04:00
|
|
|
printf("%s\n", GetStringInfo(slot, i, space, 40));
|
1993-09-29 09:08:37 +03:00
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static int
|
|
|
|
print_rsrcinfo(slot, p)
|
|
|
|
struct slot *slot;
|
|
|
|
struct dir *p;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
int i = 0;
|
|
|
|
int failsafe = 20;
|
|
|
|
|
|
|
|
if (p == NULL)
|
|
|
|
return 1;
|
|
|
|
while (failsafe--) {
|
|
|
|
printf("RSRC %02x :%06lx\n", p[i].rsrc, p[i].offset);
|
|
|
|
if (p[i].rsrc == 0xff)
|
|
|
|
break;
|
1993-09-29 09:08:37 +03:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static struct dir *
|
|
|
|
getRsrcByNum(slot, p, num, out, max)
|
|
|
|
struct slot *slot;
|
|
|
|
struct dir *p;
|
|
|
|
int num;
|
|
|
|
struct dir *out;
|
|
|
|
int max;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
int i = 0;
|
|
|
|
int failsafe = 20;
|
|
|
|
long nextoffset = 0;
|
|
|
|
u_char *base;
|
|
|
|
|
|
|
|
if (p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
base = getDataAtRsrc(slot, p, num);
|
|
|
|
|
|
|
|
if (NULL == base)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
GetRsrcs(slot, base, out, max);
|
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static char *
|
|
|
|
GetStringInfo(slot, data, space, len)
|
|
|
|
struct slot *slot;
|
|
|
|
u_char *data;
|
|
|
|
char *space;
|
|
|
|
int len;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
|
|
|
int i;
|
1995-04-21 06:47:35 +04:00
|
|
|
char *p = space;
|
|
|
|
|
|
|
|
if (NULL == data)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
for (i = 0; (i < len) && *data; i++, p++) {
|
|
|
|
*p = GetByteInfo(slot, data);
|
|
|
|
data = IncPtr(slot, data, 1);
|
1993-09-29 09:08:37 +03:00
|
|
|
}
|
1995-04-21 06:47:35 +04:00
|
|
|
*p = '\0';
|
1993-09-29 09:08:37 +03:00
|
|
|
return space;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static long
|
|
|
|
GetLongInfo(slot, data)
|
|
|
|
struct slot *slot;
|
|
|
|
u_char *data;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
long ret = 0;
|
|
|
|
|
|
|
|
switch (slot->size) {
|
|
|
|
case 1:
|
|
|
|
ret = (u_long) data[0] << 24 | (u_long) data[1] << 16
|
|
|
|
| (u_long) data[2] << 8 | data[3];
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
ret = (u_long) data[0] << 24 | (u_long) data[2] << 16
|
|
|
|
| (u_long) data[4] << 8 | data[6];
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
ret = (u_long) data[0] << 24 | (u_long) data[4] << 16
|
|
|
|
| (u_long) data[8] << 8 | data[12];
|
|
|
|
break;
|
1993-09-29 09:08:37 +03:00
|
|
|
}
|
1995-04-21 06:47:35 +04:00
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static short
|
|
|
|
GetShortInfo(slot, data)
|
|
|
|
struct slot *slot;
|
|
|
|
u_char *data;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
short ret;
|
|
|
|
|
|
|
|
switch (slot->size) {
|
|
|
|
case 1:
|
|
|
|
ret = (u_long) data[0] << 8 | data[1];
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
ret = (u_long) data[0] << 8 | data[2];
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
ret = (u_long) data[0] << 8 | data[4];
|
|
|
|
break;
|
1993-09-29 09:08:37 +03:00
|
|
|
}
|
1995-04-21 06:47:35 +04:00
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static char
|
|
|
|
GetByteInfo(slot, data)
|
|
|
|
struct slot *slot;
|
|
|
|
u_char *data;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
/* boring .... */
|
1993-09-29 09:08:37 +03:00
|
|
|
return data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static int
|
|
|
|
FindMagic(data)
|
|
|
|
u_long data[];
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
u_short *data2;
|
|
|
|
u_char *data3 = (u_char *) data;
|
|
|
|
|
|
|
|
data2 = (u_short *) data;
|
|
|
|
data3 = (u_char *) data;
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
/* char data */
|
1995-04-21 06:47:35 +04:00
|
|
|
if (((data3[0]) == 0x5a) &&
|
|
|
|
((data3[1]) == 0x93) &&
|
|
|
|
((data3[2]) == 0x2b) &&
|
|
|
|
((data3[3]) == 0xc7))
|
1993-09-29 09:08:37 +03:00
|
|
|
return 1;
|
1995-04-21 06:47:35 +04:00
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
/* short data */
|
1995-04-21 06:47:35 +04:00
|
|
|
if (((data3[0]) == 0x5a) &&
|
|
|
|
((data3[2]) == 0x93) &&
|
|
|
|
((data3[4]) == 0x2b) &&
|
|
|
|
((data3[6]) == 0xc7))
|
1993-09-29 09:08:37 +03:00
|
|
|
return 2;
|
1995-04-21 06:47:35 +04:00
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
/* long data */
|
1995-04-21 06:47:35 +04:00
|
|
|
if (((data3[0]) == 0x5a) &&
|
|
|
|
((data3[4]) == 0x93) &&
|
|
|
|
((data3[8]) == 0x2b) &&
|
|
|
|
((data3[12]) == 0xc7))
|
1993-09-29 09:08:37 +03:00
|
|
|
return 4;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static u_char *
|
|
|
|
IncPtr(slot, p, size)
|
|
|
|
struct slot *slot;
|
|
|
|
u_char *p;
|
|
|
|
int size;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *tmp;
|
|
|
|
|
|
|
|
tmp = p + size * slot->size;
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static int
|
|
|
|
GetRsrcs(slot, p, dir, maxdir)
|
|
|
|
struct slot *slot;
|
|
|
|
u_char *p;
|
|
|
|
struct dir *dir;
|
|
|
|
int maxdir;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (p == NULL)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
while (maxdir--) {
|
|
|
|
long entry;
|
|
|
|
|
|
|
|
entry = GetLongInfo(slot, p);
|
|
|
|
|
|
|
|
dir[i].rsrc = (entry & 0xff000000) >> 24;
|
|
|
|
dir[i].offset = entry & 0x00ffffff;
|
|
|
|
dir[i].base = (u_long) p;
|
|
|
|
p = IncPtr(slot, p, 4);
|
|
|
|
if (dir[i].rsrc == 0xff)
|
1993-09-29 09:08:37 +03:00
|
|
|
break;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static u_char *
|
|
|
|
getDataAtRsrc(slot, p, num)
|
|
|
|
struct slot *slot;
|
|
|
|
struct dir *p;
|
|
|
|
int num;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
int i = 0;
|
|
|
|
int failsafe = num;
|
|
|
|
long nextoffset = 0;
|
|
|
|
u_char *base;
|
|
|
|
|
|
|
|
if (p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
while (failsafe--) {
|
|
|
|
if (p[i].rsrc == num) {
|
|
|
|
base = (u_char *) ((u_long) slot->size * p[i].offset +
|
|
|
|
(u_long) p[i].base);
|
1993-09-29 09:08:37 +03:00
|
|
|
return base;
|
|
|
|
}
|
1995-04-21 06:47:35 +04:00
|
|
|
if (p[i].rsrc == 0xff)
|
|
|
|
return NULL;
|
1993-09-29 09:08:37 +03:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
static int
|
|
|
|
InitNubusSlot(slotaddr, newslot)
|
|
|
|
u_long slotaddr;
|
|
|
|
struct slot *newslot;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
int i = 0;
|
|
|
|
struct slot slot;
|
1993-09-29 09:08:37 +03:00
|
|
|
struct dir *b;
|
|
|
|
struct dir bSpace[5];
|
|
|
|
struct dir *d;
|
|
|
|
struct dir dSpace[5];
|
|
|
|
struct dir *f;
|
|
|
|
struct dir fSpace[5];
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *c;
|
|
|
|
u_char *e;
|
|
|
|
u_char *g;
|
|
|
|
u_long slotend;
|
|
|
|
|
|
|
|
slotend = slotaddr + NBMEMSIZE - 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If magic is not on the card, then we will quite likely bus error,
|
|
|
|
* because we will read a long word when there are only 3 bytes left
|
|
|
|
* on the card, unless there is a card in the next slot that has
|
|
|
|
* readable memory starting at 0, so more than likely we crash. Oh well.
|
|
|
|
*
|
|
|
|
* The directory and the rest of the card can be in different formats.
|
|
|
|
* This code won't handle that case.
|
|
|
|
*/
|
|
|
|
for (i = 5; i < 100; i++) {
|
|
|
|
if (slot.size = FindMagic((u_long *) (slotend - i))) {
|
|
|
|
GetHeader(&slot, slotend - i);
|
1993-09-29 09:08:37 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1995-04-21 06:47:35 +04:00
|
|
|
|
|
|
|
if (slot.size) {
|
|
|
|
b = getRsrcByNum(&slot, slot.mainDir, 1, bSpace, 5);
|
|
|
|
c = getDataAtRsrc(&slot, b, 2);
|
|
|
|
d = getRsrcByNum(&slot, b, 0x24, dSpace, 5);
|
|
|
|
e = getDataAtRsrc(&slot, d, 1);
|
|
|
|
f = getRsrcByNum(&slot, slot.mainDir, 0x80, fSpace, 5);
|
|
|
|
g = getDataAtRsrc(&slot, f, 1);
|
|
|
|
GetStringInfo(&slot, c, slot.name, 40);
|
|
|
|
|
|
|
|
GetStringInfo(&slot, e, slot.manufacturer, 40);
|
|
|
|
|
1993-09-29 09:08:37 +03:00
|
|
|
/* info here is two long words (cat,type,drvrsw,drvrhw) */
|
1995-04-21 06:47:35 +04:00
|
|
|
slot.type = (GetLongInfo(&slot, g) & 0xffff0000) >> 16;
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
} else
|
1993-09-29 09:08:37 +03:00
|
|
|
return 1;
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
*newslot = slot;
|
1993-09-29 09:08:37 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
struct imagedata *
|
|
|
|
NUBUS_GetImageData(slot, Rimage)
|
|
|
|
struct slot *slot;
|
|
|
|
struct imagedata *Rimage;
|
1993-09-29 09:08:37 +03:00
|
|
|
{
|
|
|
|
struct imagedata image;
|
1995-04-21 06:47:35 +04:00
|
|
|
struct dir *dir;
|
1993-09-29 09:08:37 +03:00
|
|
|
struct dir dirSpace[10];
|
|
|
|
struct dir dirSpace2[10];
|
1995-04-21 06:47:35 +04:00
|
|
|
u_char *rawImage;
|
|
|
|
|
|
|
|
|
|
|
|
dir = getRsrcByNum(slot, slot->mainDir, 128, dirSpace, 10);
|
|
|
|
dir = getRsrcByNum(slot, dir, 128, dirSpace2, 10);
|
|
|
|
|
|
|
|
rawImage = getDataAtRsrc(slot, dir, 1);
|
|
|
|
|
|
|
|
image.whatTheHellIsThis = GetLongInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.offset = GetLongInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.rowbytes = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.top = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.left = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.bottom = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.right = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.version = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.packType = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.packSize = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.hRes = GetLongInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.vRes = GetLongInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 4);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.pixelType = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
image.pixelSize = GetShortInfo(slot, rawImage);
|
|
|
|
rawImage = IncPtr(slot, rawImage, 2);
|
1993-09-29 09:08:37 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
*Rimage = image;
|
1993-09-29 09:08:37 +03:00
|
|
|
|
|
|
|
return Rimage;
|
|
|
|
}
|
1993-11-29 03:32:22 +03:00
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
struct nubus_hw nubus_table[NUBUS_MAXSLOTS];
|
1993-11-29 03:32:22 +03:00
|
|
|
|
1993-12-21 06:18:00 +03:00
|
|
|
extern int
|
1995-04-21 06:47:35 +04:00
|
|
|
nubus_addr_to_slot(addr)
|
|
|
|
caddr_t addr;
|
1993-12-21 06:18:00 +03:00
|
|
|
{
|
|
|
|
int nubus_num;
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++)
|
1993-12-21 06:18:00 +03:00
|
|
|
if (nubus_table[nubus_num].addr == addr)
|
|
|
|
return nubus_num;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
1993-11-29 03:32:22 +03:00
|
|
|
static void
|
1995-04-21 06:47:35 +04:00
|
|
|
find_nubus()
|
1993-11-29 03:32:22 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
/*
|
|
|
|
* This function sets up the array "nubus_table" which contains the
|
|
|
|
* basic information about each card in the Nubus slot. When device
|
|
|
|
* drivers are initialized later, they can look through this array to
|
|
|
|
* see if their hardware is present and claim it.
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern u_long NuBusBase;
|
|
|
|
register struct nubus_hw *nu;
|
|
|
|
int nubus_num;
|
|
|
|
|
|
|
|
for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++)
|
|
|
|
nubus_table[nubus_num].found = 0; /* Empty */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LAK: For now we can only check 9..F because that's all we map in
|
|
|
|
* locore.s. Eventually (i.e. near future) we should put THIS
|
|
|
|
* function in locore.s before enabling the MMU and only map the slots
|
|
|
|
* that have a card in them. Also, the next loop should go from 1 to
|
|
|
|
* 0xF inclusive (0 is "reserved") to cover all possible hardware.
|
|
|
|
* Even if the MacII only has 9..F, it won't hurt us to probe 1..8
|
|
|
|
* also.
|
|
|
|
*/
|
|
|
|
for (nubus_num = 0; nubus_num < 6; nubus_num++) {
|
|
|
|
nu = nubus_table + nubus_num + 9;
|
|
|
|
nu->addr = (caddr_t) (NuBusBase + nubus_num * NBMEMSIZE);
|
|
|
|
nu->rom = nu->addr + NBROMOFFSET;
|
|
|
|
|
|
|
|
if (!badbaddr(nu->addr + NBMEMSIZE - 1)) {
|
|
|
|
InitNubusSlot((u_long) nu->addr, &(nu->slot));
|
|
|
|
|
|
|
|
nu->found = 1;
|
|
|
|
nu->claimed = 0; /* No driver has claimed this
|
|
|
|
* slot yet */
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
1993-11-29 03:32:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
nubus_print(aux, name)
|
1995-04-21 06:47:35 +04:00
|
|
|
void *aux;
|
|
|
|
char *name;
|
1993-11-29 03:32:22 +03:00
|
|
|
{
|
1995-04-21 06:47:35 +04:00
|
|
|
struct nubus_hw *nu = (struct nubus_hw *) aux;
|
|
|
|
int i;
|
1993-11-29 03:32:22 +03:00
|
|
|
|
|
|
|
if (name) {
|
|
|
|
i = nu - nubus_table;
|
1995-04-21 06:47:35 +04:00
|
|
|
printf("%s: s:%d t:%d \"",
|
|
|
|
name, i, nu->slot.type);
|
|
|
|
printf("%s, ", nu->slot.name);
|
|
|
|
printf("%s\"", nu->slot.manufacturer);
|
1993-11-29 03:32:22 +03:00
|
|
|
}
|
1995-04-21 06:47:35 +04:00
|
|
|
return (UNCONF);
|
1993-11-29 03:32:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1995-04-12 18:57:40 +04:00
|
|
|
nubus_attach(parent, self, aux)
|
1995-04-21 06:47:35 +04:00
|
|
|
struct device *parent, *self;
|
|
|
|
void *aux;
|
1993-11-29 03:32:22 +03:00
|
|
|
{
|
|
|
|
register struct nubus_hw *nu;
|
1995-04-21 06:47:35 +04:00
|
|
|
int i;
|
1993-11-29 03:32:22 +03:00
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
find_nubus();
|
|
|
|
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
nu = nubus_table + i + 9;
|
|
|
|
|
|
|
|
if (!nu->found)
|
|
|
|
continue;
|
|
|
|
|
1995-04-12 18:57:40 +04:00
|
|
|
if (config_found(self, nu, nubus_print))
|
1993-11-29 03:32:22 +03:00
|
|
|
nu->claimed = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern int matchbyname();
|
|
|
|
|
1995-04-21 06:47:35 +04:00
|
|
|
struct cfdriver nubuscd = {
|
|
|
|
NULL, "nubus", matchbyname, nubus_attach,
|
|
|
|
DV_DULL, sizeof(struct device), 1
|
|
|
|
};
|