⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nubus.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* Ditto */			nubus_get_rsrc_mem(&dev->iosize, &ent, 4);			printk(KERN_INFO "    memory length: 0x%08lx\n",			       dev->iosize);			break;					case NUBUS_RESID_FLAGS:			dev->flags = ent.data;			printk(KERN_INFO "    flags: 0x%06x\n", dev->flags);			break;		case NUBUS_RESID_HWDEVID:			dev->hwdevid = ent.data;			printk(KERN_INFO "    hwdevid: 0x%06x\n", dev->hwdevid);			break;		default:			/* Local/Private resources have their own			   function */			nubus_show_private_resource(dev, &ent);		}	}			return dev;}/* This is cool. */static int __init nubus_get_vidnames(struct nubus_board* board,				     const struct nubus_dirent* parent){	struct nubus_dir    dir;	struct nubus_dirent ent;	/* FIXME: obviously we want to put this in a header file soon */	struct vidmode {		u32 size;		/* Don't know what this is yet */		u16 id;		/* Longest one I've seen so far is 26 characters */		char name[32];	};	printk(KERN_INFO "    video modes supported:\n");	nubus_get_subdir(parent, &dir);	if (console_loglevel >= 10)		printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n",		       parent->base, dir.base);	while(nubus_readdir(&dir, &ent) != -1)	{		struct vidmode mode;		u32 size;		/* First get the length */		nubus_get_rsrc_mem(&size, &ent, 4);				/* Now clobber the whole thing */		if (size > sizeof(mode) - 1)			size = sizeof(mode) - 1;		memset(&mode, 0, sizeof(mode));		nubus_get_rsrc_mem(&mode, &ent, size);		printk (KERN_INFO "      %02X: (%02X) %s\n", ent.type,			mode.id, mode.name);	}	return 0;}/* This is *really* cool. */static int __init nubus_get_icon(struct nubus_board* board,				 const struct nubus_dirent* ent){	/* Should be 32x32 if my memory serves me correctly */	unsigned char icon[128];	int x, y;		nubus_get_rsrc_mem(&icon, ent, 128);	printk(KERN_INFO "    icon:\n");	/* We should actually plot these somewhere in the framebuffer	   init.  This is just to demonstrate that they do, in fact,	   exist */	for (y = 0; y < 32; y++) {		printk(KERN_INFO "      ");		for (x = 0; x < 32; x++) {			if (icon[y*4 + x/8]			    & (0x80 >> (x%8)))				printk("*");			else				printk(" ");		}		printk("\n");	}	return 0;}static int __init nubus_get_vendorinfo(struct nubus_board* board,				       const struct nubus_dirent* parent){	struct nubus_dir    dir;	struct nubus_dirent ent;	static char* vendor_fields[6] = {"ID", "serial", "revision",					 "part", "date", "unknown field"};	printk(KERN_INFO "    vendor info:\n");	nubus_get_subdir(parent, &dir);	if (console_loglevel >= 10)		printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n",		       parent->base, dir.base);	while(nubus_readdir(&dir, &ent) != -1)	{		char name[64];				/* These are all strings, we think */		nubus_get_rsrc_str(name, &ent, 64);		if (ent.type > 5)			ent.type = 5;		printk(KERN_INFO "    %s: %s\n",		       vendor_fields[ent.type-1], name);	}	return 0;}static int __init nubus_get_board_resource(struct nubus_board* board, int slot,					   const struct nubus_dirent* parent){	struct nubus_dir    dir;	struct nubus_dirent ent;		nubus_get_subdir(parent, &dir);	if (console_loglevel >= 10)		printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",		       parent->base, dir.base);	while(nubus_readdir(&dir, &ent) != -1)	{		switch (ent.type) {		case NUBUS_RESID_TYPE:		{			unsigned short nbtdata[4];			/* This type is always the same, and is not			   useful except insofar as it tells us that			   we really are looking at a board resource. */			nubus_get_rsrc_mem(nbtdata, &ent, 8);			printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",			       nbtdata[0], nbtdata[1], nbtdata[2],			       nbtdata[3]);			if (nbtdata[0] != 1 || nbtdata[1] != 0 ||			    nbtdata[2] != 0 || nbtdata[3] != 0)				printk(KERN_ERR "this sResource is not a board resource!\n");			break;		}		case NUBUS_RESID_NAME:			nubus_get_rsrc_str(board->name, &ent, 64);			printk(KERN_INFO "    name: %s\n", board->name);			break;		case NUBUS_RESID_ICON:			nubus_get_icon(board, &ent);			break;		case NUBUS_RESID_BOARDID:			printk(KERN_INFO "    board id: 0x%x\n", ent.data);			break;		case NUBUS_RESID_PRIMARYINIT:			printk(KERN_INFO "    primary init offset: 0x%06x\n", ent.data);			break;		case NUBUS_RESID_VENDORINFO:			nubus_get_vendorinfo(board, &ent);			break;		case NUBUS_RESID_FLAGS:			printk(KERN_INFO "    flags: 0x%06x\n", ent.data);			break;		case NUBUS_RESID_HWDEVID:			printk(KERN_INFO "    hwdevid: 0x%06x\n", ent.data);			break;		case NUBUS_RESID_SECONDINIT:			printk(KERN_INFO "    secondary init offset: 0x%06x\n", ent.data);			break;			/* WTF isn't this in the functional resources? */ 		case NUBUS_RESID_VIDNAMES:			nubus_get_vidnames(board, &ent);			break;			/* Same goes for this */		case NUBUS_RESID_VIDMODES:			printk(KERN_INFO "    video mode parameter directory offset: 0x%06x\n",			       ent.data);			break;					default:			printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",			       ent.type, ent.data);		}	}	return 0;}/* Attempt to bypass the somewhat non-obvious arrangement of   sResources in the motherboard ROM */static void __init nubus_find_rom_dir(struct nubus_board* board){	unsigned char* rp;	unsigned char* romdir;	struct nubus_dir dir;	struct nubus_dirent ent;	/* Check for the extra directory just under the format block */	rp = board->fblock;	nubus_rewind(&rp, 4, board->lanes);	if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) {		/* OK, the ROM was telling the truth */		board->directory = board->fblock;		nubus_move(&board->directory,			   nubus_expand32(board->doffset),			   board->lanes);		return;	}	/* On "slot zero", you have to walk down a few more	   directories to get to the equivalent of a real card's root	   directory.  We don't know what they were smoking when they	   came up with this. */	romdir = nubus_rom_addr(board->slot);	nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes);	dir.base = dir.ptr = romdir;	dir.done = 0;	dir.mask = board->lanes;	/* This one points to an "Unknown Macintosh" directory */	if (nubus_readdir(&dir, &ent) == -1)		goto badrom;	if (console_loglevel >= 10)		printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);	/* This one takes us to where we want to go. */	if (nubus_readdir(&dir, &ent) == -1) 		goto badrom;	if (console_loglevel >= 10)		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);	nubus_get_subdir(&ent, &dir);	/* Resource ID 01, also an "Unknown Macintosh" */	if (nubus_readdir(&dir, &ent) == -1) 		goto badrom;	if (console_loglevel >= 10)		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);	/* FIXME: the first one is *not* always the right one.  We	   suspect this has something to do with the ROM revision.	   "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR	   Continues" (Q630) uses 0x7b.  The DAFB Macs evidently use	   something else.  Please run "Slots" on your Mac (see	   include/linux/nubus.h for where to get this program) and	   tell us where the 'SiDirPtr' for Slot 0 is.  If you feel	   brave, you should also use MacsBug to walk down the ROM	   directories like this function does and try to find the	   path to that address... */	if (nubus_readdir(&dir, &ent) == -1)		goto badrom;	if (console_loglevel >= 10)		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);		/* Bwahahahaha... */	nubus_get_subdir(&ent, &dir);	board->directory = dir.base;	return;		/* Even more evil laughter... */ badrom:	board->directory = board->fblock;	nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes);	printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness!  Notify the developers...\n");}/* Add a board (might be many devices) to the list */static struct nubus_board* __init nubus_add_board(int slot, int bytelanes){	struct nubus_board* board;	struct nubus_board** boardp;	unsigned char *rp;	unsigned long dpat;	struct nubus_dir dir;	struct nubus_dirent ent;	/* Move to the start of the format block */	rp = nubus_rom_addr(slot);			nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);	/* Actually we should probably panic if this fails */	if ((board = kmalloc(sizeof(*board), GFP_ATOMIC)) == NULL)		return NULL;		memset(board, 0, sizeof(*board));	board->fblock = rp;	/* Dump the format block for debugging purposes */	if (console_loglevel >= 10) {		int i;		printk(KERN_DEBUG "Slot %X, format block at 0x%p\n",		       slot, rp);		printk(KERN_DEBUG "Format block: ");		for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) {			unsigned short foo, bar;			foo = nubus_get_rom(&rp, 2, bytelanes);			bar = nubus_get_rom(&rp, 2, bytelanes);			printk("%04x %04x  ", foo, bar);		}		printk("\n");		rp = board->fblock;	}		board->slot = slot;	board->slot_addr = (unsigned long) nubus_slot_addr(slot);	board->doffset = nubus_get_rom(&rp, 4, bytelanes);	/* rom_length is *supposed* to be the total length of the	 * ROM.  In practice it is the "amount of ROM used to compute	 * the CRC."  So some jokers decide to set it to zero and	 * set the crc to zero so they don't have to do any math.	 * See the Performa 460 ROM, for example.  Those Apple "engineers".	 */	board->rom_length = nubus_get_rom(&rp, 4, bytelanes);	board->crc = nubus_get_rom(&rp, 4, bytelanes);	board->rev = nubus_get_rom(&rp, 1, bytelanes);	board->format = nubus_get_rom(&rp,1, bytelanes);	board->lanes = bytelanes;	/* Directory offset should be small and negative... */	if(!(board->doffset & 0x00FF0000))		printk(KERN_WARNING "Dodgy doffset!\n");	dpat = nubus_get_rom(&rp, 4, bytelanes);	if(dpat != NUBUS_TEST_PATTERN)		printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat);			/*	 *	I wonder how the CRC is meant to work -	 *		any takers ?	 * CSA: According to MAC docs, not all cards pass the CRC anyway,	 * since the initial Macintosh ROM releases skipped the check.	 */	/* Attempt to work around slot zero weirdness */	nubus_find_rom_dir(board);	nubus_get_root_dir(board, &dir);		/* We're ready to rock */	printk(KERN_INFO "Slot %X:\n", slot);	/* Each slot should have one board resource and any number of	   functional resources.  So we'll fill in some fields in the	   struct nubus_board from the board resource, then walk down	   the list of functional resources, spinning out a nubus_dev	   for each of them. */	if (nubus_readdir(&dir, &ent) == -1) {		/* We can't have this! */		printk(KERN_ERR "Board resource not found!\n");		return NULL;	} else {		printk(KERN_INFO "  Board resource:\n");		nubus_get_board_resource(board, slot, &ent);	}	/* Aaaarrrrgghh!  The LC III motherboard has *two* board	   resources.  I have no idea WTF to do about this. */	while (nubus_readdir(&dir, &ent) != -1) {		struct nubus_dev*  dev;		struct nubus_dev** devp;		dev = nubus_get_functional_resource(board, slot, &ent);		if (dev == NULL)			continue;		/* We zeroed this out above */		if (board->first_dev == NULL)			board->first_dev = dev;				/* Put it on the global NuBus device chain. Keep entries in order. */		for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next))			/* spin */;		*devp = dev;		dev->next = NULL;			}	/* Put it on the global NuBus board chain. Keep entries in order. */	for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next))		/* spin */;	*boardp = board;	board->next = NULL;		return board;}void __init nubus_probe_slot(int slot){	unsigned char dp;	unsigned char* rp;	int i;	rp = nubus_rom_addr(slot);		for(i = 4; i; i--)	{		unsigned long flags;		int card_present;		rp--;		save_flags(flags);		cli();		card_present = hwreg_present(rp);		restore_flags(flags);	       		if (!card_present)			continue;		printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp);		dp = *rp;		if(dp == 0)			continue;		/* The last byte of the format block consists of two		   nybbles which are "mirror images" of each other.		   These show us the valid bytelanes */		if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)			continue;		/* Check that this value is actually *on* one of the		   bytelanes it claims are valid! */		if ((dp & 0x0F) >= (1<<i))			continue;		/* Looks promising.  Let's put it on the list. */		nubus_add_board(slot, dp);		return;	}}#if defined(CONFIG_PROC_FS)/* /proc/nubus stuff */static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len){	if(len < 100)		return -1;		sprintf(ptr, "Slot %X: %s\n",		board->slot, board->name);		return strlen(ptr);}static int nubus_read_proc(char *buf, char **start, off_t off,				int count, int *eof, void *data){	int nprinted, len, begin = 0;	int slot,size;	struct nubus_board* board;		len   = sprintf(buf, "Nubus devices found:\n");	/* Walk the list of NuBus boards */	for (board = nubus_boards; board != NULL; board = board->next)	{		nprinted = sprint_nubus_board(board, buf + len, size - len);		if (nprinted < 0)			break;		len += nprinted;		if (len+begin < off) {			begin += len;			len = 0;		}		if (len+begin >= off+count)			break;	}	if (slot==16 || len+begin < off)		*eof = 1;	off -= begin;	*start = buf + off;	len -= off;	if (len>count)		len = count;	if (len<0)		len = 0;	return len;}#endifvoid __init nubus_scan_bus(void){	int slot;	/* This might not work on your machine */#ifdef I_WANT_TO_PROBE_SLOT_ZERO	nubus_probe_slot(0);#endif	for(slot = 9; slot < 15; slot++)	{		nubus_probe_slot(slot);	}}void __init nubus_init(void){	if (!MACH_IS_MAC) 		return;	/* Initialize the NuBus interrupts */	if (oss_present) {		oss_nubus_init();	} else {		via_nubus_init();	}#ifdef TRY_TO_DODGE_WSOD	/* Rogue Ethernet interrupts can kill the machine if we don't	   do this.  Obviously this is bogus.  Hopefully the local VIA	   gurus can fix the real cause of the problem. */	mdelay(1000);#endif		/* And probe */	printk("NuBus: Scanning NuBus slots.\n");	nubus_devices = NULL;	nubus_boards  = NULL;	nubus_scan_bus();#ifdef CONFIG_PROC_FS	create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);	nubus_proc_init();#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -