From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60488) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VCZcS-0004lS-S7 for qemu-devel@nongnu.org; Thu, 22 Aug 2013 14:28:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VCZcL-0006yH-LC for qemu-devel@nongnu.org; Thu, 22 Aug 2013 14:28:28 -0400 Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa ([2001:8b0:1d0::1]:59406 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VCZcL-0006vb-Ek for qemu-devel@nongnu.org; Thu, 22 Aug 2013 14:28:21 -0400 From: Peter Maydell Date: Thu, 22 Aug 2013 19:28:11 +0100 Message-Id: <1377196092-7482-2-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1377196092-7482-1-git-send-email-peter.maydell@linaro.org> References: <1377196092-7482-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [RFC 1/2] hw/pci: Add PCI capability to allow BARs at 0 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , patches@linaro.org The PCI specification says that 0 isn't a valid address for an MMIO bar. However some devices won't object if you program a BAR at address 0 and will then respond to bus accesses at that address. (In particular the host PCI controller for the Versatile/Realview boards behaves like this, and Linux relies on it for setting up a 1:1 mapping between PCI address space and system address space for bus-mastering DMA.) To allow us to model devices with this out-of-spec quirk, add a new QEMU_PCI_ADDR0_ALLOWED flag to cap_present which bypasses the "address 0 is not valid" test in pci_bar_address(). Signed-off-by: Peter Maydell --- hw/pci/pci.c | 3 ++- include/hw/pci/pci.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 4c004f5..f09d799 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1058,7 +1058,8 @@ static pcibus_t pci_bar_address(PCIDevice *d, /* XXX: as we cannot support really dynamic mappings, we handle specific values as invalid mappings. */ - if (last_addr <= new_addr || new_addr == 0 || + if (last_addr <= new_addr || + (new_addr == 0 && !(d->cap_present & QEMU_PCI_ADDR0_ALLOWED)) || last_addr == PCI_BAR_UNMAPPED) { return PCI_BAR_UNMAPPED; } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index ccec2ba..3d6a940 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -157,6 +157,9 @@ enum { QEMU_PCI_CAP_SHPC = (1 << QEMU_PCI_SHPC_BITNR), #define QEMU_PCI_SLOTID_BITNR 6 QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR), + /* PCI device (in breach of the spec) allows MMIO BAR at address 0 */ +#define QEMU_PCI_ADDR0_ALLOWED_BITNR 7 + QEMU_PCI_ADDR0_ALLOWED = (1 << QEMU_PCI_ADDR0_ALLOWED_BITNR) }; #define TYPE_PCI_DEVICE "pci-device" -- 1.7.9.5