mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-08 11:39:39 +00:00
HV: add get_pbar_base() to get pbar base address in 64-bit
pbar base can be built by using the base address fields stored in struct pci_bar's reg member. get_pbar_base: return pbar's base address in 64-bit. For 64-bit MMIO bar, its lower 32-bits base address and upper 32-bits base are combined into one 64-bit base address pci_bar_2_bar_base: helper function that is called by get_pbar_base And changed related code to use get_pbar_base to get pbar base address in 64-bit Tracked-On: #3241 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
8707834f83
commit
1b4dbdab70
@ -33,6 +33,87 @@
|
|||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include "vpci_priv.h"
|
#include "vpci_priv.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get bar's full base address in 64-bit
|
||||||
|
* @pre idx < nr_bars
|
||||||
|
* For 64-bit MMIO bar, its lower 32-bits base address and upper 32-bits base are combined
|
||||||
|
* into one 64-bit base address
|
||||||
|
*/
|
||||||
|
static uint64_t pci_bar_2_bar_base(const struct pci_bar *pbars, uint32_t nr_bars, uint32_t idx)
|
||||||
|
{
|
||||||
|
uint64_t base = 0UL;
|
||||||
|
uint64_t tmp;
|
||||||
|
const struct pci_bar *bar;
|
||||||
|
|
||||||
|
bar = &pbars[idx];
|
||||||
|
|
||||||
|
if (bar->is_64bit_high) {
|
||||||
|
ASSERT(idx > 0U, "idx for upper 32-bit of the 64-bit bar should be greater than 0!");
|
||||||
|
if (idx > 0U) {
|
||||||
|
const struct pci_bar *prev_bar = &pbars[idx - 1U];
|
||||||
|
|
||||||
|
/* Upper 32-bit of 64-bit bar (does not have flags portion) */
|
||||||
|
base = (uint64_t)(bar->reg.value);
|
||||||
|
base <<= 32U;
|
||||||
|
|
||||||
|
/* Lower 32-bit of a 64-bit bar (BITS 31-4 = base address, 16-byte aligned) */
|
||||||
|
tmp = (uint64_t)(prev_bar->reg.bits.mem.base);
|
||||||
|
tmp <<= 4U;
|
||||||
|
|
||||||
|
base |= tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
enum pci_bar_type type = pci_get_bar_type(bar->reg.value);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PCIBAR_IO_SPACE:
|
||||||
|
/* IO bar, BITS 31-2 = base address, 4-byte aligned */
|
||||||
|
base = (uint64_t)(bar->reg.bits.io.base);
|
||||||
|
base <<= 2U;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCIBAR_MEM32:
|
||||||
|
base = (uint64_t)(bar->reg.bits.mem.base);
|
||||||
|
base <<= 4U;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCIBAR_MEM64:
|
||||||
|
ASSERT((idx + 1U) < nr_bars, "idx for upper 32-bit of the 64-bit bar is out of range!");
|
||||||
|
if ((idx + 1U) < nr_bars) {
|
||||||
|
const struct pci_bar *next_bar = &pbars[idx + 1U];
|
||||||
|
|
||||||
|
/* Upper 32-bit of 64-bit bar */
|
||||||
|
base = (uint64_t)(next_bar->reg.value);
|
||||||
|
base <<= 32U;
|
||||||
|
|
||||||
|
/* Lower 32-bit of a 64-bit bar (BITS 31-4 = base address, 16-byte aligned) */
|
||||||
|
tmp = (uint64_t)(bar->reg.bits.mem.base);
|
||||||
|
tmp <<= 4U;
|
||||||
|
|
||||||
|
base |= tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Nothing to do */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get pbar's full address in 64-bit
|
||||||
|
* For 64-bit MMIO bar, its lower 32-bits base address and upper 32-bits base are combined
|
||||||
|
* into one 64-bit base address
|
||||||
|
* @pre pdev != NULL
|
||||||
|
*/
|
||||||
|
static uint64_t get_pbar_base(const struct pci_pdev *pdev, uint32_t idx)
|
||||||
|
{
|
||||||
|
return pci_bar_2_bar_base(&pdev->bar[0], pdev->nr_bars, idx);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vdev != NULL
|
* @pre vdev != NULL
|
||||||
* @pre vdev->vpci != NULL
|
* @pre vdev->vpci != NULL
|
||||||
@ -63,7 +144,7 @@ void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev)
|
|||||||
uint64_t addr_hi, addr_lo;
|
uint64_t addr_hi, addr_lo;
|
||||||
struct pci_msix *msix = &vdev->msix;
|
struct pci_msix *msix = &vdev->msix;
|
||||||
struct pci_pdev *pdev = vdev->pdev;
|
struct pci_pdev *pdev = vdev->pdev;
|
||||||
struct pci_bar *bar;
|
struct pci_bar *pbar;
|
||||||
|
|
||||||
ASSERT(vdev->pdev->msix.table_bar < vdev->nr_bars, "msix->table_bar is out of range");
|
ASSERT(vdev->pdev->msix.table_bar < vdev->nr_bars, "msix->table_bar is out of range");
|
||||||
|
|
||||||
@ -74,15 +155,16 @@ void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev)
|
|||||||
msix->table_entries[i].data = 0U;
|
msix->table_entries[i].data = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
bar = &pdev->bar[msix->table_bar];
|
pbar = &pdev->bar[msix->table_bar];
|
||||||
if (bar != NULL) {
|
if (pbar != NULL) {
|
||||||
msix->mmio_hpa = bar->base;
|
uint64_t pbar_base = get_pbar_base(pdev, msix->table_bar); /* pbar (hpa) */
|
||||||
|
msix->mmio_hpa = pbar_base;
|
||||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||||
msix->mmio_gpa = vdev->bar[msix->table_bar].base;
|
msix->mmio_gpa = vdev->bar[msix->table_bar].base;
|
||||||
} else {
|
} else {
|
||||||
msix->mmio_gpa = sos_vm_hpa2gpa(bar->base);
|
msix->mmio_gpa = sos_vm_hpa2gpa(pbar_base);
|
||||||
}
|
}
|
||||||
msix->mmio_size = bar->size;
|
msix->mmio_size = pbar->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -175,9 +257,11 @@ static void vdev_pt_remap_generic_mem_vbar(const struct pci_vdev *vdev, uint32_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (new_base != 0U) {
|
if (new_base != 0U) {
|
||||||
|
uint64_t pbar_base = get_pbar_base(vdev->pdev, idx); /* pbar (hpa) */
|
||||||
|
|
||||||
/* Map the physical BAR in the guest MMIO space */
|
/* Map the physical BAR in the guest MMIO space */
|
||||||
ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
|
ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
|
||||||
vdev->pdev->bar[idx].base, /* HPA */
|
pbar_base, /* HPA (pbar) */
|
||||||
new_base, /*GPA*/
|
new_base, /*GPA*/
|
||||||
vdev->bar[idx].size,
|
vdev->bar[idx].size,
|
||||||
EPT_WR | EPT_RD | EPT_UNCACHED);
|
EPT_WR | EPT_RD | EPT_UNCACHED);
|
||||||
|
Loading…
Reference in New Issue
Block a user