diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Haswell/SampleCode/Library | |
download | zprj-master.tar.xz |
Diffstat (limited to 'ReferenceCode/Haswell/SampleCode/Library')
32 files changed, 2529 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c new file mode 100644 index 0000000..8adbe64 --- /dev/null +++ b/ReferenceCode/Haswell/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 +/// +/// Function implemenations +/// +static EFI_ACPI_SUPPORT_PROTOCOL *mAcpiSupport = NULL; +static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL; + +/** + Initialize the ASL update library state. + This must be called prior to invoking other library functions. + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +InitializeAslUpdateLib ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Locate ACPI tables + /// + Status = gBS->LocateProtocol (&gEfiAcpiSupportGuid, 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/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.inf b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.inf new file mode 100644 index 0000000..138e053 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.inf @@ -0,0 +1,46 @@ +## @file +# Component description file. +# +#@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 = DxeAslUpdateLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + DxeAslUpdateLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(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 + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.cif b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.cif new file mode 100644 index 0000000..5cfa2b1 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.cif @@ -0,0 +1,11 @@ +<component> + name = "PpmAslUpdateLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\AslUpdate\Dxe" + RefName = "PpmAslUpdateLib" +[files] +"PpmAslUpdateLib.sdl" +"PpmAslUpdateLib.mak" +"DxeAslUpdateLib.c" +"DxeAslUpdateLib.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.mak b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.mak new file mode 100644 index 0000000..adcce28 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : PpmAslUpdateLib + +$(BUILD_DIR)\PpmAslUpdateLib.lib : PpmAslUpdateLib + +PpmAslUpdateLib : $(BUILD_DIR)\PpmAslUpdateLib.mak PpmAslUpdateLibBin + +$(BUILD_DIR)\PpmAslUpdateLib.mak : $(PpmAslUpdateLib_DIR)\$(@B).cif $(PpmAslUpdateLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PpmAslUpdateLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PpmAslUpdateLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +PpmAslUpdateLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +PpmAslUpdateLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +PpmAslUpdateLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PpmAslUpdateLib.mak all \ + "MY_INCLUDES=$(PpmAslUpdateLib_INCLUDES)"\ + "MY_DEFINES=$(PpmAslUpdateLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.sdl new file mode 100644 index 0000000..0a74ab2 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = PpmAslUpdateLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AslUpdateLib support in Project" +End + +MODULE + Help = "Includes PpmAslUpdateLib.mak to Project" + File = "PpmAslUpdateLib.mak" +End + +PATH + Name = "PpmAslUpdateLib_DIR" +End + +ELINK + Name = "PpmAslUpdateLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PpmAslUpdateLib.lib" + Parent = "PpmAslUpdateLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.c b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.c new file mode 100644 index 0000000..2a3ff51 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.c @@ -0,0 +1,34 @@ +/** @file + This file is SampleCode for Boot Guard revocation notification. + +@copyright + Copyright (c) 2012 - 2013 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 + +**/ + +#include "BootGuardRevocationLib.h" + +/** + Provide a hook for OEM to deal with Boot Guard revocation flow. +**/ +VOID +EFIAPI +BootGuardOemRevocationHook ( + VOID + ) +{ + + return; +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.cif b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.cif new file mode 100644 index 0000000..fdad18a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.cif @@ -0,0 +1,11 @@ +<component> + name = "BootGuardRevocationLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\BootGuardRevocationLib\Dxe" + RefName = "BootGuardRevocationLib" +[files] +"BootGuardRevocationLib.sdl" +"BootGuardRevocationLib.mak" +"BootGuardRevocationLib.c" +"BootGuardRevocationLib.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.inf b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.inf new file mode 100644 index 0000000..295dcf6 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.inf @@ -0,0 +1,73 @@ +## @file +# Provides services to display Boot Guard revocation notification. +# +#@copyright +# Copyright (c) 2012 - 2013 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 = BootGuardRevocationLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + BootGuardRevocationLib.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_CPU_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] + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueBaseMemoryLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiLib + EdkFrameworkProtocolLib + +[nmake.common] + + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.mak b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.mak new file mode 100644 index 0000000..2d3c433 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : BootGuardRevocationLib + +$(BUILD_DIR)\BootGuardRevocationLib.lib : BootGuardRevocationLib + +BootGuardRevocationLib : $(BUILD_DIR)\BootGuardRevocationLib.mak BootGuardRevocationLibBin + +$(BUILD_DIR)\BootGuardRevocationLib.mak : $(BootGuardRevocationLib_DIR)\$(@B).cif $(BootGuardRevocationLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(BootGuardRevocationLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +BootGuardRevocationLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +BootGuardRevocationLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +BootGuardRevocationLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +BootGuardRevocationLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\BootGuardRevocationLib.mak all \ + "MY_INCLUDES=$(BootGuardRevocationLib_INCLUDES)"\ + "MY_DEFINES=$(BootGuardRevocationLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.sdl new file mode 100644 index 0000000..b7405cf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = BootGuardRevocationLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable BootGuardRevocationLib support in Project" +End + +MODULE + Help = "Includes BootGuardRevocationLib.mak to Project" + File = "BootGuardRevocationLib.mak" +End + +PATH + Name = "BootGuardRevocationLib_DIR" +End + +ELINK + Name = "BootGuardRevocationLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\BootGuardRevocationLib.lib" + Parent = "BootGuardRevocationLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c new file mode 100644 index 0000000..ffb8480 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c @@ -0,0 +1,838 @@ +/** @file + This file is SampleCode for Boot Guard TPM event log. + +@copyright + Copyright (c) 2013 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 "EdkIIGlueBase.h" +#include "EdkIIGluePeim.h" +#include "CpuAccess.h" +#endif + +#include <EfiTpm.h> +#include "BootGuardTpmEventLogLib.h" + +// +// Data structure definition +// +#pragma pack (1) + +#define BASE_4GB 0x0000000100000000ULL +// +// FIT definition +// +#define FIT_TABLE_TYPE_HEADER 0x0 +#define FIT_TABLE_TYPE_MICROCODE 0x1 +#define FIT_TABLE_TYPE_STARTUP_ACM 0x2 +#define FIT_TABLE_TYPE_BIOS_MODULE 0x7 +#define FIT_TABLE_TYPE_KEY_MANIFEST 0xB +#define FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST 0xC + +typedef struct { + UINT64 Address; + UINT8 Size[3]; + UINT8 Reserved; + UINT16 Version; + UINT8 Type : 7; + UINT8 Cv : 1; + UINT8 Chksum; +} FIRMWARE_INTERFACE_TABLE_ENTRY; + +// +// ACM definition +// +#define MMIO_ACM_STATUS (TXT_PUBLIC_BASE + R_CPU_BOOT_GUARD_ACM_STATUS) +#define ACM_KEY_HASH_MMIO_ADDR_0 0xFED30400 +#define ACM_KEY_HASH_MMIO_ADDR_1 (ACM_KEY_HASH_MMIO_ADDR_0 + 8) +#define ACM_KEY_HASH_MMIO_ADDR_2 (ACM_KEY_HASH_MMIO_ADDR_0 + 16) +#define ACM_KEY_HASH_MMIO_ADDR_3 (ACM_KEY_HASH_MMIO_ADDR_0 + 24) +#define ACM_PKCS_1_5_RSA_SIGNATURE_SIZE 256 +#define ACM_HEADER_FLAG_DEBUG_SIGNED BIT15 +#define ACM_NPW_SVN 0x2 + +typedef struct { + UINT32 ModuleType; + UINT32 HeaderLen; + UINT32 HeaderVersion; + UINT16 ChipsetId; + UINT16 Flags; + UINT32 ModuleVendor; + UINT32 Date; + UINT32 Size; + UINT16 AcmSvn; + UINT16 Reserved1; + UINT32 CodeControl; + UINT32 ErrorEntryPoint; + UINT32 GdtLimit; + UINT32 GdtBasePtr; + UINT32 SegSel; + UINT32 EntryPoint; + UINT8 Reserved2[64]; + UINT32 KeySize; + UINT32 ScratchSize; + UINT8 RsaPubKey[64 * 4]; + UINT32 RsaPubExp; + UINT8 RsaSig[256]; +} ACM_FORMAT; + +// +// Manifest definition +// +#define SHA256_DIGEST_SIZE 32 + +typedef struct { + UINT16 HashAlg; + UINT16 Size; + UINT8 HashBuffer[SHA256_DIGEST_SIZE]; +} HASH_STRUCTURE; + +#define RSA_PUBLIC_KEY_STRUCT_KEY_SIZE_DEFAULT 2048 +#define RSA_PUBLIC_KEY_STRUCT_KEY_LEN_DEFAULT (RSA_PUBLIC_KEY_STRUCT_KEY_SIZE_DEFAULT/8) + +typedef struct { + UINT8 Version; + UINT16 KeySize; + UINT32 Exponent; + UINT8 Modulus[RSA_PUBLIC_KEY_STRUCT_KEY_LEN_DEFAULT]; +} RSA_PUBLIC_KEY_STRUCT; + +#define RSASSA_SIGNATURE_STRUCT_KEY_SIZE_DEFAULT 2048 +#define RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT (RSASSA_SIGNATURE_STRUCT_KEY_SIZE_DEFAULT/8) +typedef struct { + UINT8 Version; + UINT16 KeySize; + UINT16 HashAlg; + UINT8 Signature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; +} RSASSA_SIGNATURE_STRUCT; + +typedef struct { + UINT8 Version; + UINT16 KeyAlg; + RSA_PUBLIC_KEY_STRUCT Key; + UINT16 SigScheme; + RSASSA_SIGNATURE_STRUCT Signature; +} KEY_SIGNATURE_STRUCT; + +#define BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID (*(UINT64 *)"__ACBP__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 HdrStructVersion; + UINT8 PMBPMVersion; + UINT8 BPSVN; + UINT8 ACMSVN; + UINT8 Reserved; + UINT16 NEMDataStack; +} BOOT_POLICY_MANIFEST_HEADER; + +#define IBB_SEGMENT_FLAG_IBB 0x0 +#define IBB_SEGMENT_FLAG_NON_IBB 0x1 +typedef struct { + UINT8 Reserved[2]; + UINT16 Flags; + UINT32 Base; + UINT32 Size; +} IBB_SEGMENT_ELEMENT; + +#define BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__IBBS__") +#define IBB_FLAG_AUTHORITY_MEASURE 0x4 + +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 Reserved1[2]; + UINT8 PbetValue; + UINT32 Flags; + UINT64 IbbMchBar; + UINT64 VtdBar; + UINT32 PmrlBase; + UINT32 PmrlLimit; + UINT64 Reserved2[2]; + HASH_STRUCTURE PostIbbHash; + UINT32 EntryPoint; + HASH_STRUCTURE Digest; + UINT8 SegmentCount; + IBB_SEGMENT_ELEMENT IbbSegment[1]; +} IBB_ELEMENT; + +#define BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__PMDA__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT16 PmDataSize; +} PLATFORM_MANUFACTURER_ELEMENT; + +#define BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__PMSG__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + KEY_SIGNATURE_STRUCT KeySignature; +} BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT; + +#define KEY_MANIFEST_STRUCTURE_ID (*(UINT64 *)"__KEYM__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 KeyManifestVersion; + UINT8 KmSvn; + UINT8 KeyManifestId; + HASH_STRUCTURE BpKey; + KEY_SIGNATURE_STRUCT KeyManifestSignature; +} KEY_MANIFEST_STRAUCTURE; + +// +// DetailPCR data +// +typedef struct { + UINT8 BpRstrLow; + UINT8 BpTypeLow; + UINT16 AcmSvn; + UINT8 AcmRsaSignature[ACM_PKCS_1_5_RSA_SIGNATURE_SIZE]; + UINT8 KmRsaSignature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; + UINT8 BpmRsaSignature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; + UINT8 IbbHash[SHA256_DIGEST_SIZE]; +} DETAIL_PCR_DATA; + +// +// AuthorityPCR data +// +typedef struct { + UINT8 BpRstrLow; + UINT8 BpTypeLow; + UINT16 AcmSvn; + UINT8 AcmKeyHash[SHA256_DIGEST_SIZE]; + UINT8 BpKeyHash[SHA256_DIGEST_SIZE]; + UINT8 BpmKeyHashFromKm[SHA256_DIGEST_SIZE]; + UINT8 VerifiedBoot; +} AUTHORITY_PCR_DATA; + +// +// Boot Policy Restrictions definition +// +typedef union { + struct { + UINT8 Facb : 1; + UINT8 Dcd : 1; + UINT8 Dbi : 1; + UINT8 Pbe : 1; + UINT8 Bbp : 1; + UINT8 Reserved : 2; + UINT8 BpInvd : 1; + } Bits; + UINT8 Data; +} BP_RSTR_LOW; + +// +// Boot Policy Type definition +// +typedef union { + struct { + UINT8 MeasuredBoot : 1; + UINT8 VerifiedBoot : 1; + UINT8 Hap : 1; + UINT8 Reserved : 5; + } Bits; + UINT8 Data; +} BP_TYPE_LOW; + +#pragma pack () + +// +// OEM_IMPLEMENTATION_BEGIN +// +// SHA calculation and TPM functions are OEM Core/Platform code depended, +// OEM can customize these empty functions for their specific. +// +// For the detail of SHA algorithm, please refer to FIPS PUB 180-2. +// For TPM event log, please refer to TCG EFI Protocol Specification. +// + +// +// Null-defined macro for passing EDK build +// +#define SHA_INIT +#define SHA_UPDATE +#define SHA_FINAL + +/** + Calculate SHA-1 Hash + + @param[in] Data Data to be hashed. + @param[in] Size Size of data. + @param[out] Digest SHA-1 digest value. +**/ +VOID +CreateSha1Hash ( + IN UINT8 *Data, + IN UINTN Size, + OUT UINT8 *Digest + ) +{ + VOID *Context; + + SHA_INIT (Context); + SHA_UPDATE (Context, Data, Size); + SHA_FINAL (Context, Digest); + + return; +} + +/** + Calculate SHA256 Hash + + @param[in] Data Data to be hashed. + @param[in] Size Size of data. + @param[out] Digest SHA256 digest value. +**/ +VOID +CreateSha256Hash ( + IN UINT8 *Data, + IN UINTN Size, + OUT UINT8 *Digest + ) +{ + VOID *Context; + + SHA_INIT (Context); + SHA_UPDATE (Context, Data, Size); + SHA_FINAL (Context, Digest); + + return; +} + +/** + Add a new entry to the Event Log. + + @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. + @param[in] NewEventData Pointer to the new event data. + + @retval EFI_SUCCESS The new event log entry was added. + @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. +**/ +EFI_STATUS +LogEvent ( + IN TCG_PCR_EVENT_HDR *NewEventHdr, + IN UINT8 *NewEventData + ) +{ + + return EFI_SUCCESS; +} +// +// OEM_IMPLEMENTATION_END +// + +/** + Find FIT Entry address data by type + + @param[in] Type FIT Entry type + + @return FIT entry address +**/ +VOID * +FindFitEntryData ( + IN UINT8 Type + ) +{ + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry; + UINT32 EntryNum; + UINT64 FitTableOffset; + UINT32 Index; + + FitTableOffset = *(UINT64 *)(UINTN)(BASE_4GB - 0x40); + FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *)(UINTN)FitTableOffset; + if (FitEntry[0].Address != *(UINT64 *)"_FIT_ ") { + return NULL; + } + if (FitEntry[0].Type != FIT_TABLE_TYPE_HEADER) { + return NULL; + } + EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; + for (Index = 0; Index < EntryNum; Index++) { + if (FitEntry[Index].Type == Type) { + return (VOID *)(UINTN)FitEntry[Index].Address; + } + } + + return NULL; +} + +/** + Find the address of ACM. + + @return A pointer to ACM. +**/ +VOID * +FindAcm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_STARTUP_ACM); +} + +/** + Find the address of Boot Policy Manifest. + + @return A pointer to Key Manifest data structure. +**/ +VOID * +FindBpm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST); +} + +/** + Find the address of Key Manifest. + + @return A pointer to Key Manifest data structure. +**/ +VOID * +FindKm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_KEY_MANIFEST); +} + +/** + Find BPM element by structureID + + @param[in] Bpm A pointer to BPM data structure. + @param[in] StructureId BPM element StructureID + + @return A pointer to BPM element data structure. +**/ +VOID * +FindBpmElement ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm, + IN UINT64 StructureId + ) +{ + BOOT_POLICY_MANIFEST_HEADER *BpmHeader; + IBB_ELEMENT *IbbElement; + PLATFORM_MANUFACTURER_ELEMENT *PmElement; + BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *BpmSignatureElement; + UINT8 *Buffer; + + Buffer = (UINT8 *)Bpm; + + BpmHeader = (BOOT_POLICY_MANIFEST_HEADER *)Buffer; + if (*(UINT64 *)BpmHeader->StructureId != BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(BOOT_POLICY_MANIFEST_HEADER); + + IbbElement = (IBB_ELEMENT *)Buffer; + if (*(UINT64 *)IbbElement->StructureId != BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(IBB_ELEMENT) + sizeof(IBB_SEGMENT_ELEMENT) * (IbbElement->SegmentCount - 1); + + PmElement = (PLATFORM_MANUFACTURER_ELEMENT *)Buffer; + while (*(UINT64 *)PmElement->StructureId == BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID) { + if (StructureId == BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(PLATFORM_MANUFACTURER_ELEMENT) + PmElement->PmDataSize; + PmElement = (PLATFORM_MANUFACTURER_ELEMENT *)Buffer; + } + + BpmSignatureElement = (BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *)Buffer; + if (*(UINT64 *)BpmSignatureElement->StructureId != BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + return NULL; +} + +/** + Find BPM IBB element + + @param[in] Bpm A pointer to BPM data structure. + + @return A pointer to BPM IBB element data structure. +**/ +VOID * +FindBpmIbb ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm + ) +{ + return FindBpmElement (Bpm, BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID); +} + +/** + Find BPM Signature element + + @param[in] Bpm BPM address + + @return BPM Signature element +**/ +VOID * +FindBpmSignature ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm + ) +{ + return FindBpmElement (Bpm, BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID); +} + +/** + Check if ACM is a NPW ACM. + + @retval TRUE It is a NPW ACM + @retval FALSE It is NOT a NPW ACM +**/ +BOOLEAN +IsNpwAcm ( + VOID + ) +{ + ACM_FORMAT *Acm; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + if (Acm == NULL) { + return FALSE; + } + + if (((Acm->Flags & ACM_HEADER_FLAG_DEBUG_SIGNED) == 0) && (Acm->AcmSvn < ACM_NPW_SVN)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Check if Boot Guard verifies the IBB. + + @retval TRUE It is VerifiedBoot + @retval FALSE It is NOT VerifiedBoot +**/ +BOOLEAN +IsVerifiedBoot ( + VOID + ) +{ + if ((AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & B_VERIFIED) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Check if Boot Guard measures IBB into TPM's PCRs. + + @retval TRUE It is MeasuredBoot + @retval FALSE It is NOT MeasuredBoot +**/ +BOOLEAN +IsMeasuredBoot ( + VOID + ) +{ + if ((AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & B_MEASURED) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Get the lower 8 bits of Boot Policy Restrictions + + @return The lower 8 bits of BP.RSTR +**/ +UINT8 +GetBpRstrLow ( + VOID + ) +{ + BP_RSTR_LOW BpRstr; + UINT32 AcmStatus; + UINT64 SacmInfo; + + AcmStatus = MmioRead32 (MMIO_ACM_STATUS); + SacmInfo = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO); + + BpRstr.Bits.Facb = (UINT8)((SacmInfo & BIT4) >> 4); + BpRstr.Bits.Dcd = (UINT8)((AcmStatus & BIT21) >> 21); + BpRstr.Bits.Dbi = (UINT8)((AcmStatus & BIT22) >> 22); + BpRstr.Bits.Pbe = (UINT8)((AcmStatus & BIT23) >> 23); + BpRstr.Bits.Bbp = (UINT8)((AcmStatus & BIT24) >> 24); + BpRstr.Bits.Reserved = 0; + BpRstr.Bits.BpInvd = 0; + + return BpRstr.Data; +} + +/** + Get the lower 8 bits of Boot Policy Type + + @return The lower 8 bits of BP.TYPE +**/ +UINT8 +GetBpTypeLow ( + VOID + ) +{ + BP_TYPE_LOW BpType; + UINT32 AcmStatus; + UINT64 SacmInfo; + + AcmStatus = MmioRead32 (MMIO_ACM_STATUS); + SacmInfo = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO); + + BpType.Bits.MeasuredBoot = (UINT8)((SacmInfo & BIT5) >> 5); + BpType.Bits.VerifiedBoot = (UINT8)((SacmInfo & BIT6) >> 6); + BpType.Bits.Hap = (UINT8)((AcmStatus & BIT20) >> 20); + BpType.Bits.Reserved = 0; + + return BpType.Data; +} + +/** + Calculate IBB Hash + + @param[in] BpmIbb A pointer to BPM IBB element data structure. + @param[out] Digest IBB digest value. +**/ +VOID +CreateIbbHash ( + IN IBB_ELEMENT *BpmIbb, + OUT UINT8 *Digest + ) +{ + VOID *Context; + UINTN Index; + + SHA_INIT (Context); + + for (Index = 0; Index < BpmIbb->SegmentCount; Index++) { + if (BpmIbb->IbbSegment[Index].Flags == IBB_SEGMENT_FLAG_IBB) { + SHA_UPDATE (Context, (VOID *)(UINTN)BpmIbb->IbbSegment[Index].Base, BpmIbb->IbbSegment[Index].Size); + } + } + + SHA_FINAL (Context, Digest); + + return; +} + +/** + Calculate DetailPCR extend value + + @param[out] Digest DetailPCR digest +**/ +VOID +CaculateDetailPCRExtendValue ( + OUT TCG_DIGEST *Digest + ) +{ + ACM_FORMAT *Acm; + KEY_MANIFEST_STRAUCTURE *Km; + BOOT_POLICY_MANIFEST_HEADER *Bpm; + IBB_ELEMENT *BpmIbb; + BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *BpmSignature; + DETAIL_PCR_DATA DetailPcrData; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + + Km = FindKm (); + ASSERT (Km != NULL); + + Bpm = FindBpm (); + ASSERT (Bpm != NULL); + + BpmIbb = FindBpmIbb (Bpm); + ASSERT (BpmIbb != NULL); + + BpmSignature = FindBpmSignature (Bpm); + ASSERT (BpmSignature != NULL); + + DetailPcrData.BpRstrLow = GetBpRstrLow (); + DetailPcrData.BpTypeLow = GetBpTypeLow (); + DetailPcrData.AcmSvn = Acm->AcmSvn; + CopyMem (&DetailPcrData.AcmRsaSignature, &Acm->RsaSig, sizeof(DetailPcrData.AcmRsaSignature)); + CopyMem (&DetailPcrData.KmRsaSignature, &Km->KeyManifestSignature.Signature.Signature, sizeof(DetailPcrData.KmRsaSignature)); + CopyMem (&DetailPcrData.BpmRsaSignature, &BpmSignature->KeySignature.Signature.Signature, sizeof(DetailPcrData.BpmRsaSignature)); + if (IsVerifiedBoot ()) { + CopyMem (&DetailPcrData.IbbHash, &BpmIbb->Digest.HashBuffer, sizeof(DetailPcrData.IbbHash)); + } else { + // + // Calculate IBB hash because it is NOT verified boot, the Digest from IBB can not be trust. + // + CreateIbbHash (BpmIbb, (UINT8 *)&DetailPcrData.IbbHash); + } + + CreateSha1Hash ((UINT8 *)&DetailPcrData, sizeof(DetailPcrData), (UINT8 *)Digest); +} + +/** + Calculate AuthorityPCR extend value + + @param[out] Digest AuthorityPCR digest +**/ +VOID +CaculateAuthorityPCRExtendValue ( + OUT TCG_DIGEST *Digest + ) +{ + ACM_FORMAT *Acm; + KEY_MANIFEST_STRAUCTURE *Km; + AUTHORITY_PCR_DATA AuthorityPcrData; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + + Km = FindKm (); + ASSERT (Km != NULL); + + AuthorityPcrData.BpRstrLow = GetBpRstrLow (); + AuthorityPcrData.BpTypeLow = GetBpTypeLow (); + AuthorityPcrData.AcmSvn = Acm->AcmSvn; + + // + // Get ACM Key hash + // + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[0] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_0); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[8] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_1); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[16] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_2); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[24] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_3); + + // + // Calculate BP Key hash + // + CreateSha256Hash ((UINT8 *)&Km->KeyManifestSignature.Key.Modulus, sizeof(Km->KeyManifestSignature.Key.Modulus), (UINT8 *)&AuthorityPcrData.BpKeyHash); + + CopyMem (&AuthorityPcrData.BpmKeyHashFromKm, &Km->BpKey.HashBuffer, sizeof(AuthorityPcrData.BpmKeyHashFromKm)); + if (IsVerifiedBoot ()) { + AuthorityPcrData.VerifiedBoot = 0; + } else { + AuthorityPcrData.VerifiedBoot = 1; + } + + CreateSha1Hash ((UINT8 *)&AuthorityPcrData, sizeof(AuthorityPcrData), (UINT8 *)Digest); +} + +/** + Check if we need AuthorityPCR measurement + + @retval TRUE Need AuthorityPCR measurement + @retval FALSE Do NOT need AuthorityPCR measurement +**/ +BOOLEAN +NeedAuthorityMeasure ( + VOID + ) +{ + BOOT_POLICY_MANIFEST_HEADER *Bpm; + IBB_ELEMENT *BpmIbb; + + Bpm = FindBpm (); + ASSERT (Bpm != NULL); + + BpmIbb = FindBpmIbb (Bpm); + ASSERT (BpmIbb != NULL); + + if ((BpmIbb->Flags & IBB_FLAG_AUTHORITY_MEASURE) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Create DetailPCR event log + + @param[in] TpmType TPM type +**/ +VOID +CreateDetailPcrEvent ( + IN TPM_TYPE TpmType + ) +{ + TCG_PCR_EVENT_HDR NewEventHdr; + + NewEventHdr.PCRIndex = 0; + NewEventHdr.EventType = EV_S_CRTM_CONTENTS; + CaculateDetailPCRExtendValue (&NewEventHdr.Digest); + + if (IsNpwAcm()) { + NewEventHdr.EventSize = sizeof ("Boot Guard Debug Measured S-CRTM"); + LogEvent (&NewEventHdr, "Boot Guard Debug Measured S-CRTM"); + } else { + NewEventHdr.EventSize = sizeof ("Boot Guard Measured S-CRTM"); + LogEvent (&NewEventHdr, "Boot Guard Measured S-CRTM"); + } +} + +/** + Create AuthorityPCR event log + + @param[in] TpmType TPM type +**/ +VOID +CreateAuthorityPcrEvent ( + IN TPM_TYPE TpmType + ) +{ + TCG_PCR_EVENT_HDR NewEventHdr; + + if (NeedAuthorityMeasure() && IsVerifiedBoot()) { + if (TpmType == dTpm12) { + NewEventHdr.PCRIndex = 6; + } else { + NewEventHdr.PCRIndex = 7; + } + NewEventHdr.EventType = EV_EFI_VARIABLE_DRIVER_CONFIG; + CaculateAuthorityPCRExtendValue (&NewEventHdr.Digest); + + if (IsNpwAcm()) { + NewEventHdr.EventSize = sizeof (L"Boot Guard Debug Measured S-CRTM"); + LogEvent (&NewEventHdr, (UINT8 *)L"Boot Guard Debug Measured S-CRTM"); + } else { + NewEventHdr.EventSize = sizeof (L"Boot Guard Measured S-CRTM"); + LogEvent (&NewEventHdr, (UINT8 *)L"Boot Guard Measured S-CRTM"); + } + } +} + +/** + Create Boot Guard TPM event log + + @param[in] TpmType Which type of TPM is available on system. +**/ +VOID +CreateTpmEventLog ( + IN TPM_TYPE TpmType + ) +{ + if (IsMeasuredBoot()) { + CreateDetailPcrEvent (TpmType); + CreateAuthorityPcrEvent (TpmType); + } +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif new file mode 100644 index 0000000..06d608a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif @@ -0,0 +1,11 @@ +<component> + name = "BootGuardTpmEventLogLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\BootGuardTpmEventLogLib" + RefName = "BootGuardTpmEventLogLib" +[files] +"BootGuardTpmEventLogLib.sdl" +"BootGuardTpmEventLogLib.mak" +"BootGuardTpmEventLogLib.c" +"BootGuardTpmEventLogLib.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h new file mode 100644 index 0000000..ca91990 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h @@ -0,0 +1,33 @@ +/** @file + Header file for Boot Guard TPM event log. + +@copyright + Copyright (c) 2013 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 +**/ +#ifndef _BOOT_GUARD_TPM_EVENT_LOG_LIB_H_ +#define _BOOT_GUARD_TPM_EVENT_LOG_LIB_H_ + +#include EFI_PPI_DEFINITION (CpuPlatformPolicy) + +/** + Create Boot Guard TPM event log + + @param[in] TpmType - Which type of TPM is available on system. +**/ +VOID +CreateTpmEventLog ( + IN TPM_TYPE TpmType + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak new file mode 100644 index 0000000..47a3d87 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : BootGuardTpmEventLogLib + +$(BUILD_DIR)\BootGuardTpmEventLogLib.lib : BootGuardTpmEventLogLib + +BootGuardTpmEventLogLib : $(BUILD_DIR)\BootGuardTpmEventLogLib.mak BootGuardTpmEventLogLibBin + +$(BUILD_DIR)\BootGuardTpmEventLogLib.mak : $(BootGuardTpmEventLogLib_DIR)\$(@B).cif $(BootGuardTpmEventLogLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(BootGuardTpmEventLogLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +BootGuardTpmEventLogLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +BootGuardTpmEventLogLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +BootGuardTpmEventLogLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +BootGuardTpmEventLogLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\BootGuardTpmEventLogLib.mak all \ + "MY_INCLUDES=$(BootGuardTpmEventLogLib_INCLUDES)"\ + "MY_DEFINES=$(BootGuardTpmEventLogLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl new file mode 100644 index 0000000..37c7417 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = BootGuardTpmEventLogLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable BootGuardTpmEventLogLib support in Project" +End + +MODULE + Help = "Includes BootGuardTpmEventLogLib.mak to Project" + File = "BootGuardTpmEventLogLib.mak" +End + +PATH + Name = "BootGuardTpmEventLogLib_DIR" +End + +ELINK + Name = "BootGuardTpmEventLogLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\BootGuardTpmEventLogLib.lib" + Parent = "BootGuardTpmEventLogLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c new file mode 100644 index 0000000..05878cd --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c @@ -0,0 +1,71 @@ +/** @file + Digital Thermal Sensor (DTS) SMM Library. + This SMM Library configures and supports the DigitalThermalSensor features + for the platform. + +@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 +**/ +#include "DTSHookLib.h" + +/** + Prepare data and protocol for Dts Hooe Lib + + @retval EFI_SUCCESS - Initialize complete +**/ +EFI_STATUS +InitializeDtsHookLib ( + VOID + ) +{ + /// + /// Nothing to do on CRB. + /// + return EFI_SUCCESS; +} + +/** + Platform may need to register some data to private data structure before generate + software SMI or SCI. +**/ +VOID +PlatformHookBeforeGenerateSCI ( + VOID + ) +{ + /// + /// Nothing to do on CRB. + /// +} + +/** + When system temperature out of specification, do platform specific programming to prevent + system damage. +**/ +VOID +PlatformEventOutOfSpec ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Handle critical event by shutting down via EC + /// + Status = InitializeKscLib (); + if (Status == EFI_SUCCESS) { + SendKscCommand (KSC_C_SYSTEM_POWER_OFF); + } +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.cif b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.cif new file mode 100644 index 0000000..6eddca3 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.cif @@ -0,0 +1,12 @@ +<component> + name = "DTSHookLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\DTSHookLib\Smm\" + RefName = "DTSHookLib" +[files] +"DTSHookLib.sdl" +"DTSHookLib.mak" +"DTSHookLib.inf" +"DTSHookLib.c" +"DTSHookLib.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.h b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.h new file mode 100644 index 0000000..7dfaa9b --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.h @@ -0,0 +1,27 @@ +/** @file + Defines and prototypes for the DigitalThermalSensor SMM driver + +@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 +**/ +#ifndef _DTS_LIB_H_ +#define _DTS_LIB_H_ +/// +/// Include files +/// +#include "Tiano.h" +#include "KscLib.h" + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf new file mode 100644 index 0000000..f4011cf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf @@ -0,0 +1,49 @@ +## @file +# Component description file. +# +#@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 = DTSHookLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + DTSHookLib.c + DTSHookLib.h + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(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 + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] + C_STD_INCLUDE= diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.mak b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.mak new file mode 100644 index 0000000..9b10b29 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(DTSHookLib_LIB) : DTSHookLib + +DTSHookLib : $(BUILD_DIR)\DTSHookLib.mak DTSHookLibBin + +$(BUILD_DIR)\DTSHookLib.mak : $(DTSHookLib_DIR)\$(@B).cif $(DTSHookLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(DTSHookLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +DTSHookLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\DTSHookLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(DTSHookLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.sdl new file mode 100644 index 0000000..e49c48f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = DTSHookLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable DTSHookLib support in Project" +End + +TOKEN + Name = "DTSHookLib_LIB" + Value = "$$(LIB_BUILD_DIR)\DTSHookLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes DTSHookLib.mak to Project" + File = "DTSHookLib.mak" +End + +PATH + Name = "DTSHookLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.c b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.c new file mode 100644 index 0000000..079482f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.c @@ -0,0 +1,228 @@ +/** @file + SMM KSC library implementation. + + These functions need to be SMM safe. + + These functions require the SMM IO library (SmmIoLib) to be present. + Caller must link those libraries and have the proper include path. + +@copyright + Copyright (c) 1999 - 2013 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 +**/ +#include "KscLib.h" +#include "SmmIoLib.h" +#include "PchAccess.h" +#include "PchPlatformLib.h" + +BOOLEAN mSmmKscLibInitialized = FALSE; + +/// +/// Function implemenations +/// +/** + Initialize the library. + The SMM library only requires SMM IO library and has no initialization. + However, this must be called prior to use of any other KSC library functions + for future compatibility. + + @param[in] None. + + @retval EFI_SUCCESS - KscLib is successfully initialized. +**/ +EFI_STATUS +InitializeKscLib ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Fail if EC doesn't exist. + /// + if (SmmIoRead8 (KSC_C_PORT) == 0xff) { + mSmmKscLibInitialized = FALSE; + Status = EFI_DEVICE_ERROR; + } else { + mSmmKscLibInitialized = TRUE; + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + Sends command to Keyboard System Controller. + + @param[in] Command - Command byte to send + + @retval EFI_SUCCESS - Command success + @retval EFI_DEVICE_ERROR - Command error +**/ +EFI_STATUS +SendKscCommand ( + UINT8 Command + ) +{ + UINTN Index; + UINT8 KscStatus; + + KscStatus = 0; + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + /// + /// Wait for KSC to be ready (with a timeout) + /// + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_IBF) != 0) && (Index < KSC_TIME_OUT)) { + PchPmTimerStall(15); + ReceiveKscStatus (&KscStatus); + Index++; + } + + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + /// + /// Send the KSC command + /// + SmmIoWrite8 (KSC_C_PORT, Command); + + return EFI_SUCCESS; +} + +/** + Receives status from Keyboard System Controller. + + @param[in] KscStatus - Status byte to receive + + @retval EFI_DEVICE_ERROR - Ksc library has not initialized yet or KSC not present + @retval EFI_SUCCESS - Get KSC status successfully +**/ +EFI_STATUS +ReceiveKscStatus ( + UINT8 *KscStatus + ) +{ + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + /// + /// Read and return the status + /// + *KscStatus = SmmIoRead8 (KSC_C_PORT); + + return EFI_SUCCESS; +} + +/** + Sends data to Keyboard System Controller. + + @param[in] Data - Data byte to send + + @retval EFI_SUCCESS - Success + @retval EFI_DEVICE_ERROR - Error +**/ +EFI_STATUS +SendKscData ( + UINT8 Data + ) +{ + UINTN Index; + UINT8 KscStatus; + + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + /// + /// Wait for KSC to be ready (with a timeout) + /// + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_IBF) != 0) && (Index < KSC_TIME_OUT)) { + PchPmTimerStall(15); + ReceiveKscStatus (&KscStatus); + Index++; + } + + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + /// + /// Send the data and return + /// + SmmIoWrite8 (KSC_D_PORT, Data); + + return EFI_SUCCESS; +} + +/** + Receives data from Keyboard System Controller. + + @param[in] Data - Data byte received + + @retval EFI_SUCCESS - Read success + @retval EFI_DEVICE_ERROR - Read error +**/ +EFI_STATUS +ReceiveKscData ( + UINT8 *Data + ) +{ + UINTN Index; + UINT8 KscStatus; + + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + /// + /// Wait for KSC to be ready (with a timeout) + /// + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_OBF) == 0) && (Index < KSC_TIME_OUT)) { + PchPmTimerStall(15); + ReceiveKscStatus (&KscStatus); + Index++; + } + + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + /// + /// Read KSC data and return + /// + *Data = SmmIoRead8 (KSC_D_PORT); + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.cif b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.cif new file mode 100644 index 0000000..3ee7072 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.cif @@ -0,0 +1,11 @@ +<component> + name = "SmmKscLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\Ksc\Smm" + RefName = "SmmKscLib" +[files] +"SmmKscLib.sdl" +"SmmKscLib.mak" +"SmmKscLib.c" +"SmmKscLib.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.inf b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.inf new file mode 100644 index 0000000..478ca1a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.inf @@ -0,0 +1,51 @@ +## @file +# Component description file. +# +#@copyright +# Copyright (c) 1999 - 2013 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 = SmmKscLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + SmmKscLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(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 + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library + +[libraries.common] + EdkFrameworkProtocolLib + PchPlatformLib + +[nmake.common] + C_STD_INCLUDE= diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.mak b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.mak new file mode 100644 index 0000000..ee3a5b0 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(SmmKscLib_LIB) : SmmKscLib + +SmmKscLib : $(BUILD_DIR)\SmmKscLib.mak SmmKscLibBin + +$(BUILD_DIR)\SmmKscLib.mak : $(SmmKscLib_DIR)\$(@B).cif $(SmmKscLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmmKscLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +SmmKscLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\SmmKscLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(SmmKscLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.sdl new file mode 100644 index 0000000..46ce94f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = SmmKscLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable SmmKscLib support in Project" +End + +TOKEN + Name = "SmmKscLib_LIB" + Value = "$$(LIB_BUILD_DIR)\SmmKscLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes SmmKscLib.mak to Project" + File = "SmmKscLib.mak" +End + +PATH + Name = "SmmKscLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c new file mode 100644 index 0000000..9f1e19d --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c @@ -0,0 +1,169 @@ +/** @file + SMM I/O access utility implementation file, for Ia32 + +@copyright + Copyright (c) 1999 - 2013 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 +**/ + +/// +/// Include files +/// +#include "SmmIoLib.h" + +/** + Do a one byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT8 +SmmIoRead8 ( + IN UINT16 Address + ) +{ + UINT8 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a one byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite8 ( + IN UINT16 Address, + IN UINT8 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Data + ); +} + +/** + Do a two byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT16 +SmmIoRead16 ( + IN UINT16 Address + ) +{ + UINT16 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a two byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite16 ( + IN UINT16 Address, + IN UINT16 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Data + ); +} + +/** + Do a four byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT32 +SmmIoRead32 ( + IN UINT16 Address + ) +{ + UINT32 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a four byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite32 ( + IN UINT16 Address, + IN UINT32 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Data + ); +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif new file mode 100644 index 0000000..ec8cae7 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif @@ -0,0 +1,12 @@ +<component> + name = "SmmIoLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\SmmIo" + RefName = "SmmIoLib" +[files] +"SmmIoLib.sdl" +"SmmIoLib.mak" +"SmmIoLib.inf" +"SmmIo.c" +"SmmPciIo.c" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf new file mode 100644 index 0000000..43045eb --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf @@ -0,0 +1,48 @@ +## @file +# Component description file. +# +#@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 = SmmIoLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + SmmIo.c + SmmPciIo.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(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 + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak new file mode 100644 index 0000000..12b9d5e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(SmmIoLib_LIB) : SmmIoLib + +SmmIoLib : $(BUILD_DIR)\SmmIoLib.mak SmmIoLibBin + +$(BUILD_DIR)\SmmIoLib.mak : $(SmmIoLib_DIR)\$(@B).cif $(SmmIoLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmmIoLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +SmmIoLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\SmmIoLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(SmmIoLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl new file mode 100644 index 0000000..537a750 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = SmmIoLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable SmmIoLib support in Project" +End + +TOKEN + Name = "SmmIoLib_LIB" + Value = "$$(LIB_BUILD_DIR)\SmmIoLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes SmmIoLib.mak to Project" + File = "SmmIoLib.mak" +End + +PATH + Name = "SmmIoLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c new file mode 100644 index 0000000..f6fd18f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c @@ -0,0 +1,161 @@ +/** @file + SMM PCI config space I/O access utility implementation file, for Ia32 + +@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 +**/ +#include "SmmIoLib.h" + +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO_INTERFACE *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); + +/** + Read value from the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgRead ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO_INTERFACE *SmmCpuIo; + + ASSERT (mSmst); + + SmmCpuIo = &(mSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, FALSE, Width, Address, Buffer); +} + +/** + Write value into the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgWrite ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO_INTERFACE *SmmCpuIo; + + ASSERT (mSmst); + + SmmCpuIo = &(mSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, TRUE, Width, Address, Buffer); +} + +/** + Access a PCI config space address, including read and write + + @param[in] CpuIo - The cpu I/O accessing interface provided by EFI runtime sys table + @param[in] IsWrite - Indicates whether this operation is a write access or read + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value when this is a reading operation or the data + to be written when this is a writing one + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO_INTERFACE *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + PCI_CONFIG_ACCESS_CF8 PciCf8Data; + UINT64 PciDataReg; + + /// + /// PCI Config access are all 32-bit alligned, but by accessing the + /// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types + /// are possible on PCI. + /// + /// To read a byte of PCI config space you load 0xcf8 and + /// read 0xcfc, 0xcfd, 0xcfe, 0xcff + /// + /// The validation of passed in arguments "Address" will be checked in the + /// CPU IO functions, so we don't check them here + /// + if (Width >= SmmPciWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + PciCf8Data.Reg = Address->Register & 0xfc; + PciCf8Data.Func = Address->Function; + PciCf8Data.Dev = Address->Device; + PciCf8Data.Bus = Address->Bus; + PciCf8Data.Reserved = 0; + PciCf8Data.Enable = 1; + + Status = CpuIo->Io.Write (CpuIo, SmmPciWidthUint32, 0xcf8, 1, &PciCf8Data); + if (EFI_ERROR (Status)) { + return Status; + } + + PciDataReg = 0xcfc + (Address->Register & 0x03); + + if (IsWrite) { + /// + /// This is a Pci write operation, write data into (0xcfc + offset) + /// + Status = CpuIo->Io.Write (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + /// + /// This is a Pci Read operation, read returned data from (0xcfc + offset) + /// + Status = CpuIo->Io.Read (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} |