mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-29 16:58:10 +00:00
hv: vapic: add mcfg table support
Add MCFG table support to allow guest access PCIe external CFG space by ECAM Tracked-On: #4623 Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
4eb3f5a0c7
commit
1dccbdbaa2
@ -60,6 +60,21 @@ static struct acpi_table_info acpi_table_template[CONFIG_MAX_VM_NUM] = {
|
||||
.oem_table_id = "ACRNMADT",
|
||||
.asl_compiler_id = ACPI_ASL_COMPILER_ID,
|
||||
},
|
||||
.mcfg = {
|
||||
.header.revision = 0x3U,
|
||||
.header.oem_revision = 0x1U,
|
||||
.header.asl_compiler_revision = ACPI_ASL_COMPILER_VERSION,
|
||||
.header.signature = ACPI_SIG_MCFG,
|
||||
.header.oem_id = ACPI_OEM_ID,
|
||||
.header.oem_table_id = "ACRNMADT",
|
||||
.header.asl_compiler_id = ACPI_ASL_COMPILER_ID,
|
||||
},
|
||||
.mcfg_entry = {
|
||||
.address = VIRT_PCI_MMCFG_BASE,
|
||||
.pci_segment = 0U,
|
||||
.start_bus_number = 0x0U,
|
||||
.end_bus_number = 0xFFU,
|
||||
},
|
||||
.madt = {
|
||||
.header.revision = 0x3U,
|
||||
.header.oem_revision = 0x1U,
|
||||
@ -99,6 +114,7 @@ void build_vacpi(struct acrn_vm *vm)
|
||||
struct acpi_table_xsdt *xsdt;
|
||||
struct acpi_table_fadt *fadp;
|
||||
struct acpi_table_header *dsdt;
|
||||
struct acpi_table_mcfg *mcfg;
|
||||
struct acpi_table_madt *madt;
|
||||
struct acpi_madt_local_apic *lapic;
|
||||
uint16_t i;
|
||||
@ -115,9 +131,10 @@ void build_vacpi(struct acrn_vm *vm)
|
||||
xsdt = (struct acpi_table_xsdt *)gpa2hva(vm, ACPI_XSDT_ADDR);
|
||||
stac();
|
||||
xsdt->table_offset_entry[0] = ACPI_FADT_ADDR;
|
||||
xsdt->table_offset_entry[1] = ACPI_MADT_ADDR;
|
||||
/* Currently XSDT table only pointers to 2 ACPI table entry (FADT/MADT) */
|
||||
xsdt->header.length = sizeof(struct acpi_table_header) + (2U * sizeof(uint64_t));
|
||||
xsdt->table_offset_entry[1] = ACPI_MCFG_ADDR;
|
||||
xsdt->table_offset_entry[2] = ACPI_MADT_ADDR;
|
||||
/* Currently XSDT table only pointers to 3 ACPI table entry (FADT/MCFG/MADT) */
|
||||
xsdt->header.length = sizeof(struct acpi_table_header) + (3U * sizeof(uint64_t));
|
||||
xsdt->header.checksum = calculate_checksum8(xsdt, xsdt->header.length);
|
||||
clac();
|
||||
|
||||
@ -133,6 +150,14 @@ void build_vacpi(struct acrn_vm *vm)
|
||||
/* Copy DSDT table and its subtables to guest physical memory */
|
||||
(void)copy_to_gpa(vm, dsdt, ACPI_DSDT_ADDR, dsdt->length);
|
||||
|
||||
mcfg = &acpi_table_template[vm->vm_id].mcfg;
|
||||
mcfg->header.length = sizeof(struct acpi_table_mcfg)
|
||||
+ (1U * sizeof(struct acpi_mcfg_allocation)); /* We only support one mcfg allocation structure */
|
||||
mcfg->header.checksum = calculate_checksum8(mcfg, mcfg->header.length);
|
||||
|
||||
/* Copy MCFG table and its subtables to guest physical memory */
|
||||
(void)copy_to_gpa(vm, mcfg, ACPI_MCFG_ADDR, mcfg->header.length);
|
||||
|
||||
/* Fix up MADT LAPIC subtables */
|
||||
for (i = 0U; i < vm->hw.created_vcpus; i++) {
|
||||
lapic = &acpi_table_template[vm->vm_id].lapic_array[i];
|
||||
|
@ -139,6 +139,19 @@ struct acpi_table_fadt {
|
||||
uint8_t unused3[128]; /* ACRN doesn't use these fields */
|
||||
} __packed;
|
||||
|
||||
struct acpi_table_mcfg {
|
||||
struct acpi_table_header header; /* Common ACPI table header */
|
||||
uint8_t reserved[8];
|
||||
} __packed;
|
||||
|
||||
struct acpi_mcfg_allocation {
|
||||
uint64_t address; /* Base address, processor-relative */
|
||||
uint16_t pci_segment; /* PCI segment group number */
|
||||
uint8_t start_bus_number; /* Starting PCI Bus number */
|
||||
uint8_t end_bus_number; /* Final PCI Bus number */
|
||||
uint32_t reserved;
|
||||
} __packed;
|
||||
|
||||
struct acpi_table_madt {
|
||||
/* Common ACPI table header */
|
||||
struct acpi_table_header header;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <vtd.h>
|
||||
#include <io.h>
|
||||
#include <mmu.h>
|
||||
#include <vacpi.h>
|
||||
#include <logmsg.h>
|
||||
#include "vpci_priv.h"
|
||||
#include "pci_dev.h"
|
||||
@ -248,13 +249,11 @@ void init_vpci(struct acrn_vm *vm)
|
||||
vpci_init_vdevs(vm);
|
||||
|
||||
vm_config = get_vm_config(vm->vm_id);
|
||||
if (vm_config->load_order != PRE_LAUNCHED_VM) {
|
||||
/* PCI MMCONFIG for post-launched VM is fixed to 0xE0000000 */
|
||||
pci_mmcfg_base = (vm_config->load_order == SOS_VM) ? get_mmcfg_base() : 0xE0000000UL;
|
||||
vm->vpci.pci_mmcfg_base = pci_mmcfg_base;
|
||||
register_mmio_emulation_handler(vm, vpci_mmio_cfg_access,
|
||||
/* virtual PCI MMCONFIG for SOS is same with the physical value */
|
||||
pci_mmcfg_base = (vm_config->load_order == SOS_VM) ? get_mmcfg_base() : VIRT_PCI_MMCFG_BASE;
|
||||
vm->vpci.pci_mmcfg_base = pci_mmcfg_base;
|
||||
register_mmio_emulation_handler(vm, vpci_mmio_cfg_access,
|
||||
pci_mmcfg_base, pci_mmcfg_base + PCI_MMCONFIG_SIZE, &vm->vpci, false);
|
||||
}
|
||||
|
||||
/* Intercept and handle I/O ports CF8h */
|
||||
register_pio_emulation_handler(vm, PCI_CFGADDR_PIO_IDX, &pci_cfgaddr_range,
|
||||
|
@ -36,6 +36,7 @@
|
||||
* XSDT -> 0xf2480 (36 bytes + 8*7 table addrs, 4 used)
|
||||
* FADT -> 0xf2500 (244 bytes fixed for ACPI 2.0)
|
||||
* DSDT -> 0xf2600 (36 bytes fixed for an empty DSDT)
|
||||
* MCFG -> 0xf2700 (36 bytes fixed + 8 bytes reserved + 1 * 16 bytes)
|
||||
* MADT -> 0xf2740 (depends on #CPUs)
|
||||
*/
|
||||
#define ACPI_BASE 0xf2400U
|
||||
@ -44,12 +45,16 @@
|
||||
#define ACPI_XSDT_ADDR (ACPI_BASE + 0x080U)
|
||||
#define ACPI_FADT_ADDR (ACPI_BASE + 0x100U)
|
||||
#define ACPI_DSDT_ADDR (ACPI_BASE + 0x200U)
|
||||
#define ACPI_MCFG_ADDR (ACPI_BASE + 0x300U)
|
||||
#define ACPI_MADT_ADDR (ACPI_BASE + 0x340U)
|
||||
|
||||
#define ACPI_OEM_ID "ACRN "
|
||||
#define ACPI_ASL_COMPILER_ID "INTL"
|
||||
#define ACPI_ASL_COMPILER_VERSION 0x20190802U
|
||||
|
||||
/* virtual PCI MMCFG address base for pre/post-launched VM. */
|
||||
#define VIRT_PCI_MMCFG_BASE 0xE0000000UL
|
||||
|
||||
struct acrn_vm;
|
||||
struct acpi_table_info {
|
||||
struct acpi_table_rsdp rsdp;
|
||||
@ -58,6 +63,8 @@ struct acpi_table_info {
|
||||
struct {
|
||||
struct acpi_table_fadt fadt;
|
||||
struct acpi_table_header dsdt; /* an empty DSDT */
|
||||
struct acpi_table_mcfg mcfg;
|
||||
struct acpi_mcfg_allocation mcfg_entry; /* mcfg_entry msut be declared fellowing mcfg */
|
||||
struct acpi_table_madt madt;
|
||||
struct acpi_madt_local_apic_nmi lapic_nmi;
|
||||
struct acpi_madt_local_apic lapic_array[MAX_PCPU_NUM];
|
||||
|
Loading…
Reference in New Issue
Block a user