feat(ACPI): Add rudimentary ACPI support

This commit is contained in:
Daniel Hammer
2025-05-08 19:20:19 +02:00
parent d63addfb64
commit 0874aa8784
6 changed files with 177 additions and 1 deletions
+108
View File
@@ -0,0 +1,108 @@
#include "ACPI.hpp"
#include <Terminal/Terminal.hpp>
#include <CppLib/Stream.hpp>
#include <CppLib/Vector.hpp>
#include <Libraries/String.hpp>
#include <Memory/HHDM.hpp>
using namespace Kt;
namespace Hal {
kcp::vector<const char*>* 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<CommonSDTHeader*> 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;
}
};
+46
View File
@@ -0,0 +1,46 @@
#pragma once
#include <cstdint>
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);
};
};
+12
View File
@@ -13,6 +13,8 @@
#include <Memory/PageFrameAllocator.hpp> #include <Memory/PageFrameAllocator.hpp>
#include <Common/Panic.hpp> #include <Common/Panic.hpp>
#include <initializer_list>
namespace kcp namespace kcp
{ {
template<typename T> template<typename T>
@@ -29,6 +31,16 @@ namespace kcp
array = nullptr; array = nullptr;
} }
vector(std::initializer_list<T> 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) T& operator[](std::size_t position)
{ {
if (position > (capacity - 1)) { if (position > (capacity - 1)) {
+3
View File
@@ -26,6 +26,7 @@
#include <Memory/HHDM.hpp> #include <Memory/HHDM.hpp>
#include <Io/IoPort.hpp> #include <Io/IoPort.hpp>
#include <Memory/Paging.hpp> #include <Memory/Paging.hpp>
#include <ACPI/ACPI.hpp>
using namespace Kt; using namespace Kt;
@@ -108,5 +109,7 @@ extern "C" void kmain() {
#endif #endif
Hal::ACPI g_acpi((Hal::ACPI::XSDP*)Memory::HHDM(rsdp_request.response->address));
Hal::Halt(); Hal::Halt();
} }
+1 -1
View File
@@ -16,7 +16,7 @@ namespace Memory::VMM {
void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, limine_memmap_response* memMap) { void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, limine_memmap_response* memMap) {
// Map kernel // 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) { for (std::uint64_t pageAddr = kernelBaseVirt; pageAddr < (kernelBaseVirt + kernelSize); pageAddr += 0x1000) {
Map(GetPhysKernelAddress(pageAddr), pageAddr); Map(GetPhysKernelAddress(pageAddr), pageAddr);
+7
View File
@@ -52,6 +52,13 @@ namespace {
.response = nullptr .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. // Finally, define the start and end markers for the Limine requests.