/* * rtl8139.c - read rtl8139 bios rom * */ #ifndef __i386__ # error "This program can't compile or run on non-intel computers" #else #include #include #include #include #ifdef __FreeBSD__ #include #include #define OUTB(data, port) outb(port, data) #define OUTW(data, port) outw(port, data) #define OUTL(data, port) outl(port, data) #else #include #define OUTB(data, port) outb(data, port) #define OUTW(data, port) outw(data, port) #define OUTL(data, port) outl(data, port) #include #endif int main(int argc, char **argv) { unsigned int i, j, n; unsigned int ioaddr; unsigned long recvrstat; unsigned char buf[128]; unsigned char b; unsigned long l; if (argc != 3) { printf("Usage: %s ioaddr id|read >file|pci\n", argv[0]); exit(-1); } #ifdef __FreeBSD__ /* get permissions for in/out{blw} */ open("/dev/io",O_RDONLY,0); #else setuid(0); /* if we're setuid, do it really */ if (iopl(3)) { perror("iopl()"); exit(1); } #endif sscanf(argv[1], "%x", &ioaddr); /* Set the register window to 3 for the 3c905b */ #if 0 OUTW(0x803, ioaddr+0xe); recvrstat = inl(ioaddr); /* save the receiver status */ /* set the receiver type to MII so the full bios rom address space can be accessed */ OUTL((recvrstat & 0xf00fffff)|0x00600000, ioaddr); /* Set the register window to 0 for the 3c905b */ OUTW(0x800, ioaddr+0xe); #endif #define REG_PROM 0xD4 #define REG_PROM_DATA (REG_PROM + 0x03) if (strcmp(argv[2], "id") == 0) { b = inb(ioaddr + 0x51); printf("CONFIG 0 register: 0x%08X\n", b); OUTL(0x5555, ioaddr+REG_PROM); OUTB(0xaa, ioaddr+REG_PROM_DATA); OUTL(0x2aaa, ioaddr+REG_PROM); OUTB(0x55, ioaddr+REG_PROM_DATA); OUTL(0x5555, ioaddr+REG_PROM); OUTB(0x90, ioaddr+REG_PROM_DATA); /* 10ms delay needed */ printf("Manufacturer ID - "); /* manuf. id */ OUTL(0x0000, ioaddr + REG_PROM); printf("%02x\n", inb(ioaddr + REG_PROM_DATA)); /* device id */ OUTL(0x0001, ioaddr + REG_PROM); printf("Device ID - %02x\n", inb(ioaddr + REG_PROM_DATA)); /* undo the funky chicken */ OUTL(0x5555, ioaddr+REG_PROM); OUTB(0xaa, ioaddr+REG_PROM_DATA); OUTL(0x2aaa, ioaddr+REG_PROM); OUTB(0x55, ioaddr+REG_PROM_DATA); OUTL(0x5555, ioaddr+REG_PROM); OUTB(0xf0, ioaddr+REG_PROM_DATA); } else if (strcmp(argv[2], "read") == 0) { /*static int rtl_flash_in(long ioaddr, int offset) { outl(0x1C0000 | (offset & 0x1ffff), ioaddr + FlashAccess); return inl(ioaddr + FlashAccess) >> 24; } static void rtl_flash_out(long ioaddr, int offset, int val) { outl((val<<24) | 0x1a0000 | (offset & 0x1ffff), ioaddr + FlashAccess); }*/ for (i = 0; i < 65536; i++) { //OUTL(0x1C0000 | (i & 0x01FFFF), ioaddr + REG_PROM); //OUTL(0x0C0000 | (i & 0x01FFFF), ioaddr + REG_PROM); #define SWRWEn (1<<17) #define WEB (1<<18) #define OEB (1<<19) #define ROMCSB (1<<20) //OUTL((SWRWEn | WEB | OEB | ROMCSB) | (i & 0x01FFFF), ioaddr + REG_PROM); OUTL((WEB | OEB) | (i & 0x01FFFF), ioaddr + REG_PROM); usleep(100); b = inb(ioaddr + REG_PROM_DATA); write(1, &b, 1); } } else if (strcmp(argv[2], "pci") == 0) { #define PCI_IO_ADDR 0x0CF8 #define PCI_IO_DATA 0x0CFC // // +--+----------+-------+----------+----------+----------+-+-+ // |31|30 24|23 16|15 11|10 8|7 2|1|0| // +--+----------+-------+----------+----------+----------+-+-+ // | c| reserved | bus | device | function | register |0|0| // +--+----------+-------+----------+----------+----------+-+-+ // #define PCI_REG(v) ((v & 0x3F) << 2) #define PCI_BUS(v) ((v & 0xFF) << 16) //#define PCI_RSV(v) ((v & 0x7F) << 24) #define PCI_FLG(v) ((v & 0x01) << 31) #define PCI(bus, dev, func) (PCI_BUS(bus) | PCI_DEVFN(dev, func)) //#define reg PCI_ROM_ADDRESS #define reg PCI_CLASS_REVISION l = PCI(1, 1, 0); outl(PCI_IO_ADDR, l | PCI_REG(reg)); printf("reg 0x%08x: 0x%08x\n", reg, inl(PCI_IO_DATA)); outl(PCI_IO_ADDR, 0); } #if 0 /* Set the register window to 3 for the 3c905b */ OUTW(0x803, ioaddr+0xe); /* restore the receiver status */ OUTL(recvrstat, ioaddr); #endif return 0; } #endif /* __i386__ */