diff --git a/kernel/src/ACPI/ACPI.cpp b/kernel/src/ACPI/ACPI.cpp new file mode 100644 index 0000000..db67dbb --- /dev/null +++ b/kernel/src/ACPI/ACPI.cpp @@ -0,0 +1,108 @@ +#include "ACPI.hpp" +#include +#include +#include +#include +#include + +using namespace Kt; + +namespace Hal { + kcp::vector* ACPITables; + + bool ACPI::XSDP::TestChecksum() { + std::uint8_t sum = 0; + + for (std::size_t i = 0; i < this->Length; i++) { + sum += ((char*)this)[i]; + } + + return sum == 0; + } + + bool ACPI::TestChecksum(ACPI::CommonSDTHeader* header) { + std::uint8_t sum = 0; + + for (std::size_t i = 0; i < header->Length; i++) { + sum += ((char*)header)[i]; + } + + return sum == 0; + } + + const char* ACPI::XSDP::GetOEMID() { + kcp::cstringstream oemIdStream{}; + + oemIdStream << this->OEMID[0] + << this->OEMID[1] + << this->OEMID[2] + << this->OEMID[3] + << this->OEMID[4] + << this->OEMID[5]; + + return oemIdStream.c_str(); + } + + void ACPI::HandleXSDT(CommonSDTHeader* sdtHeader) { + auto length = sdtHeader->Length; + auto entryCount = (sdtHeader->Length - sizeof(CommonSDTHeader)) / 8; + + kcp::vector discoveredTables{}; + auto currentTable = sdtHeader; + } + + void ACPI::HandleRSDT(CommonSDTHeader* sdtHeader) { + KernelLogStream(ERROR, "ACPI") << "Unimplemented - HandleRSDT"; + } + + ACPI::ACPI(XSDP* xsdp) { + ACPITables = new kcp::vector({ + "APIC", + "BERT", + "CPEP", + "DSDT", + "ECDT", + "EINJ", + "ERST", + "FACP", + "FACS", + "HEST", + "MSCT", + "MPST", + "OEM", + "PMTT", + "PSDT", + "RASF", + "SBST", + "SLIT", + "SRAT", + "SSDT" + } + ); + + if (xsdp->TestChecksum() != true) { + KernelLogStream(ERROR, "ACPI") << "Checksum failed for (R/X)SDT!"; + return; + } + + KernelLogStream(OK, "ACPI") << "Checksum passed for (R/X)SDT!"; + + + KernelLogStream(INFO, "ACPI") << "OEM ID: " << xsdp->GetOEMID(); + KernelLogStream(INFO, "ACPI") << "ACPI version: " << xsdp->Revision; + + std::uint64_t nextTableAddress; + + if (xsdp->Revision >= 2) { + nextTableAddress = xsdp->XSDTAddress; + HandleXSDT((CommonSDTHeader*)Memory::HHDM(nextTableAddress)); + } + else + { + nextTableAddress = xsdp->RSDTAddress; + HandleRSDT((CommonSDTHeader*)Memory::HHDM(nextTableAddress)); + } + + // KernelLogStream(DEBUG, "ACPI") << nextTableType.c_str() << " located at 0x" << base::hex << nextTableAddress; + } +}; \ No newline at end of file diff --git a/kernel/src/ACPI/ACPI.hpp b/kernel/src/ACPI/ACPI.hpp new file mode 100644 index 0000000..ad61e1c --- /dev/null +++ b/kernel/src/ACPI/ACPI.hpp @@ -0,0 +1,46 @@ +#pragma once +#include + +namespace Hal { + class ACPI { + + public: + struct XSDP { + char Signature[8]; + std::uint8_t Checksum; + char OEMID[6]; + std::uint8_t Revision; + std::uint32_t RSDTAddress; // Deprecated(!) + + // Xtended values + std::uint32_t Length; + std::uint64_t XSDTAddress; + std::uint8_t ExtendedChecksum; + std::uint8_t Reserved[3]; + + bool TestChecksum(); + const char* GetOEMID(); + }__attribute__((packed)); + + struct CommonSDTHeader { + char Signature[4]; + std::uint32_t Length; + std::uint8_t Revision; + std::uint8_t Checksum; + char OEMID[6]; + char OEMTableID[8]; + std::uint32_t OEMRevision; + std::uint32_t CreatorID; + std::uint32_t CreatorRevision; + }__attribute__((packed)); + + ACPI(XSDP* xsdp); + + void HandleXSDT(CommonSDTHeader* sdtHeader); + void HandleRSDT(CommonSDTHeader* sdtHeader); + + static bool TestChecksum(CommonSDTHeader* header); + + CommonSDTHeader* FindNextTable(CommonSDTHeader* table); + }; +}; \ No newline at end of file diff --git a/kernel/src/CppLib/Vector.hpp b/kernel/src/CppLib/Vector.hpp index 3188084..4ea4750 100644 --- a/kernel/src/CppLib/Vector.hpp +++ b/kernel/src/CppLib/Vector.hpp @@ -13,6 +13,8 @@ #include #include +#include + namespace kcp { template @@ -29,6 +31,16 @@ namespace kcp array = nullptr; } + vector(std::initializer_list initList) { + sz = 0; + array = nullptr; + + for (auto itr = initList.begin(); itr != initList.end(); itr++) { + T item = *itr; + push_back(item); + } + } + T& operator[](std::size_t position) { if (position > (capacity - 1)) { diff --git a/kernel/src/Main.cpp b/kernel/src/Main.cpp index 483c3fd..fc00b0e 100644 --- a/kernel/src/Main.cpp +++ b/kernel/src/Main.cpp @@ -26,6 +26,7 @@ #include #include #include +#include using namespace Kt; @@ -108,5 +109,7 @@ extern "C" void kmain() { #endif + Hal::ACPI g_acpi((Hal::ACPI::XSDP*)Memory::HHDM(rsdp_request.response->address)); + Hal::Halt(); } diff --git a/kernel/src/Memory/Paging.cpp b/kernel/src/Memory/Paging.cpp index 1a080ea..8e03b84 100644 --- a/kernel/src/Memory/Paging.cpp +++ b/kernel/src/Memory/Paging.cpp @@ -16,7 +16,7 @@ namespace Memory::VMM { void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, limine_memmap_response* memMap) { // Map kernel - Kt::KernelLogStream(Kt::DEBUG, "VMM") << "Paging::Init called with kernelBaseVirt as 0x" << base::hex << kernelBaseVirt << " and kernelSize as " << base::dec << kernelSize; + Kt::KernelLogStream(Kt::DEBUG, "VMM") << "Paging::Init called with kernelBaseVirt as 0x" << base::hex << kernelBaseVirt; for (std::uint64_t pageAddr = kernelBaseVirt; pageAddr < (kernelBaseVirt + kernelSize); pageAddr += 0x1000) { Map(GetPhysKernelAddress(pageAddr), pageAddr); diff --git a/kernel/src/Platform/Limine.hpp b/kernel/src/Platform/Limine.hpp index 1ab925e..cd0dad4 100644 --- a/kernel/src/Platform/Limine.hpp +++ b/kernel/src/Platform/Limine.hpp @@ -52,6 +52,13 @@ namespace { .response = nullptr }; + __attribute__((used, section(".limine_requests"))) + volatile limine_rsdp_request rsdp_request = { + .id = LIMINE_RSDP_REQUEST, + .revision = 0, + .response = nullptr + }; + } // Finally, define the start and end markers for the Limine requests.