From d0720096b00ccce2f14cda5442b951e797eca737 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 21 Sep 2022 13:13:27 +0800 Subject: [PATCH] ACRN:HV:VPCI: Forward access of PCI ROM bar_reg to DM for passthru device The access to PCI config_space is handled in HV for Passthrough pci devices. And it also provides one mechanism to forward cfg_access of some registers to DM. For example: the opregion reg for GPU device. This patch tried to add the support of emulated PCI ROM bar for the device. And it doesn't handle the phys PCI ROM bar of phys PCI devices. At the same time the rom firmware is provided in DM and pci rom bar_reg is also emulated in DM, this leverages the quirk mechanism so that the access to PCI rom bar_reg is forwarded to DM. Tracked-On: #8175 Signed-off-by: Zhao Yakui Acked-by: Eddie Dong Acked-by: Wang Yu --- hypervisor/dm/vpci/vpci.c | 24 ++++++++++++++++++------ hypervisor/include/hw/pci.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index caa39aee7..56fc0d88e 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -436,10 +436,15 @@ static const struct cfg_header_perm cfg_hdr_perm = { /* * @pre offset + bytes < PCI_CFG_HEADER_LENGTH */ -static void read_cfg_header(const struct pci_vdev *vdev, +static int32_t read_cfg_header(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val) { - if (vbar_access(vdev, offset)) { + int32_t ret = 0; + + if ((offset == PCIR_BIOS) && is_quirk_ptdev(vdev)) { + /* the access of PCIR_BIOS is emulated for quirk_ptdev */ + ret = -ENODEV; + } else if (vbar_access(vdev, offset)) { /* bar access must be 4 bytes and offset must also be 4 bytes aligned */ if ((bytes == 4U) && ((offset & 0x3U) == 0U)) { *val = pci_vdev_read_vcfg(vdev, offset, bytes); @@ -460,15 +465,21 @@ static void read_cfg_header(const struct pci_vdev *vdev, *val = pci_vdev_read_vcfg(vdev, offset, bytes); } } + return ret; } /* * @pre offset + bytes < PCI_CFG_HEADER_LENGTH */ -static void write_cfg_header(struct pci_vdev *vdev, +static int32_t write_cfg_header(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val) { - if (vbar_access(vdev, offset)) { + int32_t ret = 0; + + if ((offset == PCIR_BIOS) && is_quirk_ptdev(vdev)) { + /* the access of PCIR_BIOS is emulated for quirk_ptdev */ + ret = -ENODEV; + } else if (vbar_access(vdev, offset)) { /* bar write access must be 4 bytes and offset must also be 4 bytes aligned */ if ((bytes == 4U) && ((offset & 0x3U) == 0U)) { vdev_pt_write_vbar(vdev, pci_bar_index(offset), val); @@ -504,6 +515,7 @@ static void write_cfg_header(struct pci_vdev *vdev, } } + return ret; } static int32_t write_pt_dev_cfg(struct pci_vdev *vdev, uint32_t offset, @@ -512,7 +524,7 @@ static int32_t write_pt_dev_cfg(struct pci_vdev *vdev, uint32_t offset, int32_t ret = 0; if (cfg_header_access(offset)) { - write_cfg_header(vdev, offset, bytes, val); + ret = write_cfg_header(vdev, offset, bytes, val); } else if (msicap_access(vdev, offset)) { write_vmsi_cap_reg(vdev, offset, bytes, val); } else if (msixcap_access(vdev, offset)) { @@ -545,7 +557,7 @@ static int32_t read_pt_dev_cfg(struct pci_vdev *vdev, uint32_t offset, int32_t ret = 0; if (cfg_header_access(offset)) { - read_cfg_header(vdev, offset, bytes, val); + ret = read_cfg_header(vdev, offset, bytes, val); } else if (msicap_access(vdev, offset)) { *val = pci_vdev_read_vcfg(vdev, offset, bytes); } else if (msixcap_access(vdev, offset)) { diff --git a/hypervisor/include/hw/pci.h b/hypervisor/include/hw/pci.h index 2471bc055..9903e900a 100644 --- a/hypervisor/include/hw/pci.h +++ b/hypervisor/include/hw/pci.h @@ -92,6 +92,7 @@ #define PCIM_BAR_MEM_BASE 0xFFFFFFF0U #define PCIV_SUB_VENDOR_ID 0x2CU #define PCIV_SUB_SYSTEM_ID 0x2EU +#define PCIR_BIOS 0x30U #define PCIR_CAP_PTR 0x34U #define PCIR_CAP_PTR_CARDBUS 0x14U #define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)