From 2ab2ef078504c9a4979bd5c457fdf5903292e0f7 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:11 -0500 Subject: [PATCH 1/8] cmd646: Remove unused variable There was a pointer to PCIIDEState in CMD646BAR which was set but not used afterwards. Get rid of this unused variable. Signed-off-by: BALATON Zoltan Tested-by: Mark Cave-Ayland Reviewed-by: John Snow Message-id: 1e352f091aa601fb2e19771aac46529fe278dd91.1547166960.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/cmd646.c | 1 - include/hw/ide/pci.h | 1 - 2 files changed, 2 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 6bb92d717f..41c1831f9a 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -123,7 +123,6 @@ static void setup_cmd646_bar(PCIIDEState *d, int bus_num) CMD646BAR *bar = &d->cmd646_bar[bus_num]; bar->bus = bus; - bar->pci_dev = d; memory_region_init_io(&bar->cmd, OBJECT(d), &cmd646_cmd_ops, bar, "cmd646-cmd", 4); memory_region_init_io(&bar->data, OBJECT(d), &cmd646_data_ops, bar, diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index dbc6a0383d..ed723acfb4 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -41,7 +41,6 @@ typedef struct CMD646BAR { MemoryRegion cmd; MemoryRegion data; IDEBus *bus; - struct PCIIDEState *pci_dev; } CMD646BAR; #define TYPE_PCI_IDE "pci-ide" From e210ec87b93cf94212b5f522d514115dc3604975 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:11 -0500 Subject: [PATCH 2/8] cmd646: Remove IDEBus from CMD646BAR The cmd646 io mem ops callbacks only need the IDEBus which is currently passed via a CMD646BAR struct. No need to wrap it up like that, we can pass it directly to these callbacks which then allows to drop the IDEBus from the CMD646BAR. Signed-off-by: BALATON Zoltan Tested-by: Mark Cave-Ayland Reviewed-by: John Snow Message-id: 7a31c155c9899869794499d841d30c7ef32aae47.1547166960.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/cmd646.c | 29 ++++++++++++++--------------- include/hw/ide/pci.h | 1 - 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 41c1831f9a..c24f71e219 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -53,23 +53,23 @@ static void cmd646_update_irq(PCIDevice *pd); static uint64_t cmd646_cmd_read(void *opaque, hwaddr addr, unsigned size) { - CMD646BAR *cmd646bar = opaque; + IDEBus *bus = opaque; if (addr != 2 || size != 1) { return ((uint64_t)1 << (size * 8)) - 1; } - return ide_status_read(cmd646bar->bus, addr + 2); + return ide_status_read(bus, addr + 2); } static void cmd646_cmd_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { - CMD646BAR *cmd646bar = opaque; + IDEBus *bus = opaque; if (addr != 2 || size != 1) { return; } - ide_cmd_write(cmd646bar->bus, addr + 2, data); + ide_cmd_write(bus, addr + 2, data); } static const MemoryRegionOps cmd646_cmd_ops = { @@ -81,15 +81,15 @@ static const MemoryRegionOps cmd646_cmd_ops = { static uint64_t cmd646_data_read(void *opaque, hwaddr addr, unsigned size) { - CMD646BAR *cmd646bar = opaque; + IDEBus *bus = opaque; if (size == 1) { - return ide_ioport_read(cmd646bar->bus, addr); + return ide_ioport_read(bus, addr); } else if (addr == 0) { if (size == 2) { - return ide_data_readw(cmd646bar->bus, addr); + return ide_data_readw(bus, addr); } else { - return ide_data_readl(cmd646bar->bus, addr); + return ide_data_readl(bus, addr); } } return ((uint64_t)1 << (size * 8)) - 1; @@ -98,15 +98,15 @@ static uint64_t cmd646_data_read(void *opaque, hwaddr addr, static void cmd646_data_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { - CMD646BAR *cmd646bar = opaque; + IDEBus *bus = opaque; if (size == 1) { - ide_ioport_write(cmd646bar->bus, addr, data); + ide_ioport_write(bus, addr, data); } else if (addr == 0) { if (size == 2) { - ide_data_writew(cmd646bar->bus, addr, data); + ide_data_writew(bus, addr, data); } else { - ide_data_writel(cmd646bar->bus, addr, data); + ide_data_writel(bus, addr, data); } } } @@ -122,10 +122,9 @@ static void setup_cmd646_bar(PCIIDEState *d, int bus_num) IDEBus *bus = &d->bus[bus_num]; CMD646BAR *bar = &d->cmd646_bar[bus_num]; - bar->bus = bus; - memory_region_init_io(&bar->cmd, OBJECT(d), &cmd646_cmd_ops, bar, + memory_region_init_io(&bar->cmd, OBJECT(d), &cmd646_cmd_ops, bus, "cmd646-cmd", 4); - memory_region_init_io(&bar->data, OBJECT(d), &cmd646_data_ops, bar, + memory_region_init_io(&bar->data, OBJECT(d), &cmd646_data_ops, bus, "cmd646-data", 8); } diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index ed723acfb4..013d7937d2 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -40,7 +40,6 @@ typedef struct BMDMAState { typedef struct CMD646BAR { MemoryRegion cmd; MemoryRegion data; - IDEBus *bus; } CMD646BAR; #define TYPE_PCI_IDE "pci-ide" From c9ebc75dc24f99e881414e7f35544041f678235a Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:11 -0500 Subject: [PATCH 3/8] cmd646: Move PCI IDE specific functions to ide/pci.c The io mem ops callbacks are not specific to CMD646 but really follow the PCI IDE spec so move these from cmd646.c to pci.c to allow other PCI IDE implementations to use them. Signed-off-by: BALATON Zoltan Tested-by: Mark Cave-Ayland Reviewed-by: John Snow Message-id: a2b1b2b74afdc78330b8b75605687f683a249635.1547166960.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/cmd646.c | 71 ++------------------------------------------ hw/ide/pci.c | 65 ++++++++++++++++++++++++++++++++++++++++ include/hw/ide/pci.h | 2 ++ 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index c24f71e219..95f0df9742 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -50,81 +50,14 @@ static void cmd646_update_irq(PCIDevice *pd); -static uint64_t cmd646_cmd_read(void *opaque, hwaddr addr, - unsigned size) -{ - IDEBus *bus = opaque; - - if (addr != 2 || size != 1) { - return ((uint64_t)1 << (size * 8)) - 1; - } - return ide_status_read(bus, addr + 2); -} - -static void cmd646_cmd_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size) -{ - IDEBus *bus = opaque; - - if (addr != 2 || size != 1) { - return; - } - ide_cmd_write(bus, addr + 2, data); -} - -static const MemoryRegionOps cmd646_cmd_ops = { - .read = cmd646_cmd_read, - .write = cmd646_cmd_write, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -static uint64_t cmd646_data_read(void *opaque, hwaddr addr, - unsigned size) -{ - IDEBus *bus = opaque; - - if (size == 1) { - return ide_ioport_read(bus, addr); - } else if (addr == 0) { - if (size == 2) { - return ide_data_readw(bus, addr); - } else { - return ide_data_readl(bus, addr); - } - } - return ((uint64_t)1 << (size * 8)) - 1; -} - -static void cmd646_data_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size) -{ - IDEBus *bus = opaque; - - if (size == 1) { - ide_ioport_write(bus, addr, data); - } else if (addr == 0) { - if (size == 2) { - ide_data_writew(bus, addr, data); - } else { - ide_data_writel(bus, addr, data); - } - } -} - -static const MemoryRegionOps cmd646_data_ops = { - .read = cmd646_data_read, - .write = cmd646_data_write, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - static void setup_cmd646_bar(PCIIDEState *d, int bus_num) { IDEBus *bus = &d->bus[bus_num]; CMD646BAR *bar = &d->cmd646_bar[bus_num]; - memory_region_init_io(&bar->cmd, OBJECT(d), &cmd646_cmd_ops, bus, + memory_region_init_io(&bar->cmd, OBJECT(d), &pci_ide_cmd_le_ops, bus, "cmd646-cmd", 4); - memory_region_init_io(&bar->data, OBJECT(d), &cmd646_data_ops, bus, + memory_region_init_io(&bar->data, OBJECT(d), &pci_ide_data_le_ops, bus, "cmd646-data", 8); } diff --git a/hw/ide/pci.c b/hw/ide/pci.c index b75154f99f..942613a9a9 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -36,6 +36,71 @@ (IDE_RETRY_DMA | IDE_RETRY_PIO | \ IDE_RETRY_READ | IDE_RETRY_FLUSH) +static uint64_t pci_ide_cmd_read(void *opaque, hwaddr addr, unsigned size) +{ + IDEBus *bus = opaque; + + if (addr != 2 || size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + return ide_status_read(bus, addr + 2); +} + +static void pci_ide_cmd_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + IDEBus *bus = opaque; + + if (addr != 2 || size != 1) { + return; + } + ide_cmd_write(bus, addr + 2, data); +} + +const MemoryRegionOps pci_ide_cmd_le_ops = { + .read = pci_ide_cmd_read, + .write = pci_ide_cmd_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static uint64_t pci_ide_data_read(void *opaque, hwaddr addr, unsigned size) +{ + IDEBus *bus = opaque; + + if (size == 1) { + return ide_ioport_read(bus, addr); + } else if (addr == 0) { + if (size == 2) { + return ide_data_readw(bus, addr); + } else { + return ide_data_readl(bus, addr); + } + } + return ((uint64_t)1 << (size * 8)) - 1; +} + +static void pci_ide_data_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + IDEBus *bus = opaque; + + if (size == 1) { + ide_ioport_write(bus, addr, data); + } else if (addr == 0) { + if (size == 2) { + ide_data_writew(bus, addr, data); + } else { + ide_data_writel(bus, addr, data); + } + } +} + +const MemoryRegionOps pci_ide_data_le_ops = { + .read = pci_ide_data_read, + .write = pci_ide_data_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void bmdma_start_dma(IDEDMA *dma, IDEState *s, BlockCompletionFunc *dma_cb) { diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index 013d7937d2..3110633e4c 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -71,4 +71,6 @@ extern MemoryRegionOps bmdma_addr_ioport_ops; void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table); extern const VMStateDescription vmstate_ide_pci; +extern const MemoryRegionOps pci_ide_cmd_le_ops; +extern const MemoryRegionOps pci_ide_data_le_ops; #endif From 8ac98d1a97a7aeefe45f4a5af37d61caa41ded54 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:11 -0500 Subject: [PATCH 4/8] ide: Get rid of CMD646BAR struct Now that no CMD646 specific parts are left in CMD646BAR (all remaining members are really PCI IDE specific) this struct can be deleted moving the memory regions for PCI IDE BARs to PCIIDEState where they better belong. The CMD646 PCI IDE model is adjusted accordingly. Signed-off-by: BALATON Zoltan Tested-by: Mark Cave-Ayland Reviewed-by: John Snow Message-id: 4b6cb2ae150dc0d21178209e4beb1e35140a7325.1547166960.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/cmd646.c | 33 ++++++++++++++++----------------- include/hw/ide/pci.h | 10 ++-------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 95f0df9742..5a5679134a 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -50,17 +50,6 @@ static void cmd646_update_irq(PCIDevice *pd); -static void setup_cmd646_bar(PCIIDEState *d, int bus_num) -{ - IDEBus *bus = &d->bus[bus_num]; - CMD646BAR *bar = &d->cmd646_bar[bus_num]; - - memory_region_init_io(&bar->cmd, OBJECT(d), &pci_ide_cmd_le_ops, bus, - "cmd646-cmd", 4); - memory_region_init_io(&bar->data, OBJECT(d), &pci_ide_data_le_ops, bus, - "cmd646-data", 8); -} - static void cmd646_update_dma_interrupts(PCIDevice *pd) { /* Sync DMA interrupt status from UDMA interrupt status */ @@ -277,12 +266,22 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) dev->wmask[MRDMODE] = 0x0; dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1; - setup_cmd646_bar(d, 0); - setup_cmd646_bar(d, 1); - pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data); - pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd); - pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data); - pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd); + memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops, + &d->bus[0], "cmd646-data0", 8); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]); + + memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops, + &d->bus[0], "cmd646-cmd0", 4); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]); + + memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops, + &d->bus[1], "cmd646-data1", 8); + pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]); + + memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops, + &d->bus[1], "cmd646-cmd1", 4); + pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]); + bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index 3110633e4c..a9f2c33e68 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -37,11 +37,6 @@ typedef struct BMDMAState { struct PCIIDEState *pci_dev; } BMDMAState; -typedef struct CMD646BAR { - MemoryRegion cmd; - MemoryRegion data; -} CMD646BAR; - #define TYPE_PCI_IDE "pci-ide" #define PCI_IDE(obj) OBJECT_CHECK(PCIIDEState, (obj), TYPE_PCI_IDE) @@ -54,17 +49,16 @@ typedef struct PCIIDEState { BMDMAState bmdma[2]; uint32_t secondary; /* used only for cmd646 */ MemoryRegion bmdma_bar; - CMD646BAR cmd646_bar[2]; /* used only for cmd646 */ + MemoryRegion cmd_bar[2]; + MemoryRegion data_bar[2]; } PCIIDEState; - static inline IDEState *bmdma_active_if(BMDMAState *bmdma) { assert(bmdma->bus->retry_unit != (uint8_t)-1); return bmdma->bus->ifs + bmdma->bus->retry_unit; } - void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d); void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val); extern MemoryRegionOps bmdma_addr_ioport_ops; From 4eefdf7c1baa41e59cf4792df887a033e86339db Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:11 -0500 Subject: [PATCH 5/8] sii3112: Remove duplicated code and use PCI IDE ops instead Parts of the SiI3112 mmio are identical to PCI IDE registers so we can use the corresponding functions that were factored out into ide/pci.c. This removes code duplication and simplifies the SiI3112 model which also helped to spot a copy paste error where reading status of the 2nd channel read the 1st channel instead. This is also fixed here. Signed-off-by: BALATON Zoltan Tested-by: Mark Cave-Ayland Reviewed-by: John Snow Message-id: 793b6a7934ef2bba26b8d066bec446019efa6c5d.1547166960.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/sii3112.c | 52 ++++++++---------------------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c index 743a50ed51..59db09cfe4 100644 --- a/hw/ide/sii3112.c +++ b/hw/ide/sii3112.c @@ -88,35 +88,19 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr, val |= (uint32_t)d->i.bmdma[1].status << 16; break; case 0x80 ... 0x87: - if (size == 1) { - val = ide_ioport_read(&d->i.bus[0], addr - 0x80); - } else if (addr == 0x80) { - val = (size == 2) ? ide_data_readw(&d->i.bus[0], 0) : - ide_data_readl(&d->i.bus[0], 0); - } else { - val = (1ULL << (size * 8)) - 1; - } + val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size); break; case 0x8a: - val = (size == 1) ? ide_status_read(&d->i.bus[0], 4) : - (1ULL << (size * 8)) - 1; + val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size); break; case 0xa0: val = d->regs[0].confstat; break; case 0xc0 ... 0xc7: - if (size == 1) { - val = ide_ioport_read(&d->i.bus[1], addr - 0xc0); - } else if (addr == 0xc0) { - val = (size == 2) ? ide_data_readw(&d->i.bus[1], 0) : - ide_data_readl(&d->i.bus[1], 0); - } else { - val = (1ULL << (size * 8)) - 1; - } + val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size); break; case 0xca: - val = (size == 1) ? ide_status_read(&d->i.bus[0], 4) : - (1ULL << (size * 8)) - 1; + val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size); break; case 0xe0: val = d->regs[1].confstat; @@ -186,36 +170,16 @@ static void sii3112_reg_write(void *opaque, hwaddr addr, bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size); break; case 0x80 ... 0x87: - if (size == 1) { - ide_ioport_write(&d->i.bus[0], addr - 0x80, val); - } else if (addr == 0x80) { - if (size == 2) { - ide_data_writew(&d->i.bus[0], 0, val); - } else { - ide_data_writel(&d->i.bus[0], 0, val); - } - } + pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size); break; case 0x8a: - if (size == 1) { - ide_cmd_write(&d->i.bus[0], 4, val); - } + pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size); break; case 0xc0 ... 0xc7: - if (size == 1) { - ide_ioport_write(&d->i.bus[1], addr - 0xc0, val); - } else if (addr == 0xc0) { - if (size == 2) { - ide_data_writew(&d->i.bus[1], 0, val); - } else { - ide_data_writel(&d->i.bus[1], 0, val); - } - } + pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size); break; case 0xca: - if (size == 1) { - ide_cmd_write(&d->i.bus[1], 4, val); - } + pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size); break; case 0x100: d->regs[0].scontrol = val & 0xfff; From 0252e66c5a577e80ba353f3048a681c4e5ab2ddd Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:11 -0500 Subject: [PATCH 6/8] ide/via: Remove vt82c686b_init_ports() function This function is only called once from vt82c686b_ide_realize() and its content is simple enough to not need a separate function but be included in realize directly (as done in other IDE models except PIIX currently). Signed-off-by: BALATON Zoltan Message-id: 47d854e0fa41dad6861107eac61327c247965566.1548160772.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/via.c | 50 +++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index 987d99c5ec..46cac7b8d6 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -32,6 +32,15 @@ #include "hw/ide/pci.h" #include "trace.h" +static const struct { + int iobase; + int iobase2; + int isairq; +} port_info[] = { + {0x1f0, 0x3f6, 14}, + {0x170, 0x376, 15}, +}; + static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size) { @@ -143,17 +152,22 @@ static void via_reset(void *opaque) pci_set_long(pci_conf + 0xc0, 0x00020001); } -static void vt82c686b_init_ports(PCIIDEState *d) { - static const struct { - int iobase; - int iobase2; - int isairq; - } port_info[] = { - {0x1f0, 0x3f6, 14}, - {0x170, 0x376, 15}, - }; +/* via ide func */ +static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp) +{ + PCIIDEState *d = PCI_IDE(dev); + uint8_t *pci_conf = dev->config; int i; + pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ + pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); + + qemu_register_reset(via_reset, d); + bmdma_setup_bar(d); + pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); + + vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); + for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2); ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, @@ -166,24 +180,6 @@ static void vt82c686b_init_ports(PCIIDEState *d) { } } -/* via ide func */ -static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp) -{ - PCIIDEState *d = PCI_IDE(dev); - uint8_t *pci_conf = dev->config; - - pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ - pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); - - qemu_register_reset(via_reset, d); - bmdma_setup_bar(d); - pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); - - vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); - - vt82c686b_init_ports(d); -} - static void vt82c686b_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = PCI_IDE(dev); From 7dd687ba1b99009d31235d75c082279715dbf676 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:12 -0500 Subject: [PATCH 7/8] ide/via: Rename functions to match device name The device is called via-ide and the modelled IDE controller is not specific to 82C686B but is also usable independently. Therefore, change function name prefixes accordingly to match device name. Signed-off-by: BALATON Zoltan Message-id: 2905ced862c8d2ad509d73152171ce2472d72605.1548160772.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/via.c | 15 +++++++-------- hw/mips/mips_fulong2e.c | 2 +- include/hw/ide.h | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index 46cac7b8d6..c6e43a8812 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -110,7 +110,7 @@ static void bmdma_setup_bar(PCIIDEState *d) } } -static void via_reset(void *opaque) +static void via_ide_reset(void *opaque) { PCIIDEState *d = opaque; PCIDevice *pd = PCI_DEVICE(d); @@ -152,8 +152,7 @@ static void via_reset(void *opaque) pci_set_long(pci_conf + 0xc0, 0x00020001); } -/* via ide func */ -static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp) +static void via_ide_realize(PCIDevice *dev, Error **errp) { PCIIDEState *d = PCI_IDE(dev); uint8_t *pci_conf = dev->config; @@ -162,7 +161,7 @@ static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp) pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); - qemu_register_reset(via_reset, d); + qemu_register_reset(via_ide_reset, d); bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); @@ -180,7 +179,7 @@ static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp) } } -static void vt82c686b_ide_exitfn(PCIDevice *dev) +static void via_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = PCI_IDE(dev); unsigned i; @@ -191,7 +190,7 @@ static void vt82c686b_ide_exitfn(PCIDevice *dev) } } -void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) +void via_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) { PCIDevice *dev; @@ -204,8 +203,8 @@ static void via_ide_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->realize = vt82c686b_ide_realize; - k->exit = vt82c686b_ide_exitfn; + k->realize = via_ide_realize; + k->exit = via_ide_exitfn; k->vendor_id = PCI_VENDOR_ID_VIA; k->device_id = PCI_DEVICE_ID_VIA_IDE; k->revision = 0x06; diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 2fbba32c48..42d09f6892 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -249,7 +249,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); ide_drive_get(hd, ARRAY_SIZE(hd)); - vt82c686b_ide_init(pci_bus, hd, PCI_DEVFN(slot, 1)); + via_ide_init(pci_bus, hd, PCI_DEVFN(slot, 1)); pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); diff --git a/include/hw/ide.h b/include/hw/ide.h index 3ae087c572..28d8a06439 100644 --- a/include/hw/ide.h +++ b/include/hw/ide.h @@ -18,7 +18,7 @@ PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); int pci_piix3_xen_ide_unplug(DeviceState *dev, bool aux); -void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); +void via_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-mmio.c */ void mmio_ide_init_drives(DeviceState *dev, DriveInfo *hd0, DriveInfo *hd1); From 4ea98d317eb442c738f898f16cfdd47a18b7ca49 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 25 Jan 2019 14:52:12 -0500 Subject: [PATCH 8/8] ide/via: Implement and use native PCI IDE mode This device only implemented ISA compatibility mode and native PCI IDE mode was missing but no clients actually need ISA mode but to the contrary, they usually want to switch to and use device in native PCI IDE mode. Therefore implement native PCI mode and switch default to that. Signed-off-by: BALATON Zoltan Message-id: c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.balaton@eik.bme.hu Signed-off-by: John Snow --- hw/ide/via.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index c6e43a8812..ac9385228c 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -32,15 +32,6 @@ #include "hw/ide/pci.h" #include "trace.h" -static const struct { - int iobase; - int iobase2; - int isairq; -} port_info[] = { - {0x1f0, 0x3f6, 14}, - {0x170, 0x376, 15}, -}; - static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size) { @@ -110,6 +101,23 @@ static void bmdma_setup_bar(PCIIDEState *d) } } +static void via_ide_set_irq(void *opaque, int n, int level) +{ + PCIDevice *d = PCI_DEVICE(opaque); + + if (level) { + d->config[0x70 + n * 8] |= 0x80; + } else { + d->config[0x70 + n * 8] &= ~0x80; + } + + level = (d->config[0x70] & 0x80) || (d->config[0x78] & 0x80); + n = pci_get_byte(d->config + PCI_INTERRUPT_LINE); + if (n) { + qemu_set_irq(isa_get_irq(NULL, n), level); + } +} + static void via_ide_reset(void *opaque) { PCIIDEState *d = opaque; @@ -121,7 +129,7 @@ static void via_ide_reset(void *opaque) ide_bus_reset(&d->bus[i]); } - pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_WAIT); + pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_WAIT); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); @@ -158,10 +166,28 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) uint8_t *pci_conf = dev->config; int i; - pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ + pci_config_set_prog_interface(pci_conf, 0x8f); /* native PCI ATA mode */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); + dev->wmask[PCI_INTERRUPT_LINE] = 0xf; qemu_register_reset(via_ide_reset, d); + + memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops, + &d->bus[0], "via-ide0-data", 8); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]); + + memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops, + &d->bus[0], "via-ide0-cmd", 4); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]); + + memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops, + &d->bus[1], "via-ide1-data", 8); + pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]); + + memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops, + &d->bus[1], "via-ide1-cmd", 4); + pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]); + bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); @@ -169,9 +195,7 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2); - ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, - port_info[i].iobase2); - ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq)); + ide_init2(&d->bus[i], qemu_allocate_irq(via_ide_set_irq, d, i)); bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i];