ACPI4.0/5.0 have clear description:

FIRMWARE_CTRL: If the X_FIRMWARE_CTRL field contains a non zero value then this field must be zero.
X_FIRMWARE_CTRL: This field is used when the physical address of the FACS is above 4GB. If the FIRMWARE_CTRL field contains a non zero value then this field must be zero.

Update code in AcpiSupport/AcpiTable when it produces this field to set one only.
Update code in AcpiS3Save when it consumes this field, check 0 value.


Signed-off-by: jiewen.yao@intel.com
Reviewed-by: star.zeng@intel.com

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13980 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jyao1
2012-11-30 09:03:15 +00:00
parent 93b21ade88
commit c93776c2d4
3 changed files with 193 additions and 49 deletions

View File

@@ -100,6 +100,116 @@ AllocateMemoryBelow4G (
return Buffer;
}
/**
This function scan ACPI table in RSDT.
@param Rsdt ACPI RSDT
@param Signature ACPI table signature
@return ACPI table
**/
VOID *
ScanTableInRSDT (
IN EFI_ACPI_DESCRIPTION_HEADER *Rsdt,
IN UINT32 Signature
)
{
UINTN Index;
UINT32 EntryCount;
UINT32 *EntryPtr;
EFI_ACPI_DESCRIPTION_HEADER *Table;
if (Rsdt == NULL) {
return NULL;
}
EntryCount = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);
EntryPtr = (UINT32 *)(Rsdt + 1);
for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {
Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));
if (Table->Signature == Signature) {
return Table;
}
}
return NULL;
}
/**
This function scan ACPI table in XSDT.
@param Xsdt ACPI XSDT
@param Signature ACPI table signature
@return ACPI table
**/
VOID *
ScanTableInXSDT (
IN EFI_ACPI_DESCRIPTION_HEADER *Xsdt,
IN UINT32 Signature
)
{
UINTN Index;
UINT32 EntryCount;
UINT64 EntryPtr;
UINTN BasePtr;
EFI_ACPI_DESCRIPTION_HEADER *Table;
if (Xsdt == NULL) {
return NULL;
}
EntryCount = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
BasePtr = (UINTN)(Xsdt + 1);
for (Index = 0; Index < EntryCount; Index ++) {
CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(EntryPtr));
if (Table->Signature == Signature) {
return Table;
}
}
return NULL;
}
/**
To find Facs in FADT.
@param Fadt FADT table pointer
@return Facs table pointer.
**/
EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *
FindAcpiFacsFromFadt (
IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
)
{
EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
UINT64 Data64;
if (Fadt == NULL) {
return NULL;
}
if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;
} else {
if (Fadt->FirmwareCtrl != 0) {
Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;
} else {
CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof(UINT64));
Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Data64;
}
}
return Facs;
}
/**
To find Facs in Acpi tables.
@@ -117,13 +227,12 @@ FindAcpiFacsTableByAcpiGuid (
{
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
UINTN Index;
UINT32 Data32;
Rsdp = NULL;
Rsdt = NULL;
Fadt = NULL;
//
// found ACPI table RSD_PTR from system table
//
@@ -141,27 +250,33 @@ FindAcpiFacsTableByAcpiGuid (
return NULL;
}
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;
if (Rsdt == NULL || Rsdt->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
return NULL;
}
for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Rsdt->Length; Index = Index + sizeof (UINT32)) {
Data32 = *(UINT32 *) ((UINT8 *) Rsdt + Index);
Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) (UINT32 *) (UINTN) Data32;
if (Fadt->Header.Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
break;
//
// Search XSDT
//
if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress;
Fadt = ScanTableInXSDT (Xsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);
if (Fadt != NULL) {
Facs = FindAcpiFacsFromFadt (Fadt);
if (Facs != NULL) {
return Facs;
}
}
}
if (Fadt == NULL || Fadt->Header.Signature != EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
return NULL;
//
// Search RSDT
//
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;
Fadt = ScanTableInRSDT (Rsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);
if (Fadt != NULL) {
Facs = FindAcpiFacsFromFadt (Fadt);
if (Facs != NULL) {
return Facs;
}
}
Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;
return Facs;
return NULL;
}
/**

View File

@@ -1,7 +1,7 @@
/** @file
ACPI Support Protocol implementation
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -776,14 +776,24 @@ AddTableToList (
//
// Update pointers in FADT. If tables don't exist this will put NULL pointers there.
// Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
// vice-versa.
//
AcpiSupportInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs3;
Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Facs3;
CopyMem (
&AcpiSupportInstance->Fadt3->XFirmwareCtrl,
&Buffer64,
sizeof (UINT64)
);
if ((UINT64)(UINTN)AcpiSupportInstance->Facs3 < BASE_4GB) {
AcpiSupportInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs3;
ZeroMem (
&AcpiSupportInstance->Fadt3->XFirmwareCtrl,
sizeof (UINT64)
);
} else {
AcpiSupportInstance->Fadt3->FirmwareCtrl = 0;
Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Facs3;
CopyMem (
&AcpiSupportInstance->Fadt3->XFirmwareCtrl,
&Buffer64,
sizeof (UINT64)
);
}
AcpiSupportInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiSupportInstance->Dsdt3;
Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Dsdt3;
CopyMem (
@@ -900,13 +910,20 @@ AddTableToList (
// If FADT already exists, update table pointers.
//
if (AcpiSupportInstance->Fadt3 != NULL) {
AcpiSupportInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs3;
Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Facs3;
CopyMem (
&AcpiSupportInstance->Fadt3->XFirmwareCtrl,
&Buffer64,
sizeof (UINT64)
);
//
// Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
// vice-versa.
//
if ((UINT64)(UINTN)AcpiSupportInstance->Facs3 < BASE_4GB) {
AcpiSupportInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs3;
} else {
Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Facs3;
CopyMem (
&AcpiSupportInstance->Fadt3->XFirmwareCtrl,
&Buffer64,
sizeof (UINT64)
);
}
//
// Checksum FADT table