diff options
Diffstat (limited to 'dev/kernel/src/ACPIFactoryInterface.cc')
| -rw-r--r-- | dev/kernel/src/ACPIFactoryInterface.cc | 172 |
1 files changed, 79 insertions, 93 deletions
diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index b85d6ab3..a76caff2 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -1,101 +1,87 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include <modules/ACPI/ACPIFactoryInterface.h> -#include <NewKit/KString.h> #include <ArchKit/ArchKit.h> #include <KernelKit/MemoryMgr.h> +#include <NewKit/KString.h> +#include <modules/ACPI/ACPIFactoryInterface.h> + +namespace Kernel { +/// @brief Finds a descriptor table inside ACPI XSDT. +ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) { + MUST_PASS(this->fRsdp); + + if (!signature) return ErrorOr<voidPtr>{-1}; + + if (*signature == 0) return ErrorOr<voidPtr>{-1}; + + RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp); + + if (rsp_ptr->Revision <= 1) return ErrorOr<voidPtr>{-1}; + + RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress); + + Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64); + + /*** + crucial to avoid underflows. + */ + if (num < 1) { + /// stop here, we should have entries... + ke_panic(RUNTIME_CHECK_ACPI); + return ErrorOr<voidPtr>{-1}; + } + + this->fEntries = num; + + (Void)(kout << "ACPI: Number of entries: " << number(this->fEntries) << kendl); + (Void)(kout << "ACPI: Revision: " << number(xsdt->Revision) << kendl); + (Void)(kout << "ACPI: Signature: " << xsdt->Signature << kendl); + (Void)(kout << "ACPI: Address of XSDT: " << hex_number((UIntPtr) xsdt) << kendl); + + const short cAcpiSignatureLength = 4; + + for (Size index = 0; index < this->fEntries; ++index) { + SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]); + + (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); + (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); + + for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) { + if (sdt->Signature[signature_index] != signature[signature_index]) break; + + if (signature_index == (cAcpiSignatureLength - 1)) { + (Void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl); + (Void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl); + return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index])); + } + } + } + + return ErrorOr<voidPtr>{-1}; +} + +/*** +@brief Checksum on SDT header. +@param checksum the header to checksum +@param len the length of it. +*/ +bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) { + if (len == 0) return 1; + + char chr = 0; + + for (int index = 0; index < len; ++index) { + chr += checksum[index]; + } + + return chr == 0; +} -namespace Kernel -{ - /// @brief Finds a descriptor table inside ACPI XSDT. - ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) - { - MUST_PASS(this->fRsdp); - - if (!signature) - return ErrorOr<voidPtr>{-1}; - - if (*signature == 0) - return ErrorOr<voidPtr>{-1}; - - RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp); - - if (rsp_ptr->Revision <= 1) - return ErrorOr<voidPtr>{-1}; - - RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress); - - Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64); - - /*** - crucial to avoid underflows. - */ - if (num < 1) - { - /// stop here, we should have entries... - ke_panic(RUNTIME_CHECK_ACPI); - return ErrorOr<voidPtr>{-1}; - } - - this->fEntries = num; - - (void)(kout << "ACPI: Number of entries: " << number(this->fEntries) << kendl); - (void)(kout << "ACPI: Revision: " << number(xsdt->Revision) << kendl); - (void)(kout << "ACPI: Signature: " << xsdt->Signature << kendl); - (void)(kout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << kendl); - - const short cAcpiSignatureLength = 4; - - for (Size index = 0; index < this->fEntries; ++index) - { - SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]); - - (void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); - (void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); - - for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) - { - if (sdt->Signature[signature_index] != signature[signature_index]) - break; - - if (signature_index == (cAcpiSignatureLength - 1)) - { - (void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl); - (void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl); - return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index])); - } - } - } - - return ErrorOr<voidPtr>{-1}; - } - - /*** - @brief Checksum on SDT header. - @param checksum the header to checksum - @param len the length of it. - */ - bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) - { - if (len == 0) - return 1; - - char chr = 0; - - for (int index = 0; index < len; ++index) - { - chr += checksum[index]; - } - - return chr == 0; - } - - ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature) - { - return this->Find(signature); - } -} // namespace Kernel +ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature) { + return this->Find(signature); +} +} // namespace Kernel |
