RSDT read and controlled

This commit is contained in:
Adrien Bourmault 2020-02-03 17:43:05 +01:00
parent d79161c645
commit fc83361d81
3 changed files with 118 additions and 62 deletions

View File

@ -73,8 +73,7 @@ struct SDTHeader {
//----------------------------------------------------------------------------//
void IoTestAcpi(void);
RSDPDescriptor *IoFindRSDP(void);
void IoInitAcpi(void);
//----------------------------------------------------------------------------//

View File

@ -82,7 +82,7 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
IoEnableKeyb();
// ACPI
IoTestAcpi();
IoInitAcpi();
// Scheduler
PsInitSched();

View File

@ -27,8 +27,14 @@
#include <io/acpi.h>
#include <mm/paging.h>
SDTHeader *AcpiSDHeader = NULL;
SDTHeader *AcpiSDT = NULL;
SDTHeader *AcpiFADT = NULL;
char IoACPIVersion = 1;
//
// Returns the checksum of the given structure
//
static inline char DoChecksum(void *ptr, size_t size,
size_t intermediateSize, ulong reason)
{
@ -41,64 +47,10 @@ static inline char DoChecksum(void *ptr, size_t size,
return checksum;
}
void IoTestAcpi(void)
{
uchar checksum = 0;
if (BtFirmwareInfo.romValid)
KernLog("\tRom Table is valid at %p\n", BtFirmwareInfo.romTable);
if (BtFirmwareInfo.apmValid)
KernLog("\tApm Table is valid at %p\n", BtFirmwareInfo.apmTable);
// FIND RSDP
RSDPDescriptor *rsdp = IoFindRSDP();
if (!rsdp)
KeStartPanic("ACPI RSDP not found in memory");
// Checksum calculation
checksum = DoChecksum(rsdp, (size_t)sizeof(RSDPDescriptor),
(size_t)sizeof(struct RSDPLegacy),
!rsdp->legacy.revision
);
if (checksum)
KeStartPanic("Invalid checksum : %d vs 0", checksum);
if (rsdp->legacy.revision == 1 || rsdp->legacy.revision >= 3)
KeStartPanic("Invalid ACPI Revision : %d", rsdp->legacy.revision);
KernLog("\tACPI Root System Table (OEM %s) Revision %d at %p\n",
rsdp->legacy.OEMID,
(uint)rsdp->legacy.revision,
rsdp->legacy.rsdtAddress
);
AcpiSDHeader = (SDTHeader *)(ulong)rsdp->legacy.rsdtAddress;
if (rsdp->legacy.revision) {
KernLog("\tFound ACPI Extended System Table (OEM %s) Revision %d at %p\n",
rsdp->legacy.OEMID,
(uint)rsdp->legacy.revision,
rsdp->xsdtAddress
);
AcpiSDHeader = (SDTHeader *)rsdp->xsdtAddress;
}
// Map the Table Header
for (ulong i = 0; i < (sizeof(AcpiSDHeader)/KPAGESIZE) + 1; i++) {
MmMapPage((void*)((ulong)(AcpiSDHeader) + i*KPAGESIZE),
(void*)((ulong)(AcpiSDHeader) + i*KPAGESIZE),
PRESENT);
}
return;
}
RSDPDescriptor *IoFindRSDP()
//
// Returns the address of the RSDP
//
static inline RSDPDescriptor *IoFindRSDP()
{
char *rsdp = NULL;
@ -141,3 +93,108 @@ RSDPDescriptor *IoFindRSDP()
return NULL;
}
//
// R/XSDT Exploration
//
static inline void IoInitRXSDT(void)
{
char checksum = 1;
SDTHeader *rxsdt = AcpiSDT;
// Map the Table Header
for (ulong i = 0; i < (sizeof(SDTHeader)/KPAGESIZE) + 1; i++) {
MmMapPage((void*)((ulong)(rxsdt) + i*KPAGESIZE),
(void*)((ulong)(rxsdt) + i*KPAGESIZE),
PRESENT);
}
// Checksum calculation
checksum = DoChecksum(rxsdt, (size_t)rxsdt->length,
0,
0
);
if (checksum)
KeStartPanic("Invalid RSDT checksum : %d vs 0", checksum);
if (IoACPIVersion == 1) {
KernLog("\tACPI Root System Table %s (%s) length %d [%p]\n",
rxsdt->signature,
rxsdt->OEMID,
rxsdt->length,
rxsdt
);
} else {
KernLog("\tACPI Extended System Table %s (%s) length %d [%p]\n",
rxsdt->signature,
rxsdt->OEMID,
rxsdt->length,
rxsdt
);
}
}
//
// RSDP Exploration
//
static inline void IoInitRSDP(void)
{
char checksum = 1;
RSDPDescriptor *rsdp = IoFindRSDP();
if (!rsdp)
KeStartPanic("ACPI RSDP not found in memory");
// Checksum calculation
checksum = DoChecksum(rsdp, (size_t)sizeof(RSDPDescriptor),
(size_t)sizeof(struct RSDPLegacy),
!rsdp->legacy.revision
);
if (checksum)
KeStartPanic("Invalid RSDP checksum : %d vs 0", checksum);
if (rsdp->legacy.revision == 1 || rsdp->legacy.revision >= 3)
KeStartPanic("Invalid ACPI Revision : %d", rsdp->legacy.revision);
KernLog("\tACPI Revision %d (OEM %s)\n",
(uint)rsdp->legacy.revision,
rsdp->legacy.OEMID
);
AcpiSDT = (void *)(ulong)rsdp->legacy.rsdtAddress;
if (rsdp->legacy.revision) {
AcpiSDT = (void *)rsdp->xsdtAddress;
IoACPIVersion = 2;
}
}
//
// Explore all ACPI Tables
//
static inline void IoSearchAcpiTables(void)
{
return;
}
//
// Initialise the ACPI by finding tables
//
void IoInitAcpi(void)
{
if (BtFirmwareInfo.romValid)
KernLog("\tRom Table is valid at %p\n", BtFirmwareInfo.romTable);
if (BtFirmwareInfo.apmValid)
KernLog("\tApm Table is valid at %p\n", BtFirmwareInfo.apmTable);
// FIND RSDP
IoInitRSDP();
IoInitRXSDT();
}