diff --git a/src/kernel/acpi_tables.h b/src/kernel/acpi_tables.h index 100e9b3..806315f 100644 --- a/src/kernel/acpi_tables.h +++ b/src/kernel/acpi_tables.h @@ -23,7 +23,7 @@ struct acpi_table_header } __attribute__ ((packed)); #define TABLE_HEADER(signature) \ - static const uint32_t type_id = kutil::byteswap(signature); \ + static constexpr uint32_t type_id = kutil::byteswap(signature); \ acpi_table_header header; diff --git a/src/kernel/device_manager.cpp b/src/kernel/device_manager.cpp index 7a3887a..19e4939 100644 --- a/src/kernel/device_manager.cpp +++ b/src/kernel/device_manager.cpp @@ -38,7 +38,7 @@ struct acpi2_rsdp uint32_t rsdt_address; uint32_t length; - uint64_t xsdt_address; + acpi_table_header *xsdt_address; uint8_t checksum20; uint8_t reserved[3]; } __attribute__ ((packed)); @@ -73,13 +73,20 @@ device_manager::device_manager() : m_irqs[2] = ignore_endpoint; } +template static const T * +check_get_table(const acpi_table_header *header) +{ + kassert(header && header->validate(T::type_id), "Invalid ACPI table."); + return reinterpret_cast(header); +} + void device_manager::parse_acpi(const void *root_table) { kassert(root_table != 0, "ACPI root table pointer is null."); - const acpi1_rsdp *acpi1 = - reinterpret_cast(root_table); + const acpi1_rsdp *acpi1 = memory::to_virtual( + reinterpret_cast(root_table)); for (int i = 0; i < sizeof(acpi1->signature); ++i) kassert(acpi1->signature[i] == expected_signature[i], @@ -96,7 +103,7 @@ device_manager::parse_acpi(const void *root_table) sum = kutil::checksum(acpi2, sizeof(acpi2_rsdp), sizeof(acpi1_rsdp)); kassert(sum == 0, "ACPI 2.0 RSDP checksum mismatch."); - load_xsdt(reinterpret_cast(acpi2->xsdt_address)); + load_xsdt(memory::to_virtual(acpi2->xsdt_address)); } ioapic * @@ -112,9 +119,9 @@ put_sig(char *into, uint32_t type) } void -device_manager::load_xsdt(const acpi_xsdt *xsdt) +device_manager::load_xsdt(const acpi_table_header *header) { - kassert(xsdt && acpi_validate(xsdt), "Invalid ACPI XSDT."); + const auto *xsdt = check_get_table(header); char sig[5] = {0,0,0,0,0}; log::info(logs::device, "ACPI 2.0+ tables loading"); @@ -124,7 +131,8 @@ device_manager::load_xsdt(const acpi_xsdt *xsdt) size_t num_tables = acpi_table_entries(xsdt, sizeof(void*)); for (size_t i = 0; i < num_tables; ++i) { - const acpi_table_header *header = xsdt->headers[i]; + const acpi_table_header *header = + memory::to_virtual(xsdt->headers[i]); put_sig(sig, header->type); log::debug(logs::device, " Found table %s", sig); @@ -133,15 +141,15 @@ device_manager::load_xsdt(const acpi_xsdt *xsdt) switch (header->type) { case acpi_apic::type_id: - load_apic(reinterpret_cast(header)); + load_apic(header); break; case acpi_mcfg::type_id: - load_mcfg(reinterpret_cast(header)); + load_mcfg(header); break; case acpi_hpet::type_id: - load_hpet(reinterpret_cast(header)); + load_hpet(header); break; default: @@ -151,8 +159,10 @@ device_manager::load_xsdt(const acpi_xsdt *xsdt) } void -device_manager::load_apic(const acpi_apic *apic) +device_manager::load_apic(const acpi_table_header *header) { + const auto *apic = check_get_table(header); + uintptr_t local = apic->local_address; m_lapic = new lapic(local, isr::isrSpurious); @@ -249,8 +259,10 @@ device_manager::load_apic(const acpi_apic *apic) } void -device_manager::load_mcfg(const acpi_mcfg *mcfg) +device_manager::load_mcfg(const acpi_table_header *header) { + const auto *mcfg = check_get_table(header); + size_t count = acpi_table_entries(mcfg, sizeof(acpi_mcfg_entry)); m_pci.set_size(count); m_devices.set_capacity(16); @@ -271,8 +283,10 @@ device_manager::load_mcfg(const acpi_mcfg *mcfg) } void -device_manager::load_hpet(const acpi_hpet *hpet) +device_manager::load_hpet(const acpi_table_header *header) { + const auto *hpet = check_get_table(header); + log::debug(logs::device, " Found HPET device #%3d: base %016lx pmin %d attr %02x", hpet->index, hpet->base_address.address, hpet->periodic_min, hpet->attributes); diff --git a/src/kernel/device_manager.h b/src/kernel/device_manager.h index f5b412f..d18c670 100644 --- a/src/kernel/device_manager.h +++ b/src/kernel/device_manager.h @@ -6,10 +6,7 @@ #include "hpet.h" #include "pci.h" -struct acpi_xsdt; -struct acpi_apic; -struct acpi_mcfg; -struct acpi_hpet; +struct acpi_table_header; class block_device; class endpoint; @@ -100,19 +97,19 @@ public: private: /// Parse the ACPI XSDT and load relevant sub-tables. /// \arg xsdt Pointer to the XSDT from the firmware - void load_xsdt(const acpi_xsdt *xsdt); + void load_xsdt(const acpi_table_header *xsdt); /// Parse the ACPI MADT and initialize APICs from it. /// \arg apic Pointer to the MADT from the XSDT - void load_apic(const acpi_apic *apic); + void load_apic(const acpi_table_header *apic); /// Parse the ACPI MCFG and initialize PCIe from it. /// \arg mcfg Pointer to the MCFG from the XSDT - void load_mcfg(const acpi_mcfg *mcfg); + void load_mcfg(const acpi_table_header *mcfg); /// Parse the ACPI HPET and initialize an HPET from it. /// \arg hpet Pointer to the HPET from the XSDT - void load_hpet(const acpi_hpet *hpet); + void load_hpet(const acpi_table_header *hpet); /// Probe the PCIe busses and add found devices to our /// device list. The device list is destroyed and rebuilt.