diff options
Diffstat (limited to 'ReferenceCode/ME/SampleCode/Library')
5 files changed, 471 insertions, 0 deletions
diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/AslUpdateLib.inf b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/AslUpdateLib.inf new file mode 100644 index 0000000..8b5396f --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/AslUpdateLib.inf @@ -0,0 +1,66 @@ +## @file +# Provides services to update ASL tables. +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + +[defines] +BASE_NAME = AslUpdateLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + DxeAslUpdateLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/SampleCode/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + EdkIIGlueBaseMemoryLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + +[nmake.common] + + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c new file mode 100644 index 0000000..79a7c86 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c @@ -0,0 +1,333 @@ +/** @file + Boot service DXE ASL update library implementation. + These functions in this file can be called during DXE and cannot be called during runtime + or in SMM which should use a RT or SMM library. + This library uses the ACPI Support protocol. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AslUpdateLib.h" +#endif +static EFI_ACPI_SUPPORT_PROTOCOL *mAcpiSupport = NULL; +static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL; + +// +// Function implemenations +// + +/** + Initialize the ASL update library state. + This must be called prior to invoking other library functions. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +InitializeAslUpdateLib ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Locate ACPI tables + /// + Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, (VOID **) &mAcpiSupport); + ASSERT_EFI_ERROR (Status); + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable); + return EFI_SUCCESS; +} + +/** + This procedure will update two kinds of asl code. + 1: Operating Region base address and length. + 2: Resource Consumption structures in device LDRC. + + @param[in] AslSignature The signature of Operation Region that we want to update. + @param[in] BaseAddress Base address of IO trap. + @param[in] Length Length of IO address. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +UpdateAslCode ( + IN UINT32 AslSignature, + IN UINT16 BaseAddress, + IN UINT8 Length + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_TABLE_VERSION Version; + UINT8 *CurrPtr; + UINT8 *Operation; + UINT32 *Signature; + UINT8 *DsdtPointer; + INTN Index; + UINTN Handle; + UINT16 AslLength; + + /// + /// Locate table with matching ID + /// + Index = 0; + AslLength = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) &Table, &Version, &Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while (Table->Signature != EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE); + + /// + /// Fix up the following ASL Code in DSDT: + /// (1) OperationRegion's IO Base Address and Length. + /// (2) Resource Consumption in LPC Device. + /// + CurrPtr = (UINT8 *) Table; + + /// + /// Loop through the ASL looking for values that we must fix up. + /// + for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) { + /// + /// Get a pointer to compare for signature + /// + Signature = (UINT32 *) DsdtPointer; + + /// + /// Check if this is the signature we are looking for + /// + if ((*Signature) == AslSignature) { + /// + /// Conditional match. For Region Objects, the Operator will always be the + /// byte immediately before the specific name. Therefore, subtract 1 to check + /// the Operator. + /// + Operation = DsdtPointer - 1; + + /// + /// If we have an operation region, update the base address and length + /// + if (*Operation == AML_OPREGION_OP) { + /// + /// Fixup the Base Address in OperationRegion. + /// + *(UINT16 *) (DsdtPointer + 6) = BaseAddress; + + /// + /// Fixup the Length in OperationRegion. + /// + *(DsdtPointer + 9) = Length; + } + + } else if ((*Signature) == EFI_SIGNATURE_32 ('L', 'D', 'R', 'C')) { + /// + /// Make sure it's device of LDRC and read the length + /// + if (*(DsdtPointer - 2) == AML_DEVICE_OP) { + AslLength = *(DsdtPointer - 1); + } else if (*(DsdtPointer - 3) == AML_DEVICE_OP) { + AslLength = *(UINT16 *) (DsdtPointer - 2); + AslLength = (AslLength & 0x0F) + ((AslLength & 0x0FF00) >> 4); + } + /// + /// Conditional match. Search _CSR in Device (LDRC). + /// + for (Operation = DsdtPointer; Operation <= DsdtPointer + AslLength; Operation++) { + /// + /// Get a pointer to compare for signature + /// + Signature = (UINT32 *) Operation; + + /// + /// Check if this is the signature we are looking for + /// + if ((*Signature) == EFI_SIGNATURE_32 ('_', 'C', 'R', 'S')) { + /// + /// Now look for an empty resource entry, fix the base address and length fields + /// + for (Index = 0; *(UINT16 *) (Operation + 9 + 8 * Index) != 0x0079; Index++) { + if (*(UINT16 *) (Operation + 11 + 8 * Index) == UINT16_BIT_MAGIC_NUMBER) { + /// + /// Fixup the Base Address and Length. + /// + *(UINT16 *) (Operation + 11 + 8 * Index) = BaseAddress; + *(UINT16 *) (Operation + 13 + 8 * Index) = BaseAddress; + *(Operation + 16 + 8 * Index) = Length; + break; + } + } + } + } + + DsdtPointer = DsdtPointer + AslLength; + } + } + /// + /// Update the modified ACPI table + /// + Status = mAcpiTable->InstallAcpiTable ( + mAcpiTable, + Table, + Table->Length, + &Handle + ); + FreePool (Table); + + return EFI_SUCCESS; +} + +/** + This function uses the ACPI support protocol to locate an ACPI table. + It is really only useful for finding tables that only have a single instance, + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc. + + @param[in] Signature Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] Table Updated with a pointer to the table + @param[in] Handle AcpiSupport protocol table handle for the table found + @param[in] Version The version of the table desired + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableBySignature ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + INTN Index; + EFI_ACPI_TABLE_VERSION DesiredVersion; + + DesiredVersion = *Version; + /// + /// Locate table with matching ID + /// + Index = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) Table, Version, Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while ((*Table)->Signature != Signature || !(*Version & DesiredVersion)); + + /// + /// If we found the table, there will be no error. + /// + return Status; +} + +/** + This function uses the ACPI support protocol to locate an ACPI SSDT table. + + @param[in] TableId Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] TableIdSize Length of the TableId to match. Table ID are 8 bytes long, this function + will consider it a match if the first TableIdSize bytes match + @param[in] Table Updated with a pointer to the table + @param[in] Handle AcpiSupport protocol table handle for the table found + @param[in] Version See AcpiSupport protocol, GetAcpiTable function for use + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableByOemTableId ( + IN UINT8 *TableId, + IN UINT8 TableIdSize, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + INTN Index; + + /// + /// Locate table with matching ID + /// + Index = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) Table, Version, Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while (CompareMem (&(*Table)->OemTableId, TableId, TableIdSize)); + + /// + /// If we found the table, there will be no error. + /// + return Status; +} + +/** + This function calculates and updates an UINT8 checksum. + + @param[in] Buffer Pointer to buffer to checksum + @param[in] Size Number of bytes to checksum + @param[in] ChecksumOffset Offset to place the checksum result in + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AcpiChecksum ( + IN VOID *Buffer, + IN UINTN Size, + IN UINTN ChecksumOffset + ) +{ + UINT8 Sum; + UINT8 *Ptr; + + Sum = 0; + // + // Initialize pointer + // + Ptr = Buffer; + + // + // Set checksum to 0 first + // + Ptr[ChecksumOffset] = 0; + + // + // Add all content of buffer + // + while (Size--) { + Sum = (UINT8) (Sum + (*Ptr++)); + } + // + // Set checksum + // + Ptr = Buffer; + Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1); + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.cif b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.cif new file mode 100644 index 0000000..81b5bf0 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.cif @@ -0,0 +1,11 @@ +<component> + name = "MeAslUpdateLib" + category = ModulePart + LocalRoot = "ReferenceCode\ME\SampleCode\Library\AslUpdate\Dxe" + RefName = "MeAslUpdateLib" +[files] +"MeAslUpdateLib.sdl" +"MeAslUpdateLib.mak" +"DxeAslUpdateLib.c" +"AslUpdateLib.inf" +<endComponent> diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.mak b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.mak new file mode 100644 index 0000000..7417a00 --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.mak @@ -0,0 +1,32 @@ +# MAK file for the ModulePart:AslUpdateLib +all : MeAslUpdateLib + +$(BUILD_DIR)\MeAslUpdateLib.lib : MeAslUpdateLib + +MeAslUpdateLib : $(BUILD_DIR)\MeAslUpdateLib.mak MeAslUpdateLibBin + +$(BUILD_DIR)\MeAslUpdateLib.mak : $(MeAslUpdateLib_DIR)\$(@B).cif $(MeAslUpdateLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(MeAslUpdateLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +MeAslUpdateLib_INCLUDES=\ + $(EDK_INCLUDES)\ + $(ME_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +MeAslUpdateLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +MeAslUpdateLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +MeAslUpdateLibBin : $(MeAslUpdateLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\MeAslUpdateLib.mak all \ + "MY_INCLUDES=$(MeAslUpdateLib_INCLUDES)"\ + "MY_DEFINES=$(MeAslUpdateLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.sdl b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.sdl new file mode 100644 index 0000000..aae94fb --- /dev/null +++ b/ReferenceCode/ME/SampleCode/Library/AslUpdate/Dxe/MeAslUpdateLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = MeAslUpdateLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AslUpdateLib support in Project" +End + +MODULE + Help = "Includes MeAslUpdateLib.mak to Project" + File = "MeAslUpdateLib.mak" +End + +PATH + Name = "MeAslUpdateLib_DIR" +End + +ELINK + Name = "MeAslUpdateLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\MeAslUpdateLib.lib" + Parent = "MeAslUpdateLib_LIB" + InvokeOrder = AfterParent +End
\ No newline at end of file |