diff options
Diffstat (limited to 'nicrealtek.c')
-rw-r--r-- | nicrealtek.c | 139 |
1 files changed, 74 insertions, 65 deletions
diff --git a/nicrealtek.c b/nicrealtek.c index 5454b63af..5937e35ba 100644 --- a/nicrealtek.c +++ b/nicrealtek.c @@ -14,20 +14,22 @@ * GNU General Public License for more details. */ -#if defined(__i386__) || defined(__x86_64__) - #include <stdlib.h> #include "flash.h" #include "programmer.h" -#include "hwaccess.h" +#include "hwaccess_x86_io.h" +#include "platform/pci.h" #define PCI_VENDOR_ID_REALTEK 0x10ec #define PCI_VENDOR_ID_SMC1211 0x1113 -static uint32_t io_base_addr = 0; -static int bios_rom_addr, bios_rom_data; +struct nicrealtek_data { + uint32_t io_base_addr; + int bios_rom_addr; + int bios_rom_data; +}; -const struct dev_entry nics_realtek[] = { +static const struct dev_entry nics_realtek[] = { {0x10ec, 0x8139, OK, "Realtek", "RTL8139/8139C/8139C+"}, {0x10ec, 0x8169, NT, "Realtek", "RTL8169"}, {0x1113, 0x1211, OK, "SMC", "1211TX"}, /* RTL8139 clone */ @@ -35,33 +37,71 @@ const struct dev_entry nics_realtek[] = { {0}, }; -static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr); -static uint8_t nicrealtek_chip_readb(const struct flashctx *flash, const chipaddr addr); -static const struct par_master par_master_nicrealtek = { - .chip_readb = nicrealtek_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicrealtek_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, -}; +static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr) +{ + struct nicrealtek_data *data = flash->mst->par.data; + + /* Output addr and data, set WE to 0, set OE to 1, set CS to 0, + * enable software access. + */ + OUTL(((uint32_t)addr & 0x01FFFF) | 0x0A0000 | (val << 24), + data->io_base_addr + data->bios_rom_addr); + /* Output addr and data, set WE to 1, set OE to 1, set CS to 1, + * enable software access. + */ + OUTL(((uint32_t)addr & 0x01FFFF) | 0x1E0000 | (val << 24), + data->io_base_addr + data->bios_rom_addr); +} + +static uint8_t nicrealtek_chip_readb(const struct flashctx *flash, const chipaddr addr) +{ + struct nicrealtek_data *data = flash->mst->par.data; + uint8_t val; + + /* FIXME: Can we skip reading the old data and simply use 0? */ + /* Read old data. */ + val = INB(data->io_base_addr + data->bios_rom_data); + /* Output new addr and old data, set WE to 1, set OE to 0, set CS to 0, + * enable software access. + */ + OUTL(((uint32_t)addr & 0x01FFFF) | 0x060000 | (val << 24), + data->io_base_addr + data->bios_rom_addr); + + /* Read new data. */ + val = INB(data->io_base_addr + data->bios_rom_data); + /* Output addr and new data, set WE to 1, set OE to 1, set CS to 1, + * enable software access. + */ + OUTL(((uint32_t)addr & 0x01FFFF) | 0x1E0000 | (val << 24), + data->io_base_addr + data->bios_rom_addr); + + return val; +} static int nicrealtek_shutdown(void *data) { /* FIXME: We forgot to disable software access again. */ + free(data); return 0; } -int nicrealtek_init(void) +static const struct par_master par_master_nicrealtek = { + .chip_readb = nicrealtek_chip_readb, + .chip_writeb = nicrealtek_chip_writeb, + .shutdown = nicrealtek_shutdown, +}; + +static int nicrealtek_init(const struct programmer_cfg *cfg) { struct pci_dev *dev = NULL; + uint32_t io_base_addr = 0; + int bios_rom_addr; + int bios_rom_data; if (rget_io_perms()) return 1; - dev = pcidev_init(nics_realtek, PCI_BASE_ADDRESS_0); + dev = pcidev_init(cfg, nics_realtek, PCI_BASE_ADDRESS_0); if (!dev) return 1; @@ -83,52 +123,21 @@ int nicrealtek_init(void) break; } - if (register_shutdown(nicrealtek_shutdown, NULL)) + struct nicrealtek_data *data = calloc(1, sizeof(*data)); + if (!data) { + msg_perr("Unable to allocate space for PAR master data\n"); return 1; + } + data->io_base_addr = io_base_addr; + data->bios_rom_addr = bios_rom_addr; + data->bios_rom_data = bios_rom_data; - register_par_master(&par_master_nicrealtek, BUS_PARALLEL); - - return 0; -} - -static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr) -{ - /* Output addr and data, set WE to 0, set OE to 1, set CS to 0, - * enable software access. - */ - OUTL(((uint32_t)addr & 0x01FFFF) | 0x0A0000 | (val << 24), - io_base_addr + bios_rom_addr); - /* Output addr and data, set WE to 1, set OE to 1, set CS to 1, - * enable software access. - */ - OUTL(((uint32_t)addr & 0x01FFFF) | 0x1E0000 | (val << 24), - io_base_addr + bios_rom_addr); -} - -static uint8_t nicrealtek_chip_readb(const struct flashctx *flash, const chipaddr addr) -{ - uint8_t val; - - /* FIXME: Can we skip reading the old data and simply use 0? */ - /* Read old data. */ - val = INB(io_base_addr + bios_rom_data); - /* Output new addr and old data, set WE to 1, set OE to 0, set CS to 0, - * enable software access. - */ - OUTL(((uint32_t)addr & 0x01FFFF) | 0x060000 | (val << 24), - io_base_addr + bios_rom_addr); - - /* Read new data. */ - val = INB(io_base_addr + bios_rom_data); - /* Output addr and new data, set WE to 1, set OE to 1, set CS to 1, - * enable software access. - */ - OUTL(((uint32_t)addr & 0x01FFFF) | 0x1E0000 | (val << 24), - io_base_addr + bios_rom_addr); - - return val; + return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, data); } -#else -#error PCI port I/O access is not supported on this architecture yet. -#endif +const struct programmer_entry programmer_nicrealtek = { + .name = "nicrealtek", + .type = PCI, + .devs.dev = nics_realtek, + .init = nicrealtek_init, +}; |