mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 13:37:10 +00:00
ACRN/HV: Assign the parsed RSDP to acpi_rsdp to avoid multiple RSDP parsing
Currently the get_rsdp() will be called several times and on some platform it needs to scan the signature of "RSP ptr" in BIOS EBDA region and 0xE0000-0xFFFFF region. It is slow. So after the RSDP is parsed, it will be assigned to acpi_rsdp. Tracked-On: #3184 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
parent
c5d4365770
commit
1c36508e83
@ -143,22 +143,39 @@ found_rsdp(char *base, int32_t length)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RSDP parsed from BIOS region should exist.
|
||||||
|
* If it is NULL, the hypervisor can't be booted
|
||||||
|
*/
|
||||||
static struct acpi_table_rsdp *get_rsdp(void)
|
static struct acpi_table_rsdp *get_rsdp(void)
|
||||||
{
|
{
|
||||||
struct acpi_table_rsdp *rsdp = NULL;
|
struct acpi_table_rsdp *rsdp = NULL;
|
||||||
uint16_t *addr;
|
|
||||||
|
|
||||||
|
/* If acpi_rsdp is already parsed, it will be returned directly */
|
||||||
|
if (acpi_rsdp != NULL) {
|
||||||
|
rsdp = acpi_rsdp;
|
||||||
|
} else {
|
||||||
rsdp = (struct acpi_table_rsdp *)get_rsdp_ptr();
|
rsdp = (struct acpi_table_rsdp *)get_rsdp_ptr();
|
||||||
if (rsdp == NULL) {
|
if (rsdp == NULL) {
|
||||||
|
uint16_t *addr;
|
||||||
|
|
||||||
/* EBDA is addressed by the 16 bit pointer at 0x40E */
|
/* EBDA is addressed by the 16 bit pointer at 0x40E */
|
||||||
addr = (uint16_t *)hpa2hva(0x40eUL);
|
addr = (uint16_t *)hpa2hva(0x40eUL);
|
||||||
|
|
||||||
rsdp = found_rsdp((char *)hpa2hva((uint64_t)(*addr) << 4U), 0x400);
|
rsdp = found_rsdp((char *)hpa2hva((uint64_t)(*addr) << 4U), 0x400);
|
||||||
|
}
|
||||||
if (rsdp == NULL) {
|
if (rsdp == NULL) {
|
||||||
/* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
|
/* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
|
||||||
rsdp = found_rsdp((char *)hpa2hva(0xe0000UL), 0x20000);
|
rsdp = found_rsdp((char *)hpa2hva(0xe0000UL), 0x20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rsdp == NULL)
|
||||||
|
panic("No RSDP is found");
|
||||||
|
|
||||||
|
/* After RSDP is parsed, it will be assigned to acpi_rsdp */
|
||||||
|
acpi_rsdp = rsdp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return rsdp;
|
return rsdp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +202,10 @@ void *get_acpi_tbl(const char *signature)
|
|||||||
uint64_t addr = 0UL;
|
uint64_t addr = 0UL;
|
||||||
uint32_t i, count;
|
uint32_t i, count;
|
||||||
|
|
||||||
rsdp = acpi_rsdp;
|
/* the returned RSDP should always exist. Otherwise the hypervisor
|
||||||
|
* can't be booted.
|
||||||
|
*/
|
||||||
|
rsdp = get_rsdp();
|
||||||
|
|
||||||
if ((rsdp->revision >= 2U) && (rsdp->xsdt_physical_address != 0UL)) {
|
if ((rsdp->revision >= 2U) && (rsdp->xsdt_physical_address != 0UL)) {
|
||||||
/*
|
/*
|
||||||
@ -294,9 +314,10 @@ ioapic_parse_madt(void *madt, struct ioapic_info *ioapic_id_array)
|
|||||||
uint16_t parse_madt(uint32_t lapic_id_array[CONFIG_MAX_PCPU_NUM])
|
uint16_t parse_madt(uint32_t lapic_id_array[CONFIG_MAX_PCPU_NUM])
|
||||||
{
|
{
|
||||||
uint16_t ret = 0U;
|
uint16_t ret = 0U;
|
||||||
|
struct acpi_table_rsdp *rsdp = NULL;
|
||||||
|
|
||||||
acpi_rsdp = get_rsdp();
|
rsdp = get_rsdp();
|
||||||
if (acpi_rsdp != NULL) {
|
if (rsdp != NULL) {
|
||||||
struct acpi_table_madt *madt = (struct acpi_table_madt *)get_acpi_tbl(ACPI_SIG_MADT);
|
struct acpi_table_madt *madt = (struct acpi_table_madt *)get_acpi_tbl(ACPI_SIG_MADT);
|
||||||
if (madt != NULL) {
|
if (madt != NULL) {
|
||||||
ret = local_parse_madt(madt, lapic_id_array);
|
ret = local_parse_madt(madt, lapic_id_array);
|
||||||
@ -308,13 +329,16 @@ 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)
|
||||||
{
|
{
|
||||||
void *madt;
|
uint16_t ret = 0U;
|
||||||
|
struct acpi_table_rsdp *rsdp = NULL;
|
||||||
|
|
||||||
acpi_rsdp = get_rsdp();
|
rsdp = get_rsdp();
|
||||||
ASSERT(acpi_rsdp != NULL, "fail to get rsdp");
|
if (rsdp != NULL) {
|
||||||
|
void *madt = get_acpi_tbl(ACPI_SIG_MADT);
|
||||||
madt = get_acpi_tbl(ACPI_SIG_MADT);
|
if (madt != NULL) {
|
||||||
ASSERT(madt != NULL, "fail to get madt");
|
ret = ioapic_parse_madt(madt, ioapic_id_array);
|
||||||
|
}
|
||||||
return ioapic_parse_madt(madt, ioapic_id_array);
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user