feat(ACPI): Add rudimentary ACPI support
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user