From patchwork Tue Feb 9 22:01:39 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 44972 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 AEC5AB7DD0 for ; Wed, 10 Feb 2010 09:20:48 +1100 (EST) Received: from localhost ([127.0.0.1]:43784 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NeyRo-0002lK-Em for incoming@patchwork.ozlabs.org; Tue, 09 Feb 2010 17:20:44 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Ney9n-0002KT-J5 for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:02:07 -0500 Received: from [199.232.76.173] (port=52489 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ney9l-0002Ig-OY for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:02:05 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1Ney9k-0005oS-9G for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:02:05 -0500 Received: from e1.ny.us.ibm.com ([32.97.182.141]:53937) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Ney9k-0005oO-12 for qemu-devel@nongnu.org; Tue, 09 Feb 2010 17:02:04 -0500 Received: from d01relay07.pok.ibm.com (d01relay07.pok.ibm.com [9.56.227.147]) by e1.ny.us.ibm.com (8.14.3/8.13.1) with ESMTP id o19LwMwU024729 for ; Tue, 9 Feb 2010 16:58:22 -0500 Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay07.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o19M21k42048252 for ; Tue, 9 Feb 2010 17:02:01 -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 o19M21IM015209 for ; Tue, 9 Feb 2010 17:02:01 -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 o19M1eiP013399; Tue, 9 Feb 2010 17:02:00 -0500 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Tue, 9 Feb 2010 16:01:39 -0600 Message-Id: <1265752899-26980-16-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 15/15] pci: byte swap as PCI interface layer 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 PCI devices have a fixed byte order that is independent of the host byte order. For the most part, PCI devices are little endian. Because we have allowed PCI devices in the past to directly register memory functions with the CPU, these devices have been subject to automagic swapping which means that they end up returning target endianness instead of the fixed endianness that the device supports. This patch fixes this by allow devices to return native words in their interface and allowing the PCI bus to do appropriate swapping before the data makes it to the CPU. Right now, most devices do this wrong so this should, in theory, fix a lot of PCI devices on big endian targets. Signed-off-by: Anthony Liguori --- hw/e1000.c | 9 +-------- hw/pci.c | 18 ++++++++++++++++-- hw/rtl8139.c | 44 +------------------------------------------- 3 files changed, 18 insertions(+), 53 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index 823088c..0738e38 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -847,9 +847,6 @@ static void e1000_mmio_write(PCIDevice *dev, pcibus_t addr, int size, E1000State *d = DO_UPCAST(E1000State, dev, dev); unsigned int index = (addr & 0x1ffff) >> 2; -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap32(value); -#endif value = (value & size_mask(size)) << addr_shift(addr); if (index < NWRITEOPS && macreg_writeops[index]) @@ -873,11 +870,7 @@ static uint32_t e1000_mmio_read(PCIDevice *dev, pcibus_t addr, int size) DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); } - value = (value >> addr_shift(addr)) & size_mask(size); -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap32(value); -#endif - return value; + return (value >> addr_shift(addr)) & size_mask(size); } static bool is_version_1(void *opaque, int version_id) diff --git a/hw/pci.c b/hw/pci.c index 50ae917..f1816f9 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -765,6 +765,9 @@ static void pci_io_region_writew(void *opaque, target_phys_addr_t addr, uint32_t value) { PCIIORegion *r = opaque; +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap16(value); +#endif r->write(r->dev, addr, 2, value); } @@ -772,6 +775,9 @@ static void pci_io_region_writel(void *opaque, target_phys_addr_t addr, uint32_t value) { PCIIORegion *r = opaque; +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap32(value); +#endif r->write(r->dev, addr, 4, value); } @@ -784,13 +790,21 @@ static uint32_t pci_io_region_readb(void *opaque, target_phys_addr_t addr) static uint32_t pci_io_region_readw(void *opaque, target_phys_addr_t addr) { PCIIORegion *r = opaque; - return r->read(r->dev, addr, 2); + uint32_t value = r->read(r->dev, addr, 2); +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap16(value); +#endif + return value; } static uint32_t pci_io_region_readl(void *opaque, target_phys_addr_t addr) { PCIIORegion *r = opaque; - return r->read(r->dev, addr, 4); + uint32_t value = r->read(r->dev, addr, 4); +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap32(value); +#endif + return value; } static CPUReadMemoryFunc * const pci_io_region_readfn[3] = { diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 95e7aeb..a812c5f 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -3107,48 +3107,6 @@ static const VMStateDescription vmstate_rtl8139 = { /***********************************************************/ /* PCI RTL8139 definitions */ -static uint32_t rtl8139_mmio_read(PCIDevice *dev, pcibus_t addr, int size) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev); - uint32_t value; - - if (size == 1) { - value = rtl8139_io_readb(s, addr); - } else if (size == 2) { - value = rtl8139_io_readw(s, addr); -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap16(value); -#endif - } else { - value = rtl8139_io_readl(s, addr & 0xFF); -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap32(value); -#endif - } - - return value; -} - -static void rtl8139_mmio_write(PCIDevice *dev, pcibus_t addr, int size, - uint32_t value) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev); - - if (size == 1) { - rtl8139_io_writeb(s, addr, value); - } else if (size == 2) { -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap16(value); -#endif - rtl8139_io_writew(s, addr, value); - } else if (size == 4) { -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap32(value); -#endif - rtl8139_io_writel(s, addr, value); - } -} - static uint32_t rtl8139_io_read(PCIDevice *dev, pcibus_t addr, int size) { RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev); @@ -3286,7 +3244,7 @@ static int pci_rtl8139_init(PCIDevice *dev) pci_register_io_region(&s->dev, 0, 0x100, PCI_BASE_ADDRESS_SPACE_IO, rtl8139_io_read, rtl8139_io_write); pci_register_io_region(&s->dev, 1, 0x100, PCI_BASE_ADDRESS_SPACE_MEMORY, - rtl8139_mmio_read, rtl8139_mmio_write); + rtl8139_io_read, rtl8139_io_write); qemu_macaddr_default_if_unset(&s->conf.macaddr);