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:
parent
3c01a6a0cf
commit
d0720096b0
|
@ -436,10 +436,15 @@ static const struct cfg_header_perm cfg_hdr_perm = {
|
||||||
/*
|
/*
|
||||||
* @pre offset + bytes < PCI_CFG_HEADER_LENGTH
|
* @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)
|
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 */
|
/* bar access must be 4 bytes and offset must also be 4 bytes aligned */
|
||||||
if ((bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
if ((bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
||||||
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
*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);
|
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @pre offset + bytes < PCI_CFG_HEADER_LENGTH
|
* @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)
|
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 */
|
/* bar write access must be 4 bytes and offset must also be 4 bytes aligned */
|
||||||
if ((bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
if ((bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
||||||
vdev_pt_write_vbar(vdev, pci_bar_index(offset), val);
|
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,
|
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;
|
int32_t ret = 0;
|
||||||
|
|
||||||
if (cfg_header_access(offset)) {
|
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)) {
|
} else if (msicap_access(vdev, offset)) {
|
||||||
write_vmsi_cap_reg(vdev, offset, bytes, val);
|
write_vmsi_cap_reg(vdev, offset, bytes, val);
|
||||||
} else if (msixcap_access(vdev, offset)) {
|
} 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;
|
int32_t ret = 0;
|
||||||
|
|
||||||
if (cfg_header_access(offset)) {
|
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)) {
|
} else if (msicap_access(vdev, offset)) {
|
||||||
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
||||||
} else if (msixcap_access(vdev, offset)) {
|
} else if (msixcap_access(vdev, offset)) {
|
||||||
|
|
|
@ -92,6 +92,7 @@
|
||||||
#define PCIM_BAR_MEM_BASE 0xFFFFFFF0U
|
#define PCIM_BAR_MEM_BASE 0xFFFFFFF0U
|
||||||
#define PCIV_SUB_VENDOR_ID 0x2CU
|
#define PCIV_SUB_VENDOR_ID 0x2CU
|
||||||
#define PCIV_SUB_SYSTEM_ID 0x2EU
|
#define PCIV_SUB_SYSTEM_ID 0x2EU
|
||||||
|
#define PCIR_BIOS 0x30U
|
||||||
#define PCIR_CAP_PTR 0x34U
|
#define PCIR_CAP_PTR 0x34U
|
||||||
#define PCIR_CAP_PTR_CARDBUS 0x14U
|
#define PCIR_CAP_PTR_CARDBUS 0x14U
|
||||||
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
|
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
|
||||||
|
|
Loading…
Reference in New Issue