diff --git a/hypervisor/dm/vpci/ivshmem.c b/hypervisor/dm/vpci/ivshmem.c index 87382592c..a3f999eed 100644 --- a/hypervisor/dm/vpci/ivshmem.c +++ b/hypervisor/dm/vpci/ivshmem.c @@ -291,15 +291,12 @@ static int32_t write_ivshmem_vdev_cfg(struct pci_vdev *vdev, uint32_t offset, ui static void init_ivshmem_bar(struct pci_vdev *vdev, uint32_t bar_idx) { struct pci_vbar *vbar; - enum pci_bar_type type; uint64_t addr, mask, size = 0UL; struct acrn_vm_pci_dev_config *dev_config = vdev->pci_dev_config; addr = dev_config->vbar_base[bar_idx]; - type = pci_get_bar_type((uint32_t) addr); - mask = (type == PCIBAR_IO_SPACE) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; + mask = (is_pci_io_bar((uint32_t)addr)) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; vbar = &vdev->vbars[bar_idx]; - vbar->type = type; if (bar_idx == IVSHMEM_SHM_BAR) { struct ivshmem_shm_region *region = find_shm_region(dev_config->shm_region_name); if (region != NULL) { @@ -317,11 +314,11 @@ static void init_ivshmem_bar(struct pci_vdev *vdev, uint32_t bar_idx) if (size != 0UL) { vbar->size = size; vbar->mask = (uint32_t) (~(size - 1UL)); - vbar->fixed = (uint32_t) (addr & (~mask)); + vbar->bar_type.bits = (uint32_t) (addr & (~mask)); pci_vdev_write_vbar(vdev, bar_idx, (uint32_t) addr); - if (type == PCIBAR_MEM64) { + if (is_pci_mem64_bar((uint32_t)addr)) { vbar = &vdev->vbars[bar_idx + 1U]; - vbar->type = PCIBAR_MEM64HI; + vbar->is_mem64hi = true; vbar->mask = (uint32_t) ((~(size - 1UL)) >> 32U); pci_vdev_write_vbar(vdev, (bar_idx + 1U), ((uint32_t)(addr >> 32U))); } diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index b2d728778..b113bbdf1 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -292,18 +292,12 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val) { struct pci_vbar *vbar = &vdev->vbars[idx]; - switch (vbar->type) { - case PCIBAR_IO_SPACE: + if (is_pci_io_bar(vbar->bar_type.bits)) { vpci_update_one_vbar(vdev, idx, val, vdev_pt_allow_io_vbar, vdev_pt_deny_io_vbar); - break; + } - case PCIBAR_NONE: - /* Nothing to do */ - break; - - default: + if (is_pci_mem32_bar(vbar->bar_type.bits) || is_pci_mem64_bar(vbar->bar_type.bits) || vbar->is_mem64hi) { vpci_update_one_vbar(vdev, idx, val, vdev_pt_map_mem_vbar, vdev_pt_unmap_mem_vbar); - break; } } @@ -343,7 +337,6 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val) */ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar) { - enum pci_bar_type type; uint32_t idx, bar_cnt; struct pci_vbar *vbar; uint32_t size32, offset, lo, hi = 0U; @@ -368,14 +361,13 @@ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar) } lo = pci_pdev_read_cfg(pbdf, offset, 4U); - type = pci_get_bar_type(lo); - if (type == PCIBAR_NONE) { + if (!(is_pci_io_bar(lo) || is_pci_mem32_bar(lo) || is_pci_mem64_bar(lo))) { continue; } - mask = (type == PCIBAR_IO_SPACE) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; + mask = (is_pci_io_bar(lo)) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; vbar->base_hpa = (uint64_t)lo & mask; - if (type == PCIBAR_MEM64) { + if (is_pci_mem64_bar(lo)) { hi = pci_pdev_read_cfg(pbdf, offset + 4U, 4U); vbar->base_hpa |= ((uint64_t)hi << 32U); } @@ -385,16 +377,15 @@ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar) size32 = pci_pdev_read_cfg(pbdf, offset, 4U); pci_pdev_write_cfg(pbdf, offset, 4U, lo); - vbar->type = type; vbar->mask = size32 & mask; - vbar->fixed = lo & (~mask); + vbar->bar_type.bits = lo & (~mask); vbar->size = (uint64_t)size32 & mask; if (is_prelaunched_vm(vpci2vm(vdev->vpci))) { lo = (uint32_t)vdev->pci_dev_config->vbar_base[idx]; } - if (type == PCIBAR_MEM64) { + if (is_pci_mem64_bar(lo)) { idx++; if (is_sriov_bar) { offset = sriov_bar_offset(vdev, idx); @@ -416,7 +407,7 @@ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar) } vbar->mask = size32; - vbar->type = PCIBAR_MEM64HI; + vbar->is_mem64hi = true; if (is_prelaunched_vm(vpci2vm(vdev->vpci))) { hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U); @@ -428,9 +419,10 @@ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar) } } else { vbar->size = vbar->size & ~(vbar->size - 1UL); - if (type == PCIBAR_MEM32) { + if (is_pci_mem32_bar(lo)) { vbar->size = round_page_up(vbar->size); } + /* if it is parsing SRIOV VF BARs, no need to write vdev bar */ if (!is_sriov_bar) { pci_vdev_write_vbar(vdev, idx, lo); diff --git a/hypervisor/dm/vpci/vdev.c b/hypervisor/dm/vpci/vdev.c index 5b2b3afa2..c7ac38828 100644 --- a/hypervisor/dm/vpci/vdev.c +++ b/hypervisor/dm/vpci/vdev.c @@ -101,7 +101,7 @@ uint32_t pci_vdev_read_vbar(const struct pci_vdev *vdev, uint32_t idx) bar = pci_vdev_read_vcfg(vdev, offset, 4U); /* Sizing BAR */ if (bar == ~0U) { - bar = vdev->vbars[idx].mask | vdev->vbars[idx].fixed; + bar = vdev->vbars[idx].mask | vdev->vbars[idx].bar_type.bits; } return bar; } @@ -109,18 +109,16 @@ uint32_t pci_vdev_read_vbar(const struct pci_vdev *vdev, uint32_t idx) static void pci_vdev_update_vbar_base(struct pci_vdev *vdev, uint32_t idx) { struct pci_vbar *vbar; - enum pci_bar_type type; uint64_t base = 0UL; uint32_t lo, hi, offset; vbar = &vdev->vbars[idx]; offset = pci_bar_offset(idx); lo = pci_vdev_read_vcfg(vdev, offset, 4U); - if ((vbar->type != PCIBAR_NONE) && (lo != ~0U)) { - type = vbar->type; + if (((is_pci_io_bar(vbar->bar_type.bits) || is_pci_mem32_bar(vbar->bar_type.bits) || is_pci_mem64_bar(vbar->bar_type.bits) || vbar->is_mem64hi)) && (lo != ~0U)) { base = lo & vbar->mask; - if (vbar->type == PCIBAR_MEM64) { + if (is_pci_mem64_bar(vbar->bar_type.bits)) { vbar = &vdev->vbars[idx + 1U]; hi = pci_vdev_read_vcfg(vdev, (offset + 4U), 4U); if (hi != ~0U) { @@ -130,7 +128,7 @@ static void pci_vdev_update_vbar_base(struct pci_vdev *vdev, uint32_t idx) base = 0UL; } } - if (type == PCIBAR_IO_SPACE) { + if (is_pci_io_bar(vbar->bar_type.bits)) { base &= 0xffffUL; } } @@ -152,11 +150,11 @@ void pci_vdev_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val) vbar = &vdev->vbars[idx]; bar = val & vbar->mask; - bar |= vbar->fixed; + bar |= vbar->bar_type.bits; offset = pci_bar_offset(idx); pci_vdev_write_vcfg(vdev, offset, 4U, bar); - if (vbar->type == PCIBAR_MEM64HI) { + if (vbar->is_mem64hi) { update_idx -= 1U; } diff --git a/hypervisor/dm/vpci/vmcs9900.c b/hypervisor/dm/vpci/vmcs9900.c index c159b76cb..2fea12c61 100644 --- a/hypervisor/dm/vpci/vmcs9900.c +++ b/hypervisor/dm/vpci/vmcs9900.c @@ -130,18 +130,16 @@ static void init_vmcs9900(struct pci_vdev *vdev) add_vmsix_capability(vdev, 1, MCS9900_MSIX_BAR); /* initialize vuart-pci mem bar */ - mmio_vbar->type = PCIBAR_MEM32; mmio_vbar->size = 0x1000U; mmio_vbar->base_gpa = pci_cfg->vbar_base[MCS9900_MMIO_BAR]; mmio_vbar->mask = (uint32_t) (~(mmio_vbar->size - 1UL)); - mmio_vbar->fixed = (uint32_t) (mmio_vbar->base_gpa & PCI_BASE_ADDRESS_MEM_MASK); + mmio_vbar->bar_type.bits = PCIM_BAR_MEM_32; /* initialize vuart-pci msix bar */ - msix_vbar->type = PCIBAR_MEM32; msix_vbar->size = 0x1000U; msix_vbar->base_gpa = pci_cfg->vbar_base[MCS9900_MSIX_BAR]; msix_vbar->mask = (uint32_t) (~(msix_vbar->size - 1UL)); - msix_vbar->fixed = (uint32_t) (msix_vbar->base_gpa & PCI_BASE_ADDRESS_MEM_MASK); + msix_vbar->bar_type.bits = PCIM_BAR_MEM_32; vdev->nr_bars = 2; diff --git a/hypervisor/dm/vpci/vmsix_on_msi.c b/hypervisor/dm/vpci/vmsix_on_msi.c index 9f63ecc12..09fbe8217 100644 --- a/hypervisor/dm/vpci/vmsix_on_msi.c +++ b/hypervisor/dm/vpci/vmsix_on_msi.c @@ -83,7 +83,7 @@ void init_vmsix_on_msi(struct pci_vdev *vdev) if (vdev->vbars[i].base_hpa == 0UL){ break; } - if (vdev->vbars[i].type == PCIBAR_MEM64) { + if (is_pci_mem64_bar(vdev->vbars[i].bar_type.bits)) { i++; } } @@ -106,12 +106,11 @@ void init_vmsix_on_msi(struct pci_vdev *vdev) /* Init PBA table vBAR, offset is 2048 */ pci_vdev_write_vcfg(vdev, vdev->msix.capoff + 8U, 4U, 2048U + i); - vdev->vbars[i].type = PCIBAR_MEM32; vdev->vbars[i].size = 4096U; vdev->vbars[i].base_hpa = 0x0UL; vdev->vbars[i].mask = 0xFFFFF000U & PCI_BASE_ADDRESS_MEM_MASK; /* fixed for memory, 32bit, non-prefetchable */ - vdev->vbars[i].fixed = 0U; + vdev->vbars[i].bar_type.bits = PCIM_BAR_MEM_32; /* About MSI-x bar GPA: * - For Service VM: when first time init, it is programmed as 0, then OS will program diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index b5e152765..4f28ba535 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -783,7 +783,7 @@ void vpci_update_one_vbar(struct pci_vdev *vdev, uint32_t bar_idx, uint32_t val, uint32_t offset = pci_bar_offset(bar_idx); uint32_t update_idx = bar_idx; - if (vbar->type == PCIBAR_MEM64HI) { + if (vbar->is_mem64hi) { update_idx -= 1U; } unmap_cb(vdev, update_idx); diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index f530a31f4..541d11afe 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -38,11 +38,11 @@ #define VDEV_LIST_HASHSIZE (1U << VDEV_LIST_HASHBITS) struct pci_vbar { - enum pci_bar_type type; + bool is_mem64hi;; uint64_t size; /* BAR size */ uint64_t base_gpa; /* BAR guest physical address */ uint64_t base_hpa; /* BAR host physical address */ - uint32_t fixed; /* BAR fix memory type encoding */ + union pci_bar_type bar_type; uint32_t mask; /* BAR size mask */ }; diff --git a/hypervisor/include/hw/pci.h b/hypervisor/include/hw/pci.h index 761b7d6d0..4ec7242fc 100644 --- a/hypervisor/include/hw/pci.h +++ b/hypervisor/include/hw/pci.h @@ -203,12 +203,17 @@ union pci_bdf { } fields; }; -enum pci_bar_type { - PCIBAR_NONE = 0, - PCIBAR_IO_SPACE, - PCIBAR_MEM32, - PCIBAR_MEM64, - PCIBAR_MEM64HI, +union pci_bar_type { + uint32_t bits; + struct { + uint8_t indicator :1; /* BITs[0], mapped to I/O space if read as 1 */ + uint8_t reserved :1; /* BITs[1], reserved */ + } io_space; + struct { + uint8_t indicator :1; /* BITs[0], mapped to memory space if read as 0 */ + uint8_t mem_type :2; /* BITs[1:2], 32-bit address if read as 00b, 64-bit address as 01b */ + uint8_t prefetchable :1; /* BITs[3], set to 1b if the data is prefetchable and set to 0b otherwise */ + } mem_space; }; struct pci_mmcfg_region { @@ -304,29 +309,32 @@ static inline bool is_bar_offset(uint32_t nr_bars, uint32_t offset) return ret; } -static inline enum pci_bar_type pci_get_bar_type(uint32_t val) +static inline bool is_pci_io_bar(uint32_t val) { - enum pci_bar_type type = PCIBAR_NONE; + union pci_bar_type bar_type = {.bits = val}; - if ((val & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE) { - type = PCIBAR_IO_SPACE; - } else { - switch (val & PCIM_BAR_MEM_TYPE) { - case PCIM_BAR_MEM_32: - type = PCIBAR_MEM32; - break; + return (bar_type.io_space.indicator == 1U); +} - case PCIM_BAR_MEM_64: - type = PCIBAR_MEM64; - break; +static inline bool is_pci_mem_bar(uint32_t val) +{ + union pci_bar_type bar_type = {.bits = val}; - default: - /*no actions are required for other cases.*/ - break; - } - } + return ((bar_type.mem_space.indicator == 0U)); +} - return type; +static inline bool is_pci_mem32_bar(uint32_t val) +{ + union pci_bar_type bar_type = {.bits = val}; + + return (is_pci_mem_bar(val) && (bar_type.mem_space.mem_type == 0U)); +} + +static inline bool is_pci_mem64_bar(uint32_t val) +{ + union pci_bar_type bar_type = {.bits = val}; + + return (is_pci_mem_bar(val) && (bar_type.mem_space.mem_type == 2U)); } static inline bool bdf_is_equal(union pci_bdf a, union pci_bdf b)