UEFI Bootloader - ACPI Problem
Posted: Wed Dec 02, 2015 3:47 pm
So following my adventure into making a bootloader using uefi and a karnel I must doing somethingh wrong.
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 :
Than In the ParseAcpiTable function I identify table by signature:
Bu as it seem the IoInterrupt have all the field set to null for some reason. It happen the same with the facs struct
I have no idea why. Any suggestion? I noticy somethingh have to be wrong in the fadt table as per specification if we have the XFirmwareCtrl pointer we should have FirmwareCtrl set to null but on my case they are both set.
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);
}