hw/x86: prefer acpi rsdp v2 of multiboot2

over rsdp v1. The multiboot2 provided rsdp_v1 version may not contain the
xsdt pointer, but may have the very same acpi revision as the acpi rsdp v2
version of multiboot2.

Fixes #5332
This commit is contained in:
Alexander Boettcher 2024-09-06 12:19:23 +02:00 committed by Norman Feske
parent cdc45e15f1
commit eb7aea82b8
2 changed files with 17 additions and 9 deletions

View File

@ -73,7 +73,8 @@ class Genode::Multiboot2_info : Mmio<0x8>
Multiboot2_info(addr_t mbi) : Mmio({(char *)mbi, Mmio::SIZE}) { }
void for_each_tag(auto const &mem_fn,
auto const &acpi_fn,
auto const &acpi_rsdp_v1_fn,
auto const &acpi_rsdp_v2_fn,
auto const &fb_fn,
auto const &systab64_fn)
{
@ -103,6 +104,7 @@ class Genode::Multiboot2_info : Mmio<0x8>
if (tag.read<Tag::Type>() == Tag::Type::ACPI_RSDP_V1 ||
tag.read<Tag::Type>() == Tag::Type::ACPI_RSDP_V2) {
size_t const sizeof_tag = 1UL << Tag::LOG2_SIZE;
addr_t const rsdp_addr = tag_addr + sizeof_tag;
@ -113,10 +115,12 @@ class Genode::Multiboot2_info : Mmio<0x8>
Hw::Acpi_rsdp rsdp_v1;
memset (&rsdp_v1, 0, sizeof(rsdp_v1));
memcpy (&rsdp_v1, rsdp, 20);
acpi_fn(rsdp_v1);
acpi_rsdp_v1_fn(rsdp_v1);
} else
if (sizeof(*rsdp) <= tag.read<Tag::Size>() - sizeof_tag) {
/* ACPI RSDP v2 */
acpi_rsdp_v2_fn(*rsdp);
}
if (sizeof(*rsdp) <= tag.read<Tag::Size>() - sizeof_tag)
acpi_fn(*rsdp);
}
if (tag.read<Tag::Type>() == Tag::Type::FRAMEBUFFER) {

View File

@ -61,7 +61,7 @@ static Hw::Acpi_rsdp search_rsdp(addr_t area, addr_t area_size)
}
}
Hw::Acpi_rsdp invalid;
Hw::Acpi_rsdp invalid { };
return invalid;
}
@ -143,10 +143,14 @@ Bootstrap::Platform::Board::Board()
lambda(base, size);
},
[&] (Hw::Acpi_rsdp const &rsdp) {
/* prefer higher acpi revisions */
if (!acpi_rsdp.valid() || acpi_rsdp.revision < rsdp.revision)
acpi_rsdp = rsdp;
[&] (Hw::Acpi_rsdp const &rsdp_v1) {
/* only use ACPI RSDP v1 if nothing available/valid by now */
if (!acpi_rsdp.valid())
acpi_rsdp = rsdp_v1;
},
[&] (Hw::Acpi_rsdp const &rsdp_v2) {
/* prefer v2 ever, override stored previous rsdp v1 potentially */
acpi_rsdp = rsdp_v2;
},
[&] (Hw::Framebuffer const &fb) {
info.framebuffer = fb;