diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc
index 41670466ad..a62349abda 100644
--- a/repos/os/src/drivers/acpi/acpi.cc
+++ b/repos/os/src/drivers/acpi/acpi.cc
@@ -20,6 +20,7 @@
/* base includes */
#include
#include
+#include
#include
#include
@@ -311,6 +312,7 @@ struct Fadt : Genode::Mmio
Fadt(addr_t mmio, size_t size) : Genode::Mmio(mmio), size(size) { }
struct Dsdt : Register<0x28, 32> { };
+ struct Sci_int : Register<0x2e, 16> { };
struct Features : Register<0x70, 32> {
/* Table 5-35 Fixed ACPI Description Table Fixed Feature Flags */
struct Reset : Bitfield<10, 1> { };
@@ -327,6 +329,9 @@ struct Fadt : Genode::Mmio
bool dsdt_valid() {
return size >= Dsdt::OFFSET + Dsdt::ACCESS_WIDTH / 8; }
+ bool sci_int_valid() {
+ return size >= Sci_int::OFFSET + Sci_int::ACCESS_WIDTH / 8; }
+
bool io_reset_supported()
{
if (size < Reset_value::OFFSET + Reset_value::ACCESS_WIDTH / 8)
@@ -511,6 +516,21 @@ class Pci_config_space : public List::Element
*/
class Table_wrapper
{
+ public:
+
+ struct Info : Registry::Element
+ {
+ String<5> name;
+ addr_t addr;
+ size_t size;
+
+ Info(Registry ®istry,
+ char const *name, addr_t addr, size_t size)
+ :
+ Registry::Element(registry, *this),
+ name(name), addr(addr), size(size) { }
+ };
+
private:
addr_t _base; /* table base address */
@@ -634,7 +654,8 @@ class Table_wrapper
Dmar_entry::list()->insert(new (&alloc) Dmar_entry(head->clone(alloc)));
}
- Table_wrapper(Acpi::Memory &memory, addr_t base)
+ Table_wrapper(Acpi::Memory &memory, addr_t base,
+ Registry ®istry, Allocator &heap)
: _base(base), _table(0)
{
/* make table header accessible */
@@ -646,6 +667,8 @@ class Table_wrapper
memset(_name, 0, 5);
memcpy(_name, _table->signature, 4);
+ new (heap) Info(registry, name(), _base, _table->size);
+
if (verbose)
Genode::log("table mapped '", Genode::Cstring(_name), "' at ", _table, " "
"(from ", Genode::Hex(_base), ") "
@@ -1318,7 +1341,7 @@ class Acpi_table
private:
Genode::Env &_env;
- Genode::Allocator &_alloc;
+ Genode::Allocator &_heap;
Acpi::Memory _memory;
struct Reset_info
@@ -1328,6 +1351,10 @@ class Acpi_table
};
Genode::Constructible _reset_info { };
+ unsigned short _sci_int { };
+ bool _sci_int_valid { };
+
+ Registry _table_registry { };
/* BIOS range to scan for RSDP */
enum { BIOS_BASE = 0xe0000, BIOS_SIZE = 0x20000 };
@@ -1380,13 +1407,13 @@ class Acpi_table
}
template
- void _parse_tables(Genode::Allocator &alloc, T * entries, uint32_t const count)
+ void _parse_tables(T * entries, uint32_t const count)
{
/* search for SSDT and DSDT tables */
for (uint32_t i = 0; i < count; i++) {
uint32_t dsdt = 0;
try {
- Table_wrapper table(_memory, entries[i]);
+ Table_wrapper table(_memory, entries[i], _table_registry, _heap);
if (!table.valid()) {
Genode::error("ignoring table '", table.name(),
@@ -1398,7 +1425,7 @@ class Acpi_table
log("Found IVRS");
Ivrs ivrs(reinterpret_cast(table->signature));
- ivrs.parse(alloc);
+ ivrs.parse(_heap);
}
if (table.is_facp()) {
@@ -1414,6 +1441,10 @@ class Acpi_table
_reset_info.construct(Reset_info { .io_port = reset_io_port,
.value = reset_value });
}
+ if (fadt.sci_int_valid()) {
+ _sci_int = fadt.read();
+ _sci_int_valid = true;
+ }
}
if (table.is_searched()) {
@@ -1421,23 +1452,23 @@ class Acpi_table
if (verbose)
Genode::log("Found ", table.name());
- Element::parse(alloc, table.table());
+ Element::parse(_heap, table.table());
}
if (table.is_madt()) {
Genode::log("Found MADT");
- table.parse_madt(alloc);
+ table.parse_madt(_heap);
}
if (table.is_mcfg()) {
Genode::log("Found MCFG");
- table.parse_mcfg(alloc);
+ table.parse_mcfg(_heap);
}
if (table.is_dmar()) {
Genode::log("Found DMAR");
- table.parse_dmar(alloc);
+ table.parse_dmar(_heap);
}
} catch (Acpi::Memory::Unsupported_range &) { }
@@ -1445,7 +1476,7 @@ class Acpi_table
continue;
try {
- Table_wrapper table(_memory, dsdt);
+ Table_wrapper table(_memory, dsdt, _table_registry, _heap);
if (!table.valid()) {
Genode::error("ignoring table '", table.name(),
@@ -1456,7 +1487,7 @@ class Acpi_table
if (verbose)
Genode::log("Found dsdt ", table.name());
- Element::parse(alloc, table.table());
+ Element::parse(_heap, table.table());
}
} catch (Acpi::Memory::Unsupported_range &) { }
}
@@ -1465,8 +1496,8 @@ class Acpi_table
public:
- Acpi_table(Genode::Env &env, Genode::Allocator &alloc)
- : _env(env), _alloc(alloc), _memory(_env, _alloc)
+ Acpi_table(Genode::Env &env, Genode::Allocator &heap)
+ : _env(env), _heap(heap), _memory(_env, _heap)
{
addr_t rsdt = 0, xsdt = 0;
uint8_t acpi_revision = 0;
@@ -1514,33 +1545,43 @@ class Acpi_table
if (acpi_revision != 0 && xsdt && sizeof(addr_t) != sizeof(uint32_t)) {
/* running 64bit and xsdt is valid */
- Table_wrapper table(_memory, xsdt);
+ Table_wrapper table(_memory, xsdt, _table_registry, _heap);
if (!table.valid()) throw -1;
uint64_t * entries = reinterpret_cast(table.table() + 1);
- _parse_tables(alloc, entries, table.entry_count(entries));
+ _parse_tables(entries, table.entry_count(entries));
Genode::log("XSDT ", *table.table());
} else {
/* running (32bit) or (64bit and xsdt isn't valid) */
- Table_wrapper table(_memory, rsdt);
+ Table_wrapper table(_memory, rsdt, _table_registry, _heap);
if (!table.valid()) throw -1;
uint32_t * entries = reinterpret_cast(table.table() + 1);
- _parse_tables(alloc, entries, table.entry_count(entries));
+ _parse_tables(entries, table.entry_count(entries));
Genode::log("RSDT ", *table.table());
}
/* free up memory of elements not of any use */
- Element::clean_list(alloc);
+ Element::clean_list(_heap);
/* free up io memory */
_memory.free_io_memory();
}
- void generate_reset_info(Xml_generator &xml) const
+ ~Acpi_table()
{
+ _table_registry.for_each([&] (Table_wrapper::Info &info) {
+ destroy(_heap, &info);
+ });
+ }
+
+ void generate_info(Xml_generator &xml) const
+ {
+ if (_sci_int_valid)
+ xml.node("sci_int", [&] () { xml.attribute("irq", _sci_int); });
+
if (!_reset_info.constructed())
return;
@@ -1548,6 +1589,15 @@ class Acpi_table
xml.attribute("io_port", String<32>(Hex(_reset_info->io_port)));
xml.attribute("value", _reset_info->value);
});
+
+ Registry const ® = _table_registry;
+ reg.for_each([&] (Table_wrapper::Info const &info) {
+ xml.node("table", [&] {
+ xml.attribute("name", info.name);
+ xml.attribute("addr", String<20>(Hex(info.addr)));
+ xml.attribute("size", info.size);
+ });
+ });
}
};
@@ -1570,7 +1620,7 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc)
acpi.generate([&] (Genode::Xml_generator &xml) {
- acpi_table.generate_reset_info(xml);
+ acpi_table.generate_info(xml);
if (root_bridge_bdf != INVALID_ROOT_BRIDGE) {
xml.node("root_bridge", [&] () {