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 <yakui.zhao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
Acked-by: Wang Yu <yu1.wang@intel.com>
This commit is contained in:
Zhao Yakui 2022-09-21 13:13:27 +08:00 committed by acrnsi-robot
parent 3c01a6a0cf
commit d0720096b0
2 changed files with 19 additions and 6 deletions

View File

@ -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)) {

View File

@ -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)