summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/Txt/TxtInit
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/Txt/TxtInit')
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.c171
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.cif18
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.dxs50
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.inf117
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.mak72
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.sdl27
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.c1080
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.h289
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeOem.c78
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/Mmx64.inc494
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeAp.asm364
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeBsp.asm712
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16305
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf35
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf35
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm1387
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new69
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.c241
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.dxs49
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.inf104
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.mak105
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.sdl86
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.c1045
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.h560
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Txtpei.cif19
25 files changed, 7512 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.c b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.c
new file mode 100644
index 0000000..ef7ca8b
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.c
@@ -0,0 +1,171 @@
+/** @file
+ This is the main DXE file for TXT. It represents an abstract outline of the
+ steps required during DXE for enabling TXT. Each individual step is further
+ abstracted behind a function call interface. This is intended to minimize
+ the need to modify this file when porting TXT to future platforms.
+
+@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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "Txt.h"
+#include "TxtDxeLib.h"
+#endif
+
+TXT_DXE_LIB_CONTEXT mTxtDxeCtx;
+
+/**
+ This function gets registered as a callback to run the SCHECK function
+ from the TXT BIOS ACM as a result of Boot Events.
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+
+ @retval EFI_SUCCESS - Always.
+
+ **/
+EFI_STATUS
+EFIAPI
+ScheckCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DEBUG ((EFI_D_INFO, "TXTDXE::Running of DoScheck\n"));
+
+ DoScheck (&mTxtDxeCtx);
+ ///
+ /// Closed the event to avoid call twice when launch shell
+ ///
+ gBS->CloseEvent (Event);
+
+ return EFI_SUCCESS;
+}
+/**
+ This is the entry point to the TXT DXE Driver. This routine checks to see if
+ the platform should be configured for TXT and if so, configures the platform
+ by reserving and initializing TXT Configuration Space and TXT Device Memory and
+ registering a callback to run SCHECK from the TXT BIOS ACM prior to boot.
+
+ If the platform should not be configured for TXT, this routine checks the
+ establishment bit in the TPM and resets it if it is asserted.
+
+ @param[in] ImageHandle - A handle for this module
+ @param[in] SystemTable - A pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - If TXT initialization succeed
+ @retval EFI_UNLOAD_IMAGE - If TXT criterias are not met
+**/
+EFI_STATUS
+EFIAPI
+DriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT ReadyToBootEvent;
+ ///
+ /// Initialize the platform specific code
+ ///
+ Status = InitializeTxtDxeLib (ImageHandle, SystemTable, &mTxtDxeCtx);
+ ///
+ /// If failure - assume TXT is not enabled
+ ///
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TXTDXE::InitializeTxtDxeLib failed.... Unloading\n"));
+ return EFI_UNLOAD_IMAGE;
+ }
+ ///
+ /// If ESTS.TXTRESET bit is set, skip all other functions since
+ /// attempt to execute GETSEC will hang system. Skipping allows to
+ /// boot to OS and let MLE assess situation.
+ ///
+ if (IsTxtResetSet (&mTxtDxeCtx)) {
+ DEBUG ((EFI_D_ERROR, "TXTDXE::TXT_RESET bit is set.... Unloading\n"));
+ return EFI_UNLOAD_IMAGE;
+ }
+ ///
+ /// If TXT is enabled, configure platform appropriately.
+ /// Code assumes that if TXT is enabled by CPU driver than all checks
+ /// are passed, i.e. TPM is present, CPU and CS are TXT capable.
+ ///
+ ///
+ /// Add to check CPU TXT capable in case CPU drivers do not check additional requirements
+ ///
+ if ((mTxtDxeCtx.TxtInfoData->ChipsetIsTxtCapable) && IsTxtProcessor () && IsTxtEnabled (&mTxtDxeCtx)) {
+ DEBUG ((EFI_D_INFO, "TXTDXE::TXT Enabled\n"));
+ ///
+ /// Mark TXT Config Space as System Reserved in Memory Map
+ ///
+ ReserveTxtConfigSpace (&mTxtDxeCtx);
+
+ ///
+ /// Allocate and Initialize TXT Device Memory
+ ///
+ Status = SetupTxtDeviceMemory (&mTxtDxeCtx);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TXTDXE::SetupTxtDeviceMemory failed.... Unloading\n"));
+ return EFI_UNLOAD_IMAGE;
+ }
+ ///
+ /// Create callback to run SCHECK on a Legacy Boot event
+ ///
+ Status = EfiCreateEventReadyToBootEx (
+ EFI_TPL_CALLBACK,
+ ScheckCallback,
+ NULL,
+ &ReadyToBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ } else {
+ ///
+ /// TXT is not enabled, so make sure TPM Establishment
+ /// bit is de-asserted
+ ///
+ DEBUG ((EFI_D_INFO, "TXTDXE::TXT Disabled\n"));
+
+ if (IsTxtEstablished (&mTxtDxeCtx)) {
+ ///
+ /// We can invoke BIOS ACM function only if CS and CPU are TXT
+ /// capable
+ ///
+ if ((mTxtDxeCtx.TxtInfoData->ChipsetIsTxtCapable) &&
+ IsTxtProcessor () &&
+ !(mTxtDxeCtx.TxtInfoData->Flags & TPM_INIT_FAILED)
+ ) {
+ DEBUG ((EFI_D_INFO, "TXTDXE::Resetting TPM Establishment bit\n"));
+ ResetTpmEstBit (&mTxtDxeCtx);
+ }
+ }
+ ///
+ /// Reset AUX
+ ///
+ Status = ResetTpmAux (&mTxtDxeCtx);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.cif b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.cif
new file mode 100644
index 0000000..2add449
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "TxtDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Haswell\Txt\TxtInit\Dxe\"
+ RefName = "TxtDxe"
+[files]
+"TxtDxe.c"
+"TxtDxe.dxs"
+"TxtDxe.mak"
+"TxtDxe.sdl"
+"TxtDxeLib.c"
+"TxtDxeLib.h"
+"TxtDxe.inf"
+"TxtDxeOem.c"
+"x64\TxtDxeBsp.asm"
+"x64\TxtDxeAp.asm"
+"x64\Mmx64.inc"
+<endComponent>
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.dxs b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.dxs
new file mode 100644
index 0000000..7120727
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.dxs
@@ -0,0 +1,50 @@
+/** @file
+ This is the Dependency expression for the TXT Dxe architectural 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
+
+**/
+
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+#include EFI_PROTOCOL_DEFINITION (MpService)
+#include EFI_PROTOCOL_DEFINITION (BootScriptSave)
+#include EFI_PROTOCOL_DEFINITION (SmmBase)
+#include EFI_PROTOCOL_DEFINITION (PciIo)
+#include EFI_PROTOCOL_DEFINITION (CpuIo)
+#include EFI_PROTOCOL_DEFINITION (CpuPlatformPolicy)
+#endif
+
+DEPENDENCY_START
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID AND
+ EFI_MP_SERVICES_PROTOCOL_GUID AND
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ DXE_CPU_PLATFORM_POLICY_PROTOCOL_GUID AND
+
+ EFI_CPU_IO_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.inf b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.inf
new file mode 100644
index 0000000..f6c1e20
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.inf
@@ -0,0 +1,117 @@
+## @file
+# Component description file for TXTDXE module
+#
+#@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 = TxtDxe
+FILE_GUID = FF917E22-A228-448d-BDAA-68EFCCDDA5D3
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ TxtDxe.c
+ TxtDxeLib.c
+ TxtDxeOem.c
+ X64/TxtDxeBsp.asm
+ X64/TxtDxeAp.asm
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ .
+ ./X64
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/Include
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Framework/Protocol
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Sample/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
+#
+# 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
+
+[libraries.common]
+ EfiGuidLib
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ EfiScriptLib
+ CpuGuidLib
+ CpuProtocolLib
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiLib
+ EdkIIGlueDxeHobLib
+ CpuProtocolLib
+
+#
+# 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.
+#
+ CpuSampleProtocolLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = TxtDxe.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=DriverEntry
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_UEFI_LIB__ \
+ -D __EDKII_GLUE_DXE_HOB_LIB__
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.mak b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.mak
new file mode 100644
index 0000000..876fc41
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.mak
@@ -0,0 +1,72 @@
+# MAK file for the ModulePart:TxtDxe
+#-jeff debug
+all : TxtDxe
+
+TxtDxe : $(BUILD_DIR)\TxtDxe.mak TxtDxeBin
+
+$(BUILD_DIR)\TxtDxe.mak : $(TxtDxe_DIR)\$(@B).cif $(TxtDxe_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TxtDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TxtDxe_INCLUDES=\
+ $(MISCFRAMEWORK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(PROJECT_CPU_INCLUDES)\
+ $(TXT_INCLUDES)\
+
+TxtDxe_DEFINES=\
+ $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=DriverEntry"\
+ /D PlatformPciExpressBaseAddress=$(PCIEX_BASE_ADDRESS) \
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_HOB_LIB__ \
+
+TxtDxe_LIBS=\
+ $(EFIGUIDLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibX64_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueBasePciExpressLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBaseTimerLibLocalApic_LIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+ $(EdkIIGlueHiiLib_LIB)\
+ $(EFIDRIVERLIB)\
+ $(UEFIEFIIFRSUPPORTLIB)\
+ $(EFISCRIPTLIB)\
+ $(CpuProtocolLib_LIB)\
+ $(CpuGuidLib_LIB)\
+ $(SaPcieDxeLib_LIB)\
+ $(CPUIA32LIB)
+
+TxtDxeBin : $(TxtDxe_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\TxtDxe.mak all\
+ "MY_INCLUDES=$(TxtDxe_INCLUDES)"\
+ "MY_DEFINES=$(TxtDxe_DEFINES)"\
+ "GUID=FF917E22-A228-448d-BDAA-68EFCCDDA5D3"\
+ "AFLAGS=$(AFLAGS) $(PROJECT_CPU_INCLUDES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER \
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(TxtDxe_DIR)\TxtDxe.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1\
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.sdl b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.sdl
new file mode 100644
index 0000000..c17f497
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxe.sdl
@@ -0,0 +1,27 @@
+TOKEN
+ Name = "TxtDxe_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TXT DXE init support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "TxtDxe_DIR"
+ Help = "TXT DXE source directory"
+End
+
+MODULE
+ Help = "Includes TXTDXE.mak into project"
+ File = "TXTDXE.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\TxtDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+ \ No newline at end of file
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.c b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.c
new file mode 100644
index 0000000..6aef615
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.c
@@ -0,0 +1,1080 @@
+/** @file
+ This file contains an implementation of the function call interfaces
+ required by the main TXT DXE file. Hopefully, future platform porting
+ tasks will be mostly limited to modifying the functions in this 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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "Txt.h"
+#include "TxtDxeLib.h"
+#include "EfiScriptLib.h"
+#include EFI_PROTOCOL_DEFINITION (PciIo)
+#include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo)
+#include EFI_PROTOCOL_DEPENDENCY (FirmwareVolume)
+#endif
+
+EFI_GUID mTxtBiosAcmPeiFileGuid = PEI_BIOS_ACM_FILE_GUID;
+
+UINT64 mMcuAddr;
+UINT64 mAcmBase;
+UINT64 mApMtrrTab[2 * (IA32_MTRR_PHYSMASK9 - IA32_MTRR_PHYSBASE0 + 1) + 1];
+UINT64 mApIdt[2];
+UINT64 mApCr4;
+UINT64 mApSavedIa32ThermInterruptMSR[2];
+UINT32 mApSavedApicThermalValue;
+
+/**
+ This routine initializes and collects all Protocols and data required
+ by the routines in this file.
+
+ @param[in] ImageHandle - A pointer to the Image Handle for this file.
+ @param[in] SystemTable - A pointer to the EFI System Table
+ @param[in] TxtDxeCtx - A pointer to a caller allocated data structure that contains
+ all of the Protocols and data required by the routines
+ in this file.
+
+ @retval EFI_SUCCESS - Return EFI_SUCCESS if no error happen
+ @retval EFI_UNLOAD_IMAGE - If TxtInfoHob is not found
+**/
+EFI_STATUS
+InitializeTxtDxeLib (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN OUT TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ TXT_INFO_HOB *TxtInfoHob;
+ UINTN tmp;
+
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+
+ TxtDxeCtx->ImageHandle = ImageHandle;
+ TxtDxeCtx->SystemTable = SystemTable;
+
+ ///
+ /// Find the TxtPolicyprotocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gDxeCpuPlatformPolicyProtocolGuid,
+ NULL,
+ (VOID **) &(TxtDxeCtx->CpuPlatformPolicy)
+ );
+
+ if (EFI_ERROR (Status)) {
+ TxtDxeCtx->CpuPlatformPolicy = NULL;
+ }
+ ///
+ /// Find the CpuIo protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiCpuIoProtocolGuid,
+ NULL,
+ (VOID **) &(TxtDxeCtx->CpuIo)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Find the MpService Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiMpServiceProtocolGuid,
+ NULL,
+ (VOID **) &(TxtDxeCtx->MpService)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Initialize CpuCount info. Current implemetation of
+ /// GetGeneralMPInfo doesn't honor optionality of arguments. Don't use
+ /// NULL pointers.
+ ///
+ Status = TxtDxeCtx->MpService->GetGeneralMPInfo (
+ TxtDxeCtx->MpService,
+ &(TxtDxeCtx->CpuCount),
+ &tmp,
+ &tmp,
+ &tmp,
+ &tmp
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Find TxtInfoHob
+ ///
+ HobList = GetFirstGuidHob (&gTxtInfoHobGuid);
+ if (HobList == NULL) {
+ return EFI_UNLOAD_IMAGE;
+ }
+
+ TxtInfoHob = (TXT_INFO_HOB *) HobList;
+ TxtDxeCtx->TxtInfoData = &(TxtInfoHob->Data);
+
+ ///
+ /// Print out the TxtInfo HOB
+ ///
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtInfoHob passed from platform as:\n"));
+ DEBUG ((EFI_D_INFO, "TXTDXE: ChipsetIsTxtCapable = %x\n", TxtDxeCtx->TxtInfoData->ChipsetIsTxtCapable));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtMode = %x\n", TxtDxeCtx->TxtInfoData->TxtMode));
+ DEBUG ((EFI_D_INFO, "TXTDXE: PmBase = %x\n", TxtDxeCtx->TxtInfoData->PmBase));
+ DEBUG ((EFI_D_INFO, "TXTDXE: SinitMemorySize = %x\n", TxtDxeCtx->TxtInfoData->SinitMemorySize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtHeapMemorySize = %x\n", TxtDxeCtx->TxtInfoData->TxtHeapMemorySize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtDprMemoryBase = %x\n", TxtDxeCtx->TxtInfoData->TxtDprMemoryBase));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtDprMemorySize = %x\n", TxtDxeCtx->TxtInfoData->TxtDprMemorySize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: BiosAcmBase = %x\n", TxtDxeCtx->TxtInfoData->BiosAcmBase));
+ DEBUG ((EFI_D_INFO, "TXTDXE: BiosAcmSize = %x\n", TxtDxeCtx->TxtInfoData->BiosAcmSize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: McuUpdateDataAddr = %x\n", TxtDxeCtx->TxtInfoData->McuUpdateDataAddr));
+ DEBUG ((EFI_D_INFO, "TXTDXE: SinitAcmBase = %x\n", TxtDxeCtx->TxtInfoData->SinitAcmBase));
+ DEBUG ((EFI_D_INFO, "TXTDXE: SinitAcmSize = %x\n", TxtDxeCtx->TxtInfoData->SinitAcmSize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TgaSize = %x\n", TxtDxeCtx->TxtInfoData->TgaSize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtLcpPdBase = %x\n", TxtDxeCtx->TxtInfoData->TxtLcpPdBase));
+ DEBUG ((EFI_D_INFO, "TXTDXE: TxtLcpPdSize = %x\n", TxtDxeCtx->TxtInfoData->TxtLcpPdSize));
+ DEBUG ((EFI_D_INFO, "TXTDXE: Flags = %x\n", TxtDxeCtx->TxtInfoData->Flags));
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines whether or not the platform has executed an TXT launch by
+ examining the TPM Establishment bit.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval TRUE - If the TPM establishment bit is asserted.
+ @retval FALSE - If the TPM establishment bit is unasserted.
+**/
+BOOLEAN
+IsTxtEstablished (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ EFI_STATUS Status;
+ UINT8 AccessReg;
+ UINT16 TimeOutCount;
+
+ ///
+ /// TO-DO: We might locate TCG protocol to access TPM status
+ ///
+ ///
+ /// Set TPM.ACCESS polling timeout about 750ms
+ ///
+ TimeOutCount = TPM_TIME_OUT;
+ do {
+ ///
+ /// Read TPM status register
+ ///
+ Status = TxtDxeCtx->CpuIo->Mem.Read (
+ TxtDxeCtx->CpuIo,
+ EfiCpuIoWidthUint8,
+ (UINT64) TPM_STATUS_REG_ADDRESS,
+ 1,
+ &AccessReg
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// if TPM.Access == 0xFF, TPM is not present
+ ///
+ if (AccessReg == 0xFF) {
+ return FALSE;
+ }
+ ///
+ /// Check tpmRegValidSts bit before checking establishment bit
+ ///
+ if ((AccessReg & 0x80) != 0x80) {
+ ///
+ /// Delay 1ms and read again
+ ///
+ gBS->Stall (1000);
+ } else {
+ ///
+ /// tpmRegValidSts set, we can check establishment bit now.
+ ///
+ break;
+ }
+
+ TimeOutCount--;
+ } while (TimeOutCount != 0);
+
+ ///
+ /// if tpmRegValidSts is not set, TPM is not usable
+ ///
+ if ((AccessReg & 0x80) != 0x80) {
+ DEBUG ((EFI_D_ERROR, "TXTDXE: TPM Valid Status is not set!! TPM.ACCESS=%x\n", AccessReg));
+ ASSERT (TRUE);
+ EFI_DEADLOOP ();
+ }
+ ///
+ /// The bit we're interested in uses negative logic:
+ /// If bit 0 == 1 then return False
+ /// Else return True
+ ///
+ return (AccessReg & 0x1) ? FALSE : TRUE;
+}
+
+/**
+ Determines whether or not the platform has executed an TXT launch by
+ examining the TPM Establishment bit.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval TRUE - If the TPM establishment bit is asserted.
+ @retval FALSE - If the TPM establishment bit is unasserted.
+**/
+BOOLEAN
+IsTxtResetSet (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ EFI_STATUS Status;
+ UINT8 EstsReg;
+
+ ///
+ /// TO-DO: We might locate TCG protocol to access TPM status
+ ///
+ ///
+ /// Read TPM status register
+ ///
+ Status = TxtDxeCtx->CpuIo->Mem.Read (
+ TxtDxeCtx->CpuIo,
+ EfiCpuIoWidthUint8,
+ (UINT64) TXT_PUBLIC_BASE + TXT_ERROR_STATUS_REG_OFF,
+ 1,
+ &EstsReg
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return (EstsReg & 0x1) ? TRUE : FALSE;
+}
+
+/**
+ Determines whether or not the platform requires initialization for TXT use.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval TRUE - If the the platoform should be configured for TXT.
+ @retval FALSE - If TXT is not to be used.
+**/
+BOOLEAN
+IsTxtEnabled (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+
+ UINT64 Ia32FeatureControl;
+ TXT_INFO_DATA *TxtInfoData;
+
+ TxtInfoData = TxtDxeCtx->TxtInfoData;
+
+ ///
+ /// If TxtInfoHob reported TXT disabled, return FALSE to indicate TXT should be be used
+ ///
+ if (TxtInfoData->TxtMode == 0) {
+ return FALSE;
+ }
+
+ Ia32FeatureControl = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
+
+ return ((Ia32FeatureControl & TXT_OPT_IN_VMX_AND_SMX_MSR_VALUE) == TXT_OPT_IN_VMX_AND_SMX_MSR_VALUE) ? TRUE : FALSE;
+}
+
+/**
+ Determines whether or not the current processor is TXT Capable.
+
+ @retval TRUE - If the current processor supports TXT
+ @retval FALSE - If the current processor does not support TXT
+**/
+BOOLEAN
+IsTxtProcessor (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegs;
+
+ AsmCpuid (1, &CpuidRegs.RegEax, &CpuidRegs.RegEbx, &CpuidRegs.RegEcx, &CpuidRegs.RegEdx);
+
+ return (CpuidRegs.RegEcx & B_CPUID_VERSION_INFO_ECX_SME) ? TRUE : FALSE;
+}
+
+/**
+ Add extened elements to BiosOsData
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+ @param[in] Type - The element's type
+ @param[in] Buffer - A pointer to buffer which need to append the element
+ @param[in] Size - return the size of the appened element.
+
+ @retval None
+**/
+VOID
+AppendElement (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN UINT32 Type,
+ IN VOID *Buffer,
+ OUT UINT32 *Size
+ )
+{
+ VOID *Element;
+ UINT32 NumberOfAcm;
+ UINT64 *AcmBase;
+
+ NumberOfAcm = 1;
+ AcmBase = NULL;
+ Element = NULL;
+ *Size = 0;
+
+ switch (Type) {
+ case HEAP_EXTDATA_TYPE_BIOS_SPEC_VER:
+ ///
+ /// Fill BIOS spec ver element
+ ///
+ Element = AllocatePool (sizeof (HEAP_BIOS_SPEC_VER_ELEMENT));
+
+ if (Element != NULL) {
+ *Size = sizeof (HEAP_BIOS_SPEC_VER_ELEMENT);
+ ((HEAP_BIOS_SPEC_VER_ELEMENT *) Element)->Header.Type = HEAP_EXTDATA_TYPE_BIOS_SPEC_VER;
+ ((HEAP_BIOS_SPEC_VER_ELEMENT *) Element)->Header.Size = sizeof (HEAP_BIOS_SPEC_VER_ELEMENT);
+ ((HEAP_BIOS_SPEC_VER_ELEMENT *) Element)->SpecVerMajor = TXT_BIOS_SPEC_VER_MAJOR;
+ ((HEAP_BIOS_SPEC_VER_ELEMENT *) Element)->SpecVerMinor = TXT_BIOS_SPEC_VER_MINOR;
+ ((HEAP_BIOS_SPEC_VER_ELEMENT *) Element)->SpecVerRevision = TXT_BIOS_SPEC_VER_REVISION;
+ }
+ break;
+
+ case HEAP_EXTDATA_TYPE_BIOSACM:
+ ///
+ /// Fill BIOS ACM element
+ ///
+ Element = AllocatePool (sizeof (HEAP_BIOSACM_ELEMENT) + NumberOfAcm * sizeof (UINT64));
+
+ if (Element != NULL) {
+ *Size = sizeof (HEAP_BIOSACM_ELEMENT) + sizeof (UINT64) * NumberOfAcm;
+ ((HEAP_BIOSACM_ELEMENT *) Element)->Header.Type = HEAP_EXTDATA_TYPE_BIOSACM;
+ ((HEAP_BIOSACM_ELEMENT *) Element)->Header.Size = sizeof (HEAP_BIOSACM_ELEMENT) + NumberOfAcm * sizeof (UINT64);
+ ((HEAP_BIOSACM_ELEMENT *) Element)->NumAcms = NumberOfAcm;
+ AcmBase = (UINT64 *) ((UINTN) Element + sizeof (HEAP_BIOSACM_ELEMENT));
+ *AcmBase = TxtDxeCtx->TxtInfoData->BiosAcmBase;
+ }
+ break;
+
+ case HEAP_EXTDATA_TYPE_END:
+ ///
+ /// Fill end type element
+ ///
+ Element = AllocatePool (sizeof (HEAP_EXT_DATA_ELEMENT));
+
+ if (Element != NULL) {
+ *Size = sizeof (HEAP_EXT_DATA_ELEMENT);
+ ((HEAP_EXT_DATA_ELEMENT *) Element)->Type = HEAP_EXTDATA_TYPE_END;
+ ((HEAP_EXT_DATA_ELEMENT *) Element)->Size = sizeof (HEAP_EXT_DATA_ELEMENT);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (Element != NULL) {
+ CopyMem (Buffer, Element, *Size);
+ FreePool (Element);
+ }
+}
+
+/**
+ Allocates 1 MB of 1MB-aligned memory for use as TXT Device Memory. Records
+ the location of TXT Device Memory in TXT Chipset registers and then adds
+ programming instructions for these registers into BootScript.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - TXT Device memory has been successfully initialized.
+ @exception EFI_UNSUPPORTED - TXT Device memory not available.
+**/
+EFI_STATUS
+SetupTxtDeviceMemory (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ EFI_PHYSICAL_ADDRESS TopAddr;
+ UINT64 *Ptr64;
+ UINT64 Value64;
+ UINT32 Value32;
+ UINT64 TxtHeapMemoryBase;
+ UINT64 TxtSinitMemoryBase;
+ BOOLEAN Locked;
+ BIOS_OS_DATA_REGION *BiosOsDataRegion;
+ TXT_INFO_DATA *TxtInfoData;
+ UINT8 *Ptr8;
+
+ TxtHeapMemoryBase = 0;
+ TxtSinitMemoryBase = 0;
+ Locked = FALSE;
+ Ptr8 = NULL;
+ Value32 = 0;
+
+ TxtInfoData = TxtDxeCtx->TxtInfoData;
+
+ if ((TxtInfoData == 0) ||
+ (TxtInfoData->TxtDprMemoryBase == 0) ||
+ (TxtInfoData->TxtDprMemorySize == 0) ||
+ (TxtInfoData->TxtHeapMemorySize == 0) ||
+ (TxtInfoData->SinitMemorySize == 0)
+ ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ ///
+ /// Use address passed from PEI
+ ///
+ TopAddr = TxtInfoData->TxtDprMemoryBase + TxtInfoData->TxtDprMemorySize;
+
+ TxtHeapMemoryBase = (UINT64) (TopAddr - TxtInfoData->TxtHeapMemorySize);
+
+ TxtSinitMemoryBase = TxtHeapMemoryBase - TxtInfoData->SinitMemorySize;
+ }
+ ///
+ /// Program TXT Device Memory Chipset Registers and record them in
+ /// BootScript so they will be saved and restored on S3
+ ///
+ ASSERT ((TopAddr & 0x0FFFFF) == 0);
+
+ ///
+ /// DPR registers
+ ///
+ Ptr64 = (UINT64 *) (UINTN) (TXT_PUBLIC_BASE + TXT_DPR_SIZE_REG_OFF);
+ Value64 = RShiftU64 (TxtInfoData->TxtDprMemorySize, 16) | 1;
+ *Ptr64 = Value64 | TopAddr;
+ ///
+ /// Assert error if programmed value is different from requested. This
+ /// means error is requested size.
+ ///
+ Value64 = *Ptr64;
+ ASSERT ((LShiftU64 ((Value64 & 0xFFE), 16)) == TxtInfoData->TxtDprMemorySize);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (UINTN) (Ptr64),
+ 2,
+ &Value64
+ );
+
+ ///
+ /// HEAP Registers
+ /// Program size register first
+ ///
+ Ptr64 = (UINT64 *) (UINTN) (TXT_PUBLIC_BASE + TXT_HEAP_SIZE_REG_OFF);
+
+ ///
+ /// Test register locked status. If locked, skip programming since
+ /// this will be done by BIOS ACM
+ ///
+ *Ptr64 = TEST_PATTERN;
+ Value64 = *Ptr64;
+ if (Value64 != TEST_PATTERN) {
+ Locked = TRUE;
+ } else {
+ ///
+ /// To be safe invert pattern and try again
+ ///
+ *Ptr64 = (UINT64) ~TEST_PATTERN;
+ Value64 = *Ptr64;
+ if (Value64 != (UINT64) ~TEST_PATTERN) {
+ Locked = TRUE;
+ }
+ }
+
+ if (!Locked) {
+
+ *Ptr64 = TxtInfoData->TxtHeapMemorySize;
+ ///
+ /// Assert error if programmed value is different from requested. This
+ /// means error is requested size.
+ ///
+ Value64 = *Ptr64;
+ ASSERT (Value64 == TxtInfoData->TxtHeapMemorySize);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (UINTN) (Ptr64),
+ 2,
+ &Value64
+ );
+
+ ///
+ /// Program base register.
+ ///
+ Ptr64 = (UINT64 *) (UINTN) (TXT_PUBLIC_BASE + TXT_HEAP_BASE_REG_OFF);
+ *Ptr64 = TxtHeapMemoryBase;
+
+ ///
+ /// Assert error if programmed value is different from requested. This
+ /// means error is requested size.
+ ///
+ Value64 = *Ptr64;
+ ASSERT (Value64 == TxtHeapMemoryBase);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (UINTN) (Ptr64),
+ 2,
+ &Value64
+ );
+ }
+ ///
+ /// SINIT Registers
+ /// Program size register first
+ ///
+ Ptr64 = (UINT64 *) (UINTN) (TXT_PUBLIC_BASE + TXT_SINIT_SIZE_REG_OFF);
+ *Ptr64 = TxtInfoData->SinitMemorySize;
+ ///
+ /// Assert error if programmed value is different from requested. This
+ /// means error is requested size.
+ ///
+ Value64 = *Ptr64;
+ ASSERT (Value64 == TxtInfoData->SinitMemorySize);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (UINTN) (Ptr64),
+ 2,
+ &Value64
+ );
+
+ ///
+ /// Program base register
+ ///
+ Ptr64 = (UINT64 *) (UINTN) (TXT_PUBLIC_BASE + TXT_SINIT_BASE_REG_OFF);
+ *Ptr64 = TxtSinitMemoryBase;
+ ///
+ /// Assert error if programmed value is different from requested. This
+ /// means error is requested size.
+ ///
+ Value64 = *Ptr64;
+ ASSERT (Value64 == TxtSinitMemoryBase);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (UINTN) (Ptr64),
+ 2,
+ &Value64
+ );
+
+ ///
+ /// Make sure TXT Device Memory has been zeroed
+ ///
+ ZeroMem (
+ (VOID *) ((UINTN) TxtSinitMemoryBase),
+ (UINTN) (TopAddr - TxtSinitMemoryBase)
+ );
+
+ if (TxtInfoData->TgaSize) {
+ ;
+ ///
+ /// Placeholder for Trusted graphics support
+ ///
+ }
+
+ Ptr64 = (UINT64 *) TxtHeapMemoryBase;
+ *Ptr64 = sizeof (BIOS_OS_DATA_REGION);
+ ///
+ /// BiosOsDataSize plus sizew of data size feld itself
+ ///
+ BiosOsDataRegion = (BIOS_OS_DATA_REGION *) (Ptr64 + 1);
+ BiosOsDataRegion->Version = BIOS_OS_DATAREGION_VERSION;
+ BiosOsDataRegion->BiosSinitSize = 0;
+ BiosOsDataRegion->LcpPdBase = TxtInfoData->TxtLcpPdBase;
+ BiosOsDataRegion->LcpPdSize = TxtInfoData->TxtLcpPdSize;
+ BiosOsDataRegion->NumOfLogicalProcessors = (UINT32) (TxtDxeCtx->CpuCount);
+ BiosOsDataRegion->Flags = TxtInfoData->Flags;
+ Ptr8 = (UINT8 *) (UINTN) &(BiosOsDataRegion->ExtData);
+ AppendElement (TxtDxeCtx, HEAP_EXTDATA_TYPE_BIOS_SPEC_VER, Ptr8, &Value32);
+ Ptr8 += Value32;
+ AppendElement (TxtDxeCtx, HEAP_EXTDATA_TYPE_BIOSACM, Ptr8, &Value32);
+ Ptr8 += Value32;
+ AppendElement (TxtDxeCtx, HEAP_EXTDATA_TYPE_END, Ptr8, &Value32);
+ Value64 = (UINT64) Ptr8 - TxtHeapMemoryBase + Value32;
+ *Ptr64 = Value64;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Adds and allocates architecturally defined TXT Configuration Space memory
+ region to GCD.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+ReserveTxtConfigSpace (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS BaseAddr;
+
+ BaseAddr = TXT_PRIVATE_BASE;
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ TXT_PRIVATE_BASE,
+ TXT_CONFIG_SPACE_LENGTH,
+ 0
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeReserved,
+ 12, ///< 4K Boundary
+ TXT_CONFIG_SPACE_LENGTH,
+ &BaseAddr,
+ TxtDxeCtx->ImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Invokes TxtDxeLibLaunchBiosAcm to execute the SCHECK function.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+DoScheck (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ return TxtDxeLibLaunchBiosAcm (TxtDxeCtx, TXT_LAUNCH_SCHECK);
+}
+
+/**
+ Invokes TxtDxeLibLaunchBiosAcm to reset the TPM's establishment bit.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+ResetTpmEstBit (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ return TxtDxeLibLaunchBiosAcm (TxtDxeCtx, TXT_RESET_EST_BIT);
+}
+
+/**
+ Sets up the system and then launches the TXT BIOS ACM to run the function
+ requested by AcmFunction.
+
+ @param[in] AcmFunction - Constant that represents the function from the BIOS ACM
+ that should be executed.
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - BIOS ACM is set up.
+ @retval EFI_INVALID_PARAMETER - Wrong data in TxtInfoHob.
+ @retval EFI_NOT_FOUND - BIOS ACM is not found
+**/
+EFI_STATUS
+TxtDxeLibLaunchBiosAcm (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN UINT64 AcmFunction
+ )
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ UINTN CpuCount;
+ UINTN MyCpuNumber;
+ UINTN Index;
+ UINTN i;
+ EFI_MP_SERVICES_PROTOCOL *MpService;
+
+ UINTN NoHandles;
+ EFI_HANDLE *Buffer;
+ UINTN Size;
+ UINT32 FvStatus;
+ EFI_FV_FILETYPE FileType;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN NumPages;
+ EFI_PHYSICAL_ADDRESS Addr;
+ EFI_PHYSICAL_ADDRESS AlignedAddr;
+
+ FwVol = NULL;
+ ///
+ /// Initialize local variables
+ ///
+ CpuCount = TxtDxeCtx->CpuCount;
+ MpService = TxtDxeCtx->MpService;
+ Size = 0;
+ FvStatus = 0;
+ NumPages = 0;
+ Addr = 0;
+
+ if (TxtDxeCtx->TxtInfoData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Get current running CPU number
+ ///
+ Status = MpService->WhoAmI (
+ MpService,
+ &MyCpuNumber
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if ((TxtDxeCtx->TxtInfoData->BiosAcmBase == 0) || (TxtDxeCtx->TxtInfoData->BiosAcmSize == 0)) {
+ ///
+ /// If no information about placement of TXT BIOS ACM has been
+ /// passed from PEI - find it and load into memory dynamically.
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NoHandles,
+ &Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (i = 0; i < NoHandles; i++) {
+
+ Status = gBS->HandleProtocol (
+ Buffer[i],
+ &gEfiFirmwareVolumeProtocolGuid,
+ (VOID **) &FwVol
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// No output buffer - get size only
+ ///
+ Status = FwVol->ReadFile (
+ FwVol,
+ &mTxtBiosAcmPeiFileGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+
+ ASSERT (Size);
+ ///
+ /// Assert if file not found.
+ ///
+ FreePool (Buffer);
+
+ if (FwVol == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Allocate 4K aligned memory to load BIOS ACM. For this allocate
+ /// 1 page more than BIOS ACM size.
+ ///
+ NumPages = (Size + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE;
+
+ ///
+ /// Allocate buffer for BIOS ACM
+ ///
+ Status = (gBS->AllocatePages) (AllocateAnyPages, EfiRuntimeServicesData, NumPages, &Addr);
+
+ ASSERT_EFI_ERROR (Status);
+
+ AlignedAddr = Addr &~(EFI_PAGE_SIZE - 1);
+ AlignedAddr = AlignedAddr < Addr ? (AlignedAddr + EFI_PAGE_SIZE) : AlignedAddr;
+
+ ///
+ /// Read BIOS ACM into prepared buffer.
+ ///
+ Status = FwVol->ReadFile (
+ FwVol,
+ &mTxtBiosAcmPeiFileGuid,
+ ((VOID **) &AlignedAddr),
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+ } else {
+ ///
+ /// Use address passed from PEI
+ ///
+ AlignedAddr = TxtDxeCtx->TxtInfoData->BiosAcmBase;
+ }
+ ///
+ /// Save AP configuration. Run on one AP since all must be programmed
+ /// identically
+ ///
+ MpService->StartupThisAP (
+ MpService,
+ (EFI_AP_PROCEDURE) ApSaveConfig,
+ 1,
+ NULL,
+ 0,
+ NULL
+ );
+
+ ///
+ /// Initialize APs. Prepare data for DoApInit
+ ///
+ mAcmBase = AlignedAddr;
+ mMcuAddr = TxtDxeCtx->TxtInfoData->McuUpdateDataAddr;
+
+ DisableSmiSources (TxtDxeCtx, TRUE);
+
+#if defined(TXT_RLP_INIT) && (TXT_RLP_INIT == 1)
+ ///
+ /// Execute DoApInit on every AP
+ ///
+ MpService->StartupAllAPs (
+ MpService,
+ (EFI_AP_PROCEDURE) DoApInit,
+ TRUE,
+ NULL,
+ MP_TIMEOUT_FOR_STARTUP_ALL_APS,
+ NULL,
+ NULL
+ );
+#endif
+ ///
+ /// Disable every AP and put in WFS state
+ ///
+ for (Index = 0; Index < CpuCount; Index++) {
+ if (Index != MyCpuNumber) {
+ ///
+ /// Halt CPU otherwise it will not be re-enabled
+ ///
+ Status = MpService->EnableDisableAP (
+ MpService,
+ Index,
+ FALSE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = MpService->SendIPI (
+ MpService,
+ Index,
+ 0,
+ DELIVERY_MODE_INIT
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ ///
+ /// Launch the BIOS ACM to run the requested function
+ ///
+ OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
+
+ LaunchBiosAcm (AlignedAddr, AcmFunction);
+
+ gBS->RestoreTPL (OldTpl);
+
+ ///
+ /// Free memory only if it was allocated
+ ///
+ if (Addr != 0) {
+ (gBS->FreePages)(Addr, NumPages);
+ }
+ ///
+ /// Restart APs
+ ///
+ for (Index = 0; Index < CpuCount; Index++) {
+ if (Index != MyCpuNumber) {
+ Status = MpService->EnableDisableAP (
+ MpService,
+ Index,
+ TRUE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ ///
+ /// Restore AP configuration
+ ///
+ Status = MpService->StartupAllAPs (
+ MpService,
+ (EFI_AP_PROCEDURE) ApRestoreConfig,
+ TRUE,
+ NULL,
+ MP_TIMEOUT_FOR_STARTUP_ALL_APS,
+ NULL,
+ NULL
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ DisableSmiSources (TxtDxeCtx, FALSE);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable or restore possible SMI sources before or after POST SCHECK
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+ @param[in] Operation - Boolean value telling what operation is requested:
+ TRUE - to save and then disable possible SMI sources
+ FALSE - to restore original SMI settings
+
+ @retval EFI_SUCCESS - always return EFI_SUCCESS
+**/
+EFI_STATUS
+DisableSmiSources (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN BOOLEAN Operation
+ )
+{
+ EFI_STATUS Status;
+ UINT64 GlobalSmiControlIoAddr;
+ UINT32 LocalApicBaseAddr;
+ static UINT64 SavedIa32ThermInterruptMSR;
+ static UINT32 SavedSmiControl;
+ static UINT32 SavedApicThermalValue;
+ BOOLEAN x2ApicEnabled;
+
+ x2ApicEnabled = (BOOLEAN) (((AsmReadMsr64 (MSR_IA32_APIC_BASE)) & (BIT11 + BIT10)) == BIT11 + BIT10);
+ GlobalSmiControlIoAddr = TxtDxeCtx->TxtInfoData->PmBase + 0x30;
+ LocalApicBaseAddr = ((UINT32) AsmReadMsr64 (MSR_IA32_APIC_BASE)) & BASE_ADDR_MASK;
+
+ if (Operation == TRUE) {
+ ///
+ /// Save IA32_THERMAL_INTERRUPT MSR and disable the interrupts
+ ///
+ SavedIa32ThermInterruptMSR = AsmReadMsr64 ((UINT32) IA32_THERM_INTERRUPT);
+ AsmWriteMsr64 (
+ (UINT32) IA32_THERM_INTERRUPT,
+ (UINT64) (SavedIa32ThermInterruptMSR &~(BIT0 + BIT1 + BIT2 + BIT4 + BIT15 + BIT23))
+ );
+ ///
+ /// Save THERMAL LVT in local APIC and mask THERMAL LVT
+ ///
+ if (x2ApicEnabled) {
+ SavedApicThermalValue = (UINT32) AsmReadMsr64 (MSR_EXT_XAPIC_LVT_THERM);
+ AsmWriteMsr64 (
+ MSR_EXT_XAPIC_LVT_THERM,
+ ((SavedApicThermalValue &~(B_INTERRUPT_MASK | B_DELIVERY_MODE | B_VECTOR)) | (B_INTERRUPT_MASK | V_MODE_SMI))
+ );
+ } else {
+ SavedApicThermalValue = *(UINT32 *) (UINTN) (LocalApicBaseAddr + LOCAL_APIC_THERMAL_DEF);
+ *(UINT32 *) (UINTN) (LocalApicBaseAddr + LOCAL_APIC_THERMAL_DEF) = (UINT32) ((SavedApicThermalValue &~(B_INTERRUPT_MASK | B_DELIVERY_MODE | B_VECTOR)) | (B_INTERRUPT_MASK | V_MODE_SMI));
+ }
+ ///
+ /// Save SMI control register and try to disable all SMIs indivitually.
+ ///
+ SavedSmiControl = IoRead32 ((UINTN) GlobalSmiControlIoAddr);
+ ///
+ /// We can not disable Global SMI since it should be locked after SCHECK. we can only disable SMI sources indivitually.
+ /// Call to TxtDxeOemDisableSmi() for platform specific SMIs.
+ ///
+ Status = TxtDxeOemDisableSmi (TxtDxeCtx, TRUE);
+ ASSERT_EFI_ERROR (Status);
+
+ IoWrite32 (
+ (UINTN) GlobalSmiControlIoAddr,
+ (UINT32) (SavedSmiControl & 0x01)
+ );
+ } else {
+ ///
+ /// We can not disable Global SMI since it should be locked after SCHECK. we can only disable SMI sources indivitually.
+ /// Restore original SMI setting after SCHECK
+ /// Call to TxtDxeOemDisableSmi() for platform specific SMIs.
+ ///
+ Status = TxtDxeOemDisableSmi (TxtDxeCtx, FALSE);
+ ASSERT_EFI_ERROR (Status);
+
+ IoWrite32 (
+ (UINTN) GlobalSmiControlIoAddr,
+ (UINT32) (SavedSmiControl)
+ );
+ ///
+ /// Restore IA32_THERMAL_INTERRUPT MSR
+ ///
+ AsmWriteMsr64 (
+ (UINT32) IA32_THERM_INTERRUPT,
+ (UINT64) SavedIa32ThermInterruptMSR
+ );
+ if (x2ApicEnabled) {
+ AsmWriteMsr64 (MSR_EXT_XAPIC_LVT_THERM, SavedApicThermalValue);
+ } else {
+ *(UINT32 *) (UINTN) (LocalApicBaseAddr + LOCAL_APIC_THERMAL_DEF) = (UINT32) SavedApicThermalValue;
+
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read policy protocol to reset AUX content
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - No error happend
+ @retval EFI_NOT_FOUND - TxtPolicyProtocol is not found
+**/
+EFI_STATUS
+ResetTpmAux (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ ///
+ /// Check if TxtPolicy protocol installed
+ ///
+ if (TxtDxeCtx->CpuPlatformPolicy == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ ///
+ ///
+ if (TxtDxeCtx->CpuPlatformPolicy->SecurityConfig->TxtFunctionConfig->ResetAux == 1) {
+ DEBUG ((EFI_D_INFO, "TXTDXE: Reset AUX content\n"));
+ Status = TxtDxeLibLaunchBiosAcm (TxtDxeCtx, TXT_RESET_AUX);
+ }
+
+ return Status;
+}
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.h b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.h
new file mode 100644
index 0000000..573a06a
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeLib.h
@@ -0,0 +1,289 @@
+/** @file
+ This file contains function definitions that can determine
+ the TXT capabilities of a platform during DXE and perform
+ certain specific platform tasks that are required for TXT
+ during DXE.
+
+@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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#ifndef _TXT_DXE_LIB_H_
+#define _TXT_DXE_LIB_H_
+
+#include EFI_PROTOCOL_DEFINITION (MpService)
+#include "CpuAccess.h"
+
+#include EFI_PROTOCOL_DEFINITION (BootScriptSave)
+#include EFI_PROTOCOL_DEFINITION (CpuIo)
+#include EFI_GUID_DEFINITION (TxtInfoHob)
+#include EFI_PROTOCOL_DEFINITION (CpuPlatformPolicy)
+
+///
+/// The following switch is used in EfiScriptLib.h file. If enabled -
+/// forces linking to EfiScriptLib library
+///
+#define BASE_ADDR_MASK 0xFFFFF000
+#define TEST_PATTERN 0x5A5A5A5A5A5A5A5A
+#define MP_TIMEOUT_FOR_STARTUP_ALL_APS 0 ///< Set 0 for BSP always wait for APs
+
+///
+/// Chispet register
+///
+#define TXT_OPT_IN_VMX_AND_SMX_MSR_VALUE 0xFF03
+
+#define IA32_MTRR_PHYSBASE0 0x200
+#define IA32_MTRR_PHYSMASK9 0x213
+
+#define LOCAL_APIC_THERMAL_DEF 0x330
+ #define B_INTERRUPT_MASK (1 << 16)
+ #define B_DELIVERY_MODE (0x07 << 8)
+ #define V_MODE_SMI (0x02 << 8)
+ #define B_VECTOR (0xFF << 0)
+
+#pragma pack(push, 1)
+typedef struct _TXT_DXE_LIB_CONTEXT_ {
+ EFI_HANDLE ImageHandle;
+ EFI_SYSTEM_TABLE *SystemTable;
+ EFI_CPU_IO_PROTOCOL *CpuIo;
+ EFI_MP_SERVICES_PROTOCOL *MpService;
+
+ UINTN CpuCount;
+ TXT_INFO_DATA *TxtInfoData;
+ DXE_CPU_PLATFORM_POLICY_PROTOCOL *CpuPlatformPolicy;
+} TXT_DXE_LIB_CONTEXT;
+#pragma pack(pop)
+
+/**
+ This routine initializes and collects all Protocols and data required
+ by the routines in this file.
+
+ @param[in] ImageHandle - A pointer to the Image Handle for this file.
+ @param[in] SystemTable - A pointer to the EFI System Table
+ @param[in] TxtDxeCtx - A pointer to a caller allocated data structure that contains
+ all of the Protocols and data required by the routines
+ in this file.
+
+ @retval EFI_SUCCESS - Return EFI_SUCCESS if no error happen
+ @retval EFI_UNLOAD_IMAGE - If TxtInfoHob is not found
+**/
+EFI_STATUS
+InitializeTxtDxeLib (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN OUT TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Determines whether or not the current processor is TXT Capable.
+
+ @retval TRUE - If the current processor supports TXT
+ @retval FALSE - If the current processor does not support TXT
+**/
+BOOLEAN
+IsTxtProcessor (
+ VOID
+ );
+/**
+ Determines whether or not the platform has executed an TXT launch by
+ examining the TPM Establishment bit.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval TRUE - If the TPM establishment bit is asserted.
+ @retval FALSE - If the TPM establishment bit is unasserted.
+**/
+BOOLEAN
+IsTxtEstablished (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+
+/**
+ Determines whether or not the platform has executed an TXT launch by
+ examining the TPM Establishment bit.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval TRUE - If the TPM establishment bit is asserted.
+ @retval FALSE - If the TPM establishment bit is unasserted.
+**/
+BOOLEAN
+IsTxtResetSet (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Determines whether or not the platform requires initialization for TXT use.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval TRUE - If the the platoform should be configured for TXT.
+ @retval FALSE - If TXT is not to be used.
+**/
+BOOLEAN
+IsTxtEnabled (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Adds and allocates architecturally defined TXT Configuration Space memory
+ region to GCD.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+ReserveTxtConfigSpace (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Allocates 1 MB of 1MB-aligned memory for use as TXT Device Memory. Records
+ the location of TXT Device Memory in TXT Chipset registers and then adds
+ programming instructions for these registers into BootScript.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - TXT Device memory has been successfully initialized.
+ @retval EFI_ERROR - TXT Device memory not awailable.
+**/
+EFI_STATUS
+SetupTxtDeviceMemory (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Invokes TxtDxeLibLaunchBiosAcm to execute the SCHECK function.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+DoScheck (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Invokes TxtDxeLibLaunchBiosAcm to reset the TPM's establishment bit.
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+ResetTpmEstBit (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+/**
+ Sets up the system and then launches the TXT BIOS ACM to run the function
+ requested by AcmFunction.
+
+ @param[in] AcmBase - Base address of BIOS ACM location
+ @param[in] Funct - Function number of BIOS ACM to be executed
+
+ @retval EFI_SUCCESS - Always.
+**/
+VOID
+LaunchBiosAcm (
+ IN UINT64 AcmBase,
+ IN UINT64 Funct
+ );
+
+/**
+ Sets up the system and then launches the TXT BIOS ACM to run the function
+ requested by AcmFunction.
+
+ @param[in] AcmFunction - Constant that represents the function from the BIOS ACM
+ that should be executed.
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+TxtDxeLibLaunchBiosAcm (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN UINT64 AcmFunction
+ );
+/**
+ AP initial routine executed through MP service for TXT SCHECK
+**/
+VOID
+DoApInit (
+ VOID
+ );
+
+/**
+ Save AP configuration routine executed through MP service for TXT SCHECK
+**/
+VOID
+ApSaveConfig (
+ VOID
+ );
+
+/**
+ Restore AP configuration routine executed through MP service for TXT SCHECK
+**/
+VOID
+ApRestoreConfig (
+ VOID
+ );
+
+/**
+ Disable or restore possible SMI sources before or after POST SCHECK
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+ @param[in] Operation - Boolean value telling what operation is requested:
+ TRUE - to save and then disable possible SMI sources
+ FALSE - to restore original SMI settings
+
+ @retval EFI_SUCCESS - always return EFI_SUCCESS
+**/
+EFI_STATUS
+DisableSmiSources (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN BOOLEAN Operation
+ );
+
+/**
+ This function gets called before/after run the SCHECK function, intend to avoid platform specific SMIs to interfere in BIOS POST
+ if BIOS SMM MP services or synchonization code is not well considered that some of APs are not waken up from Wait-for-SIPI state.
+ Function should preserve original SMI enabling setting in augument is TRUE, and then restore it in augurment is FALSE.
+ The caller is DisableSmiSources() in TxtDxeLib.c
+
+ @param[in] Operation = TRUE - Calling before SCHECK to saved and disable platform specific SMIs setting
+ = FALSE - Calling after SCHECK to restore platform specific SMIs setting
+
+ @retval EFI_SUCCESS - Always.
+**/
+extern
+EFI_STATUS
+EFIAPI
+TxtDxeOemDisableSmi (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN BOOLEAN Operation
+ );
+
+/**
+ Read policy protocol to reset AUX content
+
+ @param[in] TxtDxeCtx - A pointer to an initialized TXT DXE Context data structure
+
+ @retval EFI_SUCCESS - No error happend
+ @retval EFI_NOT_FOUND - TxtPolicyProtocol is not found
+**/
+EFI_STATUS
+ResetTpmAux (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx
+ );
+
+#endif
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeOem.c b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeOem.c
new file mode 100644
index 0000000..bed83ec
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/TxtDxeOem.c
@@ -0,0 +1,78 @@
+/** @file
+ This file contain OEM/Platform implementation for TXT in DXE phase. It represents an abstract outline of the
+ steps required during DXE for enabling TXT. Each individual step is further
+ abstracted behind a function call interface. This is intended to minimize
+ the need to modify this file when porting TXT to future platforms.
+
+@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
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "Txt.h"
+#include "TxtDxeLib.h"
+#endif
+
+/**
+ This function gets called before/after run the SCHECK function, intend to avoid platform specific SMIs to interfere in BIOS POST
+ if BIOS SMM MP services or synchonization code is not well considered that some of APs are not waken up from Wait-for-SIPI state.
+ Function should preserve original SMI enabling setting in augument is TRUE, and then restore it in augurment is FALSE.
+ The caller is DisableSmiSources() in TxtDxeLib.c
+
+ @param[in] TxtDxeCtx - Point to TXT_DXE_LIB_CONTEXT structure
+ @param[in] Operation = TRUE - Calling before SCHECK to saved and disable platform specific SMIs setting
+ = FALSE - Calling after SCHECK to restore platform specific SMIs setting
+
+ @retval EFI_SUCCESS - Always.
+
+ **/
+EFI_STATUS
+EFIAPI
+TxtDxeOemDisableSmi (
+ IN TXT_DXE_LIB_CONTEXT *TxtDxeCtx,
+ IN BOOLEAN Operation
+ )
+{
+ static UINT16 SavedSmiControlDev29;
+ static UINT16 SavedSmiControlDev26;
+
+ if (Operation == TRUE) {
+ ///
+ /// Save and disable OEM/Platform specific SMIs
+ ///
+ /// Disable EHCI SMIs before giving control to TXT ACM. EHCI controller generating SMI during TXT ACM results in USB kbd issue
+ ///
+ SavedSmiControlDev26 = MmioRead16 (MmPciAddress (0, 0, 0, 0x1A, 0x6C));
+ SavedSmiControlDev29 = MmioRead16 (MmPciAddress (0, 0, 0, 0x1D, 0x6C));
+
+ MmioWrite16 (MmPciAddress (0, 0, 0, 0x1A, 0x6C), 0);
+ MmioWrite16 (MmPciAddress (0, 0, 0, 0x1D, 0x6C), 0);
+ } else {
+ ///
+ /// Restore or re-enable OEM/Platform specific SMIs
+ ///
+ /// Enable EHCI SMIs before giving control to TXT ACM.
+ ///
+ MmioWrite16 (MmPciAddress (0, 0, 0, 0x1A, 0x6C), SavedSmiControlDev26);
+ MmioWrite16 (MmPciAddress (0, 0, 0, 0x1D, 0x6C), SavedSmiControlDev29);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/Mmx64.inc b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/Mmx64.inc
new file mode 100644
index 0000000..027e32e
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/Mmx64.inc
@@ -0,0 +1,494 @@
+;@file
+; This file contains macros supporting 64 bit assembly
+;
+;@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 an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: _movq
+;
+; Input: rxx - general perpose 64 bit register
+; mmx - MMX register
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Performs "movq rxx, mmx" and "movq mmx, rxx" operations
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+_movq MACRO toReg:REQ, frReg:REQ
+ LOCAL gReg, mReg, op
+ db 48h ; ; REX.W prefix
+IFIDNI <toReg>, <rax>
+ gReg = 00h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rcx>
+ gReg = 01h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rdx>
+ gReg = 02h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rbx>
+ gReg = 03h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rsp>
+ gReg = 04h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rbp>
+ gReg = 05h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rsi>
+ gReg = 06h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <rdi>
+ gReg = 07h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <mm0>
+ mReg = 0C0h + 0 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm1>
+ mReg = 0C0h + 1 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm2>
+ mReg = 0C0h + 2 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm3>
+ mReg = 0C0h + 3 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm4>
+ mReg = 0C0h + 4 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm5>
+ mReg = 0C0h + 5 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm6>
+ mReg = 0C0h + 6 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm7>
+ mReg = 0C0h + 7 * 08h
+ op = 6Eh
+ENDIF
+
+;; If op = 7E format movq rxx, mmx
+
+IFIDNI <frReg>, <rax>
+ gReg = 00h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rcx>
+ gReg = 01h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rdx>
+ gReg = 02h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rbx>
+ gReg = 03h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rsp>
+ gReg = 04h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rbp>
+ gReg = 05h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rsi>
+ gReg = 06h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <rdi>
+ gReg = 07h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm0>
+ mReg = 0C0h + 0 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm1>
+ mReg = 0C0h + 1 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm2>
+ mReg = 0C0h + 2 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm3>
+ mReg = 0C0h + 3 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm4>
+ mReg = 0C0h + 4 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm5>
+ mReg = 0C0h + 5 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm6>
+ mReg = 0C0h + 6 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm7>
+ mReg = 0C0h + 7 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ENDIF
+ db 0Fh, op, gReg + mReg
+ENDM
+
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: _movd
+;
+; Input: exx - general perpose 32 bit register
+; mmx - MMX register
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Performs "movd exx, mmx" and "movd mmx, exx" operations
+; coded to perform in compatibility or protected mode but
+; assembled by ml64
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+
+_movd MACRO toReg:REQ, frReg:REQ
+ LOCAL gReg, mReg, op
+IFIDNI <toReg>, <eax>
+ gReg = 00h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <ecx>
+ gReg = 01h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <edx>
+ gReg = 02h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <ebx>
+ gReg = 03h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <esp>
+ gReg = 04h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <ebp>
+ gReg = 05h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <esi>
+ gReg = 06h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <edi>
+ gReg = 07h
+ op = 7Eh
+ELSEIFIDNI <toReg>, <mm0>
+ mReg = 0C0h + 0 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm1>
+ mReg = 0C0h + 1 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm2>
+ mReg = 0C0h + 2 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm3>
+ mReg = 0C0h + 3 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm4>
+ mReg = 0C0h + 4 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm5>
+ mReg = 0C0h + 5 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm6>
+ mReg = 0C0h + 6 * 08h
+ op = 6Eh
+ELSEIFIDNI <toReg>, <mm7>
+ mReg = 0C0h + 7 * 08h
+ op = 6Eh
+ENDIF
+
+;; If op = 7E format movq exx, mmx
+
+IFIDNI <frReg>, <eax>
+ gReg = 00h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <ecx>
+ gReg = 01h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <edx>
+ gReg = 02h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <ebx>
+ gReg = 03h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <esp>
+ gReg = 04h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <ebp>
+ gReg = 05h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <esi>
+ gReg = 06h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <edi>
+ gReg = 07h
+ IF op EQ 7Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm0>
+ mReg = 0C0h + 0 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm1>
+ mReg = 0C0h + 1 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm2>
+ mReg = 0C0h + 2 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm3>
+ mReg = 0C0h + 3 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm4>
+ mReg = 0C0h + 4 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm5>
+ mReg = 0C0h + 5 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm6>
+ mReg = 0C0h + 6 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ELSEIFIDNI <frReg>, <mm7>
+ mReg = 0C0h + 7 * 08h
+ IF op EQ 6Eh
+ .ERR
+ ENDIF
+ENDIF
+ db 0Fh, op, gReg + mReg
+ENDM
+
+;-----------------------------------------------------------------------------
+; 64 bit macros
+;
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: PUSHA_64
+;
+; Input: None
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Saves all registers on stack
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+PUSHA_64 MACRO
+ push rsp
+ push rbp
+ push rax
+ push rbx
+ push rcx
+ push rdx
+ push rsi
+ push rdi
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+ENDM
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: POPA_64
+;
+; Input: None
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Restores all registers from stack
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+POPA_64 MACRO
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rdx
+ pop rcx
+ pop rbx
+ pop rax
+ pop rbp
+ pop rsp
+ENDM
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: START_FRAME
+;
+; Input: None
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Starts frame declaration. Creates variable to hold total
+; size of all local vars.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+START_FRAME MACRO
+ SZ = 0
+ENDM
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: MAKE_LOCAL
+;
+; Input: ARG - var definition in form Label[Count]:QuolifiedType
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Defines local procedure variable. Adds size of created variable
+; to total size of locals.
+; size of all local vars.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+MAKE_LOCAL MACRO ARG:REQ
+ LOCAL brk, rbrk, clm, lbl, cnt, qtp
+ brk INSTR <ARG>, <[>
+ rbrk INSTR <ARG>, <]>
+ clm INSTR <ARG>, <:>
+ IF brk GT 0
+ lbl SUBSTR <ARG>, 1, brk-1
+ cnt SUBSTR <ARG>, brk+1, rbrk-brk-1
+ qtp SUBSTR <ARG>, clm+1
+ LOCAL lbl[cnt]:qtp
+ ELSE
+ lbl SUBSTR <ARG>, 1, clm-1
+ qtp SUBSTR <ARG>, clm+1
+ LOCAL lbl:qtp
+ ENDIF
+
+ SZ = SZ + sizeof lbl
+ENDM
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Macro: END_FRAME
+;
+; Input: None
+;
+; Output: None
+;
+; Registers:
+;
+; Description: Ends frame declaration. Creates stack sufficient to hold
+; all declared variables.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+END_FRAME MACRO
+ SZ = SZ + 10h ; Margin
+ enter SZ, 0 ; With spare room on stack
+ .allocstack SZ
+ .endprolog
+ENDM
+
+
+
+SAVED_GDT TEXTEQU <mm0>
+SAVED_SS TEXTEQU <mm1>
+SAVED_ESP TEXTEQU <mm2>
+SAVED_EBP TEXTEQU <mm3>
+ \ No newline at end of file
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeAp.asm b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeAp.asm
new file mode 100644
index 0000000..f1c44b9
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeAp.asm
@@ -0,0 +1,364 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;
+;/*++
+;
+; Copyright (c) 1999 - 2011 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.
+;
+;
+; Module Name:
+;
+; TxtDxeAp.asm
+;
+; Abstract:
+;
+; This file contains DXE AP initialization code.
+;
+;--*/
+
+ .xlist
+ include txt.inc
+ include mmx64.inc
+ .list
+
+
+ _TEXT SEGMENT
+
+
+EXTERN mAcmBase:QWORD
+EXTERN mMcuAddr:QWORD
+EXTERN mApMtrrTab:QWORD
+EXTERN mApIdt:QWORD
+EXTERN mApCr4:QWORD
+EXTERN mApSavedIa32ThermInterruptMSR:QWORD
+EXTERN mApSavedApicThermalValue:DWORD
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: DoApInit
+;
+; Input: AcmBase - Base address of LT BIOS ACM
+; McuAddr - Address of MCU patch in flash
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Initiatialize AP before GETSEC as per TXT BWG
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+DoApInit PROC FRAME
+
+ START_FRAME
+ MAKE_LOCAL ACM_SIZE_TO_CACHE:QWORD
+ MAKE_LOCAL ACM_BASE_TO_CACHE:QWORD
+ MAKE_LOCAL NEXT_MTRR_INDEX:QWORD
+ MAKE_LOCAL NEXT_MTRR_SIZE:QWORD
+ ; jmp $
+ END_FRAME
+
+ pushf
+ cli
+ PUSHA_64
+ ;
+ ; Check uCode was loaded or not
+ ;
+ mov rcx, MCU_REV_MSR
+ xor rax, rax
+ xor rdx, rdx
+ wrmsr
+ mov rax, 1
+ cpuid
+ mov rcx, MCU_REV_MSR
+ rdmsr
+ or rdx, rdx
+ jnz uCode_loaded
+
+ ;
+ ; Load uCode update
+ ;
+ mov rax, 1
+ cpuid
+
+ mov rax, mMcuAddr
+ lea rax, [rax + SIZEOF MCU] ; RAX -> MCU data (after header)
+ xor rdx, rdx
+ mov rcx, MCU_LOAD_MSR ; Trigger to load MCU
+
+ wrmsr ; Load MCU
+
+ mov rax, 1
+ cpuid
+uCode_loaded:
+;-----------------------------------------------------------------------------
+;
+; Section: Initial RLPs cache requirements
+;
+; Description: Ensure CR0.CD and CR0.NW are cleared
+;
+;-----------------------------------------------------------------------------
+ ;
+ ; Clear CR0.CD and CR0.NW
+ ;
+ mov rax, cr0
+ and rax, NOT (CR0_CD_MASK + CR0_NW_MASK)
+ mov cr0, rax
+
+;-----------------------------------------------------------------------------
+;
+; Section: Clean all MCi_STATUS MSR registers
+;
+; Description: MCA registers are cleaned
+;
+;-----------------------------------------------------------------------------
+
+ mov rcx, MCG_CAP
+ rdmsr
+ movzx rbx, al ; ebx = MCR bank count
+ xor rax, rax ; Write 0 into all MCi_STATUS registers
+ xor rdx, rdx
+ mov rcx, MC0_STATUS
+
+McaErrorCleanLoopStart:
+ wrmsr
+ dec rbx
+ jz @F
+ add rcx, 4 ; ecx = number of MSRs per bank
+ jmp McaErrorCleanLoopStart
+
+@@:
+
+ mov rcx,IA32_APIC_BASE
+ rdmsr
+ and rax,BIT11+BIT10
+ cmp rax,BIT11+BIT10
+ jne x2ApicDisabled
+ mov rcx,EFI_MSR_EXT_XAPIC_LVT_THERM
+ rdmsr
+ and eax, NOT (B_INTERRUPT_MASK + B_DELIVERY_MODE + B_VECTOR)
+ or eax, (B_INTERRUPT_MASK + V_MODE_SMI)
+ wrmsr
+ jmp @f
+x2ApicDisabled:
+ ; mask thermal LVT
+ mov rcx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and rax, BASE_ADDR_MASK ; Just need the address
+ mov edx, [rax+LOCAL_APIC_THERMAL_DEF]
+ and edx, NOT (B_INTERRUPT_MASK + B_DELIVERY_MODE + B_VECTOR)
+ or edx, (B_INTERRUPT_MASK + V_MODE_SMI)
+ mov DWORD PTR [rax+LOCAL_APIC_THERMAL_DEF], edx ;disable DTS SMIs
+@@:
+ POPA_64
+ popf
+
+ leave
+ ret 0
+DoApInit ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: ApSaveConfig
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Saves AP configuration
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+ApSaveConfig PROC FRAME
+ START_FRAME
+ END_FRAME
+
+ pushf
+ cli
+ PUSHA_64
+
+ mov rcx, IA32_MTRR_CAP
+ rdmsr
+ and rax, 0FFh
+ shl rax, 1
+ mov rcx, rax
+
+ lea rbx, mApMtrrTab
+
+SaveNextMtrr:
+ add rcx, IA32_MTRR_PHYSBASE0 - 1
+ rdmsr
+ mov QWORD PTR [rbx+0], rax
+ mov QWORD PTR [rbx+8], rdx
+ sub rcx, IA32_MTRR_PHYSBASE0 - 1
+ add rbx, 10h
+ loop SaveNextMtrr
+
+ mov rcx, IA32_MTRR_DEF_TYPE
+ rdmsr
+ mov QWORD PTR [rbx+0], rax
+ mov QWORD PTR [rbx+8], rdx
+
+ lea rbx, mApIdt
+ sidt [rbx]
+ lea rbx, mApCr4
+ mov rax, cr4
+ mov QWORD PTR [rbx], rax
+
+ mov rcx,IA32_APIC_BASE
+ rdmsr
+ and rax,BIT11+BIT10
+ cmp rax,BIT11+BIT10
+ jne x2ApicDisabled
+ mov rcx,EFI_MSR_EXT_XAPIC_LVT_THERM
+ rdmsr
+ lea rbx, mApSavedApicThermalValue
+ mov DWORD PTR [rbx], eax ; read and save thermal LVT
+ jmp @f
+x2ApicDisabled:
+
+ mov rcx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and rax, BASE_ADDR_MASK ; Just need the address
+ lea rbx, mApSavedApicThermalValue
+ mov edx, DWORD PTR [rax+LOCAL_APIC_THERMAL_DEF]
+ mov DWORD PTR [rbx], edx ; read and save thermal LVT
+@@:
+ mov rcx, EFI_MSR_IA32_THERM_INTERRUPT
+ rdmsr ;
+ lea rbx, mApSavedIa32ThermInterruptMSR
+ mov QWORD PTR [rbx+0], rax
+ mov QWORD PTR [rbx+8], rdx
+ ;disable THERMAL INT
+ and rax, NOT (BIT0+BIT1+BIT2+BIT4+BIT15+BIT23)
+ wrmsr
+
+ wbinvd
+
+ POPA_64
+ popf
+
+ leave
+ ret 0
+ApSaveConfig ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: ApRestoreConfig
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Saves AP configuration
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+ApRestoreConfig PROC FRAME
+ START_FRAME
+ END_FRAME
+
+ pushf
+ cli
+ PUSHA_64
+
+ ;
+ ; Disable cache
+ ;
+ mov rax, cr0 ; set CR0:CD and CR0:NE, clear CR0:NW
+ or rax, CR0_CD_MASK OR CR0_NE_MASK
+ and rax, NOT CR0_NW_MASK
+ mov cr0, rax
+ wbinvd
+
+ mov rcx, IA32_MTRR_CAP
+ rdmsr
+ and rax, 0FFh
+ shl rax, 1
+ mov rcx, rax
+
+ lea rbx, mApMtrrTab
+
+RestoreNextMtrr:
+ add rcx, IA32_MTRR_PHYSBASE0 - 1
+ mov rax, QWORD PTR [rbx+0]
+ mov rdx, QWORD PTR [rbx+8]
+ wrmsr
+ sub rcx, IA32_MTRR_PHYSBASE0 - 1
+ add rbx, 10h
+ loop RestoreNextMtrr
+
+ mov rax, QWORD PTR [rbx+0]
+ mov rdx, QWORD PTR [rbx+8]
+ mov rcx, IA32_MTRR_DEF_TYPE
+ wrmsr
+
+ lea rbx, mApIdt
+ lidt FWORD PTR [rbx]
+ lea rbx, mApCr4
+ mov rax, QWORD PTR [rbx]
+ mov cr4, rax
+
+ mov rcx, EFI_MSR_IA32_THERM_INTERRUPT
+ lea rbx, mApSavedIa32ThermInterruptMSR
+ mov rax, QWORD PTR [rbx+0]
+ mov rdx, QWORD PTR [rbx+8]
+ wrmsr
+
+ mov rcx,IA32_APIC_BASE
+ rdmsr
+ and rax,BIT11+BIT10
+ cmp rax,BIT11+BIT10
+ jne x2ApicDisabled
+ mov rcx,EFI_MSR_EXT_XAPIC_LVT_THERM
+ lea rbx, mApSavedApicThermalValue
+ mov eax,DWORD PTR [rbx] ;restore thermal LVT
+ xor rdx,rdx
+ wrmsr
+ jmp @f
+x2ApicDisabled:
+
+ mov rcx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and rax, BASE_ADDR_MASK ; Just need the address
+ lea rbx, mApSavedApicThermalValue
+ mov edx, DWORD PTR [rbx]
+ mov DWORD PTR [rax+LOCAL_APIC_THERMAL_DEF], edx ; restore thermal LVT
+@@:
+ ;
+ ; Enable cache
+ ;
+ mov rax, cr0
+ and rax, NOT CR0_CD_MASK
+ mov cr0, rax
+
+ POPA_64
+ popf
+
+ leave
+ ret 0
+ApRestoreConfig ENDP
+
+_TEXT ENDS
+
+ END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeBsp.asm b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeBsp.asm
new file mode 100644
index 0000000..00f9c87
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Dxe/x64/TxtDxeBsp.asm
@@ -0,0 +1,712 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;
+;/*++
+;
+; Copyright (c) 1999 - 2011 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.
+;
+;
+; Module Name:
+;
+; TxtDxeBsp.asm
+;
+; Abstract:
+;
+; This file contains code to launch BIOS ACM functions in DXE phase
+;
+;--*/
+ .xlist
+ include txt.inc
+ include mmx64.inc
+ .list
+
+
+ _TEXT SEGMENT
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: LaunchBiosAcm
+;
+; Input: AcmBase - Base address of LT BIOS ACM
+; Function - function number to execute
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc) and
+; invoke GETSEC:ENTERACCS with requested BIOS ACM entry point.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LaunchBiosAcm PROC FRAME
+
+ START_FRAME
+ MAKE_LOCAL AcmBase:QWORD
+ MAKE_LOCAL Funct:QWORD
+ MAKE_LOCAL BIOS_GDT[2]:QWORD
+ MAKE_LOCAL CompModeSel:QWORD
+ MAKE_LOCAL CompModeOff:QWORD
+ MAKE_LOCAL LongModeSel:QWORD
+ MAKE_LOCAL LongModeOff:QWORD
+ MAKE_LOCAL SavedCR3:QWORD
+ MAKE_LOCAL SavedCR4:QWORD
+ MAKE_LOCAL SavedDS:QWORD
+ MAKE_LOCAL SavedES:QWORD
+ MAKE_LOCAL SavedGS:QWORD
+ MAKE_LOCAL SavedFS:QWORD
+ MAKE_LOCAL SavedMiscEnablesRax:QWORD
+ MAKE_LOCAL SavedMiscEnablesRdx:QWORD
+ MAKE_LOCAL MtrrTab[2*(IA32_MTRR_PHYSMASK9 - IA32_MTRR_PHYSBASE0 + 1)]:QWORD
+ MAKE_LOCAL ACM_SIZE_TO_CACHE:QWORD
+ MAKE_LOCAL ACM_BASE_TO_CACHE:QWORD
+ MAKE_LOCAL NEXT_MTRR_INDEX:QWORD
+ MAKE_LOCAL NEXT_MTRR_SIZE:QWORD
+ MAKE_LOCAL MTRR_COUNT:QWORD
+ MAKE_LOCAL MtrrTypeRax:QWORD
+ MAKE_LOCAL MtrrTypeRdx:QWORD
+ END_FRAME
+
+ ;
+ ; Save input parameters
+ ;
+ mov AcmBase, rcx
+
+ mov Funct, rdx
+
+ sgdt BIOS_GDT ; save gdtr
+
+ ;
+ ; Save the general purpose register state
+ ;
+ pushf
+ cli
+
+ PUSHA_64
+ ;
+ ; Tell where we are
+ ;
+ in ax, 80h
+ mov ah, BYTE PTR Funct
+ or ah, PORT80_CODE_PREFIX
+ out 80h, ax
+ ;
+ ; Save segment registers.
+ ;
+ mov ax, ds
+ mov SavedDS, rax
+ mov ax, es
+ mov SavedES, rax
+ mov ax, gs
+ mov SavedGS, rax
+ mov ax, fs
+ mov SavedFS, rax
+
+ ; Save cr4
+ ;
+ mov rax, cr4
+ mov SavedCR4, rax
+
+ ;
+ ; Save IA32_MISC_ENABLES MSR
+ ;
+ mov rcx, IA32_MISC_ENABLE_MSR
+ rdmsr
+ mov SavedMiscEnablesRax, rax
+ mov SavedMiscEnablesRdx, rdx
+
+;-----------------------------------------------------------------------------
+;
+; Section: Save variable MTRRs
+;
+; Description: All variable MTRRs are saved in local variables.
+; They will be restored after runnong of BIOS ACM
+;
+;-----------------------------------------------------------------------------
+ mov rcx, IA32_MTRR_CAP
+ rdmsr
+ and rax, 0FFh
+ shl rax, 1
+ mov MTRR_COUNT, rax
+ mov rcx, rax
+ lea rbx, MtrrTab
+
+SaveNextMtrr:
+ add rcx, IA32_MTRR_PHYSBASE0 - 1
+ rdmsr
+ mov [rbx+0], rax
+ mov [rbx+8], rdx
+ sub rcx, IA32_MTRR_PHYSBASE0 - 1
+ add rbx, 10h
+ loop SaveNextMtrr
+
+ ;
+ ; Save IA32_MTRR_DEF_TYPE MSR
+ ;
+ mov rcx, IA32_MTRR_DEF_TYPE
+ rdmsr
+ mov MtrrTypeRax, rax
+ mov MtrrTypeRdx, rdx
+
+;-----------------------------------------------------------------------------
+;
+; Section: Program MTRRs
+;
+; Description: Variable MTRRs are programmed to cache ACM as WB
+;
+;-----------------------------------------------------------------------------
+ ;
+ ; Enable SMXE, SSE and debug extensions
+ ;
+ mov rax, cr4
+ or rax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov cr4, rax
+
+ ;
+ ; Disable cache
+ ;
+ mov rax, cr0 ; set CR0:CD and CR0:NE, clear CR0:NW
+ or rax, CR0_CD_MASK OR CR0_NE_MASK
+ and rax, NOT CR0_NW_MASK
+ mov cr0, rax
+ wbinvd
+ ;
+ ; Disable MTRRs, set Default Type to UC
+ ;
+ mov rcx, IA32_MTRR_DEF_TYPE
+ xor rax, rax
+ xor rdx, rdx
+ wrmsr
+
+ ;
+ ; Clear all of the Variable MTRRs
+ ;
+ mov rcx, MTRR_COUNT
+
+ClearNextMttr:
+ add rcx, IA32_MTRR_PHYSBASE0 - 1
+ wrmsr
+ sub rcx, IA32_MTRR_PHYSBASE0 - 1
+ loop ClearNextMttr
+
+ ;
+ ; Determine size of AC module
+ ;
+ mov rsi, AcmBase
+ xor rax, rax
+ mov eax, DWORD PTR [rsi+ACM_HEADER.AcmSize]
+ shl rax, 2 ; ...in bytes (ACM header has size in dwords)
+ ;
+ ; Round up to page size
+ ;
+ add rax, 0FFFh ;
+ and rax, 0FFFFF000h ; Aligned to a page (4KB)
+
+ ;
+ ; Program MTRRs to cover BIOS ACM
+ ;
+ sub rcx, rcx
+ mov NEXT_MTRR_INDEX, rcx ; Start from MTRR0
+
+ ;
+ ; Save remaining size to cache
+ ;
+ mov ACM_SIZE_TO_CACHE, rax ; Size of ACM that must be cached
+ mov ACM_BASE_TO_CACHE, rsi ; Base ACM address
+
+nextMtrr:
+ ;
+ ; Get remaining size to cache
+ ;
+ mov rax, ACM_SIZE_TO_CACHE
+ and rax, rax
+ jz done ; If no left size - we are done
+ ;
+ ; Determine next size to cache.
+ ; We start from bottom up. Use the following algorythm:
+ ; 1. Get our own alignment. Max size we can cache equals to our alignment
+ ; 2. Determine what is bigger - alignment or remaining size to cache.
+ ; If aligment is bigger - cache it.
+ ; Adjust remaing size to cache and base address
+ ; Loop to 1.
+ ; If remaining size to cache is bigger
+ ; Determine the biggest 2^N part of it and cache it.
+ ; Adjust remaing size to cache and base address
+ ; Loop to 1.
+ ; 3. End when there is no left size to cache or no left MTRRs
+ ;
+ mov rsi, ACM_BASE_TO_CACHE
+ bsf rcx, rsi ; Get index of lowest bit set in base address
+ ;
+ ; Convert index into size to be cached by next MTRR
+ ;
+ mov rdx, 1h
+ shl rdx, cl ; Alignment is in rdx
+ cmp rdx, rax ; What is bigger, alignment or remaining size?
+ jbe gotSize ; JIf aligment is less
+ ;
+ ; Remaining size is bigger. Get the biggest part of it, 2^N in size
+ ;
+ bsr rcx, rax ; Get index of highest set bit
+ ;
+ ; Convert index into size to be cached by next MTRR
+ ;
+ mov rdx, 1
+ shl rdx, cl ; Size to cache
+
+gotSize:
+ mov rax, rdx
+ mov NEXT_MTRR_SIZE, rax ; Save
+
+ ;
+ ; Compute MTRR mask value: Mask = NOT (Size - 1)
+ ;
+ dec rax ; eax - size to cache less one byte
+ not rax ; eax contains low 32 bits of mask
+ or rax, MTRR_VALID ; Set valid bit
+ ;
+ ; Program mask register
+ ;
+ mov rcx, IA32_MTRR_PHYSMASK0 ; setup variable mtrr
+ mov rbx, NEXT_MTRR_INDEX
+ add rcx, rbx
+
+ mov rdx, 0Fh
+ wrmsr
+ ;
+ ; Program base register
+ ;
+ sub rdx, rdx
+ mov rcx, IA32_MTRR_PHYSBASE0 ; setup variable mtrr
+ add rcx, rbx ; ebx is still NEXT_MTRR_INDEX
+
+ mov rax, ACM_BASE_TO_CACHE
+ or rax, WB ; set type to write back
+ wrmsr
+ ;
+ ; Advance and loop
+ ; Reduce remaining size to cache
+ ;
+ mov rbx, ACM_SIZE_TO_CACHE
+ mov rax, NEXT_MTRR_SIZE
+ sub rbx, rax
+ mov ACM_SIZE_TO_CACHE, rbx
+
+ ;
+ ; Increment MTRR index
+ ;
+ mov rbx, NEXT_MTRR_INDEX
+ add rbx, 2
+ mov NEXT_MTRR_INDEX, rbx
+ ;
+ ; Increment base address to cache
+ ;
+ mov rbx, ACM_BASE_TO_CACHE
+ mov rax, NEXT_MTRR_SIZE
+ add rbx, rax
+ mov ACM_BASE_TO_CACHE, rbx
+
+ jmp nextMtrr
+
+done:
+ ;
+ ; Enable Variable MTRRs
+ ;
+ xor rdx, rdx
+ mov rax, MTRR_ENABLE
+ mov rcx, IA32_MTRR_DEF_TYPE
+ wrmsr
+ ;
+ ; Enable cache
+ ;
+ mov rax, cr0
+ and rax, NOT CR0_CD_MASK
+ mov cr0, rax
+
+ ;
+ ; Clean all MCi_STATUS MSR registers
+ ; SCLEAN will generate GPF otherwise
+ ;
+ mov rcx, MCG_CAP
+ rdmsr
+ movzx rbx, al ; ebx = MCR bank count
+ xor rax, rax ; Write 0 into all MCi_STATUS registers
+ xor rdx, rdx
+ mov rcx, MC0_STATUS
+
+McaErrorCleanLoopStart:
+ wrmsr
+ dec rbx
+ jz @F
+ add rcx, 4 ; ecx = number of MSRs per bank
+ jmp McaErrorCleanLoopStart
+
+@@:
+;-----------------------------------------------------------------------------
+;
+; Section: Find Compatible Segment Descriptor in GDT
+;
+; Description: GDT is scanned until code descriptor with L bit = 0 is found
+;
+;-----------------------------------------------------------------------------
+
+ lea rax, BIOS_GDT
+ add rax, 2 ; Point to base
+ mov rax, [rax] ; Get base of GDT
+ mov rbx, rax ; Save GDT base
+
+ mov cx, WORD PTR BIOS_GDT
+ movzx rcx, cx
+ inc rcx ; rcx - total size of GDT in bytes
+ add rcx, rax ; rcx - end of GDT
+
+loopStart:
+ cmp QWORD PTR [rax], 0 ; Reserved?
+ je ApplicationDescriptor
+ test BYTE PTR [rax].SEG_DESCRIPTOR.AR0_7, MASK D_T
+ jz nextDescriptor ; JIf system descriptor
+ ;
+ ; Application descriptor found
+ ;
+ test BYTE PTR [rax].SEG_DESCRIPTOR.AR0_7, 8 ; Bit 3 of sType - code segment if set
+ jz nextDescriptor ; JIf data descriptor
+ ;
+ ; Code descriptor is found
+ ;
+ test byte ptr [rax].SEG_DESCRIPTOR.LAR16_23, MASK L
+ jnz nextDescriptor
+ ;
+ ; Compatibility mode code descriptor is found
+ ;
+ sub rax, rbx ; rax is compatibility segment selector
+ jmp CompatibilityModeJump
+
+nextDescriptor:
+ cmp rax, rcx
+ jb @F
+ jmp $ ; Nothing found - impossible situation
+
+@@:
+ test BYTE PTR [rax].SEG_DESCRIPTOR.AR0_7, MASK D_T
+ jz @F
+
+ApplicationDescriptor:
+ ;
+ ; Application descriptor - 8 bytes
+ ;
+ add rax, 8
+ jmp loopStart
+
+@@:
+ add rax, 16
+ jmp loopStart
+
+;-----------------------------------------------------------------------------
+;
+; Section: Jump to compatibility mode
+;
+; Description: Found selector and known label offset
+; are used to transfer control to compatibility mode.
+;
+; NOTE!
+; Code programmed from this point on till the return to long mode
+; looks differently than code actually executed by CPU
+; This is because assembler is in x64 mode whereas CPU is not.
+; Whereever differences are present between written and executed code,
+; actual instructions are shown in comments.
+;
+; Example1: Programmed: mov rax, cr4
+; Executed: mov eax, cr4
+; Assembler fails to assemble "mov eax, cr4" since CR4 is
+; 64 bits wide in x64 mode. Generated opcodes are nevertheless
+; correct.
+;
+; Example2: Programmed: mov eax, DWORD PTR [rbx+0]
+; Executed: mov eax, DWORD PTR [ebx+0]
+; Default addressing in x64 mode is 64 bit. If ebx were coded
+; in this example, assembler would generate unneeded REX prefix.
+; By programming rbx this prefix is not generated and
+; opcode corresponds to ebx addressing in compatibility mode
+;
+;-----------------------------------------------------------------------------
+
+CompatibilityModeJump:
+ ;
+ ; Save Long mode and Compatibility mode selectors and offsets before transition
+ ;
+ mov CompModeSel, rax ; Save Compatibility Mode selector
+ mov rcx, OFFSET ProtectedMode2
+ mov CompModeOff, rcx
+ mov cx, cs
+ movzx rcx, cx
+ mov LongModeSel, rcx
+ mov rcx, OFFSET LongMode2
+ mov LongModeOff, rcx
+
+ shl rax, 32
+ mov rcx, OFFSET CompatibilityMode
+ or rax, rcx
+ push rax
+ retf
+
+CompatibilityMode:
+;-----------------------------------------------------------------------------
+;
+; Section: Jump to protected mode
+;
+; Description: Compatibility mode is disabled since BIOS ACM must run
+; in protected 32 bit mode.
+;
+;-----------------------------------------------------------------------------
+
+ ;
+ ; Disable paging
+ ;
+ mov rcx, cr0
+ and ecx, DWORD PTR (NOT BIT31)
+ mov cr0, rcx
+ ;
+ ; Clear EFER.LME
+ ;
+ mov ecx, IA32_EFER_MSR
+ rdmsr
+ and eax, NOT LME
+ wrmsr
+ jmp ProtectedMode
+
+ProtectedMode:
+
+;-----------------------------------------------------------------------------
+;
+; Section: Launch BIOS ACM
+;
+; Description: Prepare and execute GETSEC[ENTERACCS]
+;
+;-----------------------------------------------------------------------------
+
+ ;
+ ; Save return values in MMX registers
+ ;
+
+ mov ax, ss
+ movzx eax,ax
+% _movd SAVED_SS, eax
+% _movd SAVED_EBP, ebp
+% _movd SAVED_ESP, esp
+ lea eax, BIOS_GDT
+% _movd SAVED_GDT, eax
+ mov rax, cr3 ; mov eax, cr3 - in 32 bit mode
+ mov DWORD PTR SavedCR3, eax
+ ;
+ ; Call GETSEC[ENTERACCS]
+ ;
+ mov esi, DWORD PTR Funct ; esi = ACM function
+ mov eax, DWORD PTR AcmBase
+ mov ebx, eax ; ebx = AcmBase
+ mov ecx, DWORD PTR [rbx+ACM_HEADER.AcmSize] ; mov DWORD PTR [ebx+ACM_HEADER.AcmSize] - in 32 bit mode
+ ; ecx = size of ACM in dwords
+ shl ecx, 2 ; ecx = size of ACM in bytes
+ xor edx, edx
+ xor edi, edi
+ mov eax, ENTERACCS ; eax = ENTERACCS
+
+ _GETSEC
+
+;for debugging only
+; mov ax, 055AAh
+; out 80h, ax
+;; jmp $
+;-----------------------------------------------------------------------------
+;
+; Section: Restore protected mode environment
+;
+; Description: Since BIOS ACM changes GDT,
+; BIOS GDT, stack and and CS selector are restored.
+;
+;
+;-----------------------------------------------------------------------------
+
+ ;
+ ; Reload the GDTR. Upon return CPU is loaded with selector from ACM GDT
+ ; The following instruction works simply because whatever CS selector is
+ ; currently, it is flat selector.
+ ;
+% _movd eax, SAVED_GDT
+ lgdt FWORD ptr [rax] ; lgdt FWORD ptr [eax] - in 32 bit mode
+
+ ;
+ ; Restore the stack
+ ;
+% _movd eax, SAVED_EBP
+ mov ebp, eax ; restore ebp
+% _movd eax, SAVED_ESP
+ mov esp, eax ; restore esp
+% _movd eax, SAVED_SS
+ mov ss, ax ; restore ss
+
+ ;
+ ; Reload cs register
+ ;
+ mov eax, DWORD PTR CompModeSel
+ push rax ; push eax - in 32 bit mode
+
+ mov eax, DWORD PTR CompModeOff
+ push rax ; push eax - in 32 bit mode
+ retf ; will jump to Protected label below
+
+ProtectedMode2:
+
+;-----------------------------------------------------------------------------
+;
+; Section: Restore MTRRs
+;
+; Description: BIOS MTRR values are restored.
+;
+;-----------------------------------------------------------------------------
+ ;
+ ; Disable paging
+ ;
+ mov rax, cr0
+ and eax, DWORD PTR (NOT CR0_PG_MASK)
+ mov cr0, rax
+
+ mov rcx, MTRR_COUNT
+ lea ebx, MtrrTab
+
+RestoreNextMtrr:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ mov eax, DWORD PTR [rbx+0] ; mov eax, DWORD PTR [ebx+0] - in 32 bit mode
+ mov edx, DWORD PTR [rbx+8] ; mov eax, DWORD PTR [ebx+8] - in 32 bit mode
+ wrmsr
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ add ebx, 10h
+ loop RestoreNextMtrr
+
+ mov rcx, IA32_MTRR_DEF_TYPE
+ mov rdx, MtrrTypeRdx
+ mov rax, MtrrTypeRax
+ wrmsr
+;-----------------------------------------------------------------------------
+;
+; Section: Switch to compatibility mode
+;
+; Description: Compatibility mode i srestored by enabling of paging -
+; this is done by restoring CR4 contenxt, and setting of LME bit.
+;
+;-----------------------------------------------------------------------------
+
+ ;
+ ; Enable PAE in CR4
+ ;
+ mov eax, DWORD PTR SavedCR4
+ or eax, CR4_PAE
+ mov cr4, rax
+
+ ;
+ ; Reload CR3
+ ;
+ mov eax, DWORD PTR SavedCR3
+ mov cr3, rax
+
+ ;
+ ; Set EFER.LME to re-enable ia32-e
+ ;
+ mov ecx, IA32_EFER_MSR
+ rdmsr
+ or eax, LME
+ wrmsr
+ ;
+ ; Enable paging
+ ;
+ mov rax, cr0
+ or eax, CR0_PG_MASK
+ mov cr0, rax
+
+ jmp CompatibilityMode2
+
+CompatibilityMode2:
+ wbinvd ; Flush and invalidate the cache
+ ;
+ ; Now we're in Compatibility mode - restore segment registers.
+ ;
+ mov rax, SavedDS
+ mov ds, ax
+ mov rax, SavedES
+ mov es, ax
+ mov rax, SavedGS
+ mov gs, ax
+ mov rax, SavedFS
+ mov fs, ax
+ ;
+ ; Reastore IA32_MISC_ENABLES MSR
+ ;
+ mov rcx, IA32_MISC_ENABLE_MSR
+ mov rdx, SavedMiscEnablesRdx
+ mov rax, SavedMiscEnablesRax
+ wrmsr
+
+
+;-----------------------------------------------------------------------------
+;
+; Section: Switch to long mode
+;
+; Description: Previously saved selector and offset are used to return
+; CPU to long mode.
+;
+;-----------------------------------------------------------------------------
+ ;
+ ; Reload cs register
+ ;
+ mov eax, DWORD PTR LongModeSel
+ push rax ; push eax - in 32 bit mode
+
+ mov eax, DWORD PTR LongModeOff
+ push rax ; push eax - in 32 bit mode
+ retf
+
+LongMode2:
+;-----------------------------------------------------------------------------
+;
+; Section: Resore registers, stack and exit.
+;
+; Description: Previously saved registers are restored. Stack is restored
+; by execution leave instruction and control is returned to
+; caller.
+;
+; NOTE!
+; This section ends differences between programmed and
+; executed code.
+;
+;-----------------------------------------------------------------------------
+ ;
+ ; Now we're in Long Mode
+ ; Restore control registers
+ ;
+ mov rax, SavedCR4
+ mov cr4, rax
+
+ POPA_64
+ popf
+
+ leave
+ ret 0
+
+LaunchBiosAcm ENDP
+
+_TEXT ENDS
+
+ END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16 b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16
new file mode 100644
index 0000000..9855257
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16
@@ -0,0 +1,305 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;
+;/*++
+;
+; Copyright (c) 1999 - 2011 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.
+;
+;
+; Module Name:
+;
+; TxtPeiAp.asm
+;
+; Abstract:
+;
+; This file contains AP initialization code in PEI phase
+;
+;--*/
+
+ .XLIST
+ include txt.inc
+ .LIST
+
+ .586p
+ .MMX
+
+TxtSegment16 SEGMENT PARA USE16 PUBLIC 'TXTCODE'
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure:
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Entry point of AP startup code. Target of SIPI vector.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+;
+; This point is 4K aligned somewhere in boot block.
+;
+ jmp code16bitStart
+
+ ORG 10h
+
+GDTAddress:
+ dw GDTLen ; The length of the GDT
+ dd OFFSET GDTStart ; The 32-bit physical address
+
+;
+; AP GDT table
+;
+ ALIGN 16
+GDTStart LABEL BYTE
+
+ SEG_DESCRIPTOR <> ; Unused (selector 0)
+
+;
+; Selector 8
+;
+TXT_DATA32 EQU $ - GDTStart
+
+TXT_DATA32_OFF SEG_DESCRIPTOR {0FFFFh,\
+ 0000h, \
+ 00h, \
+ <SEG_PRESENT, 0, APPLSEGMENT, DATATYPE>, \
+ <PAGEGRANULARITY, BIGSEGMENT,,,0Fh>, \
+ 00h}
+
+GDTLen EQU $ - GDTStart - 1
+
+
+code16bitStart:
+
+;L1: jmp $
+ cli
+
+ mov si, OFFSET GDTAddress
+ ;
+ ; Set DS and ES limits
+ ;
+ db 66h ; Force 32 bit load
+ lgdt FWORD PTR cs:[si]
+
+ mov eax, CR0 ; get CPU control word 0
+ or al, 01 ; enable CPU protected mode
+ mov CR0, eax ; write back to CPU control word 0
+ jmp target
+
+target:
+
+ mov ax, TXT_DATA32
+ mov ds, ax ; set DS limit
+ mov es, ax ; set ES limit
+ mov fs, ax ; set FS limit
+ mov gs, ax ; set GS limit
+ mov ss, ax ; set SS limit
+
+ ;
+ ; Disable protected mode
+ ;
+ mov eax, CR0 ; get CPU control word 0
+ and al, 0FEh ; disable CPU protected mode
+ mov CR0, eax ; write back to CPU control word 0
+ jmp target3
+
+target3:
+ xor ax, ax
+ mov ds, ax ; set flat DS
+ mov es, ax ; set flat ES
+
+ ;
+ ; Fall through to main code
+ ;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+;
+; Procedure: LoadVsmcuRetNS - Variable Size Processor Microcode Update (Stackless)
+;
+; Input: SP = Return address
+;
+; Output: None
+;
+; Registers: All but SP are modified
+;
+; Description:
+; Load MCU into processor.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LoadVsmcuRetNS PROC NEAR PUBLIC
+ ;
+ ; Check uCode was loaded or not
+ ;
+ xor eax, eax
+ xor edx, edx
+ mov ecx, MCU_REV_MSR
+ wrmsr
+ mov eax, 1
+ cpuid
+ mov ecx, MCU_REV_MSR
+ rdmsr
+ or edx, edx
+ jnz uCode_loaded
+
+ ;
+ ; Restore MCU address from scratch register
+ ;
+ mov eax, 1
+ cpuid
+
+ mov eax, TXT_PUBLIC_BASE + MCU_BASE_ADDR
+ mov eax, [eax]
+
+ lea eax, [eax + SIZEOF MCU] ; EAX -> MCU data (after header)
+ xor edx, edx
+ mov ecx, MCU_LOAD_MSR ; Trigger to load MCU
+
+ wrmsr ; Load MCU
+
+ mov eax, 1
+ cpuid
+uCode_loaded:
+ ;
+ ; Fall through
+ ;
+LoadVsmcuRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: TxtPrepareCacheForAcModuleRetNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Cache initialization per TXT BIOS spec
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+TxtPrepareCacheForAcModuleRetNS PROC NEAR PUBLIC
+
+ ;
+ ; Ensure CR0.CD and CR0.NW are cleared
+ ;
+ mov eax, cr0 ;
+ and eax, NOT (CR0_CD_MASK + CR0_NW_MASK)
+ mov cr0, eax
+ ;
+ ; Fall through
+ ;
+TxtPrepareCacheForAcModuleRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: TxtCleanMcaNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: MCA registers are cleaned
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+TxtCleanMcaNS PROC NEAR PUBLIC
+ ;
+ ; Clean MC[i]_STATUS MSR registers
+ ; SCLEAN will generate GPF otherwise
+ ;
+ mov ecx, MCG_CAP
+ rdmsr
+ movzx ebx, al ; Bank count to ebx
+ sub eax, eax ; Write 0 into all MCi_STATUS registers
+ sub edx, edx
+ mov ecx, MC0_STATUS
+
+McaErrorCleanLoopStart:
+ wrmsr
+ dec ebx
+ jz continue
+ add ecx, 4 ; Number of MSRs per bank
+ jmp McaErrorCleanLoopStart
+
+continue:
+ ;
+ ; Fall through
+ ;
+TxtCleanMcaNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: TxtHaltLoopNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: APs enter halt loop
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+TxtHaltLoopNS PROC NEAR PUBLIC
+
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+
+ mov eax, 1
+ cpuid
+ shr ebx, 24 ; ebx is initial APIC ID shifted rightmostly
+
+ ;
+ ; Since accesses to semaphore cannot be serialized, accesses among different CPUs
+ ; are orchestrated as following:
+ ; BSP will only READ semaphore
+ ; All APs will keep READING semaphore until its value EQUALS to that AP's
+ ; APIC ID minus 1. Only AFTER that AP will INCREMENT semaphore.
+ ; This allows BSP to judge WHEN all APs finished.
+ ;
+ mov ecx, [TXT_PUBLIC_BASE + SEMAPHORE]
+
+keepWaiting:
+ mov eax, [ecx]
+ inc eax
+ cmp eax, ebx
+ jb keepWaiting
+ ja hltLoop
+ mov [ecx], eax
+
+hltLoop:
+ cli
+ hlt
+ jmp hltLoop
+
+TxtHaltLoopNS ENDP
+
+TxtSegment16 ENDS
+
+END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf
new file mode 100644
index 0000000..a6e8185
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for TXTPEIAP module
+#
+#@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 = TxtPeiAp
+FILE_GUID = D1E59F50-E8C3-4545-BF61-11F002233C97
+COMPONENT_TYPE = USER_DEFINED
+
+[sources.common]
+
+[sources.ia32]
+ TxtPeiAp.asm16
+
+[includes.common]
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include
+
+[libraries.common]
+
+[nmake.common]
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf
new file mode 100644
index 0000000..e649127
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for TXTPEIAP module
+#
+#@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 = TxtPeiAp
+FILE_GUID = D1E59F50-E8C3-4545-BF61-11F002233C97
+COMPONENT_TYPE = FILE
+BUILD_TYPE = MAKEFILE
+
+[sources.common]
+
+[sources.ia32]
+ TxtPeiAp.asm16
+
+[includes.common]
+
+[libraries.common]
+
+[nmake.common]
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm
new file mode 100644
index 0000000..066aedc
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm
@@ -0,0 +1,1387 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;
+;/*++
+;
+; Copyright (c) 1999 - 2011 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.
+;
+;
+; Module Name:
+;
+; TxtPeiBsp.asm
+;
+; Abstract:
+;
+; This file contains the code to launch BIOS ACM functions in PEI phase
+;
+;--*/
+
+ .XLIST
+ include txt.inc
+ .LIST
+
+ .686P
+ .MMX
+ .XMM
+ .MODEL FLAT,C
+ .CODE
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: LaunchBiosAcmSclean
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc) and
+; invoke GETSEC:ENTERACCS with requested BIOS ACM entry point.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LaunchBiosAcmSclean PROC PUBLIC
+ ;
+ ; Tell where we are
+ ;
+ mov eax, 11110000h
+ in ax, 80h
+ mov ah, PORT80_CODE_PREFIX + TXT_LAUNCH_SCLEAN
+ out 80h, eax
+
+ ;
+ ; Enable SMXE, SSE and debug extensions always.
+ ;
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+
+ ;
+ ; Prepare cache of BSP
+ ;
+ mov esi, TXT_PUBLIC_BASE + BIOACM_ADDR
+ mov edi, 0
+
+ CALL_NS PrepareCacheForAcModuleRetNS
+
+ CALL_NS CleanMcaRetNS
+
+ifdef MKF_TXT_RLP_INIT
+ if MKF_TXT_RLP_INIT
+ CALL_NS InitializeApsRetNS
+ endif
+endif
+
+
+ ;
+ ; Call GETSEC[ENTERACCS]
+ ;
+ cli
+ mov eax, ENTERACCS ; eax = ENTERACCS
+ mov ebx, TXT_PUBLIC_BASE + BIOACM_ADDR
+ mov ebx, [ebx]
+ mov ecx, [ebx].ACM_HEADER.AcmSize
+ shl ecx, 2
+ xor edx, edx
+ xor edi, edi
+ mov esi, 0
+
+ _GETSEC
+
+ jmp DoPowerCycleReset
+LaunchBiosAcmSclean ENDP
+
+DoGlobalReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - set bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ or eax, (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0 ; system must be reset.
+ out dx, al
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 6 ; system must be reset.
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoGlobalReset ENDP
+
+DoPowerCycleReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - set bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ and eax, NOT (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0 ; system must be reset.
+ out dx, al
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0Eh ; system must be reset.
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoPowerCycleReset ENDP
+
+DoHostReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - set bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ and eax, NOT (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0 ; system must be reset.
+ out dx, al
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 6 ; system must be reset.
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoHostReset ENDP
+
+DoCpuReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - clear bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ and eax, NOT (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; Issue a CPU only reset by CF9h
+ mov al, 0 ; toggle bit2 from 0 to 1
+ out dx, al
+ mov dx, 0CF9h ; Issue a CPU only reset by CF9h
+ mov al, 4 ;
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoCpuReset ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: PrepareCacheForAcModuleRetNS
+;
+; Input: esi - bios acm address
+; edi - in memory flag
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: MTRRs are set per BIOS spec
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+PrepareCacheForAcModuleRetNS PROC FAR PUBLIC
+ ;
+ ; Enable local APIC
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov DWORD PTR [eax+SPURIOUS_VECTOR_1], 1FFh ; Enable APIC, keep spurious vector
+ ;
+ ; Disable cache
+ ;
+ mov eax, cr0 ; set CR0:CD and CR0:NE, clear CR0:NW
+ or eax, CR0_CD_MASK OR CR0_NE_MASK
+ and eax, NOT CR0_NW_MASK
+ mov cr0, eax
+ cmp edi, 0
+ je @F ; JIf stackless environment
+ wbinvd ; Invalidate the cache
+ jmp disableMtrrs
+
+@@:
+ invd
+
+disableMtrrs:
+ ;
+ ; Disable all MTRRs
+ ;
+ xor eax, eax
+ xor edx, edx
+ mov ecx, IA32_MTRR_DEF_TYPE
+ wrmsr
+
+ ;
+ ; Disable NEM
+ ;
+ mov ecx, NO_EVICT_MODE
+ rdmsr
+ and eax, NOT (BIT1)
+ wrmsr ; Clear No-Eviction Mode Run bit
+ mov ecx, NO_EVICT_MODE
+ rdmsr
+ and eax, NOT (BIT0)
+ wrmsr ; Clear No-Eviction Mode SETUP bit
+
+ invd
+
+ ;
+ ; Clear all variable MTRRs
+ ;
+ mov ecx, IA32_MTRR_CAP
+ rdmsr
+ and eax, 0FFh
+ shl eax, 1
+ mov ecx, eax
+ xor eax, eax
+ xor edx, edx
+@@:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ wrmsr
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ loop @B
+
+ ;
+ ; Determine size of AC module
+ ;
+ mov esi, [esi]
+ mov eax, [esi].ACM_HEADER.AcmSize
+ shl eax, 2 ; ...in bytes (ACM header has size in dwords)
+ ;
+ ; Round up to page size
+ ;
+ mov ecx, eax ; Save
+ and ecx, 0FFFFF000h ; Number of pages in AC module
+ and eax, 0FFFh ; Number of "less-than-page" bytes
+ jz rounded
+ mov eax, 1000h ; Add the whole page size
+
+rounded:
+ add eax, ecx ; eax - rounded up AC module size
+
+ ;
+ ; Define "local" vars for this routine
+ ;
+ ACM_SIZE_TO_CACHE TEXTEQU <mm0>
+ ACM_BASE_TO_CACHE TEXTEQU <mm1>
+ NEXT_MTRR_INDEX TEXTEQU <mm2>
+ NEXT_MTRR_SIZE TEXTEQU <mm3>
+ ;
+ ; Initialize "locals"
+ ;
+ sub ecx, ecx
+ movd NEXT_MTRR_INDEX, ecx ; Start from MTRR0
+
+ ;
+ ; Save remaining size to cache
+ ;
+ movd ACM_SIZE_TO_CACHE, eax ; Size of ACM that must be cached
+ movd ACM_BASE_TO_CACHE, esi ; Base ACM address
+
+nextMtrr:
+ ;
+ ; Get remaining size to cache
+ ;
+ movd eax, ACM_SIZE_TO_CACHE
+ and eax, eax
+ jz done ; If no left size - we are done
+ ;
+ ; Determine next size to cache.
+ ; We start from bottom up. Use the following algorythm:
+ ; 1. Get our own alignment. Max size we can cache equals to our alignment
+ ; 2. Determine what is bigger - alignment or remaining size to cache.
+ ; If aligment is bigger - cache it.
+ ; Adjust remaing size to cache and base address
+ ; Loop to 1.
+ ; If remaining size to cache is bigger
+ ; Determine the biggest 2^N part of it and cache it.
+ ; Adjust remaing size to cache and base address
+ ; Loop to 1.
+ ; 3. End when there is no left size to cache or no left MTRRs
+ ;
+ movd esi, ACM_BASE_TO_CACHE
+ bsf ecx, esi ; Get index of lowest bit set in base address
+ ;
+ ; Convert index into size to be cached by next MTRR
+ ;
+ mov edx, 1h
+ shl edx, cl ; Alignment is in edx
+ cmp edx, eax ; What is bigger, alignment or remaining size?
+ jbe gotSize ; JIf aligment is less
+ ;
+ ; Remaining size is bigger. Get the biggest part of it, 2^N in size
+ ;
+ bsr ecx, eax ; Get index of highest set bit
+ ;
+ ; Convert index into size to be cached by next MTRR
+ ;
+ mov edx, 1
+ shl edx, cl ; Size to cache
+
+gotSize:
+ mov eax, edx
+ movd NEXT_MTRR_SIZE, eax ; Save
+
+ ;
+ ; Compute MTRR mask value: Mask = NOT (Size - 1)
+ ;
+ dec eax ; eax - size to cache less one byte
+ not eax ; eax contains low 32 bits of mask
+ or eax, MTRR_VALID ; Set valid bit
+
+ ;
+ ; Program mask register
+ ;
+ mov ecx, IA32_MTRR_PHYSMASK0 ; setup variable mtrr
+ movd ebx, NEXT_MTRR_INDEX
+ add ecx, ebx
+
+ mov edx, 0Fh ; 8K range (FFFFFFE800)
+ wrmsr
+ ;
+ ; Program base register
+ ;
+ sub edx, edx
+ mov ecx, IA32_MTRR_PHYSBASE0 ; setup variable mtrr
+ add ecx, ebx ; ebx is still NEXT_MTRR_INDEX
+
+ movd eax, ACM_BASE_TO_CACHE
+ or eax, WB ; set type to write back
+ wrmsr
+ ;
+ ; Advance and loop
+ ; Reduce remaining size to cache
+ ;
+ movd ebx, ACM_SIZE_TO_CACHE
+ movd eax, NEXT_MTRR_SIZE
+ sub ebx, eax
+ movd ACM_SIZE_TO_CACHE, ebx
+
+ ;
+ ; Increment MTRR index
+ ;
+ movd ebx, NEXT_MTRR_INDEX
+ add ebx, 2
+ movd NEXT_MTRR_INDEX, ebx
+ ;
+ ; Increment base address to cache
+ ;
+ movd ebx, ACM_BASE_TO_CACHE
+ movd eax, NEXT_MTRR_SIZE
+ add ebx, eax
+ movd ACM_BASE_TO_CACHE, ebx
+
+ jmp nextMtrr
+
+done:
+ ;
+ ; Enable variable MTRRs
+ ;
+ xor edx, edx
+ mov eax, MTRR_ENABLE; enable mtrrs (but not fixed ones)
+ mov ecx, IA32_MTRR_DEF_TYPE
+ wrmsr
+ ;
+ ; Enable cache
+ ;
+ mov eax, cr0 ; Enable caching - WB (NW stays clear)
+ and eax, NOT CR0_CD_MASK
+ mov cr0, eax
+
+ RET_NS
+PrepareCacheForAcModuleRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: CleanMcaRetNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc)
+; invoke GETSEC:ENTERACCS with requested module
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+CleanMcaRetNS PROC NEAR PUBLIC
+
+ ;
+ ; Clean all MCi_STATUS MSR registers
+ ; SCLEAN will generate GPF otherwise
+ ;
+ mov ecx, MCG_CAP
+ rdmsr
+ movzx ebx, al ; Bank count to ebx
+ sub eax, eax ; Write 0 into all MCi_STATUS registers
+ sub edx, edx
+ mov ecx, MC0_STATUS
+
+McaErrorCleanLoopStart:
+ wrmsr
+ dec ebx
+ jz exit
+ add ecx, 4 ; Number of MSRs per bank
+ jmp McaErrorCleanLoopStart
+
+exit:
+ RET_NS
+CleanMcaRetNS ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: InitializeApsRetNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description:
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+InitializeApsRetNS PROC NEAR
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ cmp bl, 1 ; If 1 thread - nothing to do
+ je exit
+
+ ;
+ ; Init Timer 1
+ ;
+ mov al, 54h
+ out 43h, al
+ mov al, 12h
+ out 41h, al
+
+ ;
+ ; More than one thread
+ ; Get APIC address
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov edi, eax ; edi points to APIC base
+
+ mov esi, TXT_PUBLIC_BASE ; esi points to public space
+
+ ;
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+
+ ;
+ ; Broadcast INIT message to put all APs into Wait for SIPI state
+ ; C0500 -> Destination = All excl self, Delivery = INIT
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+ ;
+ ; Create vector used in the following SIPI message
+ ; Below address is the real mode address of AP code in Boot Block
+ ; LTCACHE.BIN containg AP thread code must be placed at the above address
+ ; in Boot block (FFFF0000h). See file LTCACHE.ASM
+ ;
+
+ mov ebx, [esi+APINIT_ADDR]
+ shr ebx, 12
+ and ebx, 0FFh
+ or ebx, 0C0600h ; This is message
+
+ ;
+ ; Broadcast SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait 200us as recommended
+ ;
+ mov edx, NeverStatusRetNS
+ mov ecx, 14
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Broadcast second SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait for semaphore reflect number of CPUs
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ dec bl ; bl is number of APs
+
+ mov edx, SemaphoreStatusRetNS
+ mov ecx, 6670
+ CALL_NS ltWaitStatusRetNS ; Wait for up to 100ms
+
+ ;
+ ; Broadcast INIT message to put all APs back into Wait for SIPI state
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+
+exit:
+ RET_NS
+InitializeApsRetNS ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: SaveApConfig
+;
+; Input: ApCfg - pointer to save area
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Function is called in memory present environment on S3 resume
+; path. Saves contents of all MTRRs into table plus some registers.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+SaveApConfig PROC NEAR PUBLIC, ApCfg:PTR QWORD
+
+ pushad
+
+ mov esi, ApCfg
+ mov ecx, IA32_MTRR_CAP
+ rdmsr
+ and eax, 0FFh
+ shl eax, 1
+ mov ecx, eax
+
+@@:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ rdmsr
+ mov [esi], eax
+ mov [esi+4], edx
+ add esi, SIZEOF QWORD
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ loop @B
+
+ mov ecx, IA32_MTRR_DEF_TYPE
+ rdmsr
+ mov [esi], eax
+ mov [esi+4], edx
+
+ sidt [esi+8]
+
+ mov ecx, IA32_MISC_ENABLE_MSR
+ rdmsr
+ mov [esi+010h], eax
+ mov [esi+014h], edx
+
+ popad
+ ret
+SaveApConfig ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: StartupAllAPs
+;
+; Input: pFunction - pointer to function to execute on AP
+; pParam - pointre to pFunction parameters
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Procedure is called in memmory present enironment on S3
+; resume path and is executed on BSP
+; It saves memory at address 1000h into buffer
+; It then copies AP start-up code into address 1000h
+; Then variables in the 1000h area are updated and APs are started
+; After APs finish execution of function passed as parameter they
+; are halted. BSP restores contents 1000h area from buffer and
+; returns.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+Func TYPEDEF PROTO
+
+PFUNC TYPEDEF PTR Func
+
+StartUp STRUCT
+ db 0FAh ; cli
+ db 066h, 0BBh ; mov ebx, OFFSET gdtLim
+ db StartUp.gdtLim, 0,0,0
+ db 066h
+ db 067h, 02Eh, 00Fh, 001h, 013h ; lgdt FWORD PTR cs:[ebx]
+ db 00Fh, 020h, 0C0h ; mov eax, CR0
+ db 00Ch, 001h ; or al, 01
+ db 00Fh, 022h, 0C0h ; mov CR0, eax
+ ;
+ ; 32 bit jump to 32 bit Function handler
+ ;
+ db 066h
+ db 0eah
+fOff dd 0
+fCs dw 0
+
+ ALIGN 16
+fDs dw 0
+gdtLim dw ? ; Size of LT GDT in bytes
+gdtBas dd ? ; Physical address of LT GDT
+fParam dd ?
+smphr dd ?
+StartUp ENDS
+
+
+StartupAllAPs PROC NEAR, pFunction:PFUNC, pParam:PTR QWORD
+ LOCAL buffer:StartUp
+ LOCAL savedESP:DWORD
+
+ pushad
+ mov savedESP, esp
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ cmp bl, 1 ; If 1 thread - nothing to do
+ je exit
+
+ ;
+ ; Init Timer 1
+ ;
+ mov al, 54h
+ out 43h, al
+ mov al, 12h
+ out 41h, al
+
+ ;
+ ; More than one thread. Prepare Startup area
+ ;
+ mov esi, 1000h ; Source
+ lea edi, buffer ; Destination
+ mov ecx, sizeof StartUp / 4
+ CALL_NS MemCopyRetNS
+
+ mov esi, offset ApHandler16 ; Source
+ mov edi, 1000h ; Destination
+ mov ecx, sizeof StartUp / 4
+ CALL_NS MemCopyRetNS
+ ;
+ ; Update Srartup area variables
+ ;
+ mov edi, 1000h
+ mov ds:[edi].StartUp.fCs, cs
+ mov ds:[edi].StartUp.fDs, ds
+ mov eax, pFunction
+ mov ds:[edi].StartUp.fOff, eax
+ sub eax, eax
+ mov ds:[edi].StartUp.smphr, eax
+ mov eax, pParam
+ mov ds:[edi].StartUp.fParam, eax
+ sgdt ds:[edi].StartUp.gdtLim
+
+ ;
+ ; Get APIC address
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov edi, eax ; edi points to APIC base
+
+ ;
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+
+ ;
+ ; Broadcast INIT message to put all APs into Wait for SIPI state
+ ; C0500 -> Destination = All excl self, Delivery = INIT
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+ ;
+ ; Create vector used in the following SIPI message
+ ;
+ mov ebx, 0C0600h + (1000h SHR 12)
+ ;
+ ; Broadcast SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait 200us as recommended
+ ;
+ mov edx, NeverStatusRetNS
+ mov ecx, 14
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Broadcast second SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait for semaphore reflect number of CPUs
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ dec bl ; bl is number of APs
+
+ mov edx, SemaphoreStatus2RetNS
+ mov ecx, 6670
+ CALL_NS ltWaitStatusRetNS ; Wait for up to 100ms
+ ;
+ ; Restore StartUp area
+ ;
+ lea esi, buffer ; Source
+ mov edi, 1000h ; Destination
+ mov ecx, sizeof StartUp / 4
+ CALL_NS MemCopyRetNS
+
+exit:
+ mov esp, savedESP
+ popad
+ ret
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Section: ApHandler16
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: Irrelevant
+;
+; Description: This code is copied over address 0:1000. After recieving SIPI
+; AP is directed to this address where it starts execution in real mode.
+; AP first switches to protected mode, loads the same GDT which is used
+; by BSP and jumps to Procedure at fCs:fOff
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+ ALIGN 16
+ ;
+ ; Note After coppying this code must be aligned on page boundary!
+ ;
+
+ApHandler16 StartUp <>
+
+StartupAllAPs ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: PutApsInWfs
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Procedure is called in memory present environment on S3 resume path.
+; INIT SIPI message is sent to all APs.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+PutApsInWfs PROC PUBLIC
+ LOCAL savedESP:DWORD
+ pushad
+ mov savedESP, esp
+
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ cmp bl, 1 ; If 1 thread - nothing to do
+ je exit
+
+ ;
+ ; Get APIC address
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov edi, eax ; edi points to APIC base
+ ;
+ ; Broadcast INIT message to put all APs back into Wait for SIPI state
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+
+exit:
+ mov esp, savedESP
+ popad
+ ret
+PutApsInWfs ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: LaunchBiosAcmScheck
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc) and
+; invoke GETSEC:ENTERACCS with requested BIOS ACM entry point.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LaunchBiosAcmScheck PROC PUBLIC, BiosAcAddr:PTR QWORD
+
+ LOCAL SavedGdtr:QWORD
+ LOCAL SavedSS:dword
+ LOCAL SavedESP:dword
+ LOCAL SavedCS:dword
+ LOCAL SavedCR3:dword
+ pushf
+ cli
+ pushad
+ ;
+ ; Tell where we are
+ ;
+ in ax, 80h
+ mov ah, PORT80_CODE_PREFIX + TXT_LAUNCH_SCHECK
+ out 80h, ax
+ ;
+ ; Save control registers
+ ;
+ mov eax, cr4
+ push eax
+ mov eax, cr0
+ push eax
+ ;
+ ; Save segment registers
+ ;
+ push ds
+ push es
+ push gs
+ push fs
+ ;
+ ; Save CS
+ ;
+ sub eax, eax ; Clean upper word
+ mov ax, cs
+ mov SavedCS, eax
+ ;
+ ; Save stack at this level
+ ;
+ mov ax, ss
+ mov SavedSS, eax
+ mov SavedESP, esp
+ mov eax, cr3
+ mov SavedCR3, eax
+
+ ;
+ ; Save GDT
+ ;
+ sgdt SavedGdtr ; save value of gdtr in local variable
+ ;
+ ; Define "local" vars for this routine
+ ;
+ SAVED_EBP TEXTEQU <mm4>
+ ;
+ ; Save ebp in MMX register
+ ;
+ movd SAVED_EBP, ebp ; Size of ACM that must be cached
+
+ ;
+ ; Enable SMXE, SSE and debug extensions always.
+ ;
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+ ;
+ ; Prepare cache of BSP
+ ;
+ mov esi, BiosAcAddr
+ mov edi, 1
+
+ CALL_NS PrepareCacheForAcModuleRetNS
+
+ CALL_NS CleanMcaRetNS
+
+ ;
+ ; Call GETSEC[ENTERACCS]
+ ;
+ mov eax, ENTERACCS ; eax = ENTERACCS
+ mov ebx, BiosAcAddr
+ mov ebx, [ebx]
+ mov ecx, [ebx].ACM_HEADER.AcmSize
+ shl ecx, 2
+ xor edx, edx
+ mov edi, S3_RESUME_PATH
+ mov esi, 4
+
+ _GETSEC
+
+ ;
+ ; Return point after ACEXIT.
+ ;
+ movd ebp, SAVED_EBP
+ lea eax, SavedGdtr
+ lgdt FWORD PTR [eax]
+ mov eax, SavedSS
+ mov ss, ax
+ mov esp, SavedESP
+ mov eax, SavedCR3
+ mov cr3, eax
+ ;
+ ; Restore segment registers
+ ;
+ pop fs
+ pop gs
+ pop es
+ pop ds
+ ;
+ ; Restore control registers
+ ;
+ pop eax
+ ;
+ ;remain cache disabled until MTRRs restored
+ ;
+ or eax, CR0_CD_MASK
+ and eax, NOT CR0_NW_MASK
+ wbinvd
+;
+ mov cr0, eax
+ pop eax
+ mov cr4, eax
+ ;
+ ; Restore CS
+ ;
+ mov eax, SavedCS
+ push eax
+ push OFFSET ReloadCS
+ retf
+
+ReloadCS:
+ popad
+ popf
+ emms
+
+ ret
+LaunchBiosAcmScheck ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: RestoreMtrrProgramming
+;
+; Input: ApMtrrTab - pointer to save area
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Function is executed on BSP in memory present environment on S3
+; resume path. Restores contents of all MTRRs from table
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+RestoreMtrrProgramming PROC NEAR PUBLIC, ApMtrrTab:PTR QWORD
+ LOCAL savedESP:DWORD
+ pushad
+ mov savedESP, esp
+
+ mov esi, ApMtrrTab
+ CALL_NS RestoreMtrrProgrammingRetNS
+
+ mov esp, savedESP
+ popad
+ ret
+RestoreMtrrProgramming ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: RestoreMtrrProgrammingRetNS
+;
+; Input: esi - pointer to save area
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Restores contents of all MTRRs from table
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+RestoreMtrrProgrammingRetNS PROC NEAR PUBLIC
+ mov eax, cr0 ; set CR0:CD and CR0:NE, clear CR0:NW
+ or eax, CR0_CD_MASK OR CR0_NE_MASK
+ and eax, NOT CR0_NW_MASK
+ mov cr0, eax
+ wbinvd ; flush and invalidate the cache
+
+ xor edx, edx
+ mov eax, MTRR_ENABLE + MTRR_FIXED_ENABLE ; enable mtrrs
+ mov ecx, 2FFh
+ wrmsr
+
+ mov ecx, IA32_MTRR_CAP
+ rdmsr
+ and eax, 0FFh
+ shl eax, 1
+ mov ecx, eax
+
+@@:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ mov eax, [esi]
+ mov edx, [esi+4]
+ wrmsr
+ add esi, SIZEOF QWORD
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ loop @B
+
+ mov ecx, IA32_MTRR_DEF_TYPE
+ mov eax, [esi]
+ mov edx, [esi+4]
+ wrmsr
+ mov ecx, IA32_MISC_ENABLE_MSR
+ mov eax, [esi+010h]
+ mov edx, [esi+014h]
+ wrmsr
+
+ mov eax, cr0 ; Enable caching - WB (NW stays clear)
+ and eax, NOT CR0_CD_MASK
+ mov cr0, eax
+
+ RET_NS
+RestoreMtrrProgrammingRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: RestoreApConfig
+;
+; Input: esi - pointer to save area
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Function is executed on AP in memory present environment on S3
+; resume path. Restores contents of all MTRRs from table
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+RestoreApConfig PROC NEAR PUBLIC
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE
+ mov CR4, eax
+
+ mov esi, 1000h
+ mov ds, cs:[esi].StartUp.fDs
+ mov es, cs:[esi].StartUp.fDs
+ mov fs, cs:[esi].StartUp.fDs
+ mov gs, cs:[esi].StartUp.fDs
+ mov ss, cs:[esi].StartUp.fDs
+
+ mov esi, [esi].StartUp.fParam
+
+ CALL_NS RestoreMtrrProgrammingRetNS
+
+ lidt FWORD PTR [esi+8]
+
+ jmp updateSemaphore
+
+RestoreApConfig ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: DoApInit
+;
+; Input: Contents of startup area at 1000h
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Executed on AP. Persforms CPU initialization for running
+; of GETSEC
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+DoApInit PROC NEAR PUBLIC
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+
+ mov esi, 1000h
+ mov ds, cs:[esi].StartUp.fDs
+
+ mov esi, [esi].StartUp.fParam
+ mov edi, 1
+
+ CALL_NS PrepareCacheForAcModuleRetNS
+
+ CALL_NS CleanMcaRetNS
+
+updateSemaphore::
+ mov ecx, 1000h + StartUp.smphr
+ lock inc DWORD PTR [ecx]
+
+hltLoop:
+ cli
+ hlt
+ jmp hltLoop
+
+DoApInit ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: MemCopyRetNS
+;
+; Input: esi - from linear address
+; edi - to linear address
+; ecx - swap size in dwords
+; ds - flat segment
+;
+; Output: None
+;
+; Registers: None
+;
+; Description: Swaps contents of two input buffers.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+MemCopyRetNS PROC NEAR
+
+start:
+ mov eax, ds:[esi] ; source
+ mov ds:[edi], eax
+ add esi, 4
+ add edi, 4
+ loop start
+ RET_NS
+MemCopyRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: ltWaitStatusRetNS
+;
+; Input: cx - Refresh bit Toggle count
+; 750000us = 50000 toggles
+; edx - offset of Status procedure
+;
+; Output: Z if status is met
+; NZ - timeout occured
+; NC - always
+;
+; Stack: Not available
+;
+; Registers: cx, ax, esp
+;
+; Description: Calls status procedure. If status is met - returns Z and
+; NZ otherwise.
+; Status procedure is required to return Z if status is met and
+; NZ if not
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+ltWaitStatusRetNS PROC NEAR
+
+ in al, PORTB ; Read initial setting.
+ and al, PORTBMASK ; Keep what we care about.
+ mov ah, al ; Keep a copy of the data.
+
+waitLoop:
+ CALL_NS edx ; Call status procedure.
+ jz exit ; Z - status met
+
+waitLoop0:
+ in al, PORTB
+ and al, PORTBMASK
+ cmp al, ah ; Refresh bit changed ?
+ je waitLoop0
+
+ mov ah, al
+ loop waitLoop
+ or ax, 1 ; Clear the ZERO flag - timeout.
+ ; This also clears C flag
+exit:
+ RET_NS
+ltWaitStatusRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: IcrStatusRetNS
+;
+; Input: ds: Flat, edi - xAPIC Base Address
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: all are preserved
+;
+; Description: Returns Z if ICR is idle
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+IcrStatusRetNS PROC NEAR PUBLIC
+ test DWORD PTR ICR_LOW[edi], BIT12
+ RET_NS
+IcrStatusRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: SemaphoreStatusRetNS
+;
+; Input: ds: Flat
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: all are preserved
+;
+; Description: Returns Z if semaphore is 0
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+SemaphoreStatusRetNS PROC NEAR PUBLIC
+ bswap eax
+ mov al, BYTE PTR [esi+SEMAPHORE]
+ cmp al, bl
+ bswap eax
+ RET_NS
+SemaphoreStatusRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: SemaphoreStatus2RetNS
+;
+; Input: ds: Flat
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: Upper byte of eax is modified
+;
+; Description: Returns Z if semaphore is 0
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+SemaphoreStatus2RetNS PROC NEAR PUBLIC
+ bswap eax
+ mov al, BYTE PTR [esi].StartUp.smphr
+ cmp al, bl
+ bswap eax
+ RET_NS
+SemaphoreStatus2RetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: NeverStatusRetNS
+;
+; Input:
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: All are preserved
+;
+; Description: Returns Z if ICR is idle
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+NeverStatusRetNS PROC NEAR PUBLIC
+ or dx, dx ; dx is never 0 so return is NZ
+ RET_NS
+NeverStatusRetNS ENDP
+
+
+
+END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new
new file mode 100644
index 0000000..e27781e
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new
@@ -0,0 +1,69 @@
+#++
+# 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
+#--
+#++
+#
+# Copyright (c) 1999 - 2011 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.
+#
+# Module Name:
+#
+# makefile.new
+#
+# Abstract:
+#
+# makefile for TxtPeiAp.asm16 file
+#
+#--
+
+
+#
+# Globals
+#
+BIN_DIR = $(BUILD_DIR)\$(PROCESSOR)
+TOOLCHAIN = TOOLCHAIN_$(PROCESSOR)
+
+TOOLBIN_DIR = $(BUILD_DIR)\Tools
+
+#
+# Include CommonTools.env enviroment
+#
+
+!INCLUDE $(BUILD_DIR)\PlatformTools.env
+
+AP_GUID = D1E59F50-E8C3-4545-BF61-11F002233C97
+
+all : $(BIN_DIR)\TxtPeiAp.bin
+
+$(BIN_DIR)\TxtPeiAp.bin: $(BIN_DIR)\TxtPeiAp.obj
+
+$(BIN_DIR)\TxtPeiAp.obj: $(SOURCE_DIR)\TxtPeiAp.asm16
+ $(ASM) /c /nologo /Fl /Sa /I$(SOURCE_DIR)\..\..\..\..\Include /Fo$(BIN_DIR)\TxtPeiAp.obj $(SOURCE_DIR)\TxtPeiAp.asm16
+ cd $(BIN_DIR)
+ $(ASMLINK) TxtPeiAp.obj, TxtPeiAp.com,,,,
+ copy TxtPeiAp.com TxtPeiAp.bin
+ $(GENFFSFILE) -B $(BIN_DIR) -V -P1 <<$(BIN_DIR)\txtpeiap.pkg
+PACKAGE.INF
+[.]
+BASE_NAME = TxtPeiAp
+FFS_FILEGUID = $(AP_GUID)
+FFS_FILETYPE = EFI_FV_FILETYPE_RAW
+FFS_ATTRIB_CHECKSUM = FALSE
+FFS_ALIGNMENT = 5
+
+IMAGE_SCRIPT =
+{
+ txtpeiap.bin
+}
+<<KEEP
+
+
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.c b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.c
new file mode 100644
index 0000000..b1b1ec5
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.c
@@ -0,0 +1,241 @@
+/** @file
+ This is the main PEIM file for TXT. It represents an abstract outline of the
+ steps required during PEI for enabling TXT. Each individual step is further
+ abstracted behind a function call interface. This is intended to minimize
+ the need to modify this file when porting TXT to future platforms.
+
+@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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include "TxtPeiLib.h"
+///
+/// #include EFI_PPI_DEFINITION (BootScriptDone)
+///
+#include EFI_PPI_DEFINITION (TxtMemoryUnlocked)
+#include EFI_PPI_DEFINITION (EndOfPeiSignal)
+#include EFI_GUID_DEFINITION (TxtInfoHob)
+#include EFI_GUID_DEFINITION (SaDataHob)
+#endif
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiTxtMemoryUnlockedPpiGuid,
+ NULL
+};
+
+STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEndOfPeiSignalPpiGuid,
+ DprUpdate
+};
+
+/**
+ This is the entry point to the TXT PEIM. The TXT PEIM checks for an TXT
+ capable platform and determines whether SCLEAN should be run. If so,
+ it launches the BIOS ACM to run SCLEAN (which will reset the platform).
+ If not, the PEIM checks to see if the platform is resuming from S3.
+
+ If the platform is resuming from S3, this code will register a callback
+ so that SCHECK will be run when BootScript is done restoring the platform's
+ configuration.
+
+ @param[in] FfsHeader - A pointer the the FFS File containing this PEIM.
+ @param[in] PeiServices - A Pointer to the PEI Services Table.
+
+ @exception EFI_UNSUPPORTED - If the platform is not TXT capable.
+ @retval EFI_SUCCESS - In all other cases not listed above.
+**/
+EFI_STATUS
+EFIAPI
+PeimEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ TXT_PEI_LIB_CONTEXT ctx;
+ BOOLEAN TxtEnvInitFail;
+ TxtEnvInitFail = FALSE;
+
+ ///
+ /// Install PPI to tell memory code that it can run.
+ /// Do it always.
+ ///
+ Status = PeiServicesInstallPpi (&mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize the TXT PEI Lib functions
+ ///
+ Status = InitializeTxtPeiLib (
+ &ctx,
+ PeiServices
+ );
+
+ if (EFI_ERROR (Status)) {
+ TxtEnvInitFail = TRUE;
+ DEBUG ((EFI_D_ERROR, "TXTPEI::PEI Lib initialization failure\n"));
+ }
+ ///
+ /// Determine TPM presence. If TPM is not present - disabling TXT through TxtInfoHob by setting TxtMode=0
+ /// Incase TXT had been enabled but TPM was removed suddenly. Although TPM presence is precondition of this module
+ /// since all commands executed by BIOS ACM don't depend on TPM state.
+ /// TPM_NV_read will be successfully executed even if TPM is disabled
+ /// and/or deactivated because all indices defined for BIOS ACM
+ /// usage don't require authorization. TPM_ResetEstablishmentBit
+ /// doesn't depend on TPM state at all and can
+ /// be executed with disabled/deactivated TPM always.
+ /// Case when TPM is completely not functional is not considered.
+ ///
+ Status = IsTpmPresent (&ctx);
+ if (EFI_ERROR (Status)) {
+ ///
+ /// If TPM is not present / not supported, set TxtMode=0 incase TPM was removed after TXT enabled
+ ///
+ if (Status == EFI_UNSUPPORTED) {
+ DEBUG ((EFI_D_WARN, "TXTPEI::TPM Support is Disabled in BIOS! Disabling TXT! TxtMode=%x\n", ctx.Hob->Data.TxtMode));
+ } else {
+ DEBUG ((EFI_D_WARN, "TXTPEI::TPM is not present! Disabling TXT! TxtMode=%x\n", ctx.Hob->Data.TxtMode));
+ }
+
+ TxtEnvInitFail = TRUE;
+ }
+ ///
+ /// Detect TXT capable Processor & PCH
+ ///
+ if (!IsTxtChipset (&ctx)) {
+ DEBUG ((EFI_D_WARN, "TXTPEI::Platform or PCH is not TXT capable\n"));
+ return EFI_UNSUPPORTED;
+ } else if (!IsTxtProcessor ()) {
+ DEBUG ((EFI_D_WARN, "TXTPEI::Processor is not TXT capable\n"));
+ return EFI_UNSUPPORTED;
+ } else {
+ DEBUG ((EFI_D_WARN, "TXTPEI::Processor, PCH & Platform is TXT capable\n"));
+ ///
+ /// If Txt Lib or TPM is initiated successful, disable TxT support.
+ ///
+ if (TxtEnvInitFail) {
+ UnlockMemory (&ctx);
+ ctx.Hob->Data.TxtMode = 0;
+ ASSERT (TRUE);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ ///
+ /// Memory is supposed to lock if system is TxT capable.
+ /// Check if we need to run SCLEAN. TxT BIOS spec Section 6.2.5
+ ///
+ if (IsEstablishmentBitAsserted (&ctx) && IsTxtWakeError (&ctx)) {
+
+ DEBUG ((EFI_D_INFO, "TXTPEI::EstablishmentBit is set\n"));
+ ///
+ /// If TXTRESET is set , we must clean TXTRESET bit otherwise SCLEAN
+ /// will fail
+ ///
+ if (IsTxtResetSet (&ctx)) {
+ DoGlobalReset ();
+ }
+ ///
+ /// Setup and Launch SCLEAN
+ ///
+ DEBUG ((EFI_D_INFO, "TXTPEI::Entering SCLEAN\n"));
+
+ DoSclean (&ctx);
+
+ ///
+ /// Reset platform - performed by DoSclean, should not return to execute the following dead looping
+ ///
+ EFI_DEADLOOP ();
+ } else {
+ ///
+ /// Unlock memory, and then continue running
+ ///
+ DEBUG ((EFI_D_INFO, "TXTPEI::EstablishmentBit not asserted - Unlock Memory\n"));
+ AsmWriteMsr64 (0x2e6, 0);
+ }
+
+ Status = PeiServicesNotifyPpi (&mNotifyDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Fix up pointers since they are located in real memory now.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+DprUpdate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ TXT_INFO_HOB *TxtInfoHob;
+ SA_DATA_HOB *SaDataHob;
+ DPR_DIRECTORY_ENTRY *DprDirectory;
+ UINT16 Index;
+
+ TxtInfoHob = NULL;
+ SaDataHob = NULL;
+ DprDirectory = NULL;
+ Index = 0;
+
+ //
+ // Get TxtInfoHob
+ //
+ TxtInfoHob = (TXT_INFO_HOB *)GetFirstGuidHob (&gTxtInfoHobGuid);
+ if (TxtInfoHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ TxtInfoHob->Data.TxtDprMemoryBase = 0;
+
+ //
+ // Get SaDataHob
+ //
+ SaDataHob = (SA_DATA_HOB *)GetFirstGuidHob (&gSaDataHobGuid);
+ if (SaDataHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ DprDirectory = (DPR_DIRECTORY_ENTRY *)&(SaDataHob->DprDirectory[0]);
+
+ //
+ // Find TxT DPR Directory
+ //
+ for (Index=0; Index<DPR_DIRECTORY_MAX; Index++) {
+ if (DprDirectory[Index].Type == DPR_DIRECTORY_TYPE_TXT) {
+ TxtInfoHob->Data.TxtDprMemoryBase = (EFI_PHYSICAL_ADDRESS)DprDirectory[Index].PhysBase;
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.dxs b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.dxs
new file mode 100644
index 0000000..fa940d7
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.dxs
@@ -0,0 +1,49 @@
+/** @file
+ This is the Dependency expression for the TXT Pei PPI
+
+@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
+
+**/
+
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+#include EFI_PPI_DEFINITION (Stall)
+#include EFI_PPI_CONSUMER (BootMode)
+#endif
+
+#include EFI_PPI_DEFINITION (TpmInitialized)
+#include EFI_PPI_DEFINITION (CpuPlatformPolicy)
+#include EFI_PPI_DEPENDENCY (SaPeiInit)
+
+DEPENDENCY_START
+ PEI_STALL_PPI_GUID AND
+ PEI_MASTER_BOOT_MODE_PEIM_PPI AND
+ PEI_CPU_PLATFORM_POLICY_PPI_GUID AND
+ SA_PEI_INIT_PPI_GUID
+DEPENDENCY_END
+
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.inf b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.inf
new file mode 100644
index 0000000..428372a
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.inf
@@ -0,0 +1,104 @@
+## @file
+# Component description file for TXT PEI module
+#
+#@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 = TxtPei
+FILE_GUID = CA9D8617-D652-403b-B6C5-BA47570116AD
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ TxtPei.c
+ TxtPeiLib.c
+ Ia32/TxtPeiBsp.asm
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ .
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include/Library
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Framework/Ppi/Stall
+ $(EDK_SOURCE)/Foundation/Library/Dxe/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
+#
+# 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
+
+[libraries.common]
+ EdkFrameworkPpiLib
+ SaGuidLib
+ CpuPpiLib
+ CpuGuidLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGluePeiHobLib
+ AnchorCoveLib
+ TxtLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = TxtPei.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PeimEntry
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_PEI_SERVICES_LIB__
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.mak b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.mak
new file mode 100644
index 0000000..ecb55ef
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.mak
@@ -0,0 +1,105 @@
+# MAK file for the ModulePart:TxtPei
+
+all : TxtPei
+
+TxtPei : $(BUILD_DIR)\TxtPei.mak TxtPeiBin TxtPeiAp.bin $(BUILD_DIR)\TxtPeiap.ffs
+
+$(BUILD_DIR)\TxtPei.mak : $(TxtPei_DIR)\$(@B).cif $(TxtPei_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TxtPei_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+MY_DEFINES=\
+ /DAMI_MICROCODE_PPI\
+!IF "$(TXT_DEBUG_INFO)"=="1"
+ /D"TXT_DEBUG_INFO=1"\
+!ELSE
+ /D"TXT_DEBUG_INFO=0"\
+!ENDIF
+
+TxtPei_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(TXT_INCLUDES)\
+ $(PROJECT_CPU_INCLUDES)\
+ $(PROJECT_INCLUDES)\
+ $(INTEL_MCH_INCLUDES)\
+ $(TCG_INCLUDES)\
+
+TxtPei_DEFINES=\
+ $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PeimEntry"\
+ /D PlatformPciExpressBaseAddress=$(PCIEX_BASE_ADDRESS) \
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_PEI_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_PEI_SERVICES_LIB__\
+ /D __EDKII_GLUE_PEI_SERVICES_TABLE_POINTER_LIB_MM7__ \
+
+TxtPei_OBJECTS=\
+ $(BUILD_DIR)\$(TxtPei_DIR)\TxtPei.obj\
+ $(BUILD_DIR)\$(TxtPei_DIR)\TxtPeiLib.obj\
+ $(BUILD_DIR)\$(TxtPei_DIR)\Ia32\TxtPeiBsp.obj
+
+TxtPei_LIBS=\
+ $(EDKFRAMEWORKPPILIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(BUILD_DIR)\IA32\EdkIIGlueBaseLib.lib\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGluePeiDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGluePeiHobLib_LIB)\
+ $(EdkIIGluePeiMemoryAllocationLib_LIB)\
+ $(CpuGuidLib_LIB)\
+ $(CPU_PPI_LIB)\
+ $(SaGuidLib_LIB)\
+ $(PEIHOBLIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueBasePciExpressLib_LIB)\
+ $(PchPlatformPeiLib_LIB)\
+ $(CpuPlatformLib_LIB)\
+ $(BootGuardLib_LIB)\
+ $(TxtLib_LIB)
+
+TxtPeiBin : $(TxtPei_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\TxtPei.mak all\
+ "MY_INCLUDES=$(TxtPei_INCLUDES)"\
+ "MY_DEFINES=$(TxtPei_DEFINES)"\
+ "OBJECTS=$(TxtPei_OBJECTS)" \
+ "AFLAGS=$(AFLAGS) $(PROJECT_CPU_INCLUDES)"\
+ GUID=CA9D8617-D652-403b-B6C5-BA47570116AD\
+ ENTRY_POINT=_ModuleEntryPoint\
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(TxtPei_DIR)\TxtPei.dxs \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=0\
+
+TxtPeiAp.bin: $(BUILD_DIR)\TxtPeiap.bin
+
+$(BUILD_DIR)\TxtPeiap.bin: $(BUILD_DIR)\TxtPeiAp.obj
+
+$(BUILD_DIR)\TxtPeiAp.obj:$(TxtPei_DIR)\Ia32\TxtPeiAp.asm16
+ $(ASM) /c /nologo $(PROJECT_CPU_INCLUDES) /Fo$(BUILD_DIR)\TxtPeiAp.obj $(TxtPei_DIR)\Ia32\TxtPeiAp.asm16
+ $(ASMLINK) $(BUILD_DIR)\TxtPeiAp.obj, $*.exe, $*.map,,,
+ exe2bin $*.exe $*.bin
+
+$(BUILD_DIR)\TxtPeiap.ffs : $(BUILD_DIR)\TxtPeiap.bin
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=$(AP_GUID) \
+ TYPE=EFI_FV_FILETYPE_RAW \
+ FFS_CHECKSUM=0 \
+ FFS_ALIGNMENT=5 \
+ RAWFILE=$(BUILD_DIR)\TxtPeiap.bin \
+ COMPRESS=0 \
+ FFSFILE=$@ \
+ NAME=DummyName
+
+TXT_AP_FIXUP:
+ $(TxtTools_DIR)\STAFixup.exe $(AP_GUID) $(AMI_ROM) $(AP_FIXUP_FILE) $(AP_OFFSET)
+
+AFTER_ROM: TXT_AP_FIXUP
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.sdl b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.sdl
new file mode 100644
index 0000000..b438250
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPei.sdl
@@ -0,0 +1,86 @@
+TOKEN
+ Name = "TxtPei_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TXT Pei init support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "TxtPei_DIR"
+ Help = "TXT PEI source directory"
+End
+
+TOKEN
+ Name = "TXT_TOOL_DIR"
+ Value = "$(TXT_DIR)\Tools"
+ Help = "TXT tools directory"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+END
+
+TOKEN
+ Name = "AP_GUID"
+ Value = "D1E59F50-E8C3-4545-BF61-11F002233C97"
+ Help = "GUID of AP initialization file."
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AP_FIXUP_FILE"
+ Value = "$(TXT_TOOL_DIR)\Apfixup.txt"
+ Help = "Name of AP FFS fixup table file."
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AP_OFFSET"
+ Value = "$(FV_BB_BLOCKS)*$(FLASH_BLOCK_SIZE)"
+ Help = "End-of-file offset of AP initialization file."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes TXTPEI.mak into project"
+ File = "TXTPEI.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\txtpeiap.ffs"
+ Parent = "FV_BB"
+ Priority = -2000
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TYPE:HOLE LOCATION:0xfffff000"
+ Parent = "$(BUILD_DIR)\txtpeiap.ffs"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\TxtPei.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "TXT_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/I$(TxtPei_DIR)"
+ Parent = "TXT_INCLUDES"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.c b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.c
new file mode 100644
index 0000000..436ca18
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.c
@@ -0,0 +1,1045 @@
+/** @file
+ This file contains an implementation of the function call interfaces
+ required by the main TXT PEIM file. Hopefully, future platform porting
+ tasks will be mostly limited to modifying the functions in this 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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "TxtPeiLib.h"
+#include "TxtLibrary.h"
+
+EFI_GUID mTxtBiosAcmPeiFileGuid = PEI_BIOS_ACM_FILE_GUID;
+EFI_GUID mTxtApStartupPeiFileGuid = PEI_AP_STARTUP_FILE_GUID;
+EFI_GUID mCpuMicrocodeFileGuid = CPU_MICROCODE_FILE_GUID;
+#define EFI_PEI_PCI_CFG2_PPI_GUID \
+ { 0x57a449a, 0x1fdc, 0x4c06, 0xbf, 0xc9, 0xf5, 0x3f, 0x6a, 0x99, 0xbb, 0x92 }
+
+EFI_GUID gPeiPciCfgPpiInServiceTableGuid2 = EFI_PEI_PCI_CFG2_PPI_GUID;
+///
+/**
+ This routine initializes and collects all PPIs and data required
+ by the routines in this file.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] mPS - A pointer to the PEI Service Table
+
+ @exception EFI_UNSUPPORTED - If any of the required PPIs or data are unavailable
+ @retval EFI_SUCCESS - In all cases not listed above
+**/
+EFI_STATUS
+InitializeTxtPeiLib (
+ IN TXT_PEI_LIB_CONTEXT *pctx,
+ IN EFI_PEI_SERVICES **mPS
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Make sure our pointers start life as NULL pointers
+ ///
+ pctx->PeiStall = NULL;
+ pctx->BiosAcmBase = NULL;
+ pctx->ApStartup = NULL;
+ pctx->McuStart = NULL;
+
+ ///
+ /// Initialize all pointers
+ ///
+ pctx->PeiServices = mPS;
+ pctx->CpuIoPpi = (**mPS).CpuIo;
+
+ Status = PeiServicesLocatePpi (
+ &gPeiPciCfgPpiInServiceTableGuid2,
+ 0,
+ NULL,
+ (VOID **) &(pctx->PciCfgPpi)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiStallPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &(pctx->PeiStall)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Find TxtInfoHob by platfrom code
+ ///
+ Status = CreateTxtInfoHob (pctx);
+
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: TXT Info Hob not found.\n"));
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Print out the TxtInfo HOB if TXT_DEBUG_INFO is set
+ ///
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtInfoHob passed from platform as:\n"));
+ DEBUG ((EFI_D_INFO, "TXTPEI: ChipsetIsTxtCapable = %x\n", pctx->Hob->Data.ChipsetIsTxtCapable));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtMode = %x\n", pctx->Hob->Data.TxtMode));
+ DEBUG ((EFI_D_INFO, "TXTPEI: PmBase = %x\n", pctx->Hob->Data.PmBase));
+ DEBUG ((EFI_D_INFO, "TXTPEI: SinitMemorySize = %x\n", pctx->Hob->Data.SinitMemorySize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtHeapMemorySize = %x\n", pctx->Hob->Data.TxtHeapMemorySize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtDprMemoryBase = %x\n", pctx->Hob->Data.TxtDprMemoryBase));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtDprMemorySize = %x\n", pctx->Hob->Data.TxtDprMemorySize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: BiosAcmBase = %x\n", pctx->Hob->Data.BiosAcmBase));
+ DEBUG ((EFI_D_INFO, "TXTPEI: BiosAcmSize = %x\n", pctx->Hob->Data.BiosAcmSize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: McuUpdateDataAddr = %x\n", pctx->Hob->Data.McuUpdateDataAddr));
+ DEBUG ((EFI_D_INFO, "TXTPEI: SinitAcmBase = %x\n", pctx->Hob->Data.SinitAcmBase));
+ DEBUG ((EFI_D_INFO, "TXTPEI: SinitAcmSize = %x\n", pctx->Hob->Data.SinitAcmSize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TgaSize = %x\n", pctx->Hob->Data.TgaSize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtLcpPdBase = %x\n", pctx->Hob->Data.TxtLcpPdBase));
+ DEBUG ((EFI_D_INFO, "TXTPEI: TxtLcpPdSize = %x\n", pctx->Hob->Data.TxtLcpPdSize));
+ DEBUG ((EFI_D_INFO, "TXTPEI: Flags = %x\n", pctx->Hob->Data.Flags));
+
+ ///
+ /// Check if platform specify BIOS ACM addrss by itself, BIOS ACM address must be 4K alignment in FLASH address space
+ ///
+ if (pctx->Hob->Data.BiosAcmBase != 0) {
+ DEBUG ((EFI_D_INFO, "TXTPEI: Customized BIOS ACM location at %x\n", pctx->Hob->Data.BiosAcmBase));
+ ///
+ /// Check BIOS ACM is 4K alignment or not
+ ///
+ if ((pctx->Hob->Data.BiosAcmBase & 0xFFF) != 0) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: Customized BIOS ACM is not 4K aligned, force TxtMode=0 and unloaded!!\n"));
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Get BIOS ACM base from TxtInfoHob provided by platform code
+ ///
+ pctx->BiosAcmBase = (ACM_HEADER *) (UINT32) pctx->Hob->Data.BiosAcmBase;
+ } else {
+ ///
+ /// Get BIOS ACM by seaching PEI firmware volume
+ ///
+ Status = FindBiosAcmInVolume (pctx, (UINT32 **) &pctx->BiosAcmBase);
+
+ ///
+ /// BIOS ACM not found, disable TXT and return EFI_UNLOAD_IMAGE
+ ///
+ if (((pctx->BiosAcmBase) == 0) || (Status == EFI_NOT_FOUND)) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: BIOS ACM not found, force TxtMode=0 and unloaded!\n"));
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((EFI_D_INFO, "TXTPEI: Found BIOS ACM location at %x\n", pctx->BiosAcmBase));
+
+ ///
+ /// Check BIOS ACM is 4K alignment, if not disable TXT and return EFI_UNLOAD_IMAGE
+ ///
+ if (((UINT32) pctx->BiosAcmBase & 0xFFF) != 0) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: BIOS ACM is not 4K aligned, force TxtMode=0 and unloaded!!\n"));
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+ }
+ ///
+ /// Check ACM is matched to chipset or not, if not, disable TXT and return EFI_UNLOAD_IMAGE
+ ///
+ if (!CheckTxtAcmMatch (pctx, pctx->BiosAcmBase)) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: BIOS ACM is not matched to chipset!! Force TxtMode=0 and unloaded!!\n"));
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ pctx->BiosAcmSize = (pctx->BiosAcmBase->Size) << 2;
+
+ Status = FindApStartupInVolume (pctx, (UINT32 **) &(pctx->ApStartup));
+
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: AP Startup code not found.\n"));
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((EFI_D_INFO, "TXTPEI: Found AP init code at %x\n", pctx->ApStartup));
+
+ ///
+ /// Check if platform specify MCU addrss by itself
+ ///
+ if (pctx->Hob->Data.McuUpdateDataAddr != 0) {
+ DEBUG ((EFI_D_INFO, "Customized MCU location at %x\n", pctx->Hob->Data.McuUpdateDataAddr));
+ pctx->McuStart = (UINT32 *) (UINTN) pctx->Hob->Data.McuUpdateDataAddr;
+ } else {
+ ///
+ /// Find microcode update by searching PEI FV
+ ///
+ Status = FindMcuInVolume (pctx, (UINT32 **) &(pctx->McuStart));
+
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: MCU not found.\n"));
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((EFI_D_INFO, "TXTPEI: Found MCU at %x\n", pctx->McuStart));
+ }
+ ///
+ /// Initialize local APIC
+ ///
+ if ((((AsmReadMsr64 (MSR_IA32_APIC_BASE)) & (BIT11 + BIT10)) == BIT11 + BIT10)) {
+ AsmWriteMsr64 (EFI_MSR_EXT_XAPIC_SVR, 0x1FF);
+ } else {
+ ///
+ /// Determine address of Local APIC
+ ///
+ pctx->Ia32ApicBase = ((UINT32) AsmReadMsr64 (MSR_IA32_APIC_BASE)) & BASE_ADDR_MASK;
+ *(UINT32 *) (pctx->Ia32ApicBase + APIC_SPURIOUS_VECTOR_REGISTER) = 0x1FF;
+ }
+ ///
+ /// Initialize TxtInfoHob fields
+ ///
+ pctx->Hob->Data.BiosAcmBase = (UINTN) pctx->BiosAcmBase;
+ pctx->Hob->Data.BiosAcmSize = (UINTN) pctx->BiosAcmSize;
+ pctx->Hob->Data.McuUpdateDataAddr = (UINTN) pctx->McuStart;
+
+ ///
+ /// Make sure none of our pointers are still NULL
+ ///
+ if (!(pctx->PeiStall && pctx->BiosAcmBase && pctx->ApStartup && pctx->McuStart)) {
+ pctx->Hob->Data.TxtMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines whether or not the current processor is TXT Capable.
+
+ @retval TRUE - If the current processor supports TXT
+ @retval FALSE - If the current processor does not support TXT
+**/
+BOOLEAN
+IsTxtProcessor (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegs;
+
+ AsmCpuid (1, &CpuidRegs.RegEax, &CpuidRegs.RegEbx, &CpuidRegs.RegEcx, &CpuidRegs.RegEdx);
+
+ return (CpuidRegs.RegEcx & B_CPUID_VERSION_INFO_ECX_SME) ? TRUE : FALSE;
+}
+
+/**
+ Determines whether or not the current chipset is TXT Capable.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the current chipset supports TXT
+ @retval FALSE - If the current chipset doesn't supports TXT
+**/
+BOOLEAN
+IsTxtChipset (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ BOOLEAN TxtCapable;
+ UINT32 Data32;
+
+ TxtCapable = FALSE;
+ Data32 = CheckSmxCapabilities();
+
+ if ((Data32 & BIT0) != 0) {
+ TxtCapable = TRUE;
+ DEBUG ((EFI_D_INFO, "Platform/PCH - TXT supported\n"));
+ } else {
+ TxtCapable = FALSE;
+ DEBUG ((EFI_D_INFO, "Platform/PCH - TXT not supported!!!\n"));
+ }
+
+ return TxtCapable;
+}
+
+/**
+ Determines whether TXT is enabled by platform setting
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If TXT is enabled by platform setting
+ @retval FALSE - If TXT is disabled by platform setting
+**/
+BOOLEAN
+IsTxtEnabled (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ if (pctx->Hob == 0) {
+ return FALSE;
+ }
+
+ return (BOOLEAN) (pctx->Hob->Data.TxtMode);
+}
+
+/**
+ Determines ACM is matched to chipset or not
+
+ @param[in] pctx - Point to TXT_PEI_LIB_CONTEXT structure
+ @param[in] BiosAcmBase - A pointer to BIOS ACM location
+
+ @retval TRUE - BIOS ACM is matched to chipset
+ @retval FALSE - BIOS ACM is NOT matched to chipset
+**/
+BOOLEAN
+CheckTxtAcmMatch (
+ IN TXT_PEI_LIB_CONTEXT *pctx,
+ IN ACM_HEADER *BiosAcmBase
+ )
+{
+ BOOLEAN ChipsetIsProduction;
+ BOOLEAN BiosAcmIsProduction;
+
+ if (BiosAcmBase == NULL) {
+ return FALSE;
+
+ }
+ ///
+ /// Initializing ChipsetIsProduction default value
+ ///
+ ChipsetIsProduction = (*(UINT32 *) (TXT_PUBLIC_BASE + 0x200) & BIT31) ? TRUE : FALSE;
+
+ ///
+ /// Check ACM is production or not
+ ///
+ BiosAcmIsProduction = (BiosAcmBase->ModuleID & BIT31) ? FALSE : TRUE;
+
+ return ChipsetIsProduction == BiosAcmIsProduction;
+}
+
+/**
+ Create TXT Info HOB
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - If TXT Info Hob is found
+ @retval EFI_NOT_FOUND - If TXT Info Hob is not found
+**/
+EFI_STATUS
+CreateTxtInfoHob (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ EFI_STATUS Status;
+ PEI_CPU_PLATFORM_POLICY_PPI *CpuPlatformPolicy;
+ TXT_INFO_HOB *TxtInfoHob;
+
+ TxtInfoHob = NULL;
+
+ ///
+ /// Locate TPM Initialized Ppi to determine TPM is present and initialized properly.
+ ///
+ Status = PeiServicesLocatePpi (
+ &gPeiCpuPlatformPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &CpuPlatformPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Create hob for storing TXT data
+ ///
+ Status = (*(pctx->PeiServices))->CreateHob (
+ pctx->PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof (TXT_INFO_HOB),
+ (VOID **) &TxtInfoHob
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ pctx->Hob = TxtInfoHob;
+ TxtInfoHob->EfiHobGuidType.Name = gTxtInfoHobGuid;
+
+ ///
+ /// Initiate Txt Info Hob
+ ///
+ ZeroMem (&(TxtInfoHob->Data), sizeof (TXT_INFO_DATA));
+
+ TxtInfoHob->Data.ChipsetIsTxtCapable = IsTxtChipset (pctx);
+ if (CpuPlatformPolicy->CpuConfig->Txt == 1) {
+ TxtInfoHob->Data.TxtMode = 1;
+ }
+ TxtInfoHob->Data.PmBase = MmioRead32 (
+ MmPciAddress (0,
+ PCI_BUS_NUMBER_PCH_LPC,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) &~1;
+
+ TxtInfoHob->Data.SinitMemorySize = CpuPlatformPolicy->SecurityConfig->TxtConfig->SinitMemorySize;
+ TxtInfoHob->Data.TxtHeapMemorySize = CpuPlatformPolicy->SecurityConfig->TxtConfig->TxtHeapMemorySize;
+ TxtInfoHob->Data.TxtDprMemoryBase = CpuPlatformPolicy->SecurityConfig->TxtConfig->TxtDprMemoryBase;
+ TxtInfoHob->Data.TxtDprMemorySize = CpuPlatformPolicy->SecurityConfig->TxtConfig->TxtDprMemorySize;
+ TxtInfoHob->Data.BiosAcmBase = CpuPlatformPolicy->SecurityConfig->TxtConfig->BiosAcmBase;
+ TxtInfoHob->Data.BiosAcmSize = CpuPlatformPolicy->SecurityConfig->TxtConfig->BiosAcmSize;
+ TxtInfoHob->Data.McuUpdateDataAddr = CpuPlatformPolicy->SecurityConfig->TxtConfig->McuUpdateDataAddr;
+ TxtInfoHob->Data.TgaSize = CpuPlatformPolicy->SecurityConfig->TxtConfig->TgaSize;
+ TxtInfoHob->Data.TxtLcpPdBase = CpuPlatformPolicy->SecurityConfig->TxtConfig->TxtLcpPdBase;
+ TxtInfoHob->Data.TxtLcpPdSize = CpuPlatformPolicy->SecurityConfig->TxtConfig->TxtLcpPdSize;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines whether or not the platform has executed an TXT launch by
+ examining the TPM Establishment bit.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the TPM establishment bit is asserted.
+ @retval FALSE - If the TPM establishment bit is unasserted.
+**/
+BOOLEAN
+IsEstablishmentBitAsserted (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT8 Access;
+ UINT16 TimeOutCount;
+
+ ///
+ /// Set TPM.ACCESS polling timeout about 750ms
+ ///
+ TimeOutCount = TPM_TIME_OUT;
+ do {
+ ///
+ /// Read TPM status register
+ ///
+
+ Access = pctx->CpuIoPpi->MemRead8 (
+ pctx->PeiServices,
+ pctx->CpuIoPpi,
+ TPM_STATUS_REG_ADDRESS
+ );
+
+ ///
+ /// if TPM.Access == 0xFF, TPM is not present
+ ///
+ if (Access == 0xFF) {
+ return FALSE;
+ }
+ ///
+ /// Check tpmRegValidSts bit before checking establishment bit
+ ///
+ if (((pctx->PeiStall) != NULL) && ((Access & 0x80) != 0x80)) {
+ ///
+ /// Delay 1ms
+ ///
+ pctx->PeiStall->Stall (pctx->PeiServices, pctx->PeiStall, 1000);
+ } else {
+ ///
+ /// tpmRegValidSts set, we can check establishment bit now.
+ ///
+ break;
+ }
+
+ TimeOutCount--;
+ } while (TimeOutCount != 0);
+ ///
+ /// if tpmRegValidSts is not set, TPM is not usable
+ ///
+ if ((Access & 0x80) != 0x80) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: TPM Valid Status is not set!! TPM.ACCESS=%x\n", Access));
+ ASSERT (TRUE);
+ EFI_DEADLOOP ();
+ }
+ ///
+ /// The bit we're interested in uses negative logic:
+ /// If bit 0 == 1 then return False
+ /// Else return True
+ ///
+ return (Access & 0x1) ? FALSE : TRUE;
+}
+
+/**
+ Determines whether or not the platform has encountered an error during
+ a sleep or power-off state.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the TXT_WAKE_ERROR bit is asserted.
+ @retval FALSE - If the TXT_WAKE_ERROR bit is unasserted.
+**/
+BOOLEAN
+IsTxtWakeError (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT8 Ests;
+
+ ///
+ /// Read TXT.ESTS register
+ ///
+ Ests = pctx->CpuIoPpi->MemRead8 (
+ pctx->PeiServices,
+ pctx->CpuIoPpi,
+ TXT_PUBLIC_BASE + TXT_ERROR_STATUS_REG_OFF
+ );
+
+ DEBUG ((EFI_D_INFO, "TXTPEI: TXT.ESTS=%x\n", Ests));
+
+ return (Ests & (0x1 << 6)) ? TRUE : FALSE;
+}
+
+/**
+ Determines whether or not the platform memory has been locked
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If memroy is locked
+ @retval FALSE - If memory is unlocked
+**/
+BOOLEAN
+IsMemoryLocked (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT32 CpuMemLockStatus;
+
+ ///
+ /// Check status register for now.
+ ///
+ CpuMemLockStatus = pctx->CpuIoPpi->MemRead32 (
+ pctx->PeiServices,
+ pctx->CpuIoPpi,
+ TXT_PUBLIC_BASE + TXT_E2STS_REG_OFF
+ );
+
+ DEBUG ((EFI_D_INFO, "TXTPEI: CPU_UNCORE_MEMLOCK_STATUS=%x\n", CpuMemLockStatus));
+ ///
+ /// if BLOCK_MEM_STS (BIT2) is set to 1, memory is in unlock.
+ ///
+ return (CpuMemLockStatus & TXT_BLOCK_MEM_STS) ? TRUE : FALSE;
+}
+
+/**
+ Determines whether or not POISON bit is set in status register
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the TXT_WAKE_ERROR bit is asserted.
+ @retval FALSE - If the TXT_WAKE_ERROR bit is unasserted.
+**/
+BOOLEAN
+IsTxtResetSet (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT8 Ests;
+
+ ///
+ /// Read TXT.ESTS register
+ ///
+ Ests = pctx->CpuIoPpi->MemRead8 (
+ pctx->PeiServices,
+ pctx->CpuIoPpi,
+ TXT_PUBLIC_BASE + TXT_ERROR_STATUS_REG_OFF
+ );
+
+ return (Ests & (0x1 << 0)) ? TRUE : FALSE;
+}
+
+/**
+ Determines whether or not SECRETS.STS bit is set in E2STS status register
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the LT.SECRETS.STS bit is asserted.
+ @retval FALSE - If the LT.SECRETS.STS bit is unasserted.
+**/
+BOOLEAN
+IsTxtSecretsSet (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT8 E2sts;
+
+ ///
+ /// Read TXT.E2STS register
+ ///
+ E2sts = pctx->CpuIoPpi->MemRead8 (
+ pctx->PeiServices,
+ pctx->CpuIoPpi,
+ TXT_PUBLIC_BASE + TXT_E2STS_REG_OFF
+ );
+
+ return (E2sts & TXT_SECRETS_STS) ? TRUE : FALSE;
+}
+
+/**
+ Determines presence of TPM in system
+
+ @param[in] pctx - Point to TXT_PEI_LIB_CONTEXT structure
+ @param[in] TxtPeiCtx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - If the TPM is present.
+ @retval EFI_NOT_FOUND - If the TPM is not present.
+**/
+EFI_STATUS
+IsTpmPresent (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ EFI_STATUS Status;
+ VOID *TpmInitialize;
+
+ ///
+ /// Locate TPM Initialized Ppi to determine TPM is present and initialized properly.
+ ///
+ Status = PeiServicesLocatePpi (
+ &gPeiTpmInitializedPpiGuid,
+ 0,
+ NULL,
+ &TpmInitialize
+ );
+ if (EFI_ERROR (Status)) {
+ ///
+ /// TPM initiated failed
+ ///
+ pctx->Hob->Data.Flags |= TPM_INIT_FAILED;
+ }
+
+ return Status;
+}
+
+/**
+ Clear Sleep Type register.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - Always
+**/
+EFI_STATUS
+ClearSlpTyp (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT32 Pm1Addr;
+ UINT32 Pm1Value;
+
+ ///
+ /// Make address for PM1_CNT
+ ///
+ Pm1Addr = ((UINT32) pctx->Hob->Data.PmBase) + 4;
+
+ ///
+ /// Read 32-bits from PM1_CNT
+ ///
+ Pm1Value = IoRead32 ((UINTN) Pm1Addr);
+
+ ///
+ /// Clear SLP_TYP bits 10-12
+ ///
+ Pm1Value = Pm1Value & 0xffffe3ff;
+ IoWrite32 (
+ (UINTN) Pm1Addr,
+ (UINT32) (Pm1Value)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Searches PEI firemare volume (FV_BB) for file containig BIOS ACM.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] BiosAcBase - A pointer to pointer to variable to hold found address
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI_NOT_FOUND - If address has not been found
+**/
+EFI_STATUS
+FindBiosAcmInVolume (
+ IN TXT_PEI_LIB_CONTEXT *pctx,
+ OUT UINT32 **BiosAcBase
+ )
+{
+ EFI_STATUS Status;
+
+ Status = FindModuleInFlash (pctx, &mTxtBiosAcmPeiFileGuid, BiosAcBase);
+
+ ///
+ /// If BIOS ACM is not found - don't hang system. Assume that TXT
+ /// must be disabled.
+ ///
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ASSERT (((((UINT32) (*BiosAcBase)) & 0xFFF) == 0) ? TRUE : FALSE);
+
+ return EFI_SUCCESS;
+
+}
+
+/**
+ Searches PEI firmware volume (FV_BB) for file containig AP Startup code
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] ApStartupBase - A pointer to pointer to variable to hold address
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI_NOT_FOUND - If address has not been found
+**/
+EFI_STATUS
+FindApStartupInVolume (
+ IN TXT_PEI_LIB_CONTEXT *pctx,
+ OUT UINT32 **ApStartupBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID PeiBiosApStartupFileGuid;
+ BOOLEAN GoodPlacement;
+
+ PeiBiosApStartupFileGuid = mTxtApStartupPeiFileGuid;
+ Status = FindModuleInFlash (pctx, &PeiBiosApStartupFileGuid, ApStartupBase);
+ ///
+ /// If AP Startup code is not found - don't hang system. Assume that TXT
+ /// must be disabled.
+ ///
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ASSERT (((((UINT32) (*ApStartupBase)) & 0xFFF) == 0) ? TRUE : FALSE);
+
+ GoodPlacement = (BOOLEAN) (((UINT32) (*ApStartupBase) >= 0xFFFE0000) && ((UINT32) (*ApStartupBase) <= 0xFFFFF000));
+
+ ASSERT (GoodPlacement);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Searches PEI firmware volume (FV_BB) for offset of currently loaded MCU patch
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] McuBase - A pointer to pointer to variable to hold found offset
+ @param[in] address.
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI_NOT_FOUND - If address has not been found
+**/
+EFI_STATUS
+FindMcuInVolume (
+ IN TXT_PEI_LIB_CONTEXT *pctx,
+ OUT UINT32 **McuBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID MicrocodeGuid;
+ MSR_REGISTER Reg;
+ UINT32 PlatformId;
+ UINT32 McuRevision;
+ EFI_CPUID_REGISTER CpuidRegs;
+ MCU *McuAddr;
+ UINT8 *i;
+ UINT8 *j;
+ UINT8 *b;
+ UINT32 c;
+ //(AMI_CHG+)>
+ UINT32 MicroCodeFfsMaxSize;
+ EFI_FFS_FILE_HEADER *MicroCodeFfs;
+ UINT8 *McuFfsAddress;
+ MicroCodeFfs = NULL;
+ //<(AMI_CHG+)
+ McuAddr = NULL;
+
+ McuRevision = 0;
+ MicrocodeGuid = mCpuMicrocodeFileGuid;
+ Status = FindModuleInFlash (pctx, &MicrocodeGuid, (UINT32 **) &McuAddr);
+ ///
+ /// If MCU update is not found - don't hang system. Assume that TXT
+ /// must be disabled.
+ ///
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+ //(AMI_CHG+)>
+ McuFfsAddress = (UINT8 *) McuAddr;
+ MicroCodeFfs = (EFI_FFS_FILE_HEADER *)(McuFfsAddress - sizeof (EFI_FFS_FILE_HEADER));
+ MicroCodeFfsMaxSize = (UINT32)MicroCodeFfs->Size[2]*0x10000 + (UINT32)MicroCodeFfs->Size[1]*0x100 + (UINT32)MicroCodeFfs->Size[0];
+ DEBUG ((EFI_D_ERROR, "TXTPEI: MicroCodeFfsMaxSize = %X\n", MicroCodeFfsMaxSize));
+ //<(AMI_CHG+)
+ ///
+ /// MCU base address has been found. Find exact address of MCU
+ /// loaded in BSP
+ ///
+ Reg.Qword = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+ PlatformId = (Reg.Dwords.High >> (PLATFORM_ID_SHIFT - 32)) & PLATFORM_ID_MASK;
+
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+
+ AsmCpuid (1, &CpuidRegs.RegEax, &CpuidRegs.RegEbx, &CpuidRegs.RegEcx, &CpuidRegs.RegEdx);
+
+ Reg.Qword = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
+
+ McuRevision = Reg.Dwords.High;
+
+ ///
+ /// if BSP MCU is not loaded before. Return EFI_NOT_FOUND
+ /// This is pre-requisit.
+ ///
+ if (McuRevision == 0) {
+ DEBUG ((EFI_D_ERROR, "TXTPEI: BSP microcode is not loaded!! TXT aborted!\n"));
+ return EFI_NOT_FOUND;
+ }
+ //(AMI_CHG+)>
+ //for (i = (UINT8 *) McuAddr; i < ((UINT8 *) McuAddr) + 0x10000; i = i + 0x400) {
+ for (i = (UINT8 *) McuAddr; i < ((UINT8 *) McuAddr) + MicroCodeFfsMaxSize; i = i + 0x400) {
+ //<(AMI_CHG+)
+ if (((MCU *) i)->revision != McuRevision) {
+ continue;
+ }
+
+ if (!(((MCU *) i)->procFlags & (UINT32) LShiftU64 (1, PlatformId))) {
+ continue;
+ }
+
+ if ((((MCU *) i)->signature) == CpuidRegs.RegEax) {
+ *McuBase = (UINT32 *) i;
+ return EFI_SUCCESS;
+ }
+
+ if ((((MCU *) i)->dataSize) == 0) {
+ continue;
+ }
+
+ if ((((MCU *) i)->dataSize + sizeof (MCU)) >= (((MCU *) i)->totalSize)) {
+ continue;
+ }
+ ///
+ /// Extended signature table exists.
+ ///
+ b = i + (((MCU *) i)->dataSize);
+ ///
+ /// Base of EST table
+ ///
+ c = ((EST *) b)->count;
+ ///
+ /// Count of entries
+ ///
+ b += sizeof (EST);
+ ///
+ /// Base of PSS table entries
+ ///
+ for (j = b; j < b + (c * sizeof (PSS)); j = j + sizeof (PSS)) {
+ if ((((PSS *) j)->signature) == CpuidRegs.RegEax) {
+ *McuBase = (UINT32 *) i;
+ return EFI_SUCCESS;
+ }
+ }
+
+ continue;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Searches PEI firmware volume (FV_BB) for the file with specified GUID through pGuid
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] Guid - A pointer GUID
+ @param[in] Module - A pointer to pointer to variable to hold address
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI ERROR - If address has not been found
+**/
+EFI_STATUS
+FindModuleInFlash (
+ IN TXT_PEI_LIB_CONTEXT *pctx,
+ IN EFI_GUID *Guid,
+ OUT UINT32 **Module
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FFS_FILE_HEADER *FfsFile;
+ EFI_STATUS Status;
+ UINTN Instance;
+
+ Instance = BFV;
+
+ while (TRUE) {
+ Status = (*(pctx->PeiServices))->FfsFindNextVolume (pctx->PeiServices, Instance, &FvHeader);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FfsFile = NULL;
+ ///
+ /// Start new search in volume
+ ///
+ while (TRUE) {
+ Status = (*(pctx->PeiServices))->FfsFindNextFile (pctx->PeiServices, EFI_FV_FILETYPE_RAW, FvHeader, &FfsFile);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ if (CompareGuid (&(FfsFile->Name), Guid)) {
+ *Module = (UINT32 *) ((UINT8 *) FfsFile + sizeof (EFI_FFS_FILE_HEADER));
+ return EFI_SUCCESS;
+ }
+ }
+
+ Instance += 1;
+ }
+}
+
+/**
+ Initializes values passed to AP
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+**/
+VOID
+PrepareApParams (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ UINT32 TxtPublicSpace;
+
+ TxtPublicSpace = TXT_PUBLIC_BASE;
+
+ *(UINT32 *) (TxtPublicSpace + BIOACM_ADDR) = (UINT32) (pctx->BiosAcmBase);
+
+ *(UINT32 *) (TxtPublicSpace + MCU_BASE_ADDR) = (UINT32) (pctx->McuStart);
+
+ *(UINT32 *) (TxtPublicSpace + APINIT_ADDR) = (UINT32) (pctx->ApStartup);
+
+ *(UINT32 *) (TxtPublicSpace + SEMAPHORE) = 0;
+
+}
+
+/**
+ Returns CPU count
+
+ @retval Number of CPUs
+**/
+UINT32
+GetCpuCount (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegs;
+ AsmCpuid (1, &CpuidRegs.RegEax, &CpuidRegs.RegEbx, &CpuidRegs.RegEcx, &CpuidRegs.RegEdx);
+ return CpuidRegs.RegEbx >> 16;
+}
+
+/**
+ Invokes the SCLEAN function from the TXT BIOS ACM.
+ 1. Clearing of sleep type is necessary because SCLEAN destroys memory
+ context, so S3 after it is run and system is reset is impossible. We
+ do it here since there is no any indication that can sustain reset
+ for any other module to do it on our behalf.
+ 2. APs are initialized before calling of SCLEAN
+ 3. SCLEAN function is invoked.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+DoSclean (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ ClearSlpTyp (pctx);
+
+ PrepareApParams (pctx);
+#ifdef BOOT_GUARD_SUPPORT_FLAG
+#if BOOT_GUARD_SUPPORT_FLAG == 1
+ //
+ // Disable PBET before send IPI to APs
+ //
+ StopPbeTimer ();
+#endif
+#endif
+
+ LaunchBiosAcmSclean ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unlock memory when security is set and TxT is not enabled
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - Complete memory unlock
+ @exception EFI_UNSUPPORTED - CPU doesn't support TxT.
+**/
+EFI_STATUS
+UnlockMemory (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ )
+{
+ BOOLEAN EstablishmentBitAsserted;
+
+ EstablishmentBitAsserted = IsEstablishmentBitAsserted (pctx);
+
+ ///
+ /// Need to read FED40000 before unlocking memory
+ ///
+ if (!EstablishmentBitAsserted) {
+ DEBUG ((EFI_D_INFO, "TXTPEI::Unlock memory\n"));
+ AsmWriteMsr64 (0x2e6, 0);
+ } else {
+ ///
+ /// Lunch SCLEAN if wake error bit is set.
+ ///
+ if (IsTxtWakeError (pctx)) {
+ ///
+ /// If TXTRESET is set , we must clean TXTRESET bit otherwise SCLEAN
+ /// will fail
+ ///
+ if (IsTxtResetSet (pctx)) {
+ DoGlobalReset ();
+ }
+
+ if ((pctx->BiosAcmBase == 0) || (pctx->ApStartup == 0) || (pctx->McuStart == 0)) {
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Setup and Launch SCLEAN
+ ///
+ DEBUG ((EFI_D_INFO, "TXTPEI::Entering SCLEAN to unlock memory\n"));
+ DoSclean (pctx);
+
+ ///
+ /// Reset platform - performed by DoSclean, should not return to execute the following dead looping
+ ///
+ EFI_DEADLOOP ();
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.h b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.h
new file mode 100644
index 0000000..28c1303
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/TxtPeiLib.h
@@ -0,0 +1,560 @@
+/** @file
+ This file contains function definitions that can determine
+ the TXT capabilities of a platform during PEI and perform
+ certain specific platform tasks that are required for TXT
+ during PEI.
+
+@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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#ifndef _TXT_PEI_LIB_H_
+#define _TXT_PEI_LIB_H_
+
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include "Txt.h"
+#include "CpuAccess.h"
+#include "BootGuardLibrary.h"
+
+#include EFI_PPI_DEPENDENCY (Variable)
+#include EFI_PPI_DEPENDENCY (Stall)
+#include EFI_PPI_DEFINITION (TxtMemoryUnlocked)
+#include EFI_GUID_DEFINITION (TxtInfoHob)
+#include EFI_PPI_PRODUCER (CpuPlatformPolicy)
+#endif
+#include EFI_PPI_CONSUMER (TpmInitialized)
+
+#define RESET_PORT 0x0CF9
+#define FULL_RESET_VALUE 0xE
+
+#define PCI_BUS_NUMBER_PCH_LPC 0
+#define PCI_DEVICE_NUMBER_PCH_LPC 31
+#define PCI_FUNCTION_NUMBER_PCH_LPC 0
+#define R_PCH_LPC_ACPI_BASE 0x40
+
+#define APIC_SPURIOUS_VECTOR_REGISTER 0xF0
+#define DEST_FIELD (0 << 18)
+#define ALL_EXCLUDING_SELF BIT19 + BIT18
+#define SIPI BIT10 + BIT9
+#define INIT BIT10 + BIT8
+#define LEVEL_ASSERT BIT14
+#define LEVEL_DEASSERT (0 << 14)
+#define DELIVERY_STATUS BIT13
+#define BASE_ADDR_MASK 0xFFFFF000
+///
+/// #define EFI_MSR_EXT_XAPIC_LVT_THERM 0x833
+///
+#define EFI_MSR_EXT_XAPIC_SVR 0x80F
+#define AP_STARTUP_SIZE 0x1000
+#define AP_STARTUP_ADDR 0x1000
+#define AP_STARTUP_STKOFF AP_STARTUP_ADDR + 0xFF0
+
+#define BFV 0 ///< Boot Firmware Voume
+#define PCI_CMD 0x0004 ///< PCI Command Register
+#define BM_BIT 0x4 ///< Bus Master bit
+#define PCI_SCC 0x000A ///< Sub Class Code Register
+#define PCI_HDR 0x000E ///< Header Type Register
+#define MF_BIT 0x80 ///< Multi-function bit
+///
+/// Machne check architecture MSR registers
+///
+#define MCG_CAP 0x179
+#define MCG_STATUS 0x17A
+#define MCG_CTL 0x17B
+#define MC0_CTL 0x400
+#define MC0_STATUS 0x401
+#define MC0_ADDR 0x402
+#define MC0_MISC 0x403
+
+typedef struct _ACM_HEADER {
+ UINT32 ModuleType; ///< Module type
+ UINT32 HeaderLen; ///< 4 4 Header length (in multiples of four bytes)
+ /// (161 for version 0.0)
+ ///
+ UINT32 HeaderVersion; ///< 8 4 Module format version
+ UINT32 ModuleID; ///< 12 4 Module release identifier
+ UINT32 ModuleVendor; ///< 16 4 Module vendor identifier
+ UINT32 Date; ///< 20 4 Creation date (BCD format:
+ /// year.month.day)
+ ///
+ UINT32 Size; ///< 24 4 Module size (in multiples of four bytes)
+ UINT32 Reserved1; ///< 28 4 Reserved for future extensions
+ UINT32 CodeControl; ///< 32 4 Authenticated code control flags
+ UINT32 ErrorEntryPoint; ///< 36 4 Error response entry point offset (bytes)
+ UINT32 GDTLimit; ///< 40 4 GDT limit (defines last byte of GDT)
+ UINT32 GDTBasePtr; ///< 44 4 GDT base pointer offset (bytes)
+ UINT32 SegSel; ///< 48 4 Segment selector initializer
+ UINT32 EntryPoint; ///< 52 4 Authenticated code entry point offset (bytes)
+ UINT32 Reserved2; ///< 56 64 Reserved for future extensions
+ UINT32 KeySize; ///< 120 4 Module public key size less the exponent
+ /// (in multiples of four bytes
+ /// - 64 for version 0.0)
+ ///
+ UINT32 ScratchSize; ///< 124 4 Scratch field size (in multiples of four bytes)
+ /// (2 * KeySize + 15 for version 0.0)
+ ///
+ UINT8 RSAPubKey[65 * 4]; ///< 128 KeySize * 4 + 4 Module public key
+ UINT8 RSASig[256]; ///< 388 256 PKCS #1.5 RSA Signature.
+} ACM_HEADER;
+
+typedef struct _TXT_PEI_LIB_CONTEXT {
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_CPU_IO_PPI *CpuIoPpi;
+ PEI_PCI_CFG_PPI *PciCfgPpi;
+ PEI_STALL_PPI *PeiStall;
+ ACM_HEADER *BiosAcmBase;
+ UINT32 BiosAcmSize;
+ VOID *ApStartup;
+ UINT32 *McuStart;
+ UINT32 Ia32ApicBase;
+ TXT_INFO_HOB *Hob;
+} TXT_PEI_LIB_CONTEXT;
+
+#pragma pack(1)
+typedef union _MSR_REGISTER {
+ UINT64 Qword;
+
+ struct _DWORDS {
+ UINT32 Low;
+ UINT32 High;
+ } Dwords;
+
+ struct _BYTES {
+ UINT8 FirstByte;
+ UINT8 SecondByte;
+ UINT8 ThirdByte;
+ UINT8 FouthByte;
+ UINT8 FifthByte;
+ UINT8 SixthByte;
+ UINT8 SeventhByte;
+ UINT8 EighthByte;
+ } Bytes;
+
+} MSR_REGISTER;
+
+
+#pragma pack()
+
+#define PLATFORM_ID_SHIFT 50
+#define PLATFORM_ID_MASK 7 ///< Bits 52:50
+typedef struct _MCU {
+ UINT32 headerVer; ///< MCU Header Version ( = 00000001h )
+ UINT32 revision; ///< MCU Revision
+ UINT32 date; ///< MCU Date
+ UINT32 signature; ///< MCU Processor Signature
+ UINT32 checksum; ///< MCU Main checksum
+ UINT32 loaderRev; ///< MCU Loader Revision
+ UINT32 procFlags; ///< MCU Processor Flags (Platform ID)
+ UINT32 dataSize; ///< MCU Data Size
+ UINT32 totalSize; ///< MCU Total Size
+ UINT32 reserved[3];
+} MCU;
+
+typedef struct _EST {
+ UINT32 count; ///< EST Count
+ UINT32 checksum; ///< EST Checksum
+ UINT32 reserved[3];
+} EST;
+
+typedef struct _PSS {
+ UINT32 signature; ///< PSS Processor Signature
+ UINT32 procFlags; ///< PSS Processor Flags (Platform ID)
+ UINT32 checksum; ///< PSS Checksum
+} PSS;
+
+/**
+ Returns CPU count
+
+ @retval Number of CPUs
+**/
+UINT32
+GetCpuCount (
+ VOID
+ );
+
+/**
+ Execute SCLEAN through BIOS ACM
+**/
+VOID
+LaunchBiosAcmSclean (
+ VOID
+ );
+
+/**
+ Issue a global reset through PCH and PORTCF9
+**/
+VOID
+DoGlobalReset (
+ VOID
+ );
+
+/**
+ Issue a cpu-only reset through PCH and PORTCF9
+**/
+VOID
+DoCpuReset (
+ VOID
+ );
+
+/**
+ Issue a HOST reset through PCH and PORTCF9
+**/
+VOID
+DoHostReset (
+ VOID
+ );
+
+/**
+ Dispatch APs to execute *Function with parameter pointed by *Param
+
+ @param[in] (*Function) - Address of Function to be executed by APs
+ @param[in] Param - Function parameter to be passed to
+**/
+VOID
+StartupAllAPs (
+ VOID (*Function)(),
+ UINT64 *Param
+ );
+
+/**
+ Put All APs into Wait-for-SIPI state
+**/
+VOID
+PutApsInWfs (
+ VOID
+ );
+
+/**
+ Restore MTRR registers
+
+ @param[in] ApCfg - Point to the MTRR buffer
+**/
+VOID
+RestoreMtrrProgramming (
+ UINT64 *ApCfg
+ );
+
+/**
+ Restore APs' registers
+
+ @param[in] ApCfg - Point to APs' registers buffer
+**/
+VOID
+RestoreApConfig (
+ UINT64 *ApCfg
+ );
+
+/**
+ Initializes values passed to AP
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+**/
+VOID
+PrepareApParams (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ This routine initializes and collects all PPIs and data required
+ by the routines in this file.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] mPS - A pointer to the PEI Service Table
+
+ @exception EFI_UNSUPPORTED - If any of the required PPIs or data are unavailable
+ @retval EFI_SUCCESS - In all cases not listed above
+**/
+EFI_STATUS
+InitializeTxtPeiLib (
+ TXT_PEI_LIB_CONTEXT *pctx,
+ IN EFI_PEI_SERVICES **mPS
+ );
+
+/**
+ Determines whether or not the current processor is TXT Capable.
+
+ @retval TRUE - If the current processor supports TXT
+ @retval FALSE - If the current processor does not support TXT
+**/
+BOOLEAN
+IsTxtProcessor (
+ VOID
+ );
+
+/**
+ Determines whether or not the current chipset is TXT Capable.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the current chipset supports TXT
+ @retval FALSE - If the current chipset doesn't supports TXT
+**/
+BOOLEAN
+IsTxtChipset (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines whether or not POISON bit is set in status register
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the TXT_WAKE_ERROR bit is asserted.
+ @retval FALSE - If the TXT_WAKE_ERROR bit is unasserted.
+**/
+BOOLEAN
+IsTxtResetSet (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines whether or not SECRETS.STS bit is set in E2STS status register
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the LT.SECRETS.STS bit is asserted.
+ @retval FALSE - If the LT.SECRETS.STS bit is unasserted.
+**/
+BOOLEAN
+IsTxtSecretsSet (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines whether or not the platform has executed an TXT launch by
+ examining the TPM Establishment bit.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the TPM establishment bit is asserted.
+ @retval FALSE - If the TPM establishment bit is unasserted.
+**/
+BOOLEAN
+IsEstablishmentBitAsserted (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines whether or not the platform has encountered an error during
+ a sleep or power-off state.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If the TXT_WAKE_ERROR bit is asserted.
+ @retval FALSE - If the TXT_WAKE_ERROR bit is unasserted.
+**/
+BOOLEAN
+IsTxtWakeError (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines whether or not the platform memory has been locked
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If memroy is locked
+ @retval FALSE - If memory is unlocked
+**/
+BOOLEAN
+IsMemoryLocked (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval TRUE - If TXT is enabled by platform setting
+ @retval FALSE - If TXT is disabled by platform setting
+**/
+BOOLEAN
+IsTxtEnabled (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines ACM is matched to chipset or not
+
+ @param[in] pctx - Point to TXT_PEI_LIB_CONTEXT structure
+ @param[in] BiosAcmBase - A pointer to BIOS ACM location
+
+ @retval TRUE - BIOS ACM is matched to chipset
+ @retval FALSE - BIOS ACM is NOT matched to chipset
+**/
+BOOLEAN
+CheckTxtAcmMatch (
+ TXT_PEI_LIB_CONTEXT *pctx,
+ ACM_HEADER *BiosAcmBase
+ );
+
+/**
+ Clear Sleep Type register.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - Always
+**/
+EFI_STATUS
+ClearSlpTyp (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Invokes the SCLEAN function from the TXT BIOS ACM.
+ 1. Clearing of sleep type is necessary because SCLEAN destroys memory
+ context, so S3 after it is run and system is reset is impossible. We
+ do it here since there is no any indication that can sustain reset
+ for any other module to do it on our behalf.
+ 2. APs are initialized before calling of SCLEAN
+ 3. SCLEAN function is invoked.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - Always.
+**/
+
+EFI_STATUS
+DoSclean (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Determines presence of TPM in system
+
+ @param[in] pctx - Point to TXT_PEI_LIB_CONTEXT structure
+
+ @retval EFI_SUCCESS - If the TPM is present.
+ @retval EFI_NOT_FOUND - If the TPM is not present.
+**/
+EFI_STATUS
+IsTpmPresent (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Searches PEI firemare volume (FV_BB) for file containig BIOS ACM.
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] pBIOSAC_BASE - A pointer to pointer to variable to hold found address
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI_NOT_FOUND - If address has not been found
+**/
+EFI_STATUS
+FindBiosAcmInVolume (
+ TXT_PEI_LIB_CONTEXT *pctx,
+ OUT UINT32 **pBIOSAC_BASE
+ );
+
+/**
+ Searches PEI firmware volume (FV_BB) for file containig AP Startup code
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] pAP_STARTUP - A pointer to pointer to variable to hold address
+ @param[in] address.
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI_NOT_FOUND - If address has not been found
+**/
+EFI_STATUS
+FindApStartupInVolume (
+ TXT_PEI_LIB_CONTEXT *pctx,
+ OUT UINT32 **pAP_STARTUP
+ );
+
+/**
+ Searches PEI firmware volume (FV_BB) for offset of currently loaded MCU patch
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] pMCU - A pointer to pointer to variable to hold found offset
+ @param[in] address.
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI_NOT_FOUND - If address has not been found
+**/
+EFI_STATUS
+FindMcuInVolume (
+ TXT_PEI_LIB_CONTEXT *pctx,
+ OUT UINT32 **pMCU
+ );
+
+/**
+ Searches PEI firmware volume (FV_BB) for the file with specified GUID through pGuid
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+ @param[in] pGuid - A pointer GUID
+ @param[in] pModule - A pointer to pointer to variable to hold address
+
+ @retval EFI_SUCCESS - If address has been found
+ @retval EFI ERROR - If address has not been found
+**/
+EFI_STATUS
+FindModuleInFlash (
+ TXT_PEI_LIB_CONTEXT *pctx,
+ EFI_GUID *pGuid,
+ OUT UINT32 **pModule
+ );
+
+/**
+ Parses Hob list for TXT Info HOB
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - If TXT Info Hob is found
+ @retval EFI_NOT_FOUND - If TXT Info Hob is not found
+**/
+EFI_STATUS
+CreateTxtInfoHob (
+ TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Unlock memory when security is set ant TxT is not enabled
+
+ @param[in] pctx - A pointer to an initialized TXT PEI Context data structure
+
+ @retval EFI_SUCCESS - Complete memory unlock
+ @exception EFI_UNSUPPORTED - CPU doesn't support TxT.
+**/
+EFI_STATUS
+UnlockMemory (
+ IN TXT_PEI_LIB_CONTEXT *pctx
+ );
+
+/**
+ Fix up pointers since they are located in real memory now.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+DprUpdate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+#endif
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Txtpei.cif b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Txtpei.cif
new file mode 100644
index 0000000..7cba3eb
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Txtpei.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "TxtPei"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Haswell\Txt\TxtInit\Pei\"
+ RefName = "TxtPei"
+[files]
+"TxtPei.sdl"
+"TxtPei.mak"
+"TxtPei.c"
+"TxtPeiLib.c"
+"TxtPeiLib.h"
+"TxtPei.dxs"
+"TxtPei.inf"
+"Ia32\TxtPeiBsp.asm"
+"Ia32\TxtPeiAp.asm16"
+"Ia32\TxtPeiAp.inf"
+"Ia32\TxtPeiApV7.inf"
+"Ia32\makefile.new"
+<endComponent>