From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40719) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1baHpO-0003Ta-7n for qemu-devel@nongnu.org; Thu, 18 Aug 2016 03:33:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1baHp8-00015s-D7 for qemu-devel@nongnu.org; Thu, 18 Aug 2016 03:33:25 -0400 Received: from smtp5-g21.free.fr ([2a01:e0c:1:1599::14]:45971) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1baHp8-00015M-6J for qemu-devel@nongnu.org; Thu, 18 Aug 2016 03:33:10 -0400 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 18 Aug 2016 09:31:28 +0200 Message-Id: <1471505489-1221-4-git-send-email-hpoussin@reactos.org> In-Reply-To: <1471505489-1221-1-git-send-email-hpoussin@reactos.org> References: <1471505489-1221-1-git-send-email-hpoussin@reactos.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH 3/4] lsi: implement I/O memory space for Memory Move instructions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: qemu-devel@nongnu.org, =?UTF-8?q?Herv=C3=A9=20Poussineau?= Memory Move instructions can read/write data either from PCI memory or fr= om PCI I/O. Implement second case. Windows 98 now works with LSI 53C810A adapter. Signed-off-by: Herv=C3=A9 Poussineau --- hw/scsi/lsi53c895a.c | 49 +++++++++++++++++++++++++++++++++++++++-------= --- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 9d2e3eb..2e99d5e 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -210,6 +210,7 @@ typedef struct { MemoryRegion mmio_io; MemoryRegion ram_io; MemoryRegion io_io; + AddressSpace pci_io_as; =20 int carry; /* ??? Should this be an a visible register somewhere? *= / int status; @@ -407,6 +408,30 @@ static void lsi_reg_writeb(LSIState *s, int offset, = uint8_t val); static void lsi_execute_script(LSIState *s); static void lsi_reselect(LSIState *s, lsi_request *p); =20 +static inline int lsi_mem_read(LSIState *s, dma_addr_t addr, + void *buf, dma_addr_t len) +{ + if (s->dmode & LSI_DMODE_SIOM) { + address_space_read(&s->pci_io_as, addr, MEMTXATTRS_UNSPECIFIED, + buf, len); + return 0; + } else { + return pci_dma_read(PCI_DEVICE(s), addr, buf, len); + } +} + +static inline int lsi_mem_write(LSIState *s, dma_addr_t addr, + const void *buf, dma_addr_t len) +{ + if (s->dmode & LSI_DMODE_DIOM) { + address_space_write(&s->pci_io_as, addr, MEMTXATTRS_UNSPECIFIED, + buf, len); + return 0; + } else { + return pci_dma_write(PCI_DEVICE(s), addr, buf, len); + } +} + static inline uint32_t read_dword(LSIState *s, uint32_t addr) { uint32_t buf; @@ -550,7 +575,6 @@ static void lsi_bad_selection(LSIState *s, uint32_t i= d) /* Initiate a SCSI layer data transfer. */ static void lsi_do_dma(LSIState *s, int out) { - PCIDevice *pci_dev; uint32_t count; dma_addr_t addr; SCSIDevice *dev; @@ -562,7 +586,6 @@ static void lsi_do_dma(LSIState *s, int out) return; } =20 - pci_dev =3D PCI_DEVICE(s); dev =3D s->current->req->dev; assert(dev); =20 @@ -588,9 +611,9 @@ static void lsi_do_dma(LSIState *s, int out) } /* ??? Set SFBR to first data byte. */ if (out) { - pci_dma_read(pci_dev, addr, s->current->dma_buf, count); + lsi_mem_read(s, addr, s->current->dma_buf, count); } else { - pci_dma_write(pci_dev, addr, s->current->dma_buf, count); + lsi_mem_write(s, addr, s->current->dma_buf, count); } s->current->dma_len -=3D count; if (s->current->dma_len =3D=3D 0) { @@ -1022,15 +1045,14 @@ bad: #define LSI_BUF_SIZE 4096 static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int cou= nt) { - PCIDevice *d =3D PCI_DEVICE(s); int n; uint8_t buf[LSI_BUF_SIZE]; =20 DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count= ); while (count) { n =3D (count > LSI_BUF_SIZE) ? LSI_BUF_SIZE : count; - pci_dma_read(d, src, buf, n); - pci_dma_write(d, dest, buf, n); + lsi_mem_read(s, src, buf, n); + lsi_mem_write(s, dest, buf, n); src +=3D n; dest +=3D n; count -=3D n; @@ -1877,9 +1899,6 @@ static void lsi_reg_writeb(LSIState *s, int offset,= uint8_t val) CASE_SET_REG32(dsps, 0x30) CASE_SET_REG32(scratch[0], 0x34) case 0x38: /* DMODE */ - if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) { - BADF("IO mappings not implemented\n"); - } s->dmode =3D val; break; case 0x39: /* DIEN */ @@ -2189,6 +2208,8 @@ static void lsi_scsi_realize(PCIDevice *dev, Error = **errp) memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s, "lsi-io", 256); =20 + address_space_init(&s->pci_io_as, pci_address_space_io(dev), "lsi-pc= i-io"); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_io)= ; pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io); @@ -2200,6 +2221,13 @@ static void lsi_scsi_realize(PCIDevice *dev, Error= **errp) } } =20 +static void lsi_scsi_unrealize(DeviceState *dev, Error **errp) +{ + LSIState *s =3D LSI53C895A(dev); + + address_space_destroy(&s->pci_io_as); +} + static void lsi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -2210,6 +2238,7 @@ static void lsi_class_init(ObjectClass *klass, void= *data) k->device_id =3D PCI_DEVICE_ID_LSI_53C895A; k->class_id =3D PCI_CLASS_STORAGE_SCSI; k->subsystem_id =3D 0x1000; + dc->unrealize =3D lsi_scsi_unrealize; dc->reset =3D lsi_scsi_reset; dc->vmsd =3D &vmstate_lsi_scsi; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); --=20 2.1.4