acpi_drv: use platform_info for rsdt/xsdt lookup

Issue #2242
This commit is contained in:
Alexander Boettcher 2017-01-30 23:00:19 +01:00 committed by Norman Feske
parent f30f0a81e0
commit 04b2919a1a
2 changed files with 59 additions and 41 deletions

View File

@ -140,6 +140,7 @@ proc platform_drv_config {} {
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service> <service name="ROM"> <parent/> </service>
<service name="Report"> <child name="acpi_report_rom"/> </service> <service name="Report"> <child name="acpi_report_rom"/> </service>
<service name="ROM" label="platform_info"> <parent/> </service>
</route> </route>
</start>} </start>}

View File

@ -19,6 +19,7 @@
/* base includes */ /* base includes */
#include <base/attached_io_mem_dataspace.h> #include <base/attached_io_mem_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <util/misc_math.h> #include <util/misc_math.h>
#include <util/mmio.h> #include <util/mmio.h>
@ -1132,9 +1133,9 @@ class Acpi_table
/** /**
* Search for RSDP pointer signature in area * 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) && if (!memcmp(area + addr, "RSD PTR ", 8) &&
!Table_wrapper::checksum(area + addr, 20)) !Table_wrapper::checksum(area + addr, 20))
return area + addr; return area + addr;
@ -1152,21 +1153,22 @@ class Acpi_table
/* try BIOS area (0xe0000 - 0xfffffh)*/ /* try BIOS area (0xe0000 - 0xfffffh)*/
try { try {
_mmio.construct(_env, BIOS_BASE, BIOS_SIZE); _mmio.construct(_env, BIOS_BASE, BIOS_SIZE);
return _search_rsdp(_mmio->local_addr<uint8_t>()); return _search_rsdp(_mmio->local_addr<uint8_t>(), BIOS_SIZE);
} }
catch (...) { } catch (...) { }
/* search EBDA (BIOS addr + 0x40e) */ /* search EBDA (BIOS addr + 0x40e) */
try { try {
/* read RSDP base address from EBDA */ /* 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<uint8_t const>(); uint8_t const * const ebda = _mmio->local_addr<uint8_t const>();
unsigned short const rsdp_phys = unsigned short const rsdp_phys =
(*reinterpret_cast<unsigned short const *>(ebda + 0x40e)) << 4; (*reinterpret_cast<unsigned short const *>(ebda + 0x40e)) << 4;
_mmio.construct(_env, rsdp_phys, 0x1000); _mmio.construct(_env, rsdp_phys, size);
return _search_rsdp(_mmio->local_addr<uint8_t>()); return _search_rsdp(_mmio->local_addr<uint8_t>(), size);
} }
catch (...) { } catch (...) { }
@ -1229,6 +1231,21 @@ class Acpi_table
Acpi_table(Genode::Env &env, Genode::Allocator &alloc) Acpi_table(Genode::Env &env, Genode::Allocator &alloc)
: _env(env), _alloc(alloc), _memory(_env, _alloc) : _env(env), _alloc(alloc), _memory(_env, _alloc)
{ {
addr_t rsdt = 0, xsdt = 0;
uint8_t acpi_revision = 0;
/* try platform_info ROM provided by core */
try {
Genode::Attached_rom_dataspace info(_env, "platform_info");
Genode::Xml_node xml(info.local_addr<char>(), 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 (...) { }
/* try legacy way if not found in platform_info */
if (!rsdt && !xsdt) {
uint8_t * ptr_rsdp = _rsdp(); uint8_t * ptr_rsdp = _rsdp();
struct rsdp { struct rsdp {
@ -1247,8 +1264,7 @@ class Acpi_table
struct rsdp * rsdp = reinterpret_cast<struct rsdp *>(ptr_rsdp); struct rsdp * rsdp = reinterpret_cast<struct rsdp *>(ptr_rsdp);
if (!rsdp) { if (!rsdp) {
if (verbose) Genode::error("No valid ACPI RSDP structure found");
Genode::log("No rsdp structure found");
return; return;
} }
@ -1262,11 +1278,12 @@ class Acpi_table
"xsdt:", Genode::Hex(rsdp->xsdt)); "xsdt:", Genode::Hex(rsdp->xsdt));
} }
addr_t const rsdt = rsdp->rsdt; rsdt = rsdp->rsdt;
addr_t const xsdt = rsdp->xsdt; xsdt = rsdp->xsdt;
uint8_t const acpi_revision = rsdp->revision; acpi_revision = rsdp->revision;
/* drop rsdp io_mem mapping since rsdt/xsdt may overlap */ /* drop rsdp io_mem mapping since rsdt/xsdt may overlap */
_mmio.destruct(); _mmio.destruct();
}
if (acpi_revision != 0 && xsdt && sizeof(addr_t) != sizeof(uint32_t)) { if (acpi_revision != 0 && xsdt && sizeof(addr_t) != sizeof(uint32_t)) {
/* running 64bit and xsdt is valid */ /* running 64bit and xsdt is valid */