📄 btpci.c
字号:
}#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 + -