acpi_drv: report IOAPIC devices

genodelabs/genode#5066
This commit is contained in:
Johannes Schlatow
2024-03-20 13:45:59 +01:00
committed by Christian Helmuth
parent 811e51a24e
commit 54153be983

View File

@@ -42,13 +42,11 @@ static const bool verbose = false;
*/ */
struct Apic_struct struct Apic_struct
{ {
enum Types { SRC_OVERRIDE = 2 }; enum Types { IOAPIC = 1, SRC_OVERRIDE = 2 };
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
bool is_override() { return type == SRC_OVERRIDE; }
Apic_struct *next() { return reinterpret_cast<Apic_struct *>((uint8_t *)this + length); } Apic_struct *next() { return reinterpret_cast<Apic_struct *>((uint8_t *)this + length); }
} __attribute__((packed)); } __attribute__((packed));
@@ -75,6 +73,15 @@ struct Apic_override : Apic_struct
uint16_t flags; uint16_t flags;
} __attribute__((packed)); } __attribute__((packed));
/* ACPI spec 5.2.12.3 */
struct Apic_ioapic : Apic_struct
{
uint8_t id;
uint8_t reserved;
uint32_t addr;
uint32_t base_irq;
} __attribute__((packed));
struct Dmar_struct_header; struct Dmar_struct_header;
/* ACPI spec 5.2.6 */ /* ACPI spec 5.2.6 */
@@ -169,6 +176,7 @@ struct Device_scope : Genode::Mmio<0x6>
struct Type : Register<0x0, 8> { enum { PCI_END_POINT = 0x1 }; }; struct Type : Register<0x0, 8> { enum { PCI_END_POINT = 0x1 }; };
struct Length : Register<0x1, 8> { }; struct Length : Register<0x1, 8> { };
struct Id : Register<0x4, 8> { };
struct Bus : Register<0x5, 8> { }; struct Bus : Register<0x5, 8> { };
struct Path : Genode::Mmio<0x2> struct Path : Genode::Mmio<0x2>
@@ -406,6 +414,34 @@ class Irq_override : public List<Irq_override>::Element
}; };
/**
* List that holds IOAPIC information
*/
class Ioapic : public List<Ioapic>::Element
{
private:
uint8_t _id; /* I/O APIC id */
uint32_t _addr; /* physical address */
uint32_t _base_irq; /* base irq number */
public:
Ioapic(uint8_t id, uint32_t addr, uint32_t base)
: _id(id), _addr(addr), _base_irq(base) { }
static List<Ioapic> *list()
{
static List<Ioapic> _list;
return &_list;
}
uint8_t id() const { return _id; }
uint32_t addr() const { return _addr; }
uint32_t base_irq() const { return _base_irq; }
};
/** /**
* List that holds the result of the mcfg table parsing which are pointers * List that holds the result of the mcfg table parsing which are pointers
* to the extended pci config space - 4k for each device. * to the extended pci config space - 4k for each device.
@@ -611,22 +647,37 @@ class Table_wrapper
bool is_dmar() { return _cmp("DMAR"); } bool is_dmar() { return _cmp("DMAR"); }
/** /**
* Parse override structures * Parse MADT/APIC table
*/ */
void parse_madt(Genode::Allocator &alloc) void parse_madt(Genode::Allocator &alloc)
{ {
Apic_struct *apic = _table->apic_struct(); Apic_struct *apic = _table->apic_struct();
for (; apic < _table->end(); apic = apic->next()) { for (; apic < _table->end(); apic = apic->next()) {
if (!apic->is_override()) Apic_override *o;
continue; Apic_ioapic *ioapic;
Apic_override *o = static_cast<Apic_override *>(apic); switch (apic->type) {
Genode::log("MADT IRQ ", o->irq, " -> GSI ", (unsigned)o->gsi, " " case Apic_struct::Types::SRC_OVERRIDE:
"flags: ", (unsigned)o->flags); o = static_cast<Apic_override *>(apic);
Irq_override::list()->insert(new (&alloc) Genode::log("MADT IRQ ", o->irq, " -> GSI ", (unsigned)o->gsi, " "
"flags: ", (unsigned)o->flags);
Irq_override::list()->insert(new (&alloc)
Irq_override(o->irq, o->gsi, o->flags)); Irq_override(o->irq, o->gsi, o->flags));
break;
case Apic_struct::Types::IOAPIC:
ioapic = static_cast<Apic_ioapic *>(apic);
Ioapic::list()->insert(new (&alloc)
Ioapic(ioapic->id, ioapic->addr, ioapic->base_irq));
break;
default:
break;
}
} }
} }
@@ -1672,11 +1723,21 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc,
}); });
} }
for (Ioapic *i = Ioapic::list()->first(); i; i = i->next())
{
xml.node("ioapic", [&] () {
xml.attribute("id", i->id());
xml.attribute("base_irq", i->base_irq());
attribute_hex(xml, "addr", i->addr());
});
}
/* lambda definition for scope evaluation in rmrr */ /* lambda definition for scope evaluation in rmrr */
auto func_scope = [&] (Device_scope const &scope) auto func_scope = [&] (Device_scope const &scope)
{ {
xml.node("scope", [&] () { xml.node("scope", [&] () {
xml.attribute("bus_start", scope.read<Device_scope::Bus>()); xml.attribute("bus_start", scope.read<Device_scope::Bus>());
xml.attribute("id", scope.read<Device_scope::Id>());
xml.attribute("type", scope.read<Device_scope::Type>()); xml.attribute("type", scope.read<Device_scope::Type>());
scope.for_each_path([&](auto const &path) { scope.for_each_path([&](auto const &path) {