Kernel/core/acpi.cpp
2024-02-29 00:28:34 +02:00

208 lines
6.4 KiB
C++

/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <acpi.hpp>
#include <debug.h>
#include <io.h>
#include "../kernel.h"
namespace ACPI
{
__no_sanitize("alignment") void *ACPI::FindTable(ACPI::ACPIHeader *ACPIHeader, char *Signature)
{
for (uint64_t t = 0; t < ((ACPIHeader->Length - sizeof(ACPI::ACPIHeader)) / (XSDTSupported ? 8 : 4)); t++)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
// TODO: Should I be concerned about unaligned memory access?
ACPI::ACPIHeader *SDTHdr = nullptr;
if (XSDTSupported)
SDTHdr = (ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 8)));
else
SDTHdr = (ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 4)));
#pragma GCC diagnostic pop
size_t signLength = strlen(Signature);
for (size_t i = 0; i < signLength; i++)
{
if (SDTHdr->Signature[i] != Signature[i])
break;
if (i == 3)
{
#ifdef DEBUG
KPrint("ACPI: %.4s [%.6s:%.8s] found at address %#lx",
Signature,
SDTHdr->OEMID,
SDTHdr->OEMTableID,
(uintptr_t)SDTHdr);
#endif
trace("%s found at address %#lx", Signature, (uintptr_t)SDTHdr);
Tables[Signature] = SDTHdr;
return SDTHdr;
}
}
}
// warn("%s not found!", Signature);
return nullptr;
}
void ACPI::SearchTables(ACPIHeader *Header)
{
if (!Header)
return;
HPET = (HPETHeader *)FindTable(Header, (char *)"HPET");
FADT = (FADTHeader *)FindTable(Header, (char *)"FACP");
MCFG = (MCFGHeader *)FindTable(Header, (char *)"MCFG");
BGRT = (BGRTHeader *)FindTable(Header, (char *)"BGRT");
SRAT = (SRATHeader *)FindTable(Header, (char *)"SRAT");
TPM2 = (TPM2Header *)FindTable(Header, (char *)"TPM2");
TCPA = (TCPAHeader *)FindTable(Header, (char *)"TCPA");
WAET = (WAETHeader *)FindTable(Header, (char *)"WAET");
MADT = (MADTHeader *)FindTable(Header, (char *)"APIC");
HEST = (HESTHeader *)FindTable(Header, (char *)"HEST");
SSDT = (SSDTHeader *)FindTable(Header, (char *)"SSDT");
DBGP = (DBGPHeader *)FindTable(Header, (char *)"DBGP");
DBG2 = (DBG2Header *)FindTable(Header, (char *)"DBG2");
FindTable(Header, (char *)"BERT");
FindTable(Header, (char *)"CPEP");
FindTable(Header, (char *)"DSDT");
FindTable(Header, (char *)"ECDT");
FindTable(Header, (char *)"EINJ");
FindTable(Header, (char *)"ERST");
FindTable(Header, (char *)"FACS");
FindTable(Header, (char *)"MSCT");
FindTable(Header, (char *)"MPST");
FindTable(Header, (char *)"OEMx");
FindTable(Header, (char *)"PMTT");
FindTable(Header, (char *)"PSDT");
FindTable(Header, (char *)"RASF");
FindTable(Header, (char *)"RSDT");
FindTable(Header, (char *)"SBST");
FindTable(Header, (char *)"SLIT");
FindTable(Header, (char *)"XSDT");
FindTable(Header, (char *)"DRTM");
FindTable(Header, (char *)"FPDT");
FindTable(Header, (char *)"GTDT");
FindTable(Header, (char *)"PCCT");
FindTable(Header, (char *)"S3PT");
FindTable(Header, (char *)"MATR");
FindTable(Header, (char *)"MSDM");
FindTable(Header, (char *)"WPBT");
FindTable(Header, (char *)"OSDT");
FindTable(Header, (char *)"RSDP");
FindTable(Header, (char *)"NFIT");
FindTable(Header, (char *)"ASF!");
FindTable(Header, (char *)"BOOT");
FindTable(Header, (char *)"CSRT");
FindTable(Header, (char *)"BDAT");
FindTable(Header, (char *)"CDAT");
FindTable(Header, (char *)"DMAR");
FindTable(Header, (char *)"IBFT");
FindTable(Header, (char *)"IORT");
FindTable(Header, (char *)"IVRS");
FindTable(Header, (char *)"LPIT");
FindTable(Header, (char *)"MCHI");
FindTable(Header, (char *)"MTMR");
FindTable(Header, (char *)"SLIC");
FindTable(Header, (char *)"SPCR");
FindTable(Header, (char *)"SPMI");
FindTable(Header, (char *)"UEFI");
FindTable(Header, (char *)"VRTC");
FindTable(Header, (char *)"WDAT");
FindTable(Header, (char *)"WDDT");
FindTable(Header, (char *)"WDRT");
FindTable(Header, (char *)"ATKG");
FindTable(Header, (char *)"GSCI");
FindTable(Header, (char *)"IEIT");
FindTable(Header, (char *)"HMAT");
FindTable(Header, (char *)"CEDT");
FindTable(Header, (char *)"AEST");
FindTable(Header, (char *)"AGDI");
FindTable(Header, (char *)"APMT");
FindTable(Header, (char *)"ETDT");
FindTable(Header, (char *)"MPAM");
FindTable(Header, (char *)"PDTT");
FindTable(Header, (char *)"PPTT");
FindTable(Header, (char *)"RAS2");
FindTable(Header, (char *)"SDEI");
FindTable(Header, (char *)"STAO");
FindTable(Header, (char *)"XENV");
FindTable(Header, (char *)"PHAT");
FindTable(Header, (char *)"SVKL");
FindTable(Header, (char *)"UUID");
FindTable(Header, (char *)"CCEL");
FindTable(Header, (char *)"WSMT");
FindTable(Header, (char *)"PRMT");
FindTable(Header, (char *)"NBFT");
FindTable(Header, (char *)"RSD PTR");
FindTable(Header, (char *)"TDX");
FindTable(Header, (char *)"CXL");
FindTable(Header, (char *)"DSD");
FindTable(Header, (char *)"BSA");
}
ACPI::ACPI()
{
trace("Initializing ACPI");
if (!bInfo.RSDP)
{
error("RSDP not found!");
return;
}
if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress)
{
debug("XSDT supported");
XSDTSupported = true;
XSDT = (ACPIHeader *)(bInfo.RSDP->XSDTAddress);
}
else
{
debug("RSDT supported");
XSDT = (ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress;
}
if (!Memory::Virtual().Check(XSDT))
{
warn("%s is not mapped!",
XSDTSupported ? "XSDT" : "RSDT");
debug("XSDT: %p", XSDT);
Memory::Virtual().Map(XSDT, XSDT, Memory::RW);
}
this->SearchTables(XSDT);
if (FADT)
{
outb(s_cst(uint16_t, FADT->SMI_CommandPort), FADT->AcpiEnable);
/* TODO: Sleep for ~5 seconds before polling PM1a CB? */
while (!(inw(s_cst(uint16_t, FADT->PM1aControlBlock)) & 1))
CPU::Pause();
}
}
ACPI::~ACPI()
{
}
}