#include "net.h"
#include "loader.h"
#include "qemu-timer.h"
+#include "dma.h"
#include "pcnet.h"
#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)
{
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;
}
{
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);
+ }
}
}
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)
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);
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,
};
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);
}
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)