- eliminated coalesced mmio support, need new api Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> --- hw/e1000.c | 164 ++++++++++++++++++++++-------------------------------------- 1 files changed, 60 insertions(+), 104 deletions(-)
diff --git a/hw/e1000.c b/hw/e1000.c index fd3059a..823088c 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -148,12 +148,18 @@ static const char phy_regcap[0x20] = { [PHY_ID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R }; -static void -ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, - pcibus_t size, int type) +static uint32_t e1000_io_read(PCIDevice *dev, pcibus_t addr, int size) +{ + DBGOUT(IO, "e1000_io_read addr=0x%04"FMT_PCIBUS + " size=%d\n", addr, size); + return 0xFFFFFFFF; +} + +static void e1000_io_write(PCIDevice *dev, pcibus_t addr, int size, + uint32_t value) { - DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS - " size=0x%08"FMT_PCIBUS"\n", addr, size); + DBGOUT(IO, "e1000_io_write addr=0x%04"FMT_PCIBUS + " size=%d value=%u\n", addr, size, value); } static void @@ -456,7 +462,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) bytes = split_size; if (tp->size + bytes > msh) bytes = msh - tp->size; - cpu_physical_memory_read(addr, tp->data + tp->size, bytes); + pci_memory_read(&s->dev, addr, tp->data + tp->size, bytes); if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) memmove(tp->header, tp->data, hdr); tp->size = sz; @@ -471,7 +477,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) // context descriptor TSE is not set, while data descriptor TSE is set DBGOUT(TXERR, "TCP segmentaion Error\n"); } else { - cpu_physical_memory_read(addr, tp->data + tp->size, split_size); + pci_memory_read(&s->dev, addr, tp->data + tp->size, split_size); tp->size += split_size; } @@ -487,7 +493,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) } static uint32_t -txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) +txdesc_writeback(E1000State *s, pcibus_t base, struct e1000_tx_desc *dp) { uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data); @@ -496,7 +502,7 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) & ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU); dp->upper.data = cpu_to_le32(txd_upper); - cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp), + pci_memory_write(&s->dev, base + ((char *)&dp->upper - (char *)dp), (void *)&dp->upper, sizeof(dp->upper)); return E1000_ICR_TXDW; } @@ -504,7 +510,7 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) static void start_xmit(E1000State *s) { - target_phys_addr_t base; + pcibus_t base; struct e1000_tx_desc desc; uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE; @@ -516,14 +522,14 @@ start_xmit(E1000State *s) while (s->mac_reg[TDH] != s->mac_reg[TDT]) { base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] + sizeof(struct e1000_tx_desc) * s->mac_reg[TDH]; - cpu_physical_memory_read(base, (void *)&desc, sizeof(desc)); + pci_memory_read(&s->dev, base, (void *)&desc, sizeof(desc)); DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH], (void *)(intptr_t)desc.buffer_addr, desc.lower.data, desc.upper.data); process_tx_desc(s, &desc); - cause |= txdesc_writeback(base, &desc); + cause |= txdesc_writeback(s, base, &desc); if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN]) s->mac_reg[TDH] = 0; @@ -622,7 +628,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; struct e1000_rx_desc desc; - target_phys_addr_t base; + pcibus_t base; unsigned int n, rdt; uint32_t rdh_start; uint16_t vlan_special = 0; @@ -657,17 +663,17 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) } base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] + sizeof(desc) * s->mac_reg[RDH]; - cpu_physical_memory_read(base, (void *)&desc, sizeof(desc)); + pci_memory_read(&s->dev, base, (void *)&desc, sizeof(desc)); desc.special = vlan_special; desc.status |= (vlan_status | E1000_RXD_STAT_DD); if (desc.buffer_addr) { - cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr), + pci_memory_write(&s->dev, le64_to_cpu(desc.buffer_addr), (void *)(buf + vlan_offset), size); desc.length = cpu_to_le16(size); desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM; } else // as per intel docs; skip descriptors with null buf addr DBGOUT(RX, "Null RX descriptor!!\n"); - cpu_physical_memory_write(base, (void *)&desc, sizeof(desc)); + pci_memory_write(&s->dev, base, (void *)&desc, sizeof(desc)); if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) s->mac_reg[RDH] = 0; @@ -822,72 +828,56 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = { [MTA ... MTA+127] = &mac_writereg, [VFTA ... VFTA+127] = &mac_writereg, }; + enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) }; -static void -e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +static uint32_t size_mask(int size) { - E1000State *s = opaque; + return (1ULL << (size * 8)) - 1; +} + +static int addr_shift(pcibus_t addr) +{ + return (8 * (addr & 3)); +} + +static void e1000_mmio_write(PCIDevice *dev, pcibus_t addr, int size, + uint32_t value) +{ + E1000State *d = DO_UPCAST(E1000State, dev, dev); unsigned int index = (addr & 0x1ffff) >> 2; #ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); + value = bswap32(value); #endif + value = (value & size_mask(size)) << addr_shift(addr); + if (index < NWRITEOPS && macreg_writeops[index]) - macreg_writeops[index](s, index, val); + macreg_writeops[index](d, index, value); else if (index < NREADOPS && macreg_readops[index]) - DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val); + DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, value); else DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n", - index<<2, val); + index<<2, value); } -static void -e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) +static uint32_t e1000_mmio_read(PCIDevice *dev, pcibus_t addr, int size) { - // emulate hw without byte enables: no RMW - e1000_mmio_writel(opaque, addr & ~3, - (val & 0xffff) << (8*(addr & 3))); -} - -static void -e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - // emulate hw without byte enables: no RMW - e1000_mmio_writel(opaque, addr & ~3, - (val & 0xff) << (8*(addr & 3))); -} + E1000State *d = DO_UPCAST(E1000State, dev, dev); + unsigned int index = (addr & 0x1fffc) >> 2; + uint32_t value = 0; -static uint32_t -e1000_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - E1000State *s = opaque; - unsigned int index = (addr & 0x1ffff) >> 2; + if (index < NREADOPS && macreg_readops[index]) { + value = macreg_readops[index](d, index); + } else { + DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); + } - if (index < NREADOPS && macreg_readops[index]) - { - uint32_t val = macreg_readops[index](s, index); + value = (value >> addr_shift(addr)) & size_mask(size); #ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); + value = bswap32(value); #endif - return val; - } - DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); - return 0; -} - -static uint32_t -e1000_mmio_readb(void *opaque, target_phys_addr_t addr) -{ - return ((e1000_mmio_readl(opaque, addr & ~3)) >> - (8 * (addr & 3))) & 0xff; -} - -static uint32_t -e1000_mmio_readw(void *opaque, target_phys_addr_t addr) -{ - return ((e1000_mmio_readl(opaque, addr & ~3)) >> - (8 * (addr & 3))) & 0xffff; + return value; } static bool is_version_1(void *opaque, int version_id) @@ -1009,38 +999,6 @@ static const uint32_t mac_reg_init[] = { /* PCI interface */ -static CPUWriteMemoryFunc * const e1000_mmio_write[] = { - e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel -}; - -static CPUReadMemoryFunc * const e1000_mmio_read[] = { - e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl -}; - -static void -e1000_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); - int i; - const uint32_t excluded_regs[] = { - E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS, - E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE - }; - - - DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", - addr, size); - - cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); - qemu_register_coalesced_mmio(addr, excluded_regs[0]); - - for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++) - qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4, - excluded_regs[i + 1] - - excluded_regs[i] - 4); -} - static void e1000_cleanup(VLANClientState *nc) { @@ -1054,7 +1012,6 @@ pci_e1000_uninit(PCIDevice *dev) { E1000State *d = DO_UPCAST(E1000State, dev, dev); - cpu_unregister_io_memory(d->mmio_index); qemu_del_vlan_client(&d->nic->nc); return 0; } @@ -1102,14 +1059,13 @@ static int pci_e1000_init(PCIDevice *pci_dev) /* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */ pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 - d->mmio_index = cpu_register_io_memory(e1000_mmio_read, - e1000_mmio_write, d); - - pci_register_bar((PCIDevice *)d, 0, PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map); + pci_register_io_region(pci_dev, 0, PNPMMIO_SIZE, + PCI_BASE_ADDRESS_SPACE_MEMORY, + e1000_mmio_read, e1000_mmio_write); - pci_register_bar((PCIDevice *)d, 1, IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, ioport_map); + pci_register_io_region(pci_dev, 1, IOPORT_SIZE, + PCI_BASE_ADDRESS_SPACE_IO, + e1000_io_read, e1000_io_write); memmove(d->eeprom_data, e1000_eeprom_template, sizeof e1000_eeprom_template); -- 1.6.5.2