From c93776c2d47b23b5e64691753efc7ab47ba257c0 Mon Sep 17 00:00:00 2001 From: jyao1 Date: Fri, 30 Nov 2012 09:03:15 +0000 Subject: 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 --- .../Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c | 153 ++++++++++++++++++--- .../AcpiSupportAcpiSupportProtocol.c | 47 +++++-- 2 files changed, 166 insertions(+), 34 deletions(-) (limited to 'IntelFrameworkModulePkg/Universal') diff --git a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c index bcd1882d7f..38226d0dc2 100644 --- a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c +++ b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c @@ -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; } /** diff --git a/IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportAcpiSupportProtocol.c b/IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportAcpiSupportProtocol.c index a54cffb169..107db88ed3 100644 --- a/IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportAcpiSupportProtocol.c +++ b/IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportAcpiSupportProtocol.c @@ -1,7 +1,7 @@ /** @file ACPI Support Protocol implementation -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
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 -- cgit v1.2.3