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

📄 tiara.c

📁 i386的bootloader源码grub
💻 C
字号:
/**************************************************************************Etherboot -  BOOTP/TFTP Bootstrap ProgramTIARA (Fujitsu Etherstar) NIC driver for EtherbootCopyright (c) Ken Yap 1998Information gleaned from:TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, OntarioFujitsu MB86960 spec sheet (different chip but same family)***************************************************************************//* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. *//* to get some global routines like printf */#include "etherboot.h"/* to get the interface to the body of the program */#include "nic.h"#include "cards.h"/*	EtherStar I/O Register offsets*//* Offsets of registers */#define	DLCR_XMIT_STAT	0x00#define	DLCR_XMIT_MASK	0x01#define	DLCR_RECV_STAT	0x02#define	DLCR_RECV_MASK	0x03#define	DLCR_XMIT_MODE	0x04#define	DLCR_RECV_MODE	0x05#define	DLCR_ENABLE	0x06#define	DLCR_TDR_LOW	0x07#define	DLCR_NODE_ID	0x08#define	DLCR_TDR_HIGH	0x0F#define	BMPR_MEM_PORT	0x10#define	BMPR_PKT_LEN	0x12#define	BMPR_DMA_ENABLE	0x14#define	PROM_ID		0x18#define	TMST		0x80#define	TMT_OK		0x80#define	TMT_16COLL	0x02#define	BUF_EMPTY	0x40#define	CARD_DISABLE	0x80	/* written to DLCR_ENABLE to disable card */#define	CARD_ENABLE	0	/* written to DLCR_ENABLE to enable card */#define	CLEAR_STATUS	0x0F	/* used to clear status info *//*	00001111B	!!!!!!!!--------	!!!!!!!+--------CLEAR BUS WRITE ERROR	!!!!!!+---------CLEAR 16 COLLISION	!!!!!+----------CLEAR COLLISION	!!!!+-----------CLEAR UNDERFLOW	!!!+------------NC	!!+-------------NC	!+--------------NC	+---------------NC*/#define	NO_TX_IRQS	0	/* written to clear transmit IRQs */#define	CLR_RCV_STATUS	0xCF	/* clears receive status */#define	EN_RCV_IRQS	0x80	/* enable receive interrupts *//*	10000000B	!!!!!!!!--------	!!!!!!!+--------ENABLE OVERFLOW	!!!!!!+---------ENABLE CRC	!!!!!+----------ENABLE ALIGN	!!!!+-----------ENABLE SHORT PKT	!!!+------------DISABLE REMOTE RESET	!!+-------------RESERVED	!+--------------RESERVED	+---------------ENABLE PKT READY*/#define	XMIT_MODE	0x02/*	00000010B	!!!!!!!!---------ENABLE CARRIER DETECT	!!!!!!!+---------DISABLE LOOPBACK*/#define	RECV_MODE	0x02/*	00000010B	!!!!!!!!---------ACCEPT ALL PACKETS	!!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND	!!!!!!+----------BROADCAST PACKETS	!!!!!+-----------DISABLE REMOTE RESET	!!!!+------------DISABLE SHORT PACKETS	!!!+-------------USE 6 BYTE ADDRESS	!!+--------------NC	!+---------------NC	+----------------DISABLE CRC TEST MODE*//* NIC specific static variables go here */static unsigned short	ioaddr;/**************************************************************************RESET - Reset adapter***************************************************************************/static void tiara_reset(struct nic *nic){	int		i;	outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);	outb(CLEAR_STATUS, ioaddr + DLCR_XMIT_STAT);	outb(NO_TX_IRQS, ioaddr + DLCR_XMIT_MASK);	outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);	outb(XMIT_MODE, ioaddr + DLCR_XMIT_MODE);	outb(RECV_MODE, ioaddr + DLCR_RECV_MODE);	/* Vacuum recv buffer */	while ((inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) == 0)		inb(ioaddr + BMPR_MEM_PORT);	/* Set node address */	for (i = 0; i < ETH_ALEN; ++i)		outb(nic->node_addr[i], ioaddr + DLCR_NODE_ID + i);	outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);	outb(CARD_ENABLE, ioaddr + DLCR_ENABLE);}/**************************************************************************POLL - Wait for a frame***************************************************************************/static int tiara_poll(struct nic *nic){	unsigned int		len;	if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY)		return (0);	/* Ack packet */	outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);	len = inw(ioaddr + BMPR_MEM_PORT);		/* throw away status */	len = inw(ioaddr + BMPR_MEM_PORT);	/* Drop overlength packets */	if (len > ETH_FRAME_LEN)		return (0);		/* should we drain the buffer? */	insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2);	/* If it's our own, drop it */	if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0)		return (0);	nic->packetlen = len;	return (1);}/**************************************************************************TRANSMIT - Transmit a frame***************************************************************************/static void tiara_transmit(struct nic *nic,const char *d,			/* Destination */unsigned int t,			/* Type */unsigned int s,			/* size */const char *p)			/* Packet */{	unsigned int	len;	unsigned long	time;	len = s + ETH_HLEN;	if (len < ETH_ZLEN)		len = ETH_ZLEN;	t = htons(t);	outsw(ioaddr + BMPR_MEM_PORT, d, ETH_ALEN / 2);	outsw(ioaddr + BMPR_MEM_PORT, nic->node_addr, ETH_ALEN / 2);	outw(t, ioaddr + BMPR_MEM_PORT);	outsw(ioaddr + BMPR_MEM_PORT, p, s / 2);	if (s & 1)					/* last byte */		outb(p[s-1], ioaddr + BMPR_MEM_PORT);	while (s++ < ETH_ZLEN - ETH_HLEN)	/* pad */		outb(0, ioaddr + BMPR_MEM_PORT);	outw(len | (TMST << 8), ioaddr + BMPR_PKT_LEN);	/* wait for transmit complete */	time = currticks() + TICKS_PER_SEC;		/* wait one second */	while (currticks() < time && (inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)		;	if ((inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)		printf("Tiara timed out on transmit\n");	/* Do we need to ack the transmit? */}/**************************************************************************DISABLE - Turn off ethernet interface***************************************************************************/static void tiara_disable(struct nic *nic){	/* Apparently only a power down can do this properly */	outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);}static int tiara_probe1(struct nic *nic){	/* Hope all the Tiara cards have this vendor prefix */	static char	vendor_prefix[] = { 0x08, 0x00, 0x1A };	static char	all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };	int		i;	for (i = 0; i < ETH_ALEN; ++i)		nic->node_addr[i] = inb(ioaddr + PROM_ID + i);	if (memcmp(nic->node_addr, vendor_prefix, sizeof(vendor_prefix)) != 0)		return (0);	if (memcmp(nic->node_addr, all_ones, sizeof(all_ones)) == 0)		return (0);	printf("\nTiara ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);	return (1);}/**************************************************************************PROBE - Look for an adapter, this routine's visible to the outside***************************************************************************/struct nic *tiara_probe(struct nic *nic, unsigned short *probe_addrs){	/* missing entries are addresses usually already used */	static unsigned short	io_addrs[] = {		0x100, 0x120, 0x140, 0x160,		0x180, 0x1A0, 0x1C0, 0x1E0,		0x200, 0x220, 0x240, /*Par*/		0x280, 0x2A0, 0x2C0, /*Ser*/		0x300, 0x320, 0x340, /*Par*/		0x380, /*Vid,Par*/ 0x3C0, /*Ser*/		0x0	};	unsigned short		*p;	/* 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 (tiara_probe1(nic))			break;	/* if board found */	if (ioaddr != 0)	{		tiara_reset(nic);		/* point to NIC specific routines */		nic->reset = tiara_reset;		nic->poll = tiara_poll;		nic->transmit = tiara_transmit;		nic->disable = tiara_disable;		return nic;	}	else		return (0);}

⌨️ 快捷键说明

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