]> git.proxmox.com Git - qemu.git/blobdiff - hw/pcnet-pci.c
Merge branch pci into master
[qemu.git] / hw / pcnet-pci.c
index fb2a00caad43cafd5e8b248ce05f087740c346af..31eb1a8d6f58c5b37ef99c9e9841b9e0296e7ff6 100644 (file)
@@ -31,6 +31,7 @@
 #include "net.h"
 #include "loader.h"
 #include "qemu-timer.h"
+#include "dma.h"
 
 #include "pcnet.h"
 
@@ -55,9 +56,9 @@ static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
 #ifdef PCNET_DEBUG
     printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
 #endif
-    /* Check APROMWE bit to enable write access */
-    if (pcnet_bcr_readw(s,2) & 0x100)
+    if (BCR_APROMWE(s)) {
         s->prom[addr & 15] = val;
+    }
 }
 
 static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
@@ -75,12 +76,24 @@ static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr,
 {
     PCNetState *d = opaque;
 
-    if (addr < 16 && size == 1) {
-        return pcnet_aprom_readb(d, addr);
-    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
-        return pcnet_ioport_readw(d, addr);
-    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
-        return pcnet_ioport_readl(d, addr);
+    if (addr < 0x10) {
+        if (!BCR_DWIO(d) && size == 1) {
+            return pcnet_aprom_readb(d, addr);
+        } else if (!BCR_DWIO(d) && (addr & 1) == 0 && size == 2) {
+            return pcnet_aprom_readb(d, addr) |
+                   (pcnet_aprom_readb(d, addr + 1) << 8);
+        } else if (BCR_DWIO(d) && (addr & 3) == 0 && size == 4) {
+            return pcnet_aprom_readb(d, addr) |
+                   (pcnet_aprom_readb(d, addr + 1) << 8) |
+                   (pcnet_aprom_readb(d, addr + 2) << 16) |
+                   (pcnet_aprom_readb(d, addr + 3) << 24);
+        }
+    } else {
+        if (size == 2) {
+            return pcnet_ioport_readw(d, addr);
+        } else if (size == 4) {
+            return pcnet_ioport_readl(d, addr);
+        }
     }
     return ((uint64_t)1 << (size * 8)) - 1;
 }
@@ -90,12 +103,24 @@ static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,
 {
     PCNetState *d = opaque;
 
-    if (addr < 16 && size == 1) {
-        return pcnet_aprom_writeb(d, addr, data);
-    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
-        return pcnet_ioport_writew(d, addr, data);
-    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
-        return pcnet_ioport_writel(d, addr, data);
+    if (addr < 0x10) {
+        if (!BCR_DWIO(d) && size == 1) {
+            pcnet_aprom_writeb(d, addr, data);
+        } else if (!BCR_DWIO(d) && (addr & 1) == 0 && size == 2) {
+            pcnet_aprom_writeb(d, addr, data & 0xff);
+            pcnet_aprom_writeb(d, addr + 1, data >> 8);
+        } else if (BCR_DWIO(d) && (addr & 3) == 0 && size == 4) {
+            pcnet_aprom_writeb(d, addr, data & 0xff);
+            pcnet_aprom_writeb(d, addr + 1, (data >> 8) & 0xff);
+            pcnet_aprom_writeb(d, addr + 2, (data >> 16) & 0xff);
+            pcnet_aprom_writeb(d, addr + 3, data >> 24);
+        }
+    } else {
+        if (size == 2) {
+            pcnet_ioport_writew(d, addr, data);
+        } else if (size == 4) {
+            pcnet_ioport_writel(d, addr, data);
+        }
     }
 }
 
@@ -230,13 +255,13 @@ static const MemoryRegionOps pcnet_mmio_ops = {
 static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
                                       uint8_t *buf, int len, int do_bswap)
 {
-    cpu_physical_memory_write(addr, buf, len);
+    pci_dma_write(dma_opaque, addr, buf, len);
 }
 
 static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
                                      uint8_t *buf, int len, int do_bswap)
 {
-    cpu_physical_memory_read(addr, buf, len);
+    pci_dma_read(dma_opaque, addr, buf, len);
 }
 
 static void pci_pcnet_cleanup(VLANClientState *nc)
@@ -246,7 +271,7 @@ static void pci_pcnet_cleanup(VLANClientState *nc)
     pcnet_common_cleanup(d);
 }
 
-static int pci_pcnet_uninit(PCIDevice *dev)
+static void pci_pcnet_uninit(PCIDevice *dev)
 {
     PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
 
@@ -255,14 +280,14 @@ static int pci_pcnet_uninit(PCIDevice *dev)
     qemu_del_timer(d->state.poll_timer);
     qemu_free_timer(d->state.poll_timer);
     qemu_del_vlan_client(&d->state.nic->nc);
-    return 0;
 }
 
 static NetClientInfo net_pci_pcnet_info = {
-    .type = NET_CLIENT_TYPE_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = pcnet_can_receive,
     .receive = pcnet_receive,
+    .link_status_changed = pcnet_set_link_status,
     .cleanup = pci_pcnet_cleanup,
 };
 
@@ -302,14 +327,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
     s->irq = pci_dev->irq[0];
     s->phys_mem_read = pci_physical_memory_read;
     s->phys_mem_write = pci_physical_memory_write;
-
-    if (!pci_dev->qdev.hotplugged) {
-        static int loaded = 0;
-        if (!loaded) {
-            rom_add_option("pxe-pcnet.rom", -1);
-            loaded = 1;
-        }
-    }
+    s->dma_opaque = pci_dev;
 
     return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info);
 }
@@ -321,26 +339,38 @@ static void pci_reset(DeviceState *dev)
     pcnet_h_reset(&d->state);
 }
 
-static PCIDeviceInfo pcnet_info = {
-    .qdev.name  = "pcnet",
-    .qdev.size  = sizeof(PCIPCNetState),
-    .qdev.reset = pci_reset,
-    .qdev.vmsd  = &vmstate_pci_pcnet,
-    .init       = pci_pcnet_init,
-    .exit       = pci_pcnet_uninit,
-    .vendor_id  = PCI_VENDOR_ID_AMD,
-    .device_id  = PCI_DEVICE_ID_AMD_LANCE,
-    .revision   = 0x10,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property pcnet_properties[] = {
+    DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pcnet_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_pcnet_init;
+    k->exit = pci_pcnet_uninit;
+    k->romfile = "pxe-pcnet.rom",
+    k->vendor_id = PCI_VENDOR_ID_AMD;
+    k->device_id = PCI_DEVICE_ID_AMD_LANCE;
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    dc->reset = pci_reset;
+    dc->vmsd = &vmstate_pci_pcnet;
+    dc->props = pcnet_properties;
+}
+
+static TypeInfo pcnet_info = {
+    .name          = "pcnet",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIPCNetState),
+    .class_init    = pcnet_class_init,
 };
 
-static void pci_pcnet_register_devices(void)
+static void pci_pcnet_register_types(void)
 {
-    pci_qdev_register(&pcnet_info);
+    type_register_static(&pcnet_info);
 }
 
-device_init(pci_pcnet_register_devices)
+type_init(pci_pcnet_register_types)