From fc7c114f03438f77cc76481e38e2e83b034b9173 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Mon, 18 Sep 2017 15:04:23 +0100 Subject: [PATCH] pci: add support to size ROM BARs to pci_size_mem_bar MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Roger Pau Monné --- Cc: Jan Beulich --- Changes since v5: - Use the flags field. - Introduce a mask local variable. - Simplify return. Changes since v4: - New in this version. --- xen/drivers/passthrough/pci.c | 29 +++++++++++++++-------------- xen/include/xen/pci.h | 2 ++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index ba58b4d0cc..92c1f9354a 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -610,11 +610,17 @@ int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos, bool last, sbdf.func, pos); uint64_t addr, size; bool vf = flags & PCI_BAR_VF; - - ASSERT((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY); + bool rom = flags & PCI_BAR_ROM; + bool is64bits = !rom && (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64; + uint32_t mask = rom ? (uint32_t)PCI_ROM_ADDRESS_MASK + : (uint32_t)PCI_BASE_ADDRESS_MEM_MASK; + + ASSERT(!(rom && vf)); + ASSERT(rom || + (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY); pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos, ~0); - if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) + if ( is64bits ) { if ( last ) { @@ -627,10 +633,9 @@ int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos, bool last, hi = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4); pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4, ~0); } - size = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos) & - PCI_BASE_ADDRESS_MEM_MASK; - if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) + size = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, + pos) & mask; + if ( is64bits ) { size |= (uint64_t)pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4) << 32; @@ -640,17 +645,13 @@ int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos, bool last, size |= (uint64_t)~0 << 32; pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos, bar); size = -size; - addr = (bar & PCI_BASE_ADDRESS_MEM_MASK) | ((uint64_t)hi << 32); + addr = (bar & mask) | ((uint64_t)hi << 32); if ( paddr ) *paddr = addr; *psize = size; - if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) - return 2; - - return 1; + return is64bits ? 2 : 1; } int pci_add_device(u16 seg, u8 bus, u8 devfn, diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 2bee6a3247..4489edf9b5 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -191,6 +191,8 @@ const char *parse_pci_seg(const char *, unsigned int *seg, unsigned int *bus, #define _PCI_BAR_VF 0 #define PCI_BAR_VF (1u << _PCI_BAR_VF) +#define _PCI_BAR_ROM 1 +#define PCI_BAR_ROM (1u << _PCI_BAR_ROM) int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos, bool last, uint64_t *addr, uint64_t *size, unsigned int flags); -- 2.39.5