From 04b2919a1abeadb9189ac6623e21333daa15b0f6 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Mon, 30 Jan 2017 23:00:19 +0100 Subject: [PATCH] acpi_drv: use platform_info for rsdt/xsdt lookup Issue #2242 --- repos/base/run/platform_drv.inc | 1 + repos/os/src/drivers/acpi/acpi.cc | 99 ++++++++++++++++++------------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc index 06deca99d1..6a46a77646 100644 --- a/repos/base/run/platform_drv.inc +++ b/repos/base/run/platform_drv.inc @@ -140,6 +140,7 @@ proc platform_drv_config {} { + } diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc index 128d781c6d..0eb8cc6b36 100644 --- a/repos/os/src/drivers/acpi/acpi.cc +++ b/repos/os/src/drivers/acpi/acpi.cc @@ -19,6 +19,7 @@ /* base includes */ #include +#include #include #include @@ -1132,9 +1133,9 @@ class Acpi_table /** * Search for RSDP pointer signature in area */ - uint8_t *_search_rsdp(uint8_t *area) + uint8_t *_search_rsdp(uint8_t *area, size_t const area_size) { - for (addr_t addr = 0; area && addr < BIOS_SIZE; addr += 16) + for (addr_t addr = 0; area && addr < area_size; addr += 16) if (!memcmp(area + addr, "RSD PTR ", 8) && !Table_wrapper::checksum(area + addr, 20)) return area + addr; @@ -1152,21 +1153,22 @@ class Acpi_table /* try BIOS area (0xe0000 - 0xfffffh)*/ try { _mmio.construct(_env, BIOS_BASE, BIOS_SIZE); - return _search_rsdp(_mmio->local_addr()); + return _search_rsdp(_mmio->local_addr(), BIOS_SIZE); } catch (...) { } /* search EBDA (BIOS addr + 0x40e) */ try { /* read RSDP base address from EBDA */ + size_t const size = 0x1000; - _mmio.construct(_env, 0x0, 0x1000); + _mmio.construct(_env, 0x0, size); uint8_t const * const ebda = _mmio->local_addr(); unsigned short const rsdp_phys = (*reinterpret_cast(ebda + 0x40e)) << 4; - _mmio.construct(_env, rsdp_phys, 0x1000); - return _search_rsdp(_mmio->local_addr()); + _mmio.construct(_env, rsdp_phys, size); + return _search_rsdp(_mmio->local_addr(), size); } catch (...) { } @@ -1229,45 +1231,60 @@ class Acpi_table Acpi_table(Genode::Env &env, Genode::Allocator &alloc) : _env(env), _alloc(alloc), _memory(_env, _alloc) { - uint8_t * ptr_rsdp = _rsdp(); + addr_t rsdt = 0, xsdt = 0; + uint8_t acpi_revision = 0; - struct rsdp { - char signature[8]; - uint8_t checksum; - char oemid[6]; - uint8_t revision; - /* table pointer at 16 byte offset in RSDP structure (5.2.5.3) */ - uint32_t rsdt; - /* With ACPI 2.0 */ - uint32_t len; - uint64_t xsdt; - uint8_t checksum_extended; - uint8_t reserved[3]; - } __attribute__((packed)); - struct rsdp * rsdp = reinterpret_cast(ptr_rsdp); + /* try platform_info ROM provided by core */ + try { + Genode::Attached_rom_dataspace info(_env, "platform_info"); + Genode::Xml_node xml(info.local_addr(), info.size()); + Xml_node acpi_node = xml.sub_node("acpi"); + acpi_revision = acpi_node.attribute_value("revision", 0U); + rsdt = acpi_node.attribute_value("rsdt", 0UL); + xsdt = acpi_node.attribute_value("xsdt", 0UL); + } catch (...) { } - if (!rsdp) { - if (verbose) - Genode::log("No rsdp structure found"); - return; + /* try legacy way if not found in platform_info */ + if (!rsdt && !xsdt) { + uint8_t * ptr_rsdp = _rsdp(); + + struct rsdp { + char signature[8]; + uint8_t checksum; + char oemid[6]; + uint8_t revision; + /* table pointer at 16 byte offset in RSDP structure (5.2.5.3) */ + uint32_t rsdt; + /* With ACPI 2.0 */ + uint32_t len; + uint64_t xsdt; + uint8_t checksum_extended; + uint8_t reserved[3]; + } __attribute__((packed)); + struct rsdp * rsdp = reinterpret_cast(ptr_rsdp); + + if (!rsdp) { + Genode::error("No valid ACPI RSDP structure found"); + return; + } + + if (verbose) { + uint8_t oem[7]; + memcpy(oem, rsdp->oemid, 6); + oem[6] = 0; + Genode::log("ACPI revision ", rsdp->revision, " of " + "OEM '", oem, "', " + "rsdt:", Genode::Hex(rsdp->rsdt), " " + "xsdt:", Genode::Hex(rsdp->xsdt)); + } + + rsdt = rsdp->rsdt; + xsdt = rsdp->xsdt; + acpi_revision = rsdp->revision; + /* drop rsdp io_mem mapping since rsdt/xsdt may overlap */ + _mmio.destruct(); } - if (verbose) { - uint8_t oem[7]; - memcpy(oem, rsdp->oemid, 6); - oem[6] = 0; - Genode::log("ACPI revision ", rsdp->revision, " of " - "OEM '", oem, "', " - "rsdt:", Genode::Hex(rsdp->rsdt), " " - "xsdt:", Genode::Hex(rsdp->xsdt)); - } - - addr_t const rsdt = rsdp->rsdt; - addr_t const xsdt = rsdp->xsdt; - uint8_t const acpi_revision = rsdp->revision; - /* drop rsdp io_mem mapping since rsdt/xsdt may overlap */ - _mmio.destruct(); - if (acpi_revision != 0 && xsdt && sizeof(addr_t) != sizeof(uint32_t)) { /* running 64bit and xsdt is valid */ Table_wrapper table(_memory, xsdt);