mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-25 15:02:13 +00:00
HV: parse default pci mmcfg base
The default PCI mmcfg base is stored in ACPI MCFG table, when CONFIG_ACPI_PARSE_ENABLED is set, acpi_fixup() function will parse and fix up the platform mmcfg base in ACRN boot stage; when it is not set, platform mmcfg base will be initialized to DEFAULT_PCI_MMCFG_BASE which generated by acrn-config tool; Please note we will not support platform which has multiple PCI segment groups. Tracked-On: #4157 Signed-off-by: Victor Sun <victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
80a7281f1e
commit
15da33d8af
@ -33,6 +33,7 @@
|
|||||||
#include <ioapic.h>
|
#include <ioapic.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include <host_pm.h>
|
#include <host_pm.h>
|
||||||
|
#include <pci.h>
|
||||||
#include <acrn_common.h>
|
#include <acrn_common.h>
|
||||||
|
|
||||||
/* Per ACPI spec:
|
/* Per ACPI spec:
|
||||||
@ -111,15 +112,30 @@ static void *get_facs_table(const uint8_t *facp_addr)
|
|||||||
return (void *)facs_addr;
|
return (void *)facs_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put all ACPI fix up code here */
|
/* @pre mcfg_addr != NULL */
|
||||||
void acpi_fixup(void)
|
static uint64_t parse_mmcfg_base(const uint8_t *mcfg_addr)
|
||||||
{
|
{
|
||||||
uint8_t *facp_addr, *facs_addr;
|
uint64_t base = 0UL;
|
||||||
|
uint32_t length = get_acpi_dt_dword(mcfg_addr, OFFSET_MCFG_LENGTH);
|
||||||
|
|
||||||
|
if (length > OFFSET_MCFG_ENTRY1) {
|
||||||
|
pr_fatal("Multiple PCI segment groups is not supported!");
|
||||||
|
} else {
|
||||||
|
base = get_acpi_dt_qword(mcfg_addr, OFFSET_MCFG_ENTRY0_BASE);
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put all ACPI fix up code here */
|
||||||
|
int32_t acpi_fixup(void)
|
||||||
|
{
|
||||||
|
uint8_t *facp_addr = NULL, *facs_addr = NULL, *mcfg_addr = NULL;
|
||||||
|
uint64_t def_mmcfg_base = 0UL;
|
||||||
|
int32_t ret = 0;
|
||||||
struct acpi_generic_address pm1a_cnt, pm1a_evt;
|
struct acpi_generic_address pm1a_cnt, pm1a_evt;
|
||||||
struct pm_s_state_data *sx_data = get_host_sstate_data();
|
struct pm_s_state_data *sx_data = get_host_sstate_data();
|
||||||
|
|
||||||
facp_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_FADT);
|
facp_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_FADT);
|
||||||
|
|
||||||
if (facp_addr != NULL) {
|
if (facp_addr != NULL) {
|
||||||
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_EVT, &pm1a_evt);
|
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_EVT, &pm1a_evt);
|
||||||
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_CNT, &pm1a_cnt);
|
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_CNT, &pm1a_cnt);
|
||||||
@ -143,4 +159,17 @@ void acpi_fixup(void)
|
|||||||
rr_data->val = *(facp_addr + OFFSET_RESET_VALUE);
|
rr_data->val = *(facp_addr + OFFSET_RESET_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mcfg_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_MCFG);
|
||||||
|
if (mcfg_addr != NULL) {
|
||||||
|
def_mmcfg_base = parse_mmcfg_base(mcfg_addr);
|
||||||
|
set_mmcfg_base(def_mmcfg_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((facp_addr == NULL) || (facs_addr == NULL)
|
||||||
|
|| (mcfg_addr == NULL) || (def_mmcfg_base == 0UL)) {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
#define RESET_REGISTER_SPACE_ID SPACE_SYSTEM_IO
|
#define RESET_REGISTER_SPACE_ID SPACE_SYSTEM_IO
|
||||||
#define RESET_REGISTER_VALUE 0x6U
|
#define RESET_REGISTER_VALUE 0x6U
|
||||||
|
|
||||||
|
/* PCI mmcfg base of MCFG */
|
||||||
|
#define DEFAULT_PCI_MMCFG_BASE 0xE0000000UL
|
||||||
|
|
||||||
/* DRHD of DMAR */
|
/* DRHD of DMAR */
|
||||||
|
|
||||||
#define DRHD_COUNT 2U
|
#define DRHD_COUNT 2U
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#define RESET_REGISTER_VALUE 0UL
|
#define RESET_REGISTER_VALUE 0UL
|
||||||
#define RESET_REGISTER_SPACE_ID 0UL
|
#define RESET_REGISTER_SPACE_ID 0UL
|
||||||
|
|
||||||
|
/* PCI mmcfg base of MCFG, pre-assumption is platform only has one PCI segment group */
|
||||||
|
#define DEFAULT_PCI_MMCFG_BASE 0UL
|
||||||
|
|
||||||
/* DRHD of DMAR */
|
/* DRHD of DMAR */
|
||||||
#define DRHD_COUNT 8U
|
#define DRHD_COUNT 8U
|
||||||
|
|
||||||
|
@ -144,6 +144,12 @@ void init_pcpu_pre(bool is_bsp)
|
|||||||
early_init_lapic();
|
early_init_lapic();
|
||||||
|
|
||||||
init_vboot();
|
init_vboot();
|
||||||
|
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
||||||
|
ret = acpi_fixup();
|
||||||
|
if (ret != 0) {
|
||||||
|
panic("failed to parse/fix up ACPI table!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!init_percpu_lapic_id()) {
|
if (!init_percpu_lapic_id()) {
|
||||||
panic("failed to init_percpu_lapic_id!");
|
panic("failed to init_percpu_lapic_id!");
|
||||||
|
@ -68,9 +68,6 @@ void init_vboot(void)
|
|||||||
* initialized before calling other vboot_ops interface.
|
* initialized before calling other vboot_ops interface.
|
||||||
*/
|
*/
|
||||||
vboot_ops->init();
|
vboot_ops->init();
|
||||||
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
|
||||||
acpi_fixup();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @pre: vboot_ops != NULL */
|
/* @pre: vboot_ops != NULL */
|
||||||
|
@ -36,13 +36,19 @@
|
|||||||
#define OFFSET_WAKE_VECTOR_32 12U
|
#define OFFSET_WAKE_VECTOR_32 12U
|
||||||
#define OFFSET_WAKE_VECTOR_64 24U
|
#define OFFSET_WAKE_VECTOR_64 24U
|
||||||
|
|
||||||
|
/* MCFG field offsets */
|
||||||
|
#define OFFSET_MCFG_LENGTH 4U
|
||||||
|
#define OFFSET_MCFG_ENTRY0 44U
|
||||||
|
#define OFFSET_MCFG_ENTRY0_BASE 44U
|
||||||
|
#define OFFSET_MCFG_ENTRY1 60U
|
||||||
|
|
||||||
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
|
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
|
||||||
#define ACPI_SIG_FACS 0x53434146U /* "FACS" */
|
#define ACPI_SIG_FACS 0x53434146U /* "FACS" */
|
||||||
#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Ptr */
|
#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Ptr */
|
||||||
#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */
|
#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */
|
||||||
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
|
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
|
||||||
#define ACPI_SIG_DMAR "DMAR"
|
#define ACPI_SIG_DMAR "DMAR"
|
||||||
|
#define ACPI_SIG_MCFG "MCFG" /* Memory Mapped Configuration table */
|
||||||
|
|
||||||
struct packed_gas {
|
struct packed_gas {
|
||||||
uint8_t space_id;
|
uint8_t space_id;
|
||||||
@ -200,7 +206,7 @@ uint16_t parse_madt(uint32_t lapic_id_array[CONFIG_MAX_PCPU_NUM]);
|
|||||||
uint16_t parse_madt_ioapic(struct ioapic_info *ioapic_id_array);
|
uint16_t parse_madt_ioapic(struct ioapic_info *ioapic_id_array);
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
||||||
void acpi_fixup(void);
|
int32_t acpi_fixup(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !ACPI_H */
|
#endif /* !ACPI_H */
|
||||||
|
@ -41,13 +41,27 @@
|
|||||||
#include <vtd.h>
|
#include <vtd.h>
|
||||||
#include <bits.h>
|
#include <bits.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
#include <platform_acpi_info.h>
|
||||||
|
|
||||||
static spinlock_t pci_device_lock;
|
static spinlock_t pci_device_lock;
|
||||||
static uint32_t num_pci_pdev;
|
static uint32_t num_pci_pdev;
|
||||||
static struct pci_pdev pci_pdev_array[CONFIG_MAX_PCI_DEV_NUM];
|
static struct pci_pdev pci_pdev_array[CONFIG_MAX_PCI_DEV_NUM];
|
||||||
|
static uint64_t pci_mmcfg_base = DEFAULT_PCI_MMCFG_BASE;
|
||||||
|
|
||||||
static void init_pdev(uint16_t pbdf, uint32_t drhd_index);
|
static void init_pdev(uint16_t pbdf, uint32_t drhd_index);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
||||||
|
void set_mmcfg_base(uint64_t mmcfg_base)
|
||||||
|
{
|
||||||
|
pci_mmcfg_base = mmcfg_base;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint64_t get_mmcfg_base(void)
|
||||||
|
{
|
||||||
|
return pci_mmcfg_base;
|
||||||
|
}
|
||||||
|
|
||||||
/* @brief: Find the DRHD index corresponding to a PCI device
|
/* @brief: Find the DRHD index corresponding to a PCI device
|
||||||
* Runs through the pci_pdev_array and returns the value in drhd_idx
|
* Runs through the pci_pdev_array and returns the value in drhd_idx
|
||||||
* member from pdev structure that matches matches B:D.F
|
* member from pdev structure that matches matches B:D.F
|
||||||
|
@ -233,6 +233,11 @@ static inline bool bdf_is_equal(union pci_bdf a, union pci_bdf b)
|
|||||||
return (a.value == b.value);
|
return (a.value == b.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
||||||
|
void set_mmcfg_base(uint64_t mmcfg_base);
|
||||||
|
#endif
|
||||||
|
uint64_t get_mmcfg_base(void);
|
||||||
|
|
||||||
uint32_t pci_pdev_read_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes);
|
uint32_t pci_pdev_read_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes);
|
||||||
void pci_pdev_write_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes, uint32_t val);
|
void pci_pdev_write_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes, uint32_t val);
|
||||||
void enable_disable_pci_intx(union pci_bdf bdf, bool enable);
|
void enable_disable_pci_intx(union pci_bdf bdf, bool enable);
|
||||||
|
Loading…
Reference in New Issue
Block a user