From patchwork Tue Feb 9 22:01:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 44970 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 588D5B80A0 for ; Wed, 10 Feb 2010 09:15:40 +1100 (EST) Received: from localhost ([127.0.0.1]:42593 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NeyML-0000CL-U3 for incoming@patchwork.ozlabs.org; Tue, 09 Feb 2010 17:15:05 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Ney9h-0002EO-4n for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:02:01 -0500 Received: from [199.232.76.173] (port=52481 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ney9g-0002D8-5G for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:02:00 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1Ney9e-0005nc-Rf for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:01:59 -0500 Received: from e5.ny.us.ibm.com ([32.97.182.145]:44098) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Ney9d-0005mV-40 for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:01:57 -0500 Received: from d01relay01.pok.ibm.com (d01relay01.pok.ibm.com [9.56.227.233]) by e5.ny.us.ibm.com (8.14.3/8.13.1) with ESMTP id o19LmZG2007635 for ; Tue, 9 Feb 2010 16:48:35 -0500 Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o19M1mp6093480 for ; Tue, 9 Feb 2010 17:01:48 -0500 Received: from d01av01.pok.ibm.com (loopback [127.0.0.1]) by d01av01.pok.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id o19M1lo6013831 for ; Tue, 9 Feb 2010 17:01:47 -0500 Received: from localhost.localdomain (sig-9-65-47-242.mts.ibm.com [9.65.47.242]) by d01av01.pok.ibm.com (8.14.3/8.13.1/NCO v10.0 AVin) with ESMTP id o19M1eiE013399; Tue, 9 Feb 2010 17:01:47 -0500 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Tue, 9 Feb 2010 16:01:28 -0600 Message-Id: <1265752899-26980-5-git-send-email-aliguori@us.ibm.com> X-Mailer: git-send-email 1.6.5.2 In-Reply-To: <1265752899-26980-1-git-send-email-aliguori@us.ibm.com> References: <1265752899-26980-1-git-send-email-aliguori@us.ibm.com> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: Michael Tsirkin , Anthony Liguori , Alex Graf Subject: [Qemu-devel] [PATCH 04/15] e1000: convert to new pci interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org - eliminated coalesced mmio support, need new api Signed-off-by: Anthony Liguori --- 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);