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)