107 lines
3.8 KiB
C
107 lines
3.8 KiB
C
// Firmware root discovery for optional platform drivers.
|
|
|
|
#include <kernel/ke_firmware.h>
|
|
#include <ntlite/ddk/platform.h>
|
|
#include <ntlite/memory_map.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <kernel/ke_debug.h>
|
|
#include <string.h>
|
|
|
|
#define KI_RSDP_V1_SIZE 20u
|
|
#define KI_RSDP_V2_SIZE 36u
|
|
#define KI_RSDP_MAX_SIZE 4096u
|
|
|
|
static uint64_t gAcpiRsdpPhysical;
|
|
static const char* gAcpiRootDiagnostic = "absent";
|
|
static uint8_t gAcpiRsdpRevision;
|
|
|
|
// Firmware roots must remain in reserved memory after ExitBootServices.
|
|
static bool KiFirmwareReservedSpan(const MEMORY_MAP* map, uint64_t start, uint32_t length) {
|
|
if (!map || map->Magic != MEMORY_MAP_MAGIC ||
|
|
map->RegionCount > MEMORY_MAX_REGIONS || !length || start > UINT64_MAX - length)
|
|
return false;
|
|
uint64_t end = start + length;
|
|
for (uint32_t i = 0; i < map->RegionCount; i++) {
|
|
const MEMORY_REGION* region = &map->Regions[i];
|
|
if (region->Type != MemoryReserved ||
|
|
region->Base > UINT64_MAX - region->Length)
|
|
continue;
|
|
if (start >= region->Base && end <= region->Base + region->Length)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool KiFirmwareChecksumValid(const uint8_t* bytes, uint32_t length) {
|
|
uint8_t sum = 0;
|
|
for (uint32_t i = 0; i < length; i++) sum = (uint8_t)(sum + bytes[i]);
|
|
return sum == 0;
|
|
}
|
|
|
|
void KeFirmwareInitialize(const BOOT_INFO* bootInfo) {
|
|
gAcpiRsdpPhysical = 0;
|
|
gAcpiRsdpRevision = 0;
|
|
gAcpiRootDiagnostic = "absent";
|
|
if (!bootInfo || !bootInfo->RsdpPhysical) return;
|
|
if (!bootInfo->PhysicalMapBase ||
|
|
!KiFirmwareReservedSpan(&bootInfo->MemoryMap,
|
|
bootInfo->RsdpPhysical, KI_RSDP_V1_SIZE) ||
|
|
bootInfo->RsdpPhysical > UINTPTR_MAX - bootInfo->PhysicalMapBase) {
|
|
gAcpiRootDiagnostic = "invalid physical range";
|
|
return;
|
|
}
|
|
|
|
const uint8_t* rsdp = (const uint8_t*)(bootInfo->PhysicalMapBase + bootInfo->RsdpPhysical);
|
|
if (memcmp(rsdp, "RSD PTR ", 8) != 0) {
|
|
gAcpiRootDiagnostic = "invalid signature";
|
|
return;
|
|
}
|
|
if (!KiFirmwareChecksumValid(rsdp, KI_RSDP_V1_SIZE)) {
|
|
gAcpiRootDiagnostic = "invalid legacy checksum";
|
|
return;
|
|
}
|
|
|
|
if (rsdp[15] >= 2u) {
|
|
if (!KiFirmwareReservedSpan(&bootInfo->MemoryMap,
|
|
bootInfo->RsdpPhysical, KI_RSDP_V2_SIZE)) {
|
|
gAcpiRootDiagnostic = "truncated extended root";
|
|
return;
|
|
}
|
|
uint32_t length;
|
|
memcpy(&length, rsdp + 20, sizeof(length));
|
|
if (length < KI_RSDP_V2_SIZE || length > KI_RSDP_MAX_SIZE ||
|
|
!KiFirmwareReservedSpan(&bootInfo->MemoryMap,
|
|
bootInfo->RsdpPhysical, length)) {
|
|
gAcpiRootDiagnostic = "invalid extended length";
|
|
return;
|
|
}
|
|
if (!KiFirmwareChecksumValid(rsdp, length)) {
|
|
gAcpiRootDiagnostic = "invalid extended checksum";
|
|
return;
|
|
}
|
|
}
|
|
|
|
gAcpiRsdpPhysical = (uint64_t)bootInfo->RsdpPhysical;
|
|
gAcpiRsdpRevision = rsdp[15];
|
|
gAcpiRootDiagnostic = "valid";
|
|
}
|
|
|
|
// A driver chooses its own ACPI interpreter and maps tables through the DDK.
|
|
__declspec(dllexport) KSTATUS KeFirmwareQueryAcpiRsdp(uint64_t* physicalAddressOut) {
|
|
if (!physicalAddressOut) return NTLSTATUS_INVALID_PARAMETER;
|
|
*physicalAddressOut = 0;
|
|
if (!gAcpiRsdpPhysical) return NTLSTATUS_NOT_SUPPORTED;
|
|
*physicalAddressOut = gAcpiRsdpPhysical;
|
|
return NTLSTATUS_SUCCESS;
|
|
}
|
|
|
|
// Reports the firmware handoff state through the normal kernel diagnostic stream.
|
|
void KeFirmwareLog(void) {
|
|
DbgPrint("firmware: ACPI RSDP %s phys=0x%016llX revision=%u\n",
|
|
gAcpiRootDiagnostic,
|
|
(unsigned long long)gAcpiRsdpPhysical,
|
|
(unsigned)gAcpiRsdpRevision);
|
|
}
|