diff options
Diffstat (limited to 'drkaiser.c')
-rw-r--r-- | drkaiser.c | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/drkaiser.c b/drkaiser.c index ac49df304..ebf511915 100644 --- a/drkaiser.c +++ b/drkaiser.c @@ -17,7 +17,8 @@ #include <stdlib.h> #include "flash.h" #include "programmer.h" -#include "hwaccess.h" +#include "hwaccess_physmap.h" +#include "platform/pci.h" #define PCI_VENDOR_ID_DRKAISER 0x1803 @@ -29,38 +30,58 @@ /* Mask to restrict flash accesses to the 128kB memory window. */ #define DRKAISER_MEMMAP_MASK ((1 << 17) - 1) -const struct dev_entry drkaiser_pcidev[] = { +struct drkaiser_data { + struct pci_dev *dev; + uint8_t *bar; + uint16_t flash_access; +}; + +static const struct dev_entry drkaiser_pcidev[] = { {0x1803, 0x5057, OK, "Dr. Kaiser", "PC-Waechter (Actel FPGA)"}, {0}, }; -static uint8_t *drkaiser_bar; - static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val, - chipaddr addr); + chipaddr addr) +{ + struct drkaiser_data *data = flash->mst->par.data; + + pci_mmio_writeb(val, data->bar + (addr & DRKAISER_MEMMAP_MASK)); +} + static uint8_t drkaiser_chip_readb(const struct flashctx *flash, - const chipaddr addr); + const chipaddr addr) +{ + struct drkaiser_data *data = flash->mst->par.data; + + return pci_mmio_readb(data->bar + (addr & DRKAISER_MEMMAP_MASK)); +} + +static int drkaiser_shutdown(void *par_data) +{ + struct drkaiser_data *data = par_data; + + /* Restore original flash writing state. */ + pci_write_word(data->dev, PCI_MAGIC_DRKAISER_ADDR, data->flash_access); + + free(par_data); + return 0; +} + static const struct par_master par_master_drkaiser = { - .chip_readb = drkaiser_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = drkaiser_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, + .chip_readb = drkaiser_chip_readb, + .chip_writeb = drkaiser_chip_writeb, + .shutdown = drkaiser_shutdown, }; -int drkaiser_init(void) +static int drkaiser_init(const struct programmer_cfg *cfg) { struct pci_dev *dev = NULL; uint32_t addr; + uint8_t *bar; - if (rget_io_perms()) - return 1; - - dev = pcidev_init(drkaiser_pcidev, PCI_BASE_ADDRESS_2); + dev = pcidev_init(cfg, drkaiser_pcidev, PCI_BASE_ADDRESS_2); if (!dev) return 1; @@ -68,28 +89,31 @@ int drkaiser_init(void) if (!addr) return 1; - /* Write magic register to enable flash write. */ - rpci_write_word(dev, PCI_MAGIC_DRKAISER_ADDR, PCI_MAGIC_DRKAISER_VALUE); - /* Map 128kB flash memory window. */ - drkaiser_bar = rphysmap("Dr. Kaiser PC-Waechter flash memory", addr, DRKAISER_MEMMAP_SIZE); - if (drkaiser_bar == ERROR_PTR) + bar = rphysmap("Dr. Kaiser PC-Waechter flash memory", addr, DRKAISER_MEMMAP_SIZE); + if (bar == ERROR_PTR) return 1; - max_rom_decode.parallel = 128 * 1024; - register_par_master(&par_master_drkaiser, BUS_PARALLEL); + struct drkaiser_data *data = calloc(1, sizeof(*data)); + if (!data) { + msg_perr("Unable to allocate space for PAR master data\n"); + return 1; + } + data->dev = dev; + data->bar = bar; - return 0; -} + /* Write magic register to enable flash write. */ + data->flash_access = pci_read_word(dev, PCI_MAGIC_DRKAISER_ADDR); + pci_write_word(dev, PCI_MAGIC_DRKAISER_ADDR, PCI_MAGIC_DRKAISER_VALUE); -static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val, - chipaddr addr) -{ - pci_mmio_writeb(val, drkaiser_bar + (addr & DRKAISER_MEMMAP_MASK)); -} + max_rom_decode.parallel = 128 * 1024; -static uint8_t drkaiser_chip_readb(const struct flashctx *flash, - const chipaddr addr) -{ - return pci_mmio_readb(drkaiser_bar + (addr & DRKAISER_MEMMAP_MASK)); + return register_par_master(&par_master_drkaiser, BUS_PARALLEL, data); } + +const struct programmer_entry programmer_drkaiser = { + .name = "drkaiser", + .type = PCI, + .devs.dev = drkaiser_pcidev, + .init = drkaiser_init, +}; |