Index: qemu/hw/pci.c =================================================================== --- qemu.orig/hw/pci.c 2007-08-23 17:52:49.000000000 +0000 +++ qemu/hw/pci.c 2007-08-23 18:25:35.000000000 +0000 @@ -574,20 +574,20 @@ } /* Initialize a PCI NIC. */ -void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn) +void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, qemu_dma *parent_dma) { if (strcmp(nd->model, "ne2k_pci") == 0) { pci_ne2000_init(bus, nd, devfn); } else if (strcmp(nd->model, "i82551") == 0) { - pci_i82551_init(bus, nd, devfn); + pci_i82551_init(bus, nd, devfn, parent_dma); } else if (strcmp(nd->model, "i82557b") == 0) { - pci_i82557b_init(bus, nd, devfn); + pci_i82557b_init(bus, nd, devfn, parent_dma); } else if (strcmp(nd->model, "i82559er") == 0) { - pci_i82559er_init(bus, nd, devfn); + pci_i82559er_init(bus, nd, devfn, parent_dma); } else if (strcmp(nd->model, "rtl8139") == 0) { - pci_rtl8139_init(bus, nd, devfn); + pci_rtl8139_init(bus, nd, devfn, parent_dma); } else if (strcmp(nd->model, "pcnet") == 0) { - pci_pcnet_init(bus, nd, devfn); + pci_pcnet_init(bus, nd, devfn, parent_dma); } else if (strcmp(nd->model, "?") == 0) { fprintf(stderr, "qemu: Supported PCI NICs: i82551 i82557b i82559er" " ne2k_pci pcnet rtl8139\n"); Index: qemu/hw/rtl8139.c =================================================================== --- qemu.orig/hw/rtl8139.c 2007-08-23 17:44:32.000000000 +0000 +++ qemu/hw/rtl8139.c 2007-08-23 17:56:22.000000000 +0000 @@ -410,9 +410,6 @@ /* Clears all tally counters */ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters); -/* Writes tally counters to specified physical memory address */ -static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters); - /* Loads values of tally counters from VM state file */ static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters); @@ -492,8 +489,13 @@ /* PCI interrupt timer */ QEMUTimer *timer; + /* Memory access */ + qemu_dma *dma; } RTL8139State; +/* Writes tally counters to specified physical memory address */ +static void RTL8139TallyCounters_physical_memory_write(RTL8139State *s, target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters); + void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) { DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command)); @@ -752,14 +754,14 @@ if (size > wrapped) { - cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, + dma_memory_write( s->dma, s->RxBuf + s->RxBufAddr, buf, size-wrapped ); } /* reset buffer pointer */ s->RxBufAddr = 0; - cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, + dma_memory_write( s->dma, s->RxBuf + s->RxBufAddr, buf + (size-wrapped), wrapped ); s->RxBufAddr = wrapped; @@ -769,7 +771,7 @@ } /* non-wrapping path or overwrapping enabled */ - cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size ); + dma_memory_write( s->dma, s->RxBuf + s->RxBufAddr, buf, size ); s->RxBufAddr += size; } @@ -962,13 +964,13 @@ uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI; - cpu_physical_memory_read(cplus_rx_ring_desc, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_rx_ring_desc, (uint8_t *)&val, 4); rxdw0 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_rx_ring_desc+4, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_rx_ring_desc+4, (uint8_t *)&val, 4); rxdw1 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_rx_ring_desc+8, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_rx_ring_desc+8, (uint8_t *)&val, 4); rxbufLO = le32_to_cpu(val); - cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_rx_ring_desc+12, (uint8_t *)&val, 4); rxbufHI = le32_to_cpu(val); DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n", @@ -1013,7 +1015,7 @@ target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); /* receive/copy to target memory */ - cpu_physical_memory_write( rx_addr, buf, size ); + dma_memory_write( s->dma, rx_addr, buf, size ); if (s->CpCmd & CPlusRxChkSum) { @@ -1026,7 +1028,7 @@ #else val = 0; #endif - cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4); + dma_memory_write( s->dma, rx_addr+size, (uint8_t *)&val, 4); /* first segment of received packet flag */ #define CP_RX_STATUS_FS (1<<29) @@ -1075,9 +1077,9 @@ /* update ring data */ val = cpu_to_le32(rxdw0); - cpu_physical_memory_write(cplus_rx_ring_desc, (uint8_t *)&val, 4); + dma_memory_write( s->dma, cplus_rx_ring_desc, (uint8_t *)&val, 4); val = cpu_to_le32(rxdw1); - cpu_physical_memory_write(cplus_rx_ring_desc+4, (uint8_t *)&val, 4); + dma_memory_write( s->dma, cplus_rx_ring_desc+4, (uint8_t *)&val, 4); /* update tally counter */ ++s->tally_counters.RxOk; @@ -1268,50 +1270,50 @@ counters->TxUndrn = 0; } -static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters) +static void RTL8139TallyCounters_physical_memory_write(RTL8139State *s, target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters) { uint16_t val16; uint32_t val32; uint64_t val64; val64 = cpu_to_le64(tally_counters->TxOk); - cpu_physical_memory_write(tc_addr + 0, (uint8_t *)&val64, 8); + dma_memory_write( s->dma, tc_addr + 0, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->RxOk); - cpu_physical_memory_write(tc_addr + 8, (uint8_t *)&val64, 8); + dma_memory_write( s->dma, tc_addr + 8, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->TxERR); - cpu_physical_memory_write(tc_addr + 16, (uint8_t *)&val64, 8); + dma_memory_write( s->dma, tc_addr + 16, (uint8_t *)&val64, 8); val32 = cpu_to_le32(tally_counters->RxERR); - cpu_physical_memory_write(tc_addr + 24, (uint8_t *)&val32, 4); + dma_memory_write( s->dma, tc_addr + 24, (uint8_t *)&val32, 4); val16 = cpu_to_le16(tally_counters->MissPkt); - cpu_physical_memory_write(tc_addr + 28, (uint8_t *)&val16, 2); + dma_memory_write( s->dma, tc_addr + 28, (uint8_t *)&val16, 2); val16 = cpu_to_le16(tally_counters->FAE); - cpu_physical_memory_write(tc_addr + 30, (uint8_t *)&val16, 2); + dma_memory_write( s->dma, tc_addr + 30, (uint8_t *)&val16, 2); val32 = cpu_to_le32(tally_counters->Tx1Col); - cpu_physical_memory_write(tc_addr + 32, (uint8_t *)&val32, 4); + dma_memory_write( s->dma, tc_addr + 32, (uint8_t *)&val32, 4); val32 = cpu_to_le32(tally_counters->TxMCol); - cpu_physical_memory_write(tc_addr + 36, (uint8_t *)&val32, 4); + dma_memory_write( s->dma, tc_addr + 36, (uint8_t *)&val32, 4); val64 = cpu_to_le64(tally_counters->RxOkPhy); - cpu_physical_memory_write(tc_addr + 40, (uint8_t *)&val64, 8); + dma_memory_write( s->dma, tc_addr + 40, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->RxOkBrd); - cpu_physical_memory_write(tc_addr + 48, (uint8_t *)&val64, 8); + dma_memory_write( s->dma, tc_addr + 48, (uint8_t *)&val64, 8); val32 = cpu_to_le32(tally_counters->RxOkMul); - cpu_physical_memory_write(tc_addr + 56, (uint8_t *)&val32, 4); + dma_memory_write( s->dma, tc_addr + 56, (uint8_t *)&val32, 4); val16 = cpu_to_le16(tally_counters->TxAbt); - cpu_physical_memory_write(tc_addr + 60, (uint8_t *)&val16, 2); + dma_memory_write( s->dma, tc_addr + 60, (uint8_t *)&val16, 2); val16 = cpu_to_le16(tally_counters->TxUndrn); - cpu_physical_memory_write(tc_addr + 62, (uint8_t *)&val16, 2); + dma_memory_write( s->dma, tc_addr + 62, (uint8_t *)&val16, 2); } /* Loads values of tally counters from VM state file */ @@ -1779,7 +1781,7 @@ DEBUG_PRINT(("RTL8139: +++ transmit reading %d bytes from host memory at 0x%08x\n", txsize, s->TxAddr[descriptor])); - cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize); + dma_memory_read( s->dma, s->TxAddr[descriptor], txbuffer, txsize); /* Mark descriptor as transferred */ s->TxStatus[descriptor] |= TxHostOwns; @@ -1910,13 +1912,13 @@ uint32_t val, txdw0,txdw1,txbufLO,txbufHI; - cpu_physical_memory_read(cplus_tx_ring_desc, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_tx_ring_desc, (uint8_t *)&val, 4); txdw0 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_tx_ring_desc+4, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_tx_ring_desc+4, (uint8_t *)&val, 4); txdw1 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_tx_ring_desc+8, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_tx_ring_desc+8, (uint8_t *)&val, 4); txbufLO = le32_to_cpu(val); - cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4); + dma_memory_read( s->dma, cplus_tx_ring_desc+12, (uint8_t *)&val, 4); txbufHI = le32_to_cpu(val); DEBUG_PRINT(("RTL8139: +++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", @@ -2020,7 +2022,7 @@ DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n", txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset)); - cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); + dma_memory_read( s->dma, tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); s->cplus_txbuffer_offset += txsize; /* seek to next Rx descriptor */ @@ -2047,9 +2049,9 @@ /* update ring data */ val = cpu_to_le32(txdw0); - cpu_physical_memory_write(cplus_tx_ring_desc, (uint8_t *)&val, 4); + dma_memory_write( s->dma, cplus_tx_ring_desc, (uint8_t *)&val, 4); // val = cpu_to_le32(txdw1); -// cpu_physical_memory_write(cplus_tx_ring_desc+4, &val, 4); +// dma_memory_write( s->dma, cplus_tx_ring_desc+4, &val, 4); /* Now decide if descriptor being processed is holding the last segment of packet */ if (txdw0 & CP_TX_LS) @@ -2375,7 +2377,7 @@ target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]); /* dump tally counters to specified memory location */ - RTL8139TallyCounters_physical_memory_write( tc_addr, &s->tally_counters); + RTL8139TallyCounters_physical_memory_write( s, tc_addr, &s->tally_counters); /* mark dump completed */ s->TxStatus[0] &= ~0x8; @@ -3405,7 +3407,7 @@ } #endif /* RTL8139_ONBOARD_TIMER */ -void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn) +void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn, qemu_dma *parent_dma) { PCIRTL8139State *d; RTL8139State *s; @@ -3442,6 +3444,7 @@ s->pci_dev = (PCIDevice *)d; memcpy(s->macaddr, nd->macaddr, 6); + s->dma = parent_dma; rtl8139_reset(s); s->vc = qemu_new_vlan_client(nd->vlan, rtl8139_receive, rtl8139_can_receive, s); Index: qemu/vl.h =================================================================== --- qemu.orig/vl.h 2007-08-23 17:39:19.000000000 +0000 +++ qemu/vl.h 2007-08-23 20:31:01.000000000 +0000 @@ -877,7 +877,7 @@ PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, qemu_irq *pic, int devfn_min, int nirq); -void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn); +void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, qemu_dma *parent_dma); void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len); uint32_t pci_data_read(void *opaque, uint32_t addr, int len); int pci_bus_num(PCIBus *s); @@ -897,8 +897,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic); /* apb_pci.c */ -PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base, - qemu_irq *pic); +PCIBus *pci_apb_init(target_phys_addr_t special_base, + target_phys_addr_t mem_base, + qemu_irq *pic, qemu_dma *parent_dma, qemu_dma **dvma); PCIBus *pci_vpb_init(qemu_irq *pic, int irq, int realview); @@ -938,7 +939,7 @@ union { int (*init_isa) (AudioState *s, qemu_irq *pic, qemu_dma *parent_dma, qemu_dma *parent_hdma); - int (*init_pci) (PCIBus *bus, AudioState *s); + int (*init_pci) (PCIBus *bus, AudioState *s, qemu_dma *parent_dma); } init; }; @@ -1044,7 +1045,7 @@ ds1225y_t *ds1225y_init(target_phys_addr_t mem_base, const char *filename); /* es1370.c */ -int es1370_init (PCIBus *bus, AudioState *s); +int es1370_init (PCIBus *bus, AudioState *audio, qemu_dma *parent_dma); /* sb16.c */ int SB16_init (AudioState *audio, qemu_irq *pic, qemu_dma *parent_dma, @@ -1081,9 +1082,12 @@ /* eepro100.c */ -void pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn); -void pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn); -void pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn); +void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn, + qemu_dma *parent_dma); +void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn, + qemu_dma *parent_dma); +void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn, + qemu_dma *parent_dma); /* ne2000.c */ @@ -1092,11 +1096,11 @@ /* rtl8139.c */ -void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn); +void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn, qemu_dma *parent_dma); /* pcnet.c */ -void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn); +void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn, qemu_dma *parent_dma); void lance_init(NICInfo *nd, target_phys_addr_t leaddr, qemu_irq irq, qemu_dma *parent_dma, qemu_irq *reset); Index: qemu/hw/eepro100.c =================================================================== --- qemu.orig/hw/eepro100.c 2007-08-23 17:44:21.000000000 +0000 +++ qemu/hw/eepro100.c 2007-08-23 18:23:37.000000000 +0000 @@ -251,6 +251,7 @@ /* Data in mem is always in the byte order of the controller (le). */ uint8_t mem[PCI_MEM_SIZE]; + qemu_dma *dma; } EEPRO100State; /* Default values for MDI (PHY) registers */ @@ -642,7 +643,7 @@ * values which really matter. * Number of data should check configuration!!! */ - cpu_physical_memory_write(s->statsaddr, (uint8_t *) & s->statistics, 64); + dma_memory_write(s->dma, s->statsaddr, (uint8_t *) & s->statistics, 64); stl_phys(s->statsaddr + 0, s->statistics.tx_good_frames); stl_phys(s->statsaddr + 36, s->statistics.rx_good_frames); stl_phys(s->statsaddr + 48, s->statistics.rx_resource_errors); @@ -672,7 +673,7 @@ s->cu_offset = s->pointer; next_command: cb_address = s->cu_base + s->cu_offset; - cpu_physical_memory_read(cb_address, (uint8_t *) & tx, sizeof(tx)); + dma_memory_read(s->dma, cb_address, (uint8_t *) & tx, sizeof(tx)); uint16_t status = le16_to_cpu(tx.status); uint16_t command = le16_to_cpu(tx.command); logout @@ -690,12 +691,12 @@ /* Do nothing. */ break; case CmdIASetup: - cpu_physical_memory_read(cb_address + 8, &s->macaddr[0], 6); + dma_memory_read(s->dma, cb_address + 8, &s->macaddr[0], 6); logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6)); break; case CmdConfigure: - cpu_physical_memory_read(cb_address + 8, &s->configuration[0], - sizeof(s->configuration)); + dma_memory_read(s->dma, cb_address + 8, &s->configuration[0], + sizeof(s->configuration)); logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)); break; case CmdMulticastList: @@ -729,8 +730,8 @@ logout ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n", tx_buffer_address, tx_buffer_size); - cpu_physical_memory_read(tx_buffer_address, &buf[size], - tx_buffer_size); + dma_memory_read(s->dma, tx_buffer_address, &buf[size], + tx_buffer_size); size += tx_buffer_size; } if (tbd_array == 0xffffffff) { @@ -749,8 +750,8 @@ logout ("TBD (extended mode): buffer address 0x%08x, size 0x%04x\n", tx_buffer_address, tx_buffer_size); - cpu_physical_memory_read(tx_buffer_address, &buf[size], - tx_buffer_size); + dma_memory_read(s->dma, tx_buffer_address, &buf[size], + tx_buffer_size); size += tx_buffer_size; if (tx_buffer_el & 1) { break; @@ -766,8 +767,8 @@ logout ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n", tx_buffer_address, tx_buffer_size); - cpu_physical_memory_read(tx_buffer_address, &buf[size], - tx_buffer_size); + dma_memory_read(s->dma, tx_buffer_address, &buf[size], + tx_buffer_size); size += tx_buffer_size; if (tx_buffer_el & 1) { break; @@ -1112,10 +1113,10 @@ case PORT_SELFTEST: logout("selftest address=0x%08x\n", address); eepro100_selftest_t data; - cpu_physical_memory_read(address, (uint8_t *) & data, sizeof(data)); + dma_memory_read(s->dma, address, (uint8_t *) & data, sizeof(data)); data.st_sign = 0xffffffff; data.st_result = 0; - cpu_physical_memory_write(address, (uint8_t *) & data, sizeof(data)); + dma_memory_write(s->dma, address, (uint8_t *) & data, sizeof(data)); break; case PORT_SELECTIVE_RESET: logout("selective reset, selftest address=0x%08x\n", address); @@ -1534,8 +1535,8 @@ //~ !!! //~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 }} eepro100_rx_t rx; - cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx, - offsetof(eepro100_rx_t, packet)); + dma_memory_read(s->dma, s->ru_base + s->ru_offset, (uint8_t *) & rx, + offsetof(eepro100_rx_t, packet)); uint16_t rfd_command = le16_to_cpu(rx.command); uint16_t rfd_size = le16_to_cpu(rx.size); assert(size <= rfd_size); @@ -1553,8 +1554,8 @@ assert(!(s->configuration[18] & 4)); /* TODO: check stripping enable bit. */ //~ assert(!(s->configuration[17] & 1)); - cpu_physical_memory_write(s->ru_base + s->ru_offset + - offsetof(eepro100_rx_t, packet), buf, size); + dma_memory_write(s->dma, s->ru_base + s->ru_offset + + offsetof(eepro100_rx_t, packet), buf, size); s->statistics.rx_good_frames++; eepro100_fr_interrupt(s); s->ru_offset = le32_to_cpu(rx.link); @@ -1736,7 +1737,7 @@ } static void nic_init(PCIBus * bus, NICInfo * nd, - const char *name, uint32_t device) + const char *name, uint32_t device, qemu_dma *parent_dma) { PCIEEPRO100State *d; EEPRO100State *s; @@ -1750,6 +1751,7 @@ s = &d->eepro100; s->device = device; s->pci_dev = &d->dev; + s->dma = parent_dma; pci_reset(s); @@ -1789,20 +1791,23 @@ register_savevm(name, 0, 3, nic_save, nic_load, s); } -void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn) +void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn, + qemu_dma *parent_dma) { - nic_init(bus, nd, "i82551", i82551); + nic_init(bus, nd, "i82551", i82551, parent_dma); //~ uint8_t *pci_conf = d->dev.config; } -void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn) +void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn, + qemu_dma *parent_dma) { - nic_init(bus, nd, "i82557b", i82557B); + nic_init(bus, nd, "i82557b", i82557B, parent_dma); } -void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn) +void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn, + qemu_dma *parent_dma) { - nic_init(bus, nd, "i82559er", i82559ER); + nic_init(bus, nd, "i82559er", i82559ER, parent_dma); } /* eof */ Index: qemu/hw/pcnet.c =================================================================== --- qemu.orig/hw/pcnet.c 2007-08-23 18:25:26.000000000 +0000 +++ qemu/hw/pcnet.c 2007-08-23 18:27:10.000000000 +0000 @@ -1947,16 +1947,16 @@ 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); + dma_memory_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); + dma_memory_read(dma_opaque, addr, buf, len); } -void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn) +void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn, qemu_dma *parent_dma) { PCNetState *d; uint8_t *pci_conf; @@ -2002,6 +2002,7 @@ d->phys_mem_read = pci_physical_memory_read; d->phys_mem_write = pci_physical_memory_write; d->pci_dev = &d->dev; + d->dma_opaque = parent_dma; pcnet_common_init(d, nd, "pcnet"); } Index: qemu/hw/mips_malta.c =================================================================== --- qemu.orig/hw/mips_malta.c 2007-08-23 18:35:39.000000000 +0000 +++ qemu/hw/mips_malta.c 2007-08-23 20:37:52.000000000 +0000 @@ -435,7 +435,7 @@ /* Audio support */ #ifdef HAS_AUDIO -static void audio_init (PCIBus *pci_bus) +static void audio_init (PCIBus *pci_bus, qemu_dma *parent_dma) { struct soundhw *c; int audio_enabled = 0; @@ -451,7 +451,7 @@ if (s) { for (c = soundhw; c->name; ++c) { if (c->enabled) - c->init.init_pci (pci_bus, s); + c->init.init_pci (pci_bus, s, parent_dma); } } } @@ -459,7 +459,7 @@ #endif /* Network support */ -static void network_init (PCIBus *pci_bus) +static void network_init (PCIBus *pci_bus, qemu_dma *parent_dma) { int i; NICInfo *nd; @@ -471,13 +471,19 @@ } if (i == 0 && strcmp(nd->model, "pcnet") == 0) { /* The malta board has a PCNet card using PCI SLOT 11 */ - pci_nic_init(pci_bus, nd, 88); + pci_nic_init(pci_bus, nd, 88, parent_dma); } else { - pci_nic_init(pci_bus, nd, -1); + pci_nic_init(pci_bus, nd, -1, parent_dma); } } } +static void mips_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + /* ROM and pseudo bootloader The following code implements a very very simple bootloader. It first @@ -759,6 +765,7 @@ int piix4_devfn; uint8_t *eeprom_buf; i2c_bus *smbus; + qemu_dma *physical_dma, **isa_dma; int i; /* init CPUs */ @@ -853,7 +860,8 @@ smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256)); } pit = pit_init(0x40, i8259[0]); - DMA_init(0); + physical_dma = qemu_init_dma(mips_dma_memory_rw, NULL); + DMA_init(0, physical_dma, &isa_dma); /* Super I/O */ i8042_init(i8259[1], i8259[12], 0x60); @@ -870,11 +878,11 @@ /* Sound card */ #ifdef HAS_AUDIO - audio_init(pci_bus); + audio_init(pci_bus, physical_dma); #endif /* Network card */ - network_init(pci_bus); + network_init(pci_bus, physical_dma); /* Optional PCI video card */ pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size, Index: qemu/hw/pc.c =================================================================== --- qemu.orig/hw/pc.c 2007-08-23 18:34:35.000000000 +0000 +++ qemu/hw/pc.c 2007-08-23 20:34:02.000000000 +0000 @@ -645,7 +645,7 @@ } else { if (pci_bus) { - c->init.init_pci (pci_bus, s); + c->init.init_pci (pci_bus, s, parent_dma); } } } @@ -877,7 +877,7 @@ } else if (pci_enabled) { if (strcmp(nd->model, "?") == 0) fprintf(stderr, "qemu: Supported ISA NICs: ne2k_isa\n"); - pci_nic_init(pci_bus, nd, -1); + pci_nic_init(pci_bus, nd, -1, physical_dma); } else if (strcmp(nd->model, "?") == 0) { fprintf(stderr, "qemu: Supported ISA NICs: ne2k_isa\n"); exit(1); @@ -899,7 +899,8 @@ i8042_init(i8259[1], i8259[12], 0x60); DMA_init(0, physical_dma, &isa_dma); #ifdef HAS_AUDIO - audio_init(pci_enabled ? pci_bus : NULL, i8259, isa_dma[1], isa_dma[5]); + audio_init(pci_enabled ? pci_bus : NULL, i8259, + pci_enabled ? physical_dma : isa_dma[1], isa_dma[5]); #endif floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table, isa_dma[2]); Index: qemu/hw/mips_pica61.c =================================================================== --- qemu.orig/hw/mips_pica61.c 2007-08-23 18:46:50.000000000 +0000 +++ qemu/hw/mips_pica61.c 2007-08-23 18:48:17.000000000 +0000 @@ -47,6 +47,12 @@ extern FILE *logfile; +static void mips_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + static void main_cpu_reset(void *opaque) { CPUState *env = opaque; @@ -68,6 +74,7 @@ mips_def_t *def; int available_ram; qemu_irq *i8259; + qemu_dma *physical_dma, **isa_dma; /* init CPUs */ if (cpu_model == NULL) { @@ -129,6 +136,8 @@ i8259 = i8259_init(env->irq[2]); rtc_mm_init(0x80004070, 1, i8259[14]); pit_init(0x40, 0); + physical_dma = qemu_init_dma(mips_dma_memory_rw, NULL); + DMA_init(0, physical_dma, &isa_dma); /* Keyboard (i8042) */ i8042_mm_init(i8259[6], i8259[7], 0x80005060, 0); @@ -145,7 +154,7 @@ /* FIXME: missing NCR 53C94 */ /* ISA devices (floppy, serial, parallel) */ - fdctrl_init(i8259[1], 1, 1, 0x80003000, fd_table); + fdctrl_init(i8259[1], 1, 1, 0x80003000, fd_table, isa_dma[1]); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_mm_init(serial_base[i], 0, i8259[serial_irq[i]], serial_hds[i], 1); Index: qemu/hw/realview.c =================================================================== --- qemu.orig/hw/realview.c 2007-08-23 18:40:48.000000000 +0000 +++ qemu/hw/realview.c 2007-08-23 19:39:16.000000000 +0000 @@ -10,6 +10,12 @@ #include "vl.h" #include "arm_pic.h" +static void arm_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + /* Board init. */ static void realview_init(int ram_size, int vga_ram_size, int boot_device, @@ -24,6 +30,7 @@ NICInfo *nd; int n; int done_smc = 0; + qemu_dma *physical_dma; env = cpu_init(); if (!cpu_model) @@ -59,6 +66,8 @@ pl031_init(0x10017000, pic[10]); + physical_dma = qemu_init_dma(arm_dma_memory_rw, NULL); + pci_bus = pci_vpb_init(pic, 48, 1); if (usb_enabled) { usb_ohci_init_pci(pci_bus, 3, -1); @@ -76,7 +85,7 @@ if (strcmp(nd->model, "smc91c111") == 0) { smc91c111_init(nd, 0x4e000000, pic[28]); } else { - pci_nic_init(pci_bus, nd, -1); + pci_nic_init(pci_bus, nd, -1, physical_dma); } } Index: qemu/hw/ppc_chrp.c =================================================================== --- qemu.orig/hw/ppc_chrp.c 2007-08-23 18:50:55.000000000 +0000 +++ qemu/hw/ppc_chrp.c 2007-08-23 18:59:59.000000000 +0000 @@ -289,6 +289,12 @@ buf[1] = nvram_chksum(buf, 16); } +static void ppc_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + /* PowerPC CHRP hardware initialisation */ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, @@ -312,6 +318,7 @@ const char *arch_name; int vga_bios_size, bios_size; qemu_irq *dummy_irq; + qemu_dma *physical_dma; linux_boot = (kernel_filename != NULL); @@ -408,6 +415,8 @@ initrd_size = 0; } + physical_dma = qemu_init_dma(ppc_dma_memory_rw, NULL); + if (is_heathrow) { isa_mem_base = 0x80000000; @@ -434,7 +443,7 @@ for(i = 0; i < nb_nics; i++) { if (!nd_table[i].model) nd_table[i].model = "ne2k_pci"; - pci_nic_init(pci_bus, &nd_table[i], -1); + pci_nic_init(pci_bus, &nd_table[i], -1, physical_dma); } pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); @@ -524,7 +533,7 @@ for(i = 0; i < nb_nics; i++) { if (!nd_table[i].model) nd_table[i].model = "ne2k_pci"; - pci_nic_init(pci_bus, &nd_table[i], -1); + pci_nic_init(pci_bus, &nd_table[i], -1, physical_dma); } #if 1 ide0_mem_index = pmac_ide_init(&bs_table[0], pic[0x13]); Index: qemu/hw/apb_pci.c =================================================================== --- qemu.orig/hw/apb_pci.c 2007-08-23 19:15:08.000000000 +0000 +++ qemu/hw/apb_pci.c 2007-08-23 19:28:37.000000000 +0000 @@ -30,7 +30,10 @@ typedef target_phys_addr_t pci_addr_t; #include "pci_host.h" -typedef PCIHostState APBState; +typedef struct APBState { + PCIHostState pci; + qemu_dma *dma; +} APBState; static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr, uint32_t val) @@ -42,7 +45,7 @@ if ((val & (1 << i)) != 0) break; } - s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11); + s->pci.config_reg = (1 << 16) | (val & 0x7FC) | (i << 11); } static uint32_t pci_apb_config_readl (void *opaque, @@ -52,8 +55,9 @@ uint32_t val; int devfn; - devfn = (s->config_reg >> 8) & 0xFF; - val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC); + devfn = (s->pci.config_reg >> 8) & 0xFF; + val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | + (s->pci.config_reg & 0xFC); return val; } @@ -206,9 +210,18 @@ qemu_set_irq(pic[irq_num], level); } +static void apb_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + APBState *s = opaque; + + // XXX implement IOMMU + dma_memory_rw(s->dma, addr, buf, len, is_write); +} + PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base, - qemu_irq *pic) + qemu_irq *pic, qemu_dma *parent_dma, qemu_dma **dvma) { APBState *s; PCIDevice *d; @@ -217,7 +230,7 @@ s = qemu_mallocz(sizeof(APBState)); /* Ultrasparc PBM main bus */ - s->bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32); + s->pci.bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32); pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read, pci_apb_config_write, s); @@ -233,7 +246,7 @@ cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport); cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom - d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice), + d = pci_register_device(s->pci.bus, "Advanced PCI Bus", sizeof(PCIDevice), 0, NULL, NULL); d->config[0x00] = 0x8e; // vendor_id : Sun d->config[0x01] = 0x10; @@ -251,8 +264,12 @@ d->config[0x0E] = 0x00; // header_type /* APB secondary busses */ - secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 1"); - pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 2"); + secondary = pci_bridge_init(s->pci.bus, 8, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 1"); + pci_bridge_init(s->pci.bus, 9, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 2"); + + s->dma = parent_dma; + *dvma = qemu_init_dma(apb_dma_memory_rw, d); + return secondary; } Index: qemu/hw/sun4u.c =================================================================== --- qemu.orig/hw/sun4u.c 2007-08-23 19:11:40.000000000 +0000 +++ qemu/hw/sun4u.c 2007-08-23 19:21:25.000000000 +0000 @@ -47,19 +47,10 @@ { return 0; } -int DMA_read_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -int DMA_write_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} void DMA_hold_DREQ (int nchan) {} void DMA_release_DREQ (int nchan) {} void DMA_schedule(int nchan) {} void DMA_run (void) {} -void DMA_init (int high_page_enable) {} void DMA_register_channel (int nchan, DMA_transfer_handler transfer_handler, void *opaque) @@ -318,6 +309,12 @@ { } +static void sun4u_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + static const int ide_iobase[2] = { 0x1f0, 0x170 }; static const int ide_iobase2[2] = { 0x3f6, 0x376 }; static const int ide_irq[2] = { 14, 15 }; @@ -346,6 +343,7 @@ const sparc_def_t *def; QEMUBH *bh; qemu_irq *irq; + qemu_dma *physical_dma, *pci_dvma; linux_boot = (kernel_filename != NULL); @@ -425,7 +423,10 @@ } } } - pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL); + physical_dma = qemu_init_dma(sun4u_dma_memory_rw, NULL); + pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL, physical_dma, + &pci_dvma); + isa_mem_base = VGA_BASE; pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, vga_ram_size); @@ -444,7 +445,7 @@ for(i = 0; i < nb_nics; i++) { if (!nd_table[i].model) nd_table[i].model = "ne2k_pci"; - pci_nic_init(pci_bus, &nd_table[i], -1); + pci_nic_init(pci_bus, &nd_table[i], -1, pci_dvma); } irq = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, 32); @@ -452,7 +453,7 @@ pci_piix3_ide_init(pci_bus, bs_table, -1, irq); /* FIXME: wire up interrupts. */ i8042_init(NULL/*1*/, NULL/*12*/, 0x60); - floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table); + floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table, pci_dvma); nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device, KERNEL_LOAD_ADDR, kernel_size, Index: qemu/hw/versatilepb.c =================================================================== --- qemu.orig/hw/versatilepb.c 2007-08-23 19:38:10.000000000 +0000 +++ qemu/hw/versatilepb.c 2007-08-23 19:39:33.000000000 +0000 @@ -145,6 +145,12 @@ return qi; } +static void arm_dma_memory_rw(void *opaque, target_phys_addr_t addr, + uint8_t *buf, int len, int is_write) +{ + cpu_physical_memory_rw(addr, buf, len, is_write); +} + /* Board init. */ /* The AB and PB boards both use the same core, just with different @@ -163,6 +169,7 @@ void *scsi_hba; PCIBus *pci_bus; NICInfo *nd; + qemu_dma *physical_dma; int n; int done_smc = 0; @@ -181,6 +188,8 @@ pl050_init(0x10006000, sic[3], 0); pl050_init(0x10007000, sic[4], 1); + physical_dma = qemu_init_dma(arm_dma_memory_rw, NULL); + pci_bus = pci_vpb_init(sic, 27, 0); /* The Versatile PCI bridge does not provide access to PCI IO space, so many of the qemu PCI devices are not useable. */ @@ -191,7 +200,7 @@ if (strcmp(nd->model, "smc91c111") == 0) { smc91c111_init(nd, 0x10010000, sic[25]); } else { - pci_nic_init(pci_bus, nd, -1); + pci_nic_init(pci_bus, nd, -1, physical_dma); } } if (usb_enabled) { Index: qemu/hw/es1370.c =================================================================== --- qemu.orig/hw/es1370.c 2007-08-23 20:24:58.000000000 +0000 +++ qemu/hw/es1370.c 2007-08-23 20:29:54.000000000 +0000 @@ -275,6 +275,7 @@ uint32_t mempage; uint32_t codec; uint32_t sctl; + qemu_dma *dma; } ES1370State; typedef struct PCIES1370State { @@ -805,7 +806,7 @@ if (!acquired) break; - cpu_physical_memory_write (addr, tmpbuf, acquired); + dma_memory_write(s->dma, addr, tmpbuf, acquired); temp -= acquired; addr += acquired; @@ -819,7 +820,7 @@ int copied, to_copy; to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); - cpu_physical_memory_read (addr, tmpbuf, to_copy); + dma_memory_read (s->dma, addr, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy); if (!copied) break; @@ -996,7 +997,7 @@ es1370_reset (s); } -int es1370_init (PCIBus *bus, AudioState *audio) +int es1370_init (PCIBus *bus, AudioState *audio, qemu_dma *parent_dma) { PCIES1370State *d; ES1370State *s; @@ -1051,6 +1052,7 @@ s = &d->es1370; s->pci_dev = &d->dev; + s->dma = parent_dma; pci_register_io_region (&d->dev, 0, 256, PCI_ADDRESS_SPACE_IO, es1370_map); register_savevm ("es1370", 0, 1, es1370_save, es1370_load, s);