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

📄 btpci.c

📁 strongarm的bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
}#define EEPROM_BCR 19#define EEPROM_EDI (1<<0)#define EEPROM_EDO (1<<0)#define EEPROM_ESK (1<<1)#define EEPROM_ECS (1<<2)#define EEPROM_EEN (1<<4)#define EEPROM_EEDET (1<<13)#define EEPROM_PREAD (1<<14)#define EEPROM_PVALID (1<<15)static int eeprom_clk(char *ioaddr, int regval){  int result;  regval &= ~EEPROM_ESK;  pcnet_write_bcr (ioaddr, 19, regval);  regval |= EEPROM_ESK;  pcnet_write_bcr (ioaddr, 19, regval);#if 0  regval &= ~EEPROM_ESK;  pcnet_write_bcr (ioaddr, 19, regval);#endif  result = pcnet_read_bcr (ioaddr, 19);  return result;}/* enable erase and write operations */static void ewen_eeprom(char *ioaddr){  int regval = EEPROM_EEN | EEPROM_ECS; /* enable manual eeprom operations */  int abitnum;  /* send a few zeros */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  /* send start bit */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  /* send ewen opcode */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  for (abitnum = 0; abitnum < EEPROM_N_ABITS; abitnum++)	eeprom_clk(ioaddr, regval | EEPROM_EDI);  eeprom_clk(ioaddr, EEPROM_EEN & ~EEPROM_ECS);  pcnet_write_bcr (ioaddr, 19, 0);}/* enable disable and write operations */static void ewds_eeprom(char *ioaddr){  int regval = EEPROM_EEN | EEPROM_ECS; /* enable manual eeprom operations */  int abitnum;  /* send a few zeros */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  /* send start bit */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  /* send ewds opcode */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  for (abitnum = 0; abitnum < EEPROM_N_ABITS; abitnum++)	eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, EEPROM_EEN & ~EEPROM_ECS);  pcnet_write_bcr (ioaddr, 19, 0);}static void erase_eeprom(char *ioaddr, int word_number){  int regval = EEPROM_EEN; /* enable manual eeprom operations */  int abitnum;  /* set CS to one */  regval |= EEPROM_ECS;  /* send a few zeros */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  /* send start bit */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  /* send 'erase' opcode */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  eeprom_clk(ioaddr, regval | EEPROM_EDI);  for (abitnum = EEPROM_N_ABITS-1; abitnum >= 0; abitnum--) {	/* set DI to address bit, starting with MSB */	int edi = ((word_number >> abitnum)&1) ? EEPROM_EDI : 0;	/* clock */	eeprom_clk(ioaddr, regval | edi);  }  /* set CS TO zero */  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  /* now poll for #BSY */  for (abitnum = 0; abitnum < 10; abitnum++) {	int edo = eeprom_clk(ioaddr, regval) & EEPROM_EDO;	if (!edo) {	  break;	}  }  /* now poll for ready */  for (abitnum = 0; abitnum < 1000; abitnum++) {	int edo = eeprom_clk(ioaddr, regval) & EEPROM_EDO;	if (edo) {	  if (1) {             putstr("*** eeprom address ");             putHexInt8(word_number);             putstr(" erased ***\r\n");          }	  break;	}  }  /* set CS TO zero again */  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  /* disable EEPROM mode */  pcnet_write_bcr (ioaddr, EEPROM_BCR, 0);}static void write_eeprom(char *ioaddr, int word_number, int value){  int regval = EEPROM_EEN | EEPROM_ECS; /* enable manual eeprom operations */  int abitnum, dbitnum;  /* send a few zeros */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  /* send start bit */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  /* send 'write' opcode */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval | EEPROM_EDI);  for (abitnum = EEPROM_N_ABITS-1; abitnum >= 0; abitnum--) {	/* set DI to address bit, starting with MSB */	int edi = ((word_number >> abitnum)&1) ? EEPROM_EDI : 0;	/* clock */	eeprom_clk(ioaddr, regval | edi);  }  /* now send data bits */  for (dbitnum = EEPROM_N_DBITS-1; dbitnum >= 0; dbitnum--) {	int edi = ((value >> dbitnum)&1) ? EEPROM_EDI : 0;	eeprom_clk(ioaddr, regval | edi);  }  /* set CS TO zero */  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  /* now poll for #BSY */  for (abitnum = 0; abitnum < 10; abitnum++) {	int edo = eeprom_clk(ioaddr, regval) & EEPROM_EDO;	if (!edo) {	  break;	}  }  /* now poll for ready */  for (abitnum = 0; abitnum < 1000; abitnum++) {	int edo = eeprom_clk(ioaddr, regval) & EEPROM_EDO;	if (edo) {	  if (1) {             putstr("*** eeprom address ");             putHexInt8(word_number);             putstr(" written ***\r\n");          }	  break;	}  }  /* set CS TO zero again */  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  /* disable EEPROM mode */  pcnet_write_bcr (ioaddr, EEPROM_BCR, 0);}static int read_eeprom(char *ioaddr, int word_number){  int regval = EEPROM_EEN; /* enable manual eeprom operations */  int abitnum, dbitnum;  int data = 0;  /* set CS to one */  regval |= EEPROM_ECS;  /* send a few zeros */  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  /* send start bit */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  /* send read opcode */  eeprom_clk(ioaddr, regval | EEPROM_EDI);  eeprom_clk(ioaddr, regval & ~EEPROM_EDI);  for (abitnum = EEPROM_N_ABITS-1; abitnum >= 0; abitnum--) {	/* set DI to address bit, starting with MSB */	int edi = ((word_number >> abitnum)&1) ? EEPROM_EDI : 0;	/* clock */	eeprom_clk(ioaddr, regval | edi);  }  for (dbitnum = EEPROM_N_DBITS-1; dbitnum >= 0; dbitnum--) {	int edo;	/* clock */	regval = eeprom_clk(ioaddr, regval & ~EEPROM_EDI);	/* read DI, starting with msb */	edo = (regval & EEPROM_EDO) ? 1 : 0;	data |= (edo << dbitnum);  }  /* set CS TO zero */  eeprom_clk(ioaddr, regval & ~EEPROM_ECS);  /* disable EEPROM mode */  pcnet_write_bcr (ioaddr, EEPROM_BCR, 0);  return data;}#define EEPROM_MAC0_OFFSET		0#define EEPROM_MAC1_OFFSET		1#define EEPROM_MAC2_OFFSET		2#define EEPROM_CSR116_OFFSET	3#define EEPROM_HWID_OFFSET		4#define EEPROM_RESVD_OFFSET		5#define EEPROM_CKSUM1_OFFSET    6#define EEPROM_WW_OFFSET		7#define EEPROM_BCR2_OFFSET		8#define EEPROM_BCR4_OFFSET		9#define EEPROM_BCR5_OFFSET		10#define EEPROM_BCR6_OFFSET		11#define EEPROM_BCR7_OFFSET		12#define EEPROM_BCR9_OFFSET		13#define EEPROM_BCR18_OFFSET		14#define EEPROM_BCR22_OFFSET		15#define EEPROM_BCR23_OFFSET		16#define EEPROM_BCR24_OFFSET		17#define EEPROM_BCR25_OFFSET		18#define EEPROM_BCR26_OFFSET		19#define EEPROM_BCR27_OFFSET		20#define EEPROM_BCR32_OFFSET		21#define EEPROM_BCR33_OFFSET		22#define EEPROM_BCR35_OFFSET		23#define EEPROM_BCR36_OFFSET		24#define EEPROM_BCR37_OFFSET		25#define EEPROM_BCR38_OFFSET		26#define EEPROM_BCR39_OFFSET		27#define EEPROM_BCR40_OFFSET		28#define EEPROM_BCR41_OFFSET		29#define EEPROM_BCR42_OFFSET		30#define EEPROM_BCR43_OFFSET		31#define EEPROM_BCR44_OFFSET		32#define EEPROM_BCR48_OFFSET		33#define EEPROM_BCR49_OFFSET		34#define EEPROM_BCR50_OFFSET		35#define EEPROM_BCR51_OFFSET		36#define EEPROM_BCR52_OFFSET		37#define EEPROM_BCR53_OFFSET		38#define EEPROM_BCR54_OFFSET		39#define EEPROM_CKSUM2_OFFSET	40/* * Reprograms the ethernet attached to the PCNet ethernet controller * Assumes that there is only one of these on the PCI bus. */ void program_all_eeprom(){   int i;   long maclsbyte;   short eeprom_data[82];   unsigned char *bytes = (unsigned char *)eeprom_data;   char *configBase = (char *)makePCIConfigurationAddress(PCNET_DEVICE_NUMBER, 0, 0);   char *ioaddr = (char *)0x7c000000 + (readInt16(configBase, PCI_MAPREG_START)&0xFFFE);   memset(eeprom_data, 0, sizeof(eeprom_data));   /* uses MAC addresses starting with 08-00-2B-00-01-00 */   /* get per-unit part of the MAC address */   get_param_value("maclsbyte", &maclsbyte);   /* fill in the data */   eeprom_data[EEPROM_MAC0_OFFSET] = 0x0008; /* byte swapped */   eeprom_data[EEPROM_MAC1_OFFSET] = 0x002b; /* byte swapped */   eeprom_data[EEPROM_MAC2_OFFSET] = 0x0001 | ((maclsbyte&0xFF)<<8); /* byte swapped */   eeprom_data[EEPROM_HWID_OFFSET] = 0x11;   eeprom_data[EEPROM_WW_OFFSET] = 0x5757;   eeprom_data[EEPROM_BCR2_OFFSET] = 0x3100;   eeprom_data[EEPROM_BCR4_OFFSET] = 0x00c0;   eeprom_data[EEPROM_BCR5_OFFSET] = 0x0084;   eeprom_data[EEPROM_BCR6_OFFSET] = 0x0088;   eeprom_data[EEPROM_BCR7_OFFSET] = 0x0090;   eeprom_data[EEPROM_BCR18_OFFSET] = 0x9001; /* WIO mode */   eeprom_data[EEPROM_BCR22_OFFSET] = 0xFF06;   eeprom_data[EEPROM_BCR23_OFFSET] = 0xaa22;   eeprom_data[EEPROM_BCR24_OFFSET] = 0x1717;   eeprom_data[EEPROM_BCR35_OFFSET] = 0x1022;   eeprom_data[EEPROM_BCR36_OFFSET] = 0xc811;   eeprom_data[EEPROM_BCR48_OFFSET] = 0x00a0;   eeprom_data[EEPROM_BCR49_OFFSET] = 0x0080;      /* compute the MAC checksum */   {      int mac_checksum = 0;      int i;      for (i = 0; i < 16; i++)         mac_checksum += bytes[i];      /* eeprom_data[EEPROM_CKSUM1_OFFSET] needs to match this checksum */      eeprom_data[EEPROM_CKSUM1_OFFSET] = mac_checksum;   }   /* compute the eeprom checksum */   {      int eeprom_checksum = 0;      int i;      for (i = 0; i < 82; i++)         eeprom_checksum += bytes[i];      /* (eeprom_data[EEPROM_CKSUM2_OFFSET] + eeprom_cksum) & 0xFF should be 0xFF */      eeprom_data[EEPROM_CKSUM2_OFFSET] = (0xFF - eeprom_checksum)&0xFF;   }   /* now program the eeprom */   {      int i;      ewen_eeprom(ioaddr);      for (i = 0; i < 41; i++) {         short oldvalue = read_eeprom(ioaddr, i);         short newvalue = eeprom_data[i];         if (oldvalue != newvalue) {            putstr("reprogramming eeprom["); putHexInt8(i); putstr("] from "); putHexInt16(oldvalue);            putstr(" to "); putHexInt16(newvalue); putstr("\r\n");            erase_eeprom(ioaddr, i);            write_eeprom(ioaddr, i, newvalue);         }      }      ewds_eeprom(ioaddr);   }}void handlePCNetQuirks(struct PciConfigurationValues *pciConfigurationValue){  char *configBase = makePCIConfigurationAddress(pciConfigurationValue->pciDevice, 						 pciConfigurationValue->pciFunction,						 0);  char *ioaddr = (char*)0x7c000000 + (readInt16(configBase, PCI_MAPREG_START)&0xFFFE);  int valid_eeprom;  int maclsbyte;  struct bootblk_param *maclsbyte_param;     /* one more reset to be sure */  readInt16(ioaddr, PCNET_RESET_WIO_REG);  readInt32(ioaddr, PCNET_RESET_DWIO_REG);  /* put into DWIO mode */  writeInt32(ioaddr, PCNET_RDP_DWIO_REG, 0x0);  readInt32(ioaddr, PCNET_RDP_DWIO_REG);  pcnet_io_mode = PCNET_DWIO_MODE;  if (0) {    putstr("\r\n\r\n");    putLabeledWord("CONFIG: ", (int)configBase);    putLabeledWord("IOADDR: ", (int)ioaddr);    putLabeledWord("APROM0: ", readInt8(ioaddr, 0));    putLabeledWord("APROM1: ", readInt8(ioaddr, 1));    putLabeledWord("APROM2: ", readInt8(ioaddr, 2));    putLabeledWord("APROM3: ", readInt8(ioaddr, 3));    putLabeledWord("APROM4: ", readInt8(ioaddr, 4));    putLabeledWord("APROM5: ", readInt8(ioaddr, 5));    putLabeledWord("RAP16:  ", readInt16(ioaddr, PCNET_RAP_WIO_REG));    putLabeledWord("RDP16:  ", readInt16(ioaddr, PCNET_RDP_WIO_REG));    putLabeledWord("RAP32:  ", readInt32(ioaddr, PCNET_RAP_DWIO_REG));    putLabeledWord("RDP32:  ", readInt32(ioaddr, PCNET_RDP_DWIO_REG));    putLabeledWord("CSR0:  ", pcnet_read_csr(ioaddr, 0));    putLabeledWord("BCR19: ", pcnet_read_bcr(ioaddr, 19));  }  valid_eeprom = pcnet_read_bcr(ioaddr, 19) & (1<<15); /* BCR19: page 161 of Am79C978 manual */  maclsbyte = readInt8(ioaddr, 5) & 0xFF;  putLabeledWord("maclsbyte", maclsbyte);}int get_maclsbyte(void){  char *configBase = makePCIConfigurationAddress(PCNET_DEVICE_NUMBER, 0, 0);  char *ioaddr = (char*)0x7c000000 + (readInt16(configBase, PCI_MAPREG_START)&0xFFFE);  int maclsbyte;  maclsbyte = readInt8(ioaddr, 5) & 0xFF;  return maclsbyte;}

⌨️ 快捷键说明

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