ACRN:DM:PCI: Add the support of allocating resource for PCI ROM bar
Now the device model only supports the 0..5 PCI bar for PCI/PCIE devices. This tries to allocate the PCI_MEM32 resource for PCI ROM bar. V1->V2: Use the PCI_ROMBAR as bar index and PCIBAR_ROM bar type when calling the pci_emul_alloc_bar to allocate the guest physical addr for PCI ROM bar. And it will allocate the resource from PCIBAR_MEM32 region. V2->V3: Add more comments that describes the parameter of pci_emul_alloc_bar. Tracked-On: #8175 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Acked-by: Wang Yu <yu1.wang@intel.com>
This commit is contained in:
parent
50cdcb3660
commit
270aaf82d8
|
@ -784,6 +784,23 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
|
||||||
size = 16;
|
size = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (idx > PCI_ROMBAR) {
|
||||||
|
pr_err("%s: invalid bar number %d for PCI bar type\n", __func__, idx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (idx == PCI_ROMBAR) {
|
||||||
|
/*
|
||||||
|
* It needs to pass the PCIBAR_ROM for PCI_ROMBAR idx. But as it
|
||||||
|
* is allocated from PCI_EMUL_MEM32 type, the internal type is
|
||||||
|
* changed to PCIBAR_MEM32
|
||||||
|
*/
|
||||||
|
if (type != PCIBAR_ROM) {
|
||||||
|
pr_err("%s: invalid bar type %d for PCI ROM\n",
|
||||||
|
__func__, type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
type = PCIBAR_MEM32;
|
||||||
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PCIBAR_NONE:
|
case PCIBAR_NONE:
|
||||||
baseptr = NULL;
|
baseptr = NULL;
|
||||||
|
@ -853,13 +870,20 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
|
||||||
pdi->bar[idx].addr = addr;
|
pdi->bar[idx].addr = addr;
|
||||||
pdi->bar[idx].size = size;
|
pdi->bar[idx].size = size;
|
||||||
|
|
||||||
/* Initialize the BAR register in config space */
|
if (idx == PCI_ROMBAR) {
|
||||||
bar = (addr & mask) | lobits;
|
mask = PCIM_BIOS_ADDR_MASK;
|
||||||
pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar);
|
bar = addr & mask;
|
||||||
|
/* enable flag will be configured later */
|
||||||
|
pci_set_cfgdata32(pdi, PCIR_BIOS, bar);
|
||||||
|
} else {
|
||||||
|
/* Initialize the BAR register in config space */
|
||||||
|
bar = (addr & mask) | lobits;
|
||||||
|
pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar);
|
||||||
|
|
||||||
if (type == PCIBAR_MEM64) {
|
if (type == PCIBAR_MEM64) {
|
||||||
pdi->bar[idx + 1].type = PCIBAR_MEMHI64;
|
pdi->bar[idx + 1].type = PCIBAR_MEMHI64;
|
||||||
pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32);
|
pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = register_bar(pdi, idx);
|
error = register_bar(pdi, idx);
|
||||||
|
|
|
@ -103,7 +103,9 @@ enum pcibar_type {
|
||||||
PCIBAR_IO,
|
PCIBAR_IO,
|
||||||
PCIBAR_MEM32,
|
PCIBAR_MEM32,
|
||||||
PCIBAR_MEM64,
|
PCIBAR_MEM64,
|
||||||
PCIBAR_MEMHI64
|
PCIBAR_MEMHI64,
|
||||||
|
/* the type for ROM bar. It will be allocated from PCI_EMUL_MEM32 region */
|
||||||
|
PCIBAR_ROM
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pcibar {
|
struct pcibar {
|
||||||
|
@ -135,6 +137,7 @@ enum lintr_stat {
|
||||||
PENDING
|
PENDING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PCI_ROMBAR (PCIR_MAX_BAR_0 + 1) /* ROM BAR index in Type 0 Header */
|
||||||
struct pci_vdev {
|
struct pci_vdev {
|
||||||
struct pci_vdev_ops *dev_ops;
|
struct pci_vdev_ops *dev_ops;
|
||||||
struct vmctx *vmctx;
|
struct vmctx *vmctx;
|
||||||
|
@ -176,7 +179,8 @@ struct pci_vdev {
|
||||||
void *arg; /* devemu-private data */
|
void *arg; /* devemu-private data */
|
||||||
|
|
||||||
uint8_t cfgdata[PCI_REGMAX + 1];
|
uint8_t cfgdata[PCI_REGMAX + 1];
|
||||||
struct pcibar bar[PCI_BARMAX + 1];
|
/* 0..5 is used for PCI MMIO/IO bar. 6 is used for PCI ROMbar */
|
||||||
|
struct pcibar bar[PCI_BARMAX + 2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gsi_dev {
|
struct gsi_dev {
|
||||||
|
@ -311,6 +315,22 @@ void msicap_cfgwrite(struct pci_vdev *pi, int capoff, int offset,
|
||||||
void msixcap_cfgwrite(struct pci_vdev *pi, int capoff, int offset,
|
void msixcap_cfgwrite(struct pci_vdev *pi, int capoff, int offset,
|
||||||
int bytes, uint32_t val);
|
int bytes, uint32_t val);
|
||||||
void pci_callback(void);
|
void pci_callback(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief allocate bar region for virtual PCI device
|
||||||
|
*
|
||||||
|
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
|
||||||
|
* @param idx the bar_idx for the request bar region
|
||||||
|
* @param type the region type for the request bar region
|
||||||
|
* @param size the region size for the request bar region
|
||||||
|
* It can support the allocation of bar_region for bar_idx 0..5 and
|
||||||
|
* the bar type can be PCIBAR_IO/PCIBAR_MEM32/PCIBAR_MEM64.
|
||||||
|
* It can support the allocation of ROM bar for PCI_ROMBAR and only allow
|
||||||
|
* that the bar type is PCIBAR_ROM.
|
||||||
|
*
|
||||||
|
* @Return 0 indicates that the allocation is successful.
|
||||||
|
* error indicates that it fails in the allocation of bar region.
|
||||||
|
*/
|
||||||
int pci_emul_alloc_bar(struct pci_vdev *pdi, int idx,
|
int pci_emul_alloc_bar(struct pci_vdev *pdi, int idx,
|
||||||
enum pcibar_type type, uint64_t size);
|
enum pcibar_type type, uint64_t size);
|
||||||
int pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx,
|
int pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx,
|
||||||
|
|
Loading…
Reference in New Issue