[AcpiInitLib] Allocate ACPI tables from low to high memory (#314)
To make PlatformUpdateAcpiTable() hook its contents and length easily, allocate a memory from low to high and appends each tables to higher direction Signed-off-by: Aiden Park <aiden.park@intel.com>
This commit is contained in:
parent
09245f4e54
commit
63439af6db
|
@ -25,8 +25,8 @@
|
|||
#include <Library/FirmwareUpdateLib.h>
|
||||
#include <Guid/BootLoaderVersionGuid.h>
|
||||
|
||||
#define ACPI_ALLOC(x) (Current = (UINT8 *)(((UINT32)Current - (x)) & ~0x0F))
|
||||
#define ACPI_ALLOC_PAGE(x) (Current = (UINT8 *)(((UINT32)Current - (x)) & ~0x0FFF))
|
||||
#define ACPI_ALIGN() (Current = (UINT8 *)ALIGN_POINTER (Current, 0x10))
|
||||
#define ACPI_ALIGN_PAGE() (Current = (UINT8 *)ALIGN_POINTER (Current, 0x1000))
|
||||
|
||||
#define EFI_ACPI_OEM_ID {'O','E','M','I','D',' '} // OEMID 6 bytes long
|
||||
#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('O','E','M','T','A','B','L','E') // OEM table id 8 bytes long
|
||||
|
@ -202,7 +202,6 @@ AcpiTableUpdate (
|
|||
EFI_ACPI_DESCRIPTION_HEADER *AcpiHdr;
|
||||
UINT8 *Current;
|
||||
UINT8 *Previous;
|
||||
UINT8 *NewTable;
|
||||
UINT32 *RsdtEntry;
|
||||
UINT64 *XsdtEntry;
|
||||
UINT32 EntryIndex;
|
||||
|
@ -210,6 +209,9 @@ AcpiTableUpdate (
|
|||
UINT32 Size;
|
||||
UINT32 EntryNum;
|
||||
EFI_STATUS Status;
|
||||
LOADER_GLOBAL_DATA *LdrGlobal;
|
||||
S3_DATA *S3Data;
|
||||
UINT32 AcpiMax;
|
||||
|
||||
if ((AcpiTable == NULL) || (Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
@ -222,7 +224,10 @@ AcpiTableUpdate (
|
|||
XsdtEntry = (UINT64 *) ((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
|
||||
EntryNum = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32);
|
||||
|
||||
Current = (UINT8 *)Rsdp;
|
||||
LdrGlobal = (LOADER_GLOBAL_DATA *)GetLoaderGlobalDataPointer();
|
||||
S3Data = (S3_DATA *)LdrGlobal->S3DataPtr;
|
||||
Current = (UINT8 *)S3Data->AcpiTop;
|
||||
AcpiMax = S3Data->AcpiBase + PcdGet32 (PcdLoaderAcpiReclaimSize);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
Size = 0;
|
||||
|
@ -242,18 +247,18 @@ AcpiTableUpdate (
|
|||
|
||||
// Determine policy
|
||||
Previous = Current;
|
||||
NewTable = (UINT8 *)ACPI_ALLOC (AcpiHdr->Length);
|
||||
if ((UINT32)Current < PcdGet32 (PcdAcpiGnvsAddress) - PcdGet32 (PcdLoaderAcpiReclaimSize)) {
|
||||
ACPI_ALIGN ();
|
||||
if (((UINT32)Current + AcpiHdr->Length) > AcpiMax) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
CopyMem (NewTable, AcpiHdr, AcpiHdr->Length);
|
||||
CopyMem (Current, AcpiHdr, AcpiHdr->Length);
|
||||
|
||||
// Update the ACPI header to pointer to the new copy
|
||||
// And then update the table if required
|
||||
AcpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)NewTable;
|
||||
Status = PlatformUpdateAcpiTable (NewTable);
|
||||
AcpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)Current;
|
||||
Status = PlatformUpdateAcpiTable (Current);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
Current = Previous;
|
||||
continue;
|
||||
|
@ -298,6 +303,14 @@ AcpiTableUpdate (
|
|||
}
|
||||
}
|
||||
AcpiPlatformChecksum ((UINT8 *)AcpiHdr, AcpiHdr->Length);
|
||||
Current += AcpiHdr->Length;
|
||||
}
|
||||
|
||||
//
|
||||
// Check ACPI memory range again since a Table length may increase in hook
|
||||
//
|
||||
if ((UINT32)Current > AcpiMax) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Rsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EntryNum * sizeof (UINT32);
|
||||
|
@ -306,6 +319,11 @@ AcpiTableUpdate (
|
|||
Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EntryNum * sizeof (UINT64);
|
||||
AcpiPlatformChecksum ((UINT8 *)Xsdt, Xsdt->Length);
|
||||
|
||||
//
|
||||
// Update AcpiTop for gLoaderSystemTableInfoGuid
|
||||
//
|
||||
S3Data->AcpiTop = (UINT32)(UINTN)Current;
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Acpi update failed - %r\n", Status));
|
||||
}
|
||||
|
@ -440,7 +458,7 @@ UpdateFwst (
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
AcpiInit (
|
||||
IN UINT32 *AcpiMemTop
|
||||
IN UINT32 *AcpiMemBase
|
||||
)
|
||||
{
|
||||
UINT8 *TblPtr;
|
||||
|
@ -469,28 +487,38 @@ AcpiInit (
|
|||
Facp = NULL;
|
||||
UpdateRdstXsdt = 0;
|
||||
|
||||
Current = (UINT8 *) (*AcpiMemTop);
|
||||
Current = (UINT8 *)(*AcpiMemBase);
|
||||
|
||||
//
|
||||
// Create RSDP
|
||||
//
|
||||
Rsdp = (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) ACPI_ALIGN_PAGE ();
|
||||
CopyMem (Rsdp, &RsdpTmp, sizeof (RsdpTmp));
|
||||
TotalSize = sizeof (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
|
||||
Current += TotalSize;
|
||||
|
||||
//
|
||||
// Create RSDT structures and allocate buffers.
|
||||
//
|
||||
TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + PcdGet32 (PcdAcpiTablesMaxEntry) * sizeof (UINT32);
|
||||
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) ACPI_ALLOC (TotalSize);
|
||||
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) ACPI_ALIGN ();
|
||||
CopyMem (Rsdt, &XsdtTmp, sizeof (EFI_ACPI_DESCRIPTION_HEADER));
|
||||
Rsdt->Signature = EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
|
||||
Rsdt->Revision = EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
|
||||
RsdtEntry = (UINT32 *) ((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
|
||||
SetMem (RsdtEntry, PcdGet32 (PcdAcpiTablesMaxEntry) * sizeof (UINT32), 0);
|
||||
TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + PcdGet32 (PcdAcpiTablesMaxEntry) * sizeof (UINT32);
|
||||
Current += TotalSize;
|
||||
|
||||
//
|
||||
// Create XSDT structures and allocate buffers.
|
||||
//
|
||||
TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + PcdGet32 (PcdAcpiTablesMaxEntry) * sizeof (UINT64);
|
||||
Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) ACPI_ALLOC (TotalSize);
|
||||
Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) ACPI_ALIGN ();
|
||||
CopyMem (Xsdt, &XsdtTmp, sizeof (EFI_ACPI_DESCRIPTION_HEADER));
|
||||
XsdtEntry = (UINT64 *) ((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
|
||||
XsdtIndex = 0;
|
||||
SetMem (XsdtEntry, PcdGet32 (PcdAcpiTablesMaxEntry) * sizeof (UINT64), 0);
|
||||
TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + PcdGet32 (PcdAcpiTablesMaxEntry) * sizeof (UINT64);
|
||||
Current += TotalSize;
|
||||
|
||||
TblPtr = (UINT8 *)PcdGet32 (PcdAcpiTablesAddress);
|
||||
EndPtr = TblPtr + ((* ((UINT32 *) (TblPtr - 8)) & 0xFFFFFF) - 28);
|
||||
|
@ -498,7 +526,7 @@ AcpiInit (
|
|||
Previous = Current;
|
||||
|
||||
Table = (EFI_ACPI_COMMON_HEADER *)TblPtr;
|
||||
ACPI_ALLOC (Table->Length);
|
||||
ACPI_ALIGN ();
|
||||
CopyMem (Current, Table, Table->Length);
|
||||
|
||||
Status = PlatformUpdateAcpiTable (Current);
|
||||
|
@ -574,6 +602,9 @@ AcpiInit (
|
|||
|
||||
SectionLen = * (UINT32 *) (TblPtr - 4) & 0x00FFFFFF;
|
||||
TblPtr = TblPtr + ((SectionLen + 3) & ~3);
|
||||
|
||||
TotalSize = ((EFI_ACPI_COMMON_HEADER *)Current)->Length;
|
||||
Current += TotalSize;
|
||||
}
|
||||
|
||||
if (Facp == NULL || Facs == NULL || Dsdt == NULL) {
|
||||
|
@ -594,16 +625,13 @@ AcpiInit (
|
|||
AcpiPlatformChecksum ((UINT8 *)Xsdt, Xsdt->Length);
|
||||
|
||||
//
|
||||
// Make Rsdp page aligned
|
||||
// Update RSDP
|
||||
//
|
||||
Rsdp = (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) \
|
||||
ACPI_ALLOC_PAGE (sizeof (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER));
|
||||
CopyMem (Rsdp, &RsdpTmp, sizeof (RsdpTmp));
|
||||
Rsdp->RsdtAddress = (UINT32)Rsdt;
|
||||
Rsdp->XsdtAddress = (UINT64) (UINTN)Xsdt;
|
||||
Rsdp->Checksum = CalculateCheckSum8 ((UINT8 *)Rsdp, sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER));
|
||||
Rsdp->ExtendedChecksum = CalculateCheckSum8 ((UINT8 *)Rsdp, Rsdp->Length);
|
||||
*AcpiMemTop = (UINT32)Current;
|
||||
*AcpiMemBase = (UINT32)Current;
|
||||
|
||||
//
|
||||
// Keep a copy at F segment so that non-UEFI OS will find ACPI tables
|
||||
|
|
|
@ -319,7 +319,7 @@ SecStartup (
|
|||
VOID *MemPool;
|
||||
UINT32 Delta;
|
||||
UINT32 AcpiGnvs;
|
||||
UINT32 AcpiTop;
|
||||
UINT32 AcpiBase;
|
||||
LOADER_GLOBAL_DATA *LdrGlobal;
|
||||
UINT8 BootMode;
|
||||
S3_DATA *S3Data;
|
||||
|
@ -442,35 +442,31 @@ SecStartup (
|
|||
}
|
||||
|
||||
// ACPI Initialization
|
||||
if (ACPI_ENABLED()) {
|
||||
if (PcdGet32 (PcdLoaderAcpiNvsSize) < GetAcpiGnvsSize()) {
|
||||
AcpiGnvs = 0;
|
||||
AcpiTop = 0;
|
||||
} else {
|
||||
if (ACPI_ENABLED ()) {
|
||||
AcpiGnvs = 0;
|
||||
AcpiBase = 0;
|
||||
Status = (PcdGet32 (PcdLoaderAcpiNvsSize) < GetAcpiGnvsSize ()) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;
|
||||
if (!EFI_ERROR (Status)) {
|
||||
AcpiGnvs = LdrGlobal->MemPoolStart - PcdGet32 (PcdLoaderAcpiNvsSize);
|
||||
AcpiTop = AcpiGnvs;
|
||||
}
|
||||
AcpiBase = AcpiGnvs - PcdGet32 (PcdLoaderAcpiReclaimSize);
|
||||
Status = PcdSet32S (PcdAcpiGnvsAddress, AcpiGnvs);
|
||||
|
||||
S3Data = (S3_DATA *)LdrGlobal->S3DataPtr;
|
||||
Status = PcdSet32S (PcdAcpiGnvsAddress, AcpiGnvs);
|
||||
if (BootMode != BOOT_ON_S3_RESUME) {
|
||||
if ((AcpiGnvs > 0) && (AcpiTop > 0)) {
|
||||
S3Data = (S3_DATA *)LdrGlobal->S3DataPtr;
|
||||
if (BootMode != BOOT_ON_S3_RESUME) {
|
||||
PlatformUpdateAcpiGnvs ((VOID *)AcpiGnvs);
|
||||
S3Data->AcpiGnvs = AcpiGnvs;
|
||||
S3Data->AcpiTop = AcpiTop;
|
||||
S3Data->AcpiBase = AcpiBase;
|
||||
DEBUG ((DEBUG_INIT, "ACPI Init\n"));
|
||||
Status = AcpiInit (&AcpiTop);
|
||||
Status = AcpiInit (&AcpiBase);
|
||||
DEBUG ((DEBUG_INFO, "ACPI Ret: %r\n", Status));
|
||||
S3Data->AcpiBase = AcpiTop;
|
||||
S3Data->AcpiTop = AcpiBase;
|
||||
if (!EFI_ERROR (Status) && ((S3Data->AcpiTop - S3Data->AcpiBase) >
|
||||
PcdGet32 (PcdLoaderAcpiReclaimSize))) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
} else {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
Status = (S3Data->AcpiGnvs == AcpiGnvs) ? EFI_SUCCESS : EFI_ABORTED;
|
||||
}
|
||||
} else {
|
||||
Status = (S3Data->AcpiGnvs == AcpiGnvs) ? EFI_SUCCESS : EFI_ABORTED;
|
||||
}
|
||||
|
||||
AddMeasurePoint (0x30D0);
|
||||
|
|
Loading…
Reference in New Issue