Right now I'm "parsing" ACPI tables to get hardware info.
So I have this code that loop through all the table he could find in the :
Code: Select all
#pragma pack(1)
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT64 Entry;
} XSDT_TABLE;
#pragma pack()
VOID ParsingACPITables(EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Structure, CS_BOOT_INFO *BootInfo)
{
UINT64 EntryPointer = 0;
UINT32 EntryCount = 0;
UINT64 BasePtr;
XSDT_TABLE *Xsdt = NULL;
EFI_ACPI_DESCRIPTION_HEADER *CurrentTable = NULL;
//
// If XSDT table is find, just install its tables.
// Otherwise, try to find and install the RSDT tables.
//
if (Structure->XsdtAddress)
{
Xsdt = (XSDT_TABLE *)Structure->XsdtAddress;
if (Xsdt == NULL)
{
Print(L"Invalid Xsdt! Parsing ACPi Failed!\n");
return;
}
EntryCount = (Xsdt->Header.Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
BasePtr = (UINT64)&(Xsdt->Entry);
Print(L"Got %d Table Entries, BasePtr: 0x%x\n", EntryCount, BasePtr);
for (UINTN Index = 0; Index < EntryCount; Index++)
{
CopyMem(&EntryPointer, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)EntryPointer);
if (CurrentTable != NULL)
{
//TODO: Compute the cecksum ot the table
if (IsValidTable(CurrentTable))
ParseAcpiTable(CurrentTable, BootInfo);
else
{
//TODO: Error Reporting.
}
}
else
{
//TODO: Other Table Structs??
//TODO: Table Above 6 is buggy, what they are??
Print(L"Invalid Table\n");
break;
}
}
}
else if (Structure->RsdtAddress)
{
//TODO: Do Other Table Parsing Rsdt for example.
//TODO: Old Hardware, not supported for now, more important stuff before.
}
}
Code: Select all
#define BEGIN_DECLARE_STRUCT(Type, Name, Address) Type *Name = (Type *) Address; \
if(Name != NULL) \
{
#define END_DECLERE_STRUCT(Name) } \
else { Print(L"Got invalid table: "); \
Print(L#Name); \
Print(L"\n"); }
CHAR8 *Signature = (CHAR8*)&((EFI_ACPI_DESCRIPTION_HEADER *)CurrentTable)->Signature;
//Other table parsing code
if (AsciiStrnCmp(Signature, "APIC", 4) == 0)
{
Print(L"APIC\n");
BEGIN_DECLARE_STRUCT(EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER, Apic, CurrentTable);
{
//Now Query For APIC Interrupts
if (Apic->Flags & EFI_ACPI_6_0_IO_APIC)
{
Print(L"Got IO APCI Interrupt, Falg: 0x0%x\n", Apic->Flags);
BEGIN_DECLARE_STRUCT(EFI_ACPI_6_0_IO_APIC_STRUCTURE, IoInterrupt, (UINT_PTR)Apic->LocalApicAddress);
{
Print(L"Flag: %d, Lenght: %d, Io Apic Address: 0x%X Global Interrupt Table At: 0x%X\n",
IoInterrupt->Type,
IoInterrupt->Length,
IoInterrupt->IoApicAddress,
IoInterrupt->GlobalSystemInterruptBase);
}
END_DECLERE_STRUCT(EFI_ACPI_6_0_IO_APIC_STRUCTURE);
}
if(Apic->Flags & EFI_ACPI_6_0_PLATFORM_INTERRUPT_SOURCES)
{
Print(L"Got platform Interrupt Sources Interrupt, Falg: 0x0%x\n", Apic->Flags);
BEGIN_DECLARE_STRUCT(EFI_ACPI_6_0_PLATFORM_INTERRUPT_APIC_STRUCTURE, PlataformInt, (UINT_PTR)Apic->LocalApicAddress);
{
Print(L"Got Cpu With Id 0x%d\n", PlataformInt->ProcessorId);
}
END_DECLERE_STRUCT(EFI_ACPI_6_0_PLATFORM_INTERRUPT_APIC_STRUCTURE);
}
}
END_DECLERE_STRUCT(EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
}
//Other table parsing coe
Code: Select all
if (AsciiStrnCmp(Signature, "FACP", 4) == 0)
{
Print(L"FACP\n");
BEGIN_DECLARE_STRUCT(EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE, Fadt, CurrentTable);
{
Print(L"Version: %d, Creator: %d, Hypervisor: 0x%x, Flags: 0x%x\n", Fadt->Header.Revision, Fadt->Header.CreatorRevision, Fadt->HypervisorVendorIdentity, Fadt->Flags);
if (CalculateTableChesum(Fadt) != 0)
{
Print(L"Table Corrupted! %d\n", CalculateTableChesum(Fadt));
return;
}
if (Fadt->XFirmwareCtrl != 0)
{
//Now Parse FACS
BEGIN_DECLARE_STRUCT(EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, Facs, Fadt->XFirmwareCtrl);
{
Print(
L"Got FACS, Version: %d, Flag: 0x%x, Vector: 0x%x\n",
Facs->Version,
Facs->HardwareSignature,
Facs->XFirmwareWakingVector
);
}
END_DECLERE_STRUCT(EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE);
}
}
END_DECLERE_STRUCT(Fadt);
}