mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 17:40:27 +00:00
428afca32b
Most of the ACPI static parsing methods (methods that can be called without initializing a full AML parser) are not tied to any specific platform or CPU architecture. The only method that is platform-specific is the one that finds the RSDP structure. Thus, each CPU architecture/platform needs to implement it. This means that now aarch64 can implement its own method to find the ACPI RSDP structure, which would be hooked into the rest of the ACPI code elegantly, but for now I just added a FIXME and that method returns empty value of Optional<PhysicalAddress>.
69 lines
2.7 KiB
C++
69 lines
2.7 KiB
C++
/*
|
|
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/Firmware/ACPI/Definitions.h>
|
|
#include <Kernel/Firmware/ACPI/StaticParsing.h>
|
|
#include <Kernel/Library/StdLib.h>
|
|
#include <Kernel/Memory/TypedMapping.h>
|
|
|
|
namespace Kernel::ACPI::StaticParsing {
|
|
|
|
static bool match_table_signature(PhysicalAddress table_header, StringView signature)
|
|
{
|
|
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
|
|
VERIFY(signature.length() == 4);
|
|
|
|
auto table = Memory::map_typed<Structures::RSDT>(table_header).release_value_but_fixme_should_propagate_errors();
|
|
return !strncmp(table->h.sig, signature.characters_without_null_termination(), 4);
|
|
}
|
|
|
|
ErrorOr<Optional<PhysicalAddress>> search_table_in_xsdt(PhysicalAddress xsdt_address, StringView signature)
|
|
{
|
|
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
|
|
VERIFY(signature.length() == 4);
|
|
|
|
auto xsdt = TRY(Memory::map_typed<Structures::XSDT>(xsdt_address));
|
|
|
|
for (size_t i = 0; i < ((xsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u64)); ++i) {
|
|
if (match_table_signature(PhysicalAddress((PhysicalPtr)xsdt->table_ptrs[i]), signature))
|
|
return PhysicalAddress((PhysicalPtr)xsdt->table_ptrs[i]);
|
|
}
|
|
return Optional<PhysicalAddress> {};
|
|
}
|
|
|
|
ErrorOr<Optional<PhysicalAddress>> find_table(PhysicalAddress rsdp_address, StringView signature)
|
|
{
|
|
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
|
|
VERIFY(signature.length() == 4);
|
|
|
|
auto rsdp = TRY(Memory::map_typed<Structures::RSDPDescriptor20>(rsdp_address));
|
|
|
|
if (rsdp->base.revision == 0)
|
|
return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature);
|
|
|
|
if (rsdp->base.revision >= 2) {
|
|
if (rsdp->xsdt_ptr)
|
|
return search_table_in_xsdt(PhysicalAddress(rsdp->xsdt_ptr), signature);
|
|
return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature);
|
|
}
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
|
|
ErrorOr<Optional<PhysicalAddress>> search_table_in_rsdt(PhysicalAddress rsdt_address, StringView signature)
|
|
{
|
|
// FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables.
|
|
VERIFY(signature.length() == 4);
|
|
|
|
auto rsdt = TRY(Memory::map_typed<Structures::RSDT>(rsdt_address));
|
|
|
|
for (u32 i = 0; i < ((rsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u32)); i++) {
|
|
if (match_table_signature(PhysicalAddress((PhysicalPtr)rsdt->table_ptrs[i]), signature))
|
|
return PhysicalAddress((PhysicalPtr)rsdt->table_ptrs[i]);
|
|
}
|
|
return Optional<PhysicalAddress> {};
|
|
}
|
|
|
|
}
|