mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-05 19:47:48 +00:00
hv: vpci: remove 64 bits PCI BAR map logic constraint
After reshuffle pci_bar structrue we could write ~0U not BAR size mask to BAR configuration space directly when do BAR sizing. In this case, we could know whether the value in BAR configuration space is a valid base address. As a result, we could do BAR re-programming whenever we want. Tracked-On: #3475 Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
c049c5c965
commit
5fdb6cc0ac
@ -32,19 +32,6 @@
|
|||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include "vpci_priv.h"
|
#include "vpci_priv.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vdev != NULL
|
|
||||||
*/
|
|
||||||
void vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val)
|
|
||||||
{
|
|
||||||
/* bar access must be 4 bytes and offset must also be 4 bytes aligned */
|
|
||||||
if ((bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
|
||||||
*val = pci_vdev_read_cfg(vdev, offset, bytes);
|
|
||||||
} else {
|
|
||||||
*val = ~0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vdev != NULL
|
* @pre vdev != NULL
|
||||||
* @pre vdev->vpci != NULL
|
* @pre vdev->vpci != NULL
|
||||||
@ -191,7 +178,6 @@ static void vdev_pt_deny_io_vbar(struct pci_vdev *vdev, uint32_t idx)
|
|||||||
*/
|
*/
|
||||||
void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||||
{
|
{
|
||||||
bool update_bar = false;
|
|
||||||
uint32_t update_idx = idx;
|
uint32_t update_idx = idx;
|
||||||
uint32_t offset = pci_bar_offset(idx);
|
uint32_t offset = pci_bar_offset(idx);
|
||||||
struct pci_bar *vbar = &vdev->bar[idx];
|
struct pci_bar *vbar = &vdev->bar[idx];
|
||||||
@ -203,30 +189,25 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
|||||||
pci_vdev_write_bar(vdev, idx, val);
|
pci_vdev_write_bar(vdev, idx, val);
|
||||||
vdev_pt_allow_io_vbar(vdev, update_idx);
|
vdev_pt_allow_io_vbar(vdev, update_idx);
|
||||||
} else {
|
} else {
|
||||||
pci_vdev_write_cfg_u32(vdev, offset, vbar->mask);
|
pci_vdev_write_cfg_u32(vdev, offset, val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCIBAR_MEM64HI:
|
case PCIBAR_NONE:
|
||||||
update_idx = idx - 1U;
|
/* Nothing to do */
|
||||||
/* falls through */
|
|
||||||
case PCIBAR_MEM32:
|
|
||||||
update_bar = true;
|
|
||||||
/* falls through */
|
|
||||||
case PCIBAR_MEM64:
|
|
||||||
vdev_pt_unmap_mem_vbar(vdev, update_idx);
|
|
||||||
if (val != ~0U) {
|
|
||||||
pci_vdev_write_bar(vdev, idx, val);
|
|
||||||
if (update_bar) {
|
|
||||||
vdev_pt_map_mem_vbar(vdev, update_idx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pci_vdev_write_cfg_u32(vdev, offset, vbar->mask);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Nothing to do */
|
if (vbar->type == PCIBAR_MEM64HI) {
|
||||||
|
update_idx = idx - 1U;
|
||||||
|
}
|
||||||
|
vdev_pt_unmap_mem_vbar(vdev, update_idx);
|
||||||
|
if (val != ~0U) {
|
||||||
|
pci_vdev_write_bar(vdev, idx, val);
|
||||||
|
vdev_pt_map_mem_vbar(vdev, update_idx);
|
||||||
|
} else {
|
||||||
|
pci_vdev_write_cfg_u32(vdev, offset, val);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,6 +280,7 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
|||||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||||
lo = (uint32_t)vdev->pci_dev_config->vbar_base[idx];
|
lo = (uint32_t)vdev->pci_dev_config->vbar_base[idx];
|
||||||
}
|
}
|
||||||
|
pci_vdev_write_bar(vdev, idx, lo);
|
||||||
|
|
||||||
if (type == PCIBAR_MEM64) {
|
if (type == PCIBAR_MEM64) {
|
||||||
idx++;
|
idx++;
|
||||||
@ -318,14 +300,12 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
|||||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||||
hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U);
|
hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U);
|
||||||
}
|
}
|
||||||
vdev_pt_write_vbar(vdev, idx - 1U, lo);
|
pci_vdev_write_bar(vdev, idx, hi);
|
||||||
vdev_pt_write_vbar(vdev, idx, hi);
|
|
||||||
} else {
|
} else {
|
||||||
vbar->size = vbar->size & ~(vbar->size - 1UL);
|
vbar->size = vbar->size & ~(vbar->size - 1UL);
|
||||||
if (type == PCIBAR_MEM32) {
|
if (type == PCIBAR_MEM32) {
|
||||||
vbar->size = round_page_up(vbar->size);
|
vbar->size = round_page_up(vbar->size);
|
||||||
}
|
}
|
||||||
vdev_pt_write_vbar(vdev, idx, lo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,19 @@ struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf)
|
|||||||
return vdev;
|
return vdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t pci_vdev_read_bar(const struct pci_vdev *vdev, uint32_t idx)
|
||||||
|
{
|
||||||
|
uint32_t bar, offset;
|
||||||
|
|
||||||
|
offset = pci_bar_offset(idx);
|
||||||
|
bar = pci_vdev_read_cfg_u32(vdev, offset);
|
||||||
|
/* Sizing BAR */
|
||||||
|
if (bar == ~0U) {
|
||||||
|
bar = vdev->bar[idx].mask;
|
||||||
|
}
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
|
||||||
{
|
{
|
||||||
struct pci_bar *vbar;
|
struct pci_bar *vbar;
|
||||||
|
@ -349,7 +349,12 @@ static int32_t vpci_read_pt_dev_cfg(const struct pci_vdev *vdev, uint32_t offset
|
|||||||
uint32_t bytes, uint32_t *val)
|
uint32_t bytes, uint32_t *val)
|
||||||
{
|
{
|
||||||
if (vbar_access(vdev, offset)) {
|
if (vbar_access(vdev, offset)) {
|
||||||
vdev_pt_read_cfg(vdev, offset, bytes, val);
|
/* bar access must be 4 bytes and offset must also be 4 bytes aligned */
|
||||||
|
if ((bytes == 4U) && ((offset & 0x3U) == 0U)) {
|
||||||
|
*val = pci_vdev_read_bar(vdev, pci_bar_index(offset));
|
||||||
|
} else {
|
||||||
|
*val = ~0U;
|
||||||
|
}
|
||||||
} else if (msicap_access(vdev, offset)) {
|
} else if (msicap_access(vdev, offset)) {
|
||||||
vmsi_read_cfg(vdev, offset, bytes, val);
|
vmsi_read_cfg(vdev, offset, bytes, val);
|
||||||
} else if (msixcap_access(vdev, offset)) {
|
} else if (msixcap_access(vdev, offset)) {
|
||||||
|
@ -126,7 +126,6 @@ static inline bool msicap_access(const struct pci_vdev *vdev, uint32_t offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init_vdev_pt(struct pci_vdev *vdev);
|
void init_vdev_pt(struct pci_vdev *vdev);
|
||||||
void vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val);
|
|
||||||
void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
|
void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
|
||||||
|
|
||||||
void init_vmsi(struct pci_vdev *vdev);
|
void init_vmsi(struct pci_vdev *vdev);
|
||||||
@ -145,6 +144,7 @@ void pci_vdev_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes,
|
|||||||
|
|
||||||
struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf);
|
struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf);
|
||||||
|
|
||||||
|
uint32_t pci_vdev_read_bar(const struct pci_vdev *vdev, uint32_t idx);
|
||||||
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
|
void pci_vdev_write_bar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
|
||||||
uint64_t pci_vdev_get_bar_base(const struct pci_vdev *vdev, uint32_t idx);
|
uint64_t pci_vdev_get_bar_base(const struct pci_vdev *vdev, uint32_t idx);
|
||||||
#endif /* VPCI_PRIV_H_ */
|
#endif /* VPCI_PRIV_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user