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

📄 i82586.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
	*(short *)(mem_start + rx_tail + 2) = 0;	rx_tail = rx_head;	rx_head = next_rx_frame;	ack_status();	return (status);}/**************************************************************************  TRANSMIT - Transmit a frame ***************************************************************************/static void i82586_transmit(		struct nic *nic,		const char *d,			/* Destination */		unsigned int t,			/* Type */		unsigned int s,			/* size */		const char *p)			/* Packet */{	Address			bptr;	unsigned short		type, z;	static unsigned short	tx_cmd[11] = {		0x0,			/* Tx status */		CmdTx,			/* Tx command */		TX_BUF_START+16,	/* Next command is a NoOp */		TX_BUF_START+8,		/* Data Buffer offset */		0x8000,			/* | with size */		0xffff,			/* No next data buffer */		TX_BUF_START+22,	/* + scb_base */		0x0,			/* Buffer address high bits (always zero) */		0x0,			/* Nop status */		CmdNOp,			/* Nop command */		TX_BUF_START+16		/* Next is myself */	};	unsigned short	*shmem = (short *)mem_start + TX_BUF_START;	/* send the packet to destination */	/* adjust some contents */	type = htons(t);	if (s < ETH_ZLEN)		s = ETH_ZLEN;	tx_cmd[4] = (s + ETH_HLEN) | 0x8000;	tx_cmd[6] = TX_BUF_START + 22 + scb_base;	bptr = mem_start + TX_BUF_START;	memcpy((char *)bptr, (char *)tx_cmd, sizeof(tx_cmd));	bptr += sizeof(tx_cmd);	memcpy((char *)bptr, d, ETH_ALEN);	bptr += ETH_ALEN;	memcpy((char *)bptr, nic->node_addr, ETH_ALEN);	bptr += ETH_ALEN;	memcpy((char *)bptr, (char *)&type, sizeof(type));	bptr += sizeof(type);	memcpy((char *)bptr, p, s);	/* Change the offset in the IDLELOOP */	*(unsigned short *)(mem_start + IDLELOOP + 4) = TX_BUF_START;	/* Wait for transmit completion */	while (			(shmem[0] & 0x2000) == 0)		;	/* Change the offset in the IDLELOOP back and	   change the final loop to point here */	*(unsigned short *)(mem_start + IDLELOOP + 4) = IDLELOOP;	*(unsigned short *)(mem_start + TX_BUF_START + 20) = IDLELOOP;	ack_status();}/**************************************************************************  DISABLE - Turn off ethernet interface ***************************************************************************/static void i82586_disable(struct nic *nic){	unsigned short	*shmem = (short *)mem_start;#if	0	/* Flush the Tx and disable Rx. */	shmem[iSCB_CMD>>1] = RX_SUSPEND | CUC_SUSPEND;	outb(0, ioaddr + I82586_ATTN);#ifdef	INCLUDE_NI5210	outb(0, ioaddr + NI52_RESET);#endif#endif	/* 0 */}#ifdef	INCLUDE_3C507static int t507_probe1(struct nic *nic, unsigned short ioaddr){	int			i;	Address			size;	char			mem_config;	char			if_port;	if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3'		|| inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O')		return (0);	irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;	mem_config = inb(ioaddr + MEM_CONFIG);	if (mem_config & 0x20)	{		size = 65536L;		mem_start = 0xf00000L + (mem_config & 0x08 ? 0x080000L			: (((Address)mem_config & 0x3) << 17));	}	else	{		size = ((((Address)mem_config & 0x3) + 1) << 14);		mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12);	}	mem_end = mem_start + size;	scb_base = 65536L - size;	if_port = inb(ioaddr + ROM_CONFIG) & 0x80;	/* Get station address */	outb(0x01, ioaddr + MISC_CTRL);	for (i = 0; i < ETH_ALEN; ++i)	{		nic->node_addr[i] = inb(ioaddr+i);	}	printf("\n3c507 ioaddr %#hX, IRQ %d, mem [%#X-%#X], %sternal xcvr, addr %!\n",		ioaddr, irq, mem_start, mem_end, if_port ? "in" : "ex", nic->node_addr);	return (1);}/**************************************************************************PROBE - Look for an adapter, this routine's visible to the outside***************************************************************************/struct nic *t507_probe(struct nic *nic, unsigned short *probe_addrs){	static unsigned char	init_ID_done = 0;	unsigned short		lrs_state = 0xff;	static unsigned short	io_addrs[] = { 0x300, 0x320, 0x340, 0x280, 0 };	unsigned short		*p;	int			i;	if (init_ID_done == 0)	{		/* Send the ID sequence to the ID_PORT to enable the board */		outb(0x00, ID_PORT);		for (i = 0; i < 255; ++i)		{			outb(lrs_state, ID_PORT);			lrs_state <<= 1;			if (lrs_state & 0x100)				lrs_state ^= 0xe7;		}		outb(0x00, ID_PORT);		init_ID_done = 1;	}	/* if probe_addrs is 0, then routine can use a hardwired default */	if (probe_addrs == 0)		probe_addrs = io_addrs;	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)		if (t507_probe1(nic, ioaddr))			break;	if (ioaddr != 0)	{		/* point to NIC specific routines */		i82586_reset(nic);		nic->reset = i82586_reset;		nic->poll = i82586_poll;		nic->transmit = i82586_transmit;		nic->disable = i82586_disable;		return nic;	}	/* else */	{		return 0;	}}#endif#ifdef	INCLUDE_NI5210static int ni5210_probe2(void){	unsigned short		i;	unsigned short		shmem[10];	/* Fix the ISCP address and base. */	init_words[3] = scb_base;	init_words[7] = scb_base;	/* Write the words at 0xfff6. */	/* Write the words at 0x0000. */	memcpy((char *)(mem_end - 10), (char *)init_words, 10);	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);	if (*(unsigned short *)mem_start != 1)		return (0);	outb(0, ioaddr + NI52_RESET);	outb(0, ioaddr + I82586_ATTN);	udelay(32);	i = 50;	while (		shmem[iSCB_STATUS>>1] == 0)	{		if (--i == 0)		{			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",				shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);			break;		}	}	/* Issue channel-attn -- the 82586 won't start. */	outb(0, ioaddr + I82586_ATTN);	if (*(unsigned short *)mem_start != 0)		return (0);	return (1);}static int ni5210_probe1(struct nic *nic){	int			i;	static Address		mem_addrs[] = {		0xc0000, 0xc4000, 0xc8000, 0xcc000,		0xd0000, 0xd4000, 0xd8000, 0xdc000,		0xe0000, 0xe4000, 0xe8000, 0xec000,		0 };	Address			*p;	if (inb(ioaddr + 6) != 0x0 || inb(ioaddr + 7) != 0x55)		return (0);	scb_base = -8192;		/* assume 8k memory */	for (p = mem_addrs; (mem_start = *p) != 0; ++p)		if (mem_end = mem_start + 8192, ni5210_probe2())			break;	if (mem_start == 0)		return (0);	/* Get station address */	for (i = 0; i < ETH_ALEN; ++i)	{		nic->node_addr[i] = inb(ioaddr+i);	}	printf("\nNI5210 ioaddr %#hX, mem [%#X-%#X], addr %!\n",		ioaddr, mem_start, mem_end, nic->node_addr);	return (1);}struct nic *ni5210_probe(struct nic *nic, unsigned short *probe_addrs){	/* missing entries are addresses usually already used */	static unsigned short	io_addrs[] = {		0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 0x238,		0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, /*Par*/		0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8,		0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0, /*Ser*/		0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330, 0x338,		0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, /*Par*/		0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, /*Vid,Par*/		0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, /*Ser*/		0x0	};	unsigned short		*p;	int			i;	/* if probe_addrs is 0, then routine can use a hardwired default */	if (probe_addrs == 0)		probe_addrs = io_addrs;	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)		if (ni5210_probe1(nic))			break;	if (ioaddr != 0)	{		/* point to NIC specific routines */		i82586_reset(nic);		nic->reset = i82586_reset;		nic->poll = i82586_poll;		nic->transmit = i82586_transmit;		nic->disable = i82586_disable;		return nic;	}	/* else */	{		return 0;	}}#endif#ifdef	INCLUDE_EXOS205/* * Code to download to I186 in EXOS205 */static unsigned char exos_i186_init[] ={0x08,0x00,0x14,0x00,0x00,0x00,0xaa,0xfa,0x33,0xc0,0xba,0xfe,0xff,0xef,0xb8,0xf8,0xff,0xe7,0xa0,0xb8,0x7c,0x00,0xe7,0xa4,0xb8,0xbc,0x80,0xe7,0xa8,0x8c,0xc8,0x8e,0xd8,0xbb,0x2f,0x0e,0xc6,0x07,0xa5,0x33,0xc9,0xeb,0x00,0xeb,0x00,0xeb,0x00,0xe2,0xf8,0xbe,0x2c,0x0e,0xba,0x02,0x05,0x33,0xdb,0xb9,0x03,0x00,0xec,0x24,0x0f,0x8a,0xe0,0x02,0xd8,0x42,0x42,0xec,0x02,0xd8,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0x0a,0xc4,0x88,0x04,0x42,0x42,0x46,0xe2,0xe3,0x8a,0xe3,0xd0,0xec,0xd0,0xec,0xd0,0xec,0xd0,0xec,0x80,0xe3,0x0f,0x02,0xe3,0x80,0xf4,0x05,0xec,0x3a,0xe0,0x74,0x05,0xc6,0x04,0x5a,0xeb,0xfe,0xc6,0x04,0x55,0x33,0xc0,0x8e,0xd8,0xbe,0x38,0x00,0xc7,0x04,0xce,0x0e,0x46,0x46,0xc7,0x04,0x00,0xff,0xfb,0xba,0x3c,0x00,0xb8,0x03,0x00,0xef,0x33,0xdb,0x33,0xc9,0xbd,0x04,0x0f,0x90,0x90,0x90,0x90,0xe2,0xfa,0x43,0x2e,0x89,0x5e,0x00,0xeb,0xf3,0x52,0xba,0x00,0x06,0xef,0x50,0x53,0x55,0xbd,0xf8,0x0e,0x2e,0x8b,0x5e,0x00,0x43,0x2e,0x89,0x5e,0x00,0xba,0x22,0x00,0xb8,0x00,0x80,0xef,0x5d,0x5b,0x58,0x5a,0xcf,0x49,0x4e,0x54,0x52,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x4c,0x4f,0x4f,0x50,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x30,0x0e,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,00};/* These offsets are from the end of the i186 download code */#define	OFFSET_SEMA		0x1D1#define	OFFSET_ADDR		0x1D7static int exos205_probe2(void){	unsigned short		i;	unsigned short		shmem[10];	/* Fix the ISCP address and base. */	init_words[3] = scb_base;	init_words[7] = scb_base;	/* Write the words at 0xfff6. */	/* Write the words at 0x0000. */	memcpy((char *)(mem_end - 10), (char *)init_words, 10);	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);	if (*(unsigned short *)mem_start != 1)		return (0);	outb(0, ioaddr + EXOS205_RESET);	outb(0, ioaddr + I82586_ATTN);	i = 50;	while (		shmem[iSCB_STATUS>>1] == 0)	{		if (--i == 0)		{			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",				shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);			break;		}	}	/* Issue channel-attn -- the 82586 won't start. */	outb(0, ioaddr + I82586_ATTN);	if (*(unsigned short *)mem_start != 0)		return (0);	return (1);}static int exos205_probe1(struct nic *nic){	int			i;	/* If you know the other addresses please let me know */	static Address		mem_addrs[] = {		0xcc000, 0 };	Address			*p;	scb_base = -16384;		/* assume 8k memory */	for (p = mem_addrs; (mem_start = *p) != 0; ++p)		if (mem_end = mem_start + 16384, exos205_probe2())			break;	if (mem_start == 0)		return (0);	/* Get station address */	for (i = 0; i < ETH_ALEN; ++i)	{		nic->node_addr[i] = inb(ioaddr+i);	}	printf("\nEXOS205 ioaddr %#hX, mem [%#X-%#X], addr %!\n",		ioaddr, mem_start, mem_end, nic->node_addr);	return (1);}struct nic *exos205_probe(struct nic *nic, unsigned short *probe_addrs){	/* If you know the other addresses, please let me know */	static unsigned short	io_addrs[] = {		0x310, 0x0	};	unsigned short		*p;	int			i;	/* if probe_addrs is 0, then routine can use a hardwired default */	if (probe_addrs == 0)		probe_addrs = io_addrs;	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)		if (exos205_probe1(nic))			break;	if (ioaddr != 0)	{		/* point to NIC specific routines */		i82586_reset(nic);		nic->reset = i82586_reset;		nic->poll = i82586_poll;		nic->transmit = i82586_transmit;		nic->disable = i82586_disable;		return nic;	}	/* else */	{		return 0;	}}#endif

⌨️ 快捷键说明

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