From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id BBD7A5A95 for ; Tue, 17 May 2016 12:00:31 +0200 (CEST) Received: from glumotte.dev.6wind.com (unknown [10.16.0.195]) by proxy.6wind.com (Postfix) with ESMTP id 91C412A183; Tue, 17 May 2016 11:58:54 +0200 (CEST) From: Olivier Matz To: dev@dpdk.org Cc: david.marchand@6wind.com, chaozhu@linux.vnet.ibm.com, yuanhan.liu@linux.intel.com, huawei.xie@intel.com Date: Tue, 17 May 2016 11:59:51 +0200 Message-Id: <1463479192-2488-7-git-send-email-olivier.matz@6wind.com> X-Mailer: git-send-email 2.8.0.rc3 In-Reply-To: <1463479192-2488-1-git-send-email-olivier.matz@6wind.com> References: <1463143859-3105-1-git-send-email-olivier.matz@6wind.com> <1463479192-2488-1-git-send-email-olivier.matz@6wind.com> Subject: [dpdk-dev] [PATCH v2 6/7] virtio: fix pci accesses for ppc64 in legacy mode X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 May 2016 10:00:31 -0000 From: David Marchand Although ppc supports both endianesses, qemu supposes that the cpu is big endian and enforces this for the virtio-net stuff. Fix PCI accesses in legacy mode. Only ppc64le is supported at the moment. Signed-off-by: David Marchand Signed-off-by: Olivier Matz --- drivers/net/virtio/virtio_pci.c | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c index 9cdca06..ebf4cf7 100644 --- a/drivers/net/virtio/virtio_pci.c +++ b/drivers/net/virtio/virtio_pci.c @@ -55,20 +55,88 @@ */ #define VIRTIO_PCI_CONFIG(hw) (((hw)->use_msix) ? 24 : 20) +/* + * Since we are in legacy mode: + * http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf + * + * "Note that this is possible because while the virtio header is PCI (i.e. + * little) endian, the device-specific region is encoded in the native endian of + * the guest (where such distinction is applicable)." + * + * For powerpc which supports both, qemu supposes that cpu is big endian and + * enforces this for the virtio-net stuff. + */ + static void legacy_read_dev_config(struct virtio_hw *hw, size_t offset, void *dst, int length) { +#ifdef RTE_ARCH_PPC_64 + int size; + + while (length > 0) { + if (length >= 4) { + size = 4; + rte_eal_pci_ioport_read(&hw->io, dst, size, + VIRTIO_PCI_CONFIG(hw) + offset); + *(uint32_t *)dst = rte_be_to_cpu_32(*(uint32_t *)dst); + } else if (length >= 2) { + size = 2; + rte_eal_pci_ioport_read(&hw->io, dst, size, + VIRTIO_PCI_CONFIG(hw) + offset); + *(uint16_t *)dst = rte_be_to_cpu_16(*(uint16_t *)dst); + } else { + size = 1; + rte_eal_pci_ioport_read(&hw->io, dst, size, + VIRTIO_PCI_CONFIG(hw) + offset); + } + + dst = (char *)dst + size; + offset += size; + length -= size; + } +#else rte_eal_pci_ioport_read(&hw->io, dst, length, VIRTIO_PCI_CONFIG(hw) + offset); +#endif } static void legacy_write_dev_config(struct virtio_hw *hw, size_t offset, const void *src, int length) { +#ifdef RTE_ARCH_PPC_64 + union { + uint32_t u32; + uint16_t u16; + } tmp; + int size; + + while (length > 0) { + if (length >= 4) { + size = 4; + tmp.u32 = rte_cpu_to_be_32(*(const uint32_t *)src); + rte_eal_pci_ioport_write(&hw->io, &tmp.u32, size, + VIRTIO_PCI_CONFIG(hw) + offset); + } else if (length >= 2) { + size = 2; + tmp.u16 = rte_cpu_to_be_16(*(const uint16_t *)src); + rte_eal_pci_ioport_write(&hw->io, &tmp.u16, size, + VIRTIO_PCI_CONFIG(hw) + offset); + } else { + size = 1; + rte_eal_pci_ioport_write(&hw->io, src, size, + VIRTIO_PCI_CONFIG(hw) + offset); + } + + src = (const char *)src + size; + offset += size; + length -= size; + } +#else rte_eal_pci_ioport_write(&hw->io, src, length, VIRTIO_PCI_CONFIG(hw) + offset); +#endif } static uint64_t -- 2.8.0.rc3