Skip to content

Commit 15da33d

Browse files
jsun26intelwenlingz
authored andcommitted
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>
1 parent 80a7281 commit 15da33d

File tree

8 files changed

+71
-8
lines changed

8 files changed

+71
-8
lines changed

hypervisor/acpi_parser/acpi_ext.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <ioapic.h>
3434
#include <logmsg.h>
3535
#include <host_pm.h>
36+
#include <pci.h>
3637
#include <acrn_common.h>
3738

3839
/* Per ACPI spec:
@@ -111,15 +112,30 @@ static void *get_facs_table(const uint8_t *facp_addr)
111112
return (void *)facs_addr;
112113
}
113114

115+
/* @pre mcfg_addr != NULL */
116+
static uint64_t parse_mmcfg_base(const uint8_t *mcfg_addr)
117+
{
118+
uint64_t base = 0UL;
119+
uint32_t length = get_acpi_dt_dword(mcfg_addr, OFFSET_MCFG_LENGTH);
120+
121+
if (length > OFFSET_MCFG_ENTRY1) {
122+
pr_fatal("Multiple PCI segment groups is not supported!");
123+
} else {
124+
base = get_acpi_dt_qword(mcfg_addr, OFFSET_MCFG_ENTRY0_BASE);
125+
}
126+
return base;
127+
}
128+
114129
/* put all ACPI fix up code here */
115-
void acpi_fixup(void)
130+
int32_t acpi_fixup(void)
116131
{
117-
uint8_t *facp_addr, *facs_addr;
132+
uint8_t *facp_addr = NULL, *facs_addr = NULL, *mcfg_addr = NULL;
133+
uint64_t def_mmcfg_base = 0UL;
134+
int32_t ret = 0;
118135
struct acpi_generic_address pm1a_cnt, pm1a_evt;
119136
struct pm_s_state_data *sx_data = get_host_sstate_data();
120137

121138
facp_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_FADT);
122-
123139
if (facp_addr != NULL) {
124140
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_EVT, &pm1a_evt);
125141
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_CNT, &pm1a_cnt);
@@ -143,4 +159,17 @@ void acpi_fixup(void)
143159
rr_data->val = *(facp_addr + OFFSET_RESET_VALUE);
144160
}
145161
}
162+
163+
mcfg_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_MCFG);
164+
if (mcfg_addr != NULL) {
165+
def_mmcfg_base = parse_mmcfg_base(mcfg_addr);
166+
set_mmcfg_base(def_mmcfg_base);
167+
}
168+
169+
if ((facp_addr == NULL) || (facs_addr == NULL)
170+
|| (mcfg_addr == NULL) || (def_mmcfg_base == 0UL)) {
171+
ret = -1;
172+
}
173+
174+
return ret;
146175
}

hypervisor/arch/x86/configs/nuc7i7dnb/platform_acpi_info.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
#define RESET_REGISTER_SPACE_ID SPACE_SYSTEM_IO
4040
#define RESET_REGISTER_VALUE 0x6U
4141

42+
/* PCI mmcfg base of MCFG */
43+
#define DEFAULT_PCI_MMCFG_BASE 0xE0000000UL
44+
4245
/* DRHD of DMAR */
4346

4447
#define DRHD_COUNT 2U

hypervisor/arch/x86/configs/platform_acpi_info.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#define RESET_REGISTER_VALUE 0UL
2525
#define RESET_REGISTER_SPACE_ID 0UL
2626

27+
/* PCI mmcfg base of MCFG, pre-assumption is platform only has one PCI segment group */
28+
#define DEFAULT_PCI_MMCFG_BASE 0UL
29+
2730
/* DRHD of DMAR */
2831
#define DRHD_COUNT 8U
2932

hypervisor/arch/x86/cpu.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ void init_pcpu_pre(bool is_bsp)
144144
early_init_lapic();
145145

146146
init_vboot();
147+
#ifdef CONFIG_ACPI_PARSE_ENABLED
148+
ret = acpi_fixup();
149+
if (ret != 0) {
150+
panic("failed to parse/fix up ACPI table!");
151+
}
152+
#endif
147153

148154
if (!init_percpu_lapic_id()) {
149155
panic("failed to init_percpu_lapic_id!");

hypervisor/boot/guest/vboot_wrapper.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ void init_vboot(void)
6868
* initialized before calling other vboot_ops interface.
6969
*/
7070
vboot_ops->init();
71-
#ifdef CONFIG_ACPI_PARSE_ENABLED
72-
acpi_fixup();
73-
#endif
7471
}
7572

7673
/* @pre: vboot_ops != NULL */

hypervisor/boot/include/acpi.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@
3636
#define OFFSET_WAKE_VECTOR_32 12U
3737
#define OFFSET_WAKE_VECTOR_64 24U
3838

39+
/* MCFG field offsets */
40+
#define OFFSET_MCFG_LENGTH 4U
41+
#define OFFSET_MCFG_ENTRY0 44U
42+
#define OFFSET_MCFG_ENTRY0_BASE 44U
43+
#define OFFSET_MCFG_ENTRY1 60U
44+
3945
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
4046
#define ACPI_SIG_FACS 0x53434146U /* "FACS" */
4147
#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Ptr */
4248
#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */
4349
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
4450
#define ACPI_SIG_DMAR "DMAR"
45-
51+
#define ACPI_SIG_MCFG "MCFG" /* Memory Mapped Configuration table */
4652

4753
struct packed_gas {
4854
uint8_t space_id;
@@ -200,7 +206,7 @@ uint16_t parse_madt(uint32_t lapic_id_array[CONFIG_MAX_PCPU_NUM]);
200206
uint16_t parse_madt_ioapic(struct ioapic_info *ioapic_id_array);
201207

202208
#ifdef CONFIG_ACPI_PARSE_ENABLED
203-
void acpi_fixup(void);
209+
int32_t acpi_fixup(void);
204210
#endif
205211

206212
#endif /* !ACPI_H */

hypervisor/hw/pci.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,27 @@
4141
#include <vtd.h>
4242
#include <bits.h>
4343
#include <board.h>
44+
#include <platform_acpi_info.h>
4445

4546
static spinlock_t pci_device_lock;
4647
static uint32_t num_pci_pdev;
4748
static struct pci_pdev pci_pdev_array[CONFIG_MAX_PCI_DEV_NUM];
49+
static uint64_t pci_mmcfg_base = DEFAULT_PCI_MMCFG_BASE;
4850

4951
static void init_pdev(uint16_t pbdf, uint32_t drhd_index);
5052

53+
#ifdef CONFIG_ACPI_PARSE_ENABLED
54+
void set_mmcfg_base(uint64_t mmcfg_base)
55+
{
56+
pci_mmcfg_base = mmcfg_base;
57+
}
58+
#endif
59+
60+
uint64_t get_mmcfg_base(void)
61+
{
62+
return pci_mmcfg_base;
63+
}
64+
5165
/* @brief: Find the DRHD index corresponding to a PCI device
5266
* Runs through the pci_pdev_array and returns the value in drhd_idx
5367
* member from pdev structure that matches matches B:D.F

hypervisor/include/hw/pci.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ static inline bool bdf_is_equal(union pci_bdf a, union pci_bdf b)
233233
return (a.value == b.value);
234234
}
235235

236+
#ifdef CONFIG_ACPI_PARSE_ENABLED
237+
void set_mmcfg_base(uint64_t mmcfg_base);
238+
#endif
239+
uint64_t get_mmcfg_base(void);
240+
236241
uint32_t pci_pdev_read_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes);
237242
void pci_pdev_write_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes, uint32_t val);
238243
void enable_disable_pci_intx(union pci_bdf bdf, bool enable);

0 commit comments

Comments
 (0)