diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Haswell/SampleCode | |
download | zprj-master.tar.xz |
Diffstat (limited to 'ReferenceCode/Haswell/SampleCode')
82 files changed, 10223 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.cif b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.cif new file mode 100644 index 0000000..123e37c --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.cif @@ -0,0 +1,13 @@ +<component> + name = "Cpu Policy DXE" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\CpuPolicyInit\Dxe" + RefName = "Cpu Policy Dxe" +[files] +"CpuPolicyDxe.mak" +"CpuPolicyDxe.sdl" +"CpuPolicyInitDxe.c" +"CpuPolicyInitDxe.h" +"CpuPolicyInitDxe.dxs" +"CpuPolicyInitDxe.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.mak b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.mak new file mode 100644 index 0000000..da3c6dc --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.mak @@ -0,0 +1,92 @@ +# MAK file for the eModule:PowerManagement + +EDK : CpuPolicyInitDxe + +BUILD_CpuPolicyInitDxe_DIR = $(BUILD_DIR)\$(CpuPolicyInitDxe_DIR) + +$(BUILD_DIR)\CpuPolicyDxe.mak : $(CpuPolicyInitDxe_DIR)\CpuPolicyDxe.cif $(BUILD_RULES) + $(CIF2MAK) $(CpuPolicyInitDxe_DIR)\CpuPolicyDxe.cif $(CIF2MAK_DEFAULTS) + +CpuPolicyInitDxe : $(BUILD_DIR)\CpuPolicyDxe.MAK CpuPolicyInitDxeBin + +CpuInitDxe_OBJECTS = \ + $(BUILD_CpuPolicyInitDxe_DIR)\CpuPolicyInitDxe.obj \ + +CpuInitDxe_MY_INCLUDES= \ + $(EDK_INCLUDES)\ + $(PROJECT_CPU_INCLUDES)\ + /I$(PROJECT_CPU_ROOT)\ + /I$(UefiEfiIfrSupportLib_DIR)\ + /I$(PROJECT_CPU_ROOT)\Include \ + +CpuInitDxe_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=CpuPolicyInitDxeEntryPoint"\ + /D TXT_SUPPORT_FLAG=1 \ + /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_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \ + /D FV_MICROCODE_BASE=$(FV_MICROCODE_BASE) \ + /D __EDKII_GLUE_HII_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ +!ifdef PACK_MICROCODE + /D PACK_MICROCODE=$(PACK_MICROCODE) \ +!else + /D PACK_MICROCODE=0 \ +!endif + /D SMM_FROM_SMBASE_DRIVER=$(SMM_FROM_SMBASE_DRIVER) \ + /D MICROCODE_BLOCK_SIZE=$(MICROCODE_BLOCK_SIZE) \ + +CpuInitDxe_LIBS =\ + $(PchPlatformLib)\ + $(EfiRuntimeLib_LIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(EFIRUNTIMELIB)\ + $(CPUIA32LIB)\ + $(EFIPROTOCOLLIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeHobLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(CpuGuidLib_LIB)\ +!IF $(EFI_SPECIFICATION_VERSION) >= 0x0002000A + $(UEFIEFIIFRSUPPORTLIB)\ +!ELSE + $(EFIIFRSUPPORTLIB) \ +!ENDIF +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiDevicePathLib_LIB)\ + $(CpuProtocolLib_LIB)\ + $(EFIDRIVERLIB)\ + $(CpuPlatformLib_LIB)\ + $(PchPlatformDxeLib_LIB)\ + $(EFISCRIPTLIB) + +CpuPolicyInitDxeBin : $(CpuInitDxe_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\CpuPolicyDxe.mak all\ + NAME=CpuPolicyDxe\ + MAKEFILE=$(BUILD_DIR)\CpuPolicyDxe.mak \ + "MY_INCLUDES=$(CpuInitDxe_MY_INCLUDES)" \ + "MY_DEFINES=$(CpuInitDxe_DEFINES)"\ + OBJECTS="$(CpuInitDxe_OBJECTS)" \ + GUID=15B9B6DA-00A9-4de7-B8E8-ED7AFB88F16E\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(CpuPolicyInitDxe_DIR)\CpuPolicyInitDxe.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1 +#----------------------------------------------------------------------- diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.sdl b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.sdl new file mode 100644 index 0000000..be33503 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyDxe.sdl @@ -0,0 +1,58 @@ +#**************************************************************************** +#**************************************************************************** +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 ** +#** ** +#** Phone (770)-246-8600 ** +#** ** +#**************************************************************************** +#**************************************************************************** +#**************************************************************************** +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/Intel Haswell Cpu RC PKG/Cpu Policy DXE/CpuPolicyDxe.sdl 1 2/07/12 3:56a Davidhsieh $ +# +# $Revision: 1 $ +# +# $Date: 2/07/12 3:56a $ +# +#**************************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/Intel Haswell Cpu RC PKG/Cpu Policy DXE/CpuPolicyDxe.sdl $ +# +# 1 2/07/12 3:56a Davidhsieh +# +# 1 5/06/11 6:06a Davidhsieh +# First release +# +# +#**************************************************************************** +TOKEN + Name = "CpuDxePolicy_SUPPORT" + Value = "1" + Help = "Main switch to enable Cpu Pei init support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +PATH + Name = "CpuPolicyInitDxe_DIR" +End + +MODULE + Help = "Includes CpuPeiInit.mak to Project" + File = "CpuPolicyDxe.mak" +End + +ELINK + Name = "$(BUILD_DIR)\CpuPolicyDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.c b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.c new file mode 100644 index 0000000..f78b89e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.c @@ -0,0 +1,461 @@ +/** @file + This file is SampleCode for Intel CPU DXE Platform Policy initialzation. + +@copyright + Copyright (c) 2009 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" + +#if (EFI_SPECIFICATION_VERSION >= 0x2000A) +#include EFI_PROTOCOL_DEFINITION (HiiDatabase) +#else +#include EFI_PROTOCOL_DEFINITION (Hii) +#endif +#include EFI_PROTOCOL_DEFINITION (CpuInfo) +#include "CpuPolicyInitDxe.h" +#if (EFI_SPECIFICATION_VERSION >= 0x2000A) +#include "UefiIfrLibrary.h" +#endif + +//-#include "FlashMap.h" +#include "CpuPlatformLib.h" + +#define SMM_FROM_SMBASE_DRIVER 0x55 +#define SW_SMI_FROM_SMMBASE SMM_FROM_SMBASE_DRIVER + +#define PLATFORM_CPU_MAX_FSB_FREQUENCY 1066 +#endif + +//(AMI_CHG+)> +VOID CallDxeCpuPolicyInitList( + IN EFI_SYSTEM_TABLE *SystemTable, + IN OUT DXE_CPU_PLATFORM_POLICY_PROTOCOL *mCpuPolicyDataPtr); +//<(AMI_CHG+) +EFI_EXP_BASE10_DATA mCoreFrequencyList[] = { + { 0, 0}, ///< 0 Means "Auto", also, the first is the default. + {-1, 0} ///< End marker +}; + +EFI_EXP_BASE10_DATA mFsbFrequencyList[] = { + { 0, 0}, ///< 0 Means "Auto", also, the first is the default. + {-1, 0} ///< End marker +}; + +DXE_CPU_PLATFORM_POLICY_PROTOCOL mCpuPolicyData = { 0 }; +CPU_CONFIG mCpuConfig = { 0 }; +POWER_MGMT_CONFIG mCpuPmConfig = { 0 }; +SECURITY_CONFIG mSecurityConfig = { 0 }; +#if defined(TXT_SUPPORT_FLAG) && (TXT_SUPPORT_FLAG == 1) +TXT_FUNCTION_CONFIG mTxtFunctionConfig = { 0 }; +#endif + +/// +/// Function implementations +/// +/** + Platform function to get MAX CPU count + + @param[in] This - platform policy protocol + @param[in] MaxThreadsPerCore - variable that will store MaxThreadsPerCore + @param[in] MaxCoresPerDie - variable that will store MaxCoresPerDie + @param[in] MaxDiesPerPackage - variable that will store MaxDiesPerPackage + @param[in] MaxPackages - variable that will store MaxPackages + + @retval EFI_SUCCESS - Always return success +**/ +EFI_STATUS +EFIAPI +PlatformCpuGetMaxCount ( + IN DXE_CPU_PLATFORM_POLICY_PROTOCOL *This, + OUT UINT32 *MaxThreadsPerCore, + OUT UINT32 *MaxCoresPerDie, + OUT UINT32 *MaxDiesPerPackage, + OUT UINT32 *MaxPackages + ) +{ + *MaxThreadsPerCore = 2; + *MaxCoresPerDie = 4; + *MaxDiesPerPackage = 1; + *MaxPackages = 1; + + return EFI_SUCCESS; +} + +/** + Get CPU information + + @param[in] This - platform policy protocol + @param[in] Location - structure that describe CPU location information + @param[in] PlatformCpuInfo - structure that will be updated for platform CPU information + + @retval EFI_INVALID_PARAMETER - PlatformCpuInfo is NULL + @retval EFI_SUCCESS - platform CPU info structure has been updated +**/ +EFI_STATUS +EFIAPI +PlatformCpuGetCpuInfo ( + IN DXE_CPU_PLATFORM_POLICY_PROTOCOL *This, + IN CPU_PHYSICAL_LOCATION *Location, + IN OUT PLATFORM_CPU_INFORMATION *PlatformCpuInfo + ) +{ +#if (EFI_SPECIFICATION_VERSION < 0x2000A) + EFI_HII_PROTOCOL *Hii; +#endif + STRING_REF SocketNameToken; + STRING_REF FillByOemToken; + EFI_STATUS Status; + UINT64 MsrValue; + UINT8 CpuSku; + + SocketNameToken = 0; + FillByOemToken = 0; + + /// + /// For Processor SocketName definition. + /// + if (PlatformCpuInfo == NULL) { + return EFI_INVALID_PARAMETER; + } + +#if (EFI_SPECIFICATION_VERSION >= 0x2000A) + Status = IfrLibNewString (PlatformCpuInfo->StringHandle, &SocketNameToken, L"U3E1"); + ASSERT_EFI_ERROR (Status); + + Status = IfrLibNewString (PlatformCpuInfo->StringHandle, &FillByOemToken, L"To Be Filled By O.E.M."); + ASSERT_EFI_ERROR (Status); +#else + Status = gBS->LocateProtocol ( + &gEfiHiiProtocolGuid, + NULL, + (VOID **) &Hii + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Hii->NewString ( + Hii, + NULL, + PlatformCpuInfo->StringHandle, + &SocketNameToken, + L"U3E1" + ); + + Hii->NewString ( + Hii, + NULL, + PlatformCpuInfo->StringHandle, + &FillByOemToken, + L"To Be Filled By O.E.M." + ); +#endif + + PlatformCpuInfo->ApicID = Location->Thread; + PlatformCpuInfo->ReferenceString = 0; + CpuSku = GetCpuSku (); + switch (CpuSku) { + case EnumCpuTrad: + PlatformCpuInfo->SocketType = 0x2d; // @todo EfiProcessorSocketLGA1150, pending updated SMBIOS spec release + break; + + case EnumCpuUlt: + PlatformCpuInfo->SocketType = 0x2e; // @todo EfiProcessorSocketBGA1168, pending updated SMBIOS spec release + break; + + default: + PlatformCpuInfo->SocketType = EfiProcessorSocketOther; + break; + } + PlatformCpuInfo->SocketName = SocketNameToken; + + MsrValue = AsmReadMsr64 (MSR_PLATFORM_INFO); + PlatformCpuInfo->MaxCoreFrequency.Value = (100 * (((UINT32) MsrValue >> N_PLATFORM_INFO_MAX_RATIO) & B_PLATFORM_INFO_RATIO_MASK)); + PlatformCpuInfo->MaxCoreFrequency.Exponent = 6; + + PlatformCpuInfo->MaxFsbFrequency.Value = PLATFORM_CPU_MAX_FSB_FREQUENCY; + PlatformCpuInfo->MaxFsbFrequency.Exponent = 6; + + PlatformCpuInfo->PlatformCoreFrequencyList = mCoreFrequencyList; + PlatformCpuInfo->PlatformFsbFrequencyList = mFsbFrequencyList; + + PlatformCpuInfo->AssetTag = FillByOemToken; + PlatformCpuInfo->SerialNumber = FillByOemToken; + PlatformCpuInfo->PartNumber = FillByOemToken; + + return EFI_SUCCESS; +} + +/** + Get the microcode patch. + + @param[in] This - Driver context. + @param[in] MicrocodeData - Retrieved image of the microcode. + + @retval EFI_SUCCESS - Image found. + @retval EFI_NOT_FOUND - image not found. +**/ +EFI_STATUS +PlatformCpuRetrieveMicrocode ( + IN DXE_CPU_PLATFORM_POLICY_PROTOCOL *This, + OUT UINT8 **MicrocodeData + ) +{ + /*EFI_CPU_MICROCODE_HEADER *Microcode; + UINTN MicrocodeStart; + UINTN MicrocodeEnd; + UINTN TotalSize; + + /// + /// Microcode binary in SEC + /// + MicrocodeStart = FLASH_REGION_MICROCODE_BASE + + ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FLASH_REGION_MICROCODE_BASE)->HeaderLength + + sizeof (EFI_FFS_FILE_HEADER); + + MicrocodeEnd = FLASH_REGION_MICROCODE_BASE + FLASH_REGION_MICROCODE_SIZE; + + if (*MicrocodeData == NULL) { + *MicrocodeData = (UINT8 *) (UINTN) MicrocodeStart; + } else { + if (*MicrocodeData < (UINT8 *) (UINTN) MicrocodeStart) { + return EFI_NOT_FOUND; + } + + TotalSize = (UINTN) (((EFI_CPU_MICROCODE_HEADER *) *MicrocodeData)->TotalSize); + if (TotalSize == 0) { + TotalSize = 2048; + } + // + // Add alignment check - begin + // + if ((TotalSize & 0x7FF) != 0) { + TotalSize = (TotalSize & 0xFFFFF800) + 0x800; + } + // + // Add alignment check - end + // + + *MicrocodeData += TotalSize; + + Microcode = (EFI_CPU_MICROCODE_HEADER *) *MicrocodeData; + if (*MicrocodeData >= (UINT8 *) (UINTN) (MicrocodeEnd) || Microcode->TotalSize == (UINT32) -1) { + return EFI_NOT_FOUND; + } + + } + + + return EFI_SUCCESS;*/ + return EFI_NOT_FOUND; +} + +/** + Initilize Intel Cpu DXE Platform Policy + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +CpuPolicyInitDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CPU_FAMILY CpuFamilyId; + + CpuFamilyId = GetCpuFamily(); + + mCpuPolicyData.Revision = DXE_PLATFORM_CPU_POLICY_PROTOCOL_REVISION_7; + mCpuPolicyData.CpuConfig = &mCpuConfig; + mCpuPolicyData.PowerMgmtConfig = &mCpuPmConfig; + mCpuPolicyData.SecurityConfig = &mSecurityConfig; + + mCpuConfig.RetrieveMicrocode = PlatformCpuRetrieveMicrocode; + mCpuConfig.GetMaxCount = PlatformCpuGetMaxCount; + mCpuConfig.GetCpuInfo = PlatformCpuGetCpuInfo; + mSecurityConfig.TxtFunctionConfig = NULL; +#ifdef TXT_SUPPORT_FLAG + mSecurityConfig.TxtFunctionConfig = &mTxtFunctionConfig; +#endif // TXT_SUPPORT_FLAG + mCpuConfig.SmmbaseSwSmiNumber = SW_SMI_FROM_SMMBASE; + + mCpuConfig.HtState = CPU_FEATURE_ENABLE; + mCpuConfig.LimitCpuidMaximumValue = CPU_FEATURE_DISABLE; + mCpuConfig.ExecuteDisableBit = CPU_FEATURE_ENABLE; + mCpuConfig.VmxEnable = CPU_FEATURE_ENABLE; + mCpuConfig.SmxEnable = CPU_FEATURE_ENABLE; + mCpuConfig.MachineCheckEnable = CPU_FEATURE_ENABLE; + mCpuConfig.MonitorMwaitEnable = CPU_FEATURE_ENABLE; + mCpuConfig.XapicEnable = CPU_FEATURE_DISABLE; + mCpuConfig.AesEnable = CPU_FEATURE_ENABLE; + mCpuConfig.DebugInterfaceEnable = CPU_FEATURE_DISABLE; + mCpuConfig.DebugInterfaceLockEnable = CPU_FEATURE_ENABLE; + mCpuConfig.MlcStreamerPrefetcher = CPU_FEATURE_ENABLE; + mCpuConfig.MlcSpatialPrefetcher = CPU_FEATURE_ENABLE; + mCpuConfig.EnableDts = CPU_FEATURE_DISABLE; + mCpuConfig.BspSelection = 0; + mCpuConfig.ApIdleManner = 1; + mCpuConfig.ApHandoffManner = 1; + /// + /// Virtual wire to A + /// + mCpuConfig.FviReport = 1; + /// + /// Default Enable FVI SMBIOS Report + /// + mCpuConfig.FviSmbiosType = 0xDD; + /// + /// Default SMBIOS Type 221 + /// + /// Initialize Power Management Config + /// Allocate and set Power Management policy structure to recommended defaults + /// + mCpuPmConfig.pFunctionEnables = AllocateZeroPool (sizeof (PPM_FUNCTION_ENABLES)); + mCpuPmConfig.pCustomRatioTable = AllocateZeroPool (sizeof (PPM_CUSTOM_RATIO_TABLE)); + mCpuPmConfig.pTurboSettings = AllocateZeroPool (sizeof (PPM_TURBO_SETTINGS)); + mCpuPmConfig.pRatioLimit = AllocateZeroPool ((sizeof (UINT8) * 4)); + mCpuPmConfig.pPpmLockEnables = AllocateZeroPool (sizeof (PPM_LOCK_ENABLES)); + mCpuPmConfig.pCustomCtdpSettings = AllocateZeroPool (sizeof (PPM_CUSTOM_CTDP)); + mCpuPmConfig.ThermalFuncEnables = AllocateZeroPool (sizeof (THERM_FUNCTION_ENABLES)); + + if ((mCpuPmConfig.pFunctionEnables == NULL) || + (mCpuPmConfig.pCustomRatioTable == NULL) || + (mCpuPmConfig.pTurboSettings == NULL) || + (mCpuPmConfig.pPpmLockEnables == NULL) || + (mCpuPmConfig.pCustomCtdpSettings == NULL) || + (mCpuPmConfig.ThermalFuncEnables == NULL) + ) { + return EFI_OUT_OF_RESOURCES; + } + + mCpuPmConfig.pFunctionEnables->Eist = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->Cx = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C1e = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C3 = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C6 = PPM_ENABLE; + if (CpuFamilyId == EnumCpuHswUlt) { + mCpuPmConfig.pFunctionEnables->C8 = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C9 = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C10 = PPM_ENABLE; + } + mCpuPmConfig.pFunctionEnables->DeepCState = DeepC7S; + mCpuPmConfig.pFunctionEnables->C1AutoDemotion = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C3AutoDemotion = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C1UnDemotion = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->C3UnDemotion = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->PkgCStateDemotion = PPM_DISABLE; + mCpuPmConfig.pFunctionEnables->PkgCStateUnDemotion = PPM_DISABLE; + mCpuPmConfig.ThermalFuncEnables->BiProcHot = PPM_ENABLE; + mCpuPmConfig.ThermalFuncEnables->DisableProcHotOut = PPM_DISABLE; + mCpuPmConfig.ThermalFuncEnables->DisableVRThermalAlert= PPM_DISABLE; + mCpuPmConfig.ThermalFuncEnables->ProcHotResponce = PPM_DISABLE; + mCpuPmConfig.ThermalFuncEnables->TStates = PPM_DISABLE; + mCpuPmConfig.pFunctionEnables->Xe = PPM_DISABLE; + mCpuPmConfig.pFunctionEnables->TurboMode = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->PowerLimit2 = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->EnergyEfficientPState = PPM_ENABLE; + mCpuPmConfig.pFunctionEnables->CStatePreWake = PPM_ENABLE; + mCpuPmConfig.ThermalFuncEnables->AutoThermalReporting = PPM_ENABLE; + + mCpuPmConfig.pFunctionEnables->LongLatencyC6 = PPM_DISABLE; + mCpuPmConfig.pFunctionEnables->LongLatencyC7 = PPM_ENABLE; + mCpuPmConfig.ThermalFuncEnables->ThermalMonitor = PPM_ENABLE; + mCpuPmConfig.ThermalFuncEnables->Pl1ThermalControl = 2; ///< AUTO + mCpuPmConfig.ThermalFuncEnables->Pl1ThermalControlFloor.FloorIA = Percent100; + mCpuPmConfig.ThermalFuncEnables->Pl1ThermalControlFloor.FloorGT = Percent100; + mCpuPmConfig.ThermalFuncEnables->Pl1ThermalControlFloor.FloorPCH = Percent100; + mCpuPmConfig.pFunctionEnables->LakeTiny = PPM_DISABLE; + mCpuPmConfig.pFunctionEnables->TimedMwait = PPM_DISABLE; + + mCpuPmConfig.CustomPowerUnit = PowerUnit125MilliWatts; + mCpuPmConfig.pTurboSettings->PowerLimit1 = AUTO; + mCpuPmConfig.pTurboSettings->PowerLimit2 = AUTO; + mCpuPmConfig.pTurboSettings->PowerLimit1Time = AUTO; + mCpuPmConfig.pTurboSettings->PowerLimit3 = AUTO; + mCpuPmConfig.pTurboSettings->PowerLimit3Time = AUTO; + mCpuPmConfig.pTurboSettings->PowerLimit3DutyCycle = AUTO; + mCpuPmConfig.pTurboSettings->PowerLimit3Lock = PPM_ENABLE; + mCpuPmConfig.pTurboSettings->ConfigTdpLevel = 0; + mCpuPmConfig.pTurboSettings->ConfigTdpLock = PPM_DISABLE; + mCpuPmConfig.pCustomCtdpSettings->ConfigTdpCustom = PPM_DISABLE; + + mCpuPmConfig.pTurboSettings->TurboPowerLimitLock = PPM_DISABLE; + mCpuPmConfig.pTurboSettings->EnergyPolicy = 0; + + mCpuPmConfig.pPpmLockEnables->PmgCstCfgCtrlLock = PPM_ENABLE; + mCpuPmConfig.pPpmLockEnables->OverclockingLock = PPM_DISABLE; + mCpuPmConfig.pPpmLockEnables->ProcHotLock = PPM_DISABLE; + mCpuPmConfig.S3RestoreMsrSwSmiNumber = SW_SMI_S3_RESTORE_MSR; + mCpuPmConfig.PkgCStateLimit = PkgAuto; + + mCpuPmConfig.CstateLatencyControl0TimeUnit = TimeUnit1024ns; + mCpuPmConfig.CstateLatencyControl1TimeUnit = TimeUnit1024ns; + mCpuPmConfig.CstateLatencyControl2TimeUnit = TimeUnit1024ns; + mCpuPmConfig.CstateLatencyControl0Irtl = C3_LATENCY; + mCpuPmConfig.CstateLatencyControl1Irtl = C6_C7_SHORT_LATENCY; + mCpuPmConfig.CstateLatencyControl2Irtl = C6_C7_LONG_LATENCY; + if (CpuFamilyId == EnumCpuHswUlt) { + mCpuPmConfig.CstateLatencyControl3TimeUnit = TimeUnit1024ns; + mCpuPmConfig.CstateLatencyControl4TimeUnit = TimeUnit1024ns; + mCpuPmConfig.CstateLatencyControl5TimeUnit = TimeUnit1024ns; + mCpuPmConfig.CstateLatencyControl3Irtl = C8_LATENCY; + mCpuPmConfig.CstateLatencyControl4Irtl = C9_LATENCY; + // + // If PS4 is disabled, program 2750us to MSR_C_STATE_LATENCY_CONTROL_5 + // + mCpuPmConfig.CstateLatencyControl5Irtl = C10_LATENCY; + } + mCpuPmConfig.RfiFreqTunningOffsetIsNegative = 0; + mCpuPmConfig.RfiFreqTunningOffset = 0; + + if (CpuFamilyId == EnumCpuHswUlt) { + // + // Calibrate 24MHz BCLK support; 0: NO_CALIBRATE, 1: PCODE_CALIBRATE, 2: BIOS_CALIBRATE (Default :1) + // + mCpuPmConfig.PcodeCalibration = 1; + mCpuPmConfig.EnableRerunPcodeCalibration = PPM_DISABLE; + } + /// + /// TxT platform config initiate + /// +#if defined(TXT_SUPPORT_FLAG) && (TXT_SUPPORT_FLAG == 1) + mTxtFunctionConfig.ResetAux = 0; +#endif + + //AMI_REMOVE_TEMP_FOR_COMPILE + //UpdateDxeCpuPlatformPolicy (&mCpuPolicyData); //(AMI_CHG) + CallDxeCpuPolicyInitList(SystemTable, &mCpuPolicyData); // (AMI_CHG+) + /// + /// Install the DXE_CPU_PLATFORM_POLICY_PROTOCOL interface + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gDxeCpuPlatformPolicyProtocolGuid, + &mCpuPolicyData, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.dxs b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.dxs new file mode 100644 index 0000000..7ff094a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.dxs @@ -0,0 +1,42 @@ +/** @file + Dependency expression source file. + +@copyright + Copyright (c) 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 "PeimDepex.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" +#endif + +#include EFI_ARCH_PROTOCOL_DEFINITION (Variable) + + +DEPENDENCY_START + EFI_VARIABLE_ARCH_PROTOCOL_GUID +DEPENDENCY_END
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.h b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.h new file mode 100644 index 0000000..8524faf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.h @@ -0,0 +1,50 @@ +/** @file + Header file for the CpuPolicyInitDxe Driver. + +@copyright + Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _CPU_PLATFORM_POLICY_DXE_H_ +#define _CPU_PLATFORM_POLICY_DXE_H_ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "CpuAccess.h" +#endif + +#include "UefiIfrLibrary.h" +#include "PowermgmtDefinitions.h" +#include EFI_PROTOCOL_PRODUCER (CpuPlatformPolicy) +//AMI_REMOVE_FOR_COMPILE +//#include "CpuPlatformPolicyUpdateDxeLib.h" + +/** + Initilize Intel CPU DXE Policy + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +CpuPolicyInitDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN OUT EFI_SYSTEM_TABLE *SystemTable + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.inf b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.inf new file mode 100644 index 0000000..b331411 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Dxe/CpuPolicyInitDxe.inf @@ -0,0 +1,93 @@ +## @file +# Component description file for the CpuPolicyInitDxe DXE driver. +# +#@copyright +# Copyright (c) 2010 - 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 = CpuPolicyInitDxe +FILE_GUID = 15B9B6DA-00A9-4de7-B8E8-ED7AFB88F16E +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + CpuPolicyInitDxe.h + CpuPolicyInitDxe.c +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(DEST_DIR) + $(BUILD_DIR)/$(PROCESSOR) + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Pcd + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include +# +# if (EFI_SPECIFICATION_VERSION < 0x0002000A), use EfiIfrSupportLib +# if (EFI_SPECIFICATION_VERSION >= 0x0002000A), use UefiEfiIfrSupportLib +# +# $(EDK_SOURCE)/Foundation/Library/Dxe/EfiIfrSupportLib + $(EDK_SOURCE)/Foundation/Library/Dxe/UefiEfiIfrSupportLib + $(EFI_SOURCE) + $(EFI_SOURCE)/Include + $(EFI_SOURCE)/Library/CpuPolicyInitLib/Dxe + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT) + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include/Library + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Samplecode/Include + $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/Include + +[libraries.common] + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueDxeMemoryAllocationLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkFrameworkProtocolLib + EdkProtocolLib +# +# if (EFI_SPECIFICATION_VERSION < 0x0002000A), use EfiIfrSupportLib +# if (EFI_SPECIFICATION_VERSION >= 0x0002000A), use UefiEfiIfrSupportLib, EfiDriverLib +# +# EfiIfrSupportLib + EfiDriverLib + UefiEfiIfrSupportLib + CpuProtocolLib + CpuIA32Lib + PlatformPolicyUpdateDxeLib + CpuPlatformLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = CpuPolicyInitDxe.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=CpuPolicyInitDxeEntryPoint + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_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__ diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.c b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.c new file mode 100644 index 0000000..c0badcf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.c @@ -0,0 +1,268 @@ +/** @file + This file is SampleCode for Intel CPU PEI Platform Policy initialization. + +@copyright + Copyright (c) 2010 - 2014 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ +#include "CpuPolicyInitPei.h" + +//(AMI_CHG+)> +VOID CallPeiCpuPolicyInitList( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT PEI_CPU_PLATFORM_POLICY_PPI *PeiCpuPolicyPpi); +//<(AMI_CHG+) +/** + This PEIM performs CPU PEI Platform Policy initialization. + + @param[in] FfsHeader Pointer to Firmware File System file header. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The PPI is installed and initialized. + @retval EFI ERRORS The PPI is not successfully installed. +**/ +EFI_STATUS +EFIAPI +CpuPolicyInitPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *CpuPlatformPolicyPpiDesc; + PEI_CPU_PLATFORM_POLICY_PPI *CpuPlatformPolicyPpi; + CPU_CONFIG_PPI *CpuConfig; + SECURITY_CONFIG_PPI *SecurityConfig; + PFAT_CONFIG *PfatConfig; + POWER_MGMT_CONFIG_PPI *PowerMgmtConfig; + OVERCLOCKING_CONFIG_PPI *OcConfig; + BOOT_GUARD_CONFIG *BootGuardConfig; +#if defined(TXT_SUPPORT_FLAG) && (TXT_SUPPORT_FLAG == 1) + TXT_CONFIG *TxtConfig; +#endif + UINT8 PlatIdStr[] = "SHARK BAY"; + + /// + /// Allocate memory for the CPU Policy Ppi and Descriptor + /// + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), &CpuPlatformPolicyPpiDesc); + ASSERT_EFI_ERROR (Status); + + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (PEI_CPU_PLATFORM_POLICY_PPI), &CpuPlatformPolicyPpi); + ASSERT_EFI_ERROR (Status); + + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (CPU_CONFIG_PPI), &CpuConfig); + ASSERT_EFI_ERROR (Status); + + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (SECURITY_CONFIG_PPI), &SecurityConfig); + ASSERT_EFI_ERROR (Status); + + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (PFAT_CONFIG), &PfatConfig); + ASSERT_EFI_ERROR (Status); + + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (POWER_MGMT_CONFIG_PPI), &PowerMgmtConfig); + ASSERT_EFI_ERROR (Status); + + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (OVERCLOCKING_CONFIG_PPI), &OcConfig); + ASSERT_EFI_ERROR (Status); + +#if defined(TXT_SUPPORT_FLAG) && (TXT_SUPPORT_FLAG == 1) + Status = ((*PeiServices)->AllocatePool)(PeiServices, sizeof (TXT_CONFIG), &TxtConfig); + ASSERT_EFI_ERROR (Status); +#endif + + Status = ((*PeiServices)->AllocatePool) (PeiServices, sizeof (BOOT_GUARD_CONFIG), &BootGuardConfig); + ASSERT_EFI_ERROR (Status); + + CpuPlatformPolicyPpi->Revision = PEI_CPU_PLATFORM_POLICY_PPI_REVISION_8; + CpuPlatformPolicyPpi->CpuConfig = CpuConfig; + CpuPlatformPolicyPpi->SecurityConfig = SecurityConfig; + CpuPlatformPolicyPpi->SecurityConfig->PfatConfig = PfatConfig; + CpuPlatformPolicyPpi->PowerMgmtConfig = PowerMgmtConfig; + CpuPlatformPolicyPpi->OverclockingConfig = OcConfig; + CpuPlatformPolicyPpi->CpuPlatformPpiPtr = (UINTN) CpuPlatformPolicyPpi; + +#if defined(TXT_SUPPORT_FLAG) && (TXT_SUPPORT_FLAG == 1) + CpuPlatformPolicyPpi->SecurityConfig->TxtConfig = TxtConfig; +#else + CpuPlatformPolicyPpi->SecurityConfig->TxtConfig = NULL; +#endif + + CpuPlatformPolicyPpi->SecurityConfig->BootGuardConfig = BootGuardConfig; + + CpuConfig->CpuRatioOverride = CPU_FEATURE_DISABLE; + CpuConfig->CpuRatio = 63; + CpuConfig->CpuMaxNonTurboRatio = 63; + CpuConfig->BistOnReset = CPU_FEATURE_DISABLE; + CpuConfig->HyperThreading = CPU_FEATURE_ENABLE; + CpuConfig->VmxEnable = CPU_FEATURE_ENABLE; + CpuConfig->ActiveCoreCount = 0; + + /// + /// If CpuConfig->Pfat is set to ENABLE '1' then + /// PlatformData->SmmBwp (found in PchPolicyInitPei.c file) has to be set to ENABLE '1' + /// This is a PFAT Security requirement that needs to be addressed + /// If CpuConfig->Pfat is set to DISABLE '0' then + /// PlatformData->SmmBwp (found in PchPolicyInitPei.c file) value don't care, it can be + /// set to either ENABLE '1' or DISABLE '0' based on customer implementation + /// + CpuConfig->Pfat = CPU_FEATURE_DISABLE; + ZeroMem (&PfatConfig->Ppdt, sizeof (PPDT)); + PfatConfig->Ppdt.PpdtMajVer = PPDT_MAJOR_VERSION; + PfatConfig->Ppdt.PpdtMinVer = PPDT_MINOR_VERSION; + CopyMem (&PfatConfig->Ppdt.PlatId[0], &PlatIdStr[0], sizeof (PlatIdStr)); + PfatConfig->Ppdt.PfatModSvn = PFAT_SVN; + PfatConfig->Ppdt.BiosSvn = 0x01380000; + PfatConfig->Ppdt.ExecLim = 0; + PfatConfig->Ppdt.PlatAttr = 0; + PfatConfig->Ppdt.LastSfam = MIN_SFAM_COUNT - 1; + if (PfatConfig->Ppdt.LastSfam > (MAX_SFAM_COUNT - 1)) { + PfatConfig->Ppdt.LastSfam = MAX_SFAM_COUNT - 1; + } + /// + /// SfamData [LastSfam + 1] + /// + PfatConfig->Ppdt.SfamData[0].FirstByte = 0x00580000; + PfatConfig->Ppdt.SfamData[0].LastByte = 0x0058FFFF; + PfatConfig->Ppdt.PpdtSize = (sizeof (PPDT) - sizeof (PfatConfig->Ppdt.SfamData) + ((PfatConfig->Ppdt.LastSfam + 1) * sizeof (SFAM_DATA))); + PfatConfig->PpdtHash[0] = 0xae7295370672663c; + PfatConfig->PpdtHash[1] = 0x220375c996d23a36; + PfatConfig->PpdtHash[2] = 0x73aaea0f2afded9d; + PfatConfig->PpdtHash[3] = 0x707193b768a0829e; + ZeroMem (&PfatConfig->PupHeader, sizeof (PUP_HEADER)); + PfatConfig->PupHeader.Version = PUP_HDR_VERSION; + CopyMem (&PfatConfig->PupHeader.PlatId[0], &PlatIdStr[0], sizeof (PlatIdStr)); + PfatConfig->PupHeader.PkgAttributes = 0; + PfatConfig->PupHeader.PslMajorVer = PSL_MAJOR_VERSION; + PfatConfig->PupHeader.PslMinorVer = PSL_MINOR_VERSION; + PfatConfig->PupHeader.BiosSvn = PfatConfig->Ppdt.BiosSvn; + PfatConfig->PupHeader.EcSvn = 0; + PfatConfig->PupHeader.VendorSpecific = 0x808655AA; + ZeroMem (&PfatConfig->PfatLog, sizeof (PFAT_LOG)); + PfatConfig->PfatLog.Version = PFAT_LOG_VERSION; + PfatConfig->PfatLog.LastPage = 0; + if (PfatConfig->PfatLog.LastPage > (MAX_PFAT_LOG_PAGE - 1)) { + PfatConfig->PfatLog.LastPage = MAX_PFAT_LOG_PAGE - 1; + } + PfatConfig->PfatLog.LoggingOptions = 0; + PfatConfig->NumSpiComponents = 2; + PfatConfig->ComponentSize[0] = EnumSpiCompSize8MB; + PfatConfig->ComponentSize[1] = EnumSpiCompSize8MB; + PfatConfig->PfatMemSize = 0x05; + + CpuConfig->MlcStreamerPrefetcher = CPU_FEATURE_ENABLE; + CpuConfig->MlcSpatialPrefetcher = CPU_FEATURE_ENABLE; + + PowerMgmtConfig->RatioLimit[0] = 0; + PowerMgmtConfig->RatioLimit[1] = 0; + PowerMgmtConfig->RatioLimit[2] = 0; + PowerMgmtConfig->RatioLimit[3] = 0; + PowerMgmtConfig->TccActivationOffset = 0; + PowerMgmtConfig->VrCurrentLimit = VR_CURRENT_DEFAULT; + PowerMgmtConfig->VrCurrentLimitLock = CPU_FEATURE_DISABLE; + PowerMgmtConfig->Xe = CPU_FEATURE_DISABLE; + PowerMgmtConfig->BootInLfm = CPU_FEATURE_DISABLE; + /// + /// VrMiscIoutSlope = 0x200 default + /// VrMiscIoutOffsetSign = 0 means it's positive offset. 1= negative offset + /// VrMiscIoutOffset = 0 means it's 0%, 625 means 6.25% (range is +6.25% ~ -6.25%) + /// + PowerMgmtConfig->VrMiscIoutSlope = 0x200; + PowerMgmtConfig->VrMiscIoutOffsetSign = 0; + PowerMgmtConfig->VrMiscIoutOffset = 0; + + PowerMgmtConfig->VrMiscMinVid = V_MSR_VR_MISC_CONFIG_MIN_VID_DEFAULT; + PowerMgmtConfig->VrMiscIdleExitRampRate = CPU_FEATURE_ENABLE; + PowerMgmtConfig->VrMiscIdleEntryRampRate = CPU_FEATURE_DISABLE; + PowerMgmtConfig->VrMiscIdleEntryDecayEnable = CPU_FEATURE_ENABLE; + if (GetCpuFamily() == EnumCpuHswUlt) { + PowerMgmtConfig->VrMiscSlowSlewRateConfig = V_MSR_VR_MISC_CONFIG_SLOW_SLEW_RATE_CONFIG_DEFAULT; + PowerMgmtConfig->VrMisc2FastRampVoltage = V_MSR_VR_MISC_CONFIG2_FAST_RAMP_VOLTAGE_DEFAULT; + PowerMgmtConfig->VrMisc2MinC8Voltage = V_MSR_VR_MISC_CONFIG2_MIN_C8_VOLTAGE_DEFAULT; + PowerMgmtConfig->VrPSI4enable = CPU_FEATURE_ENABLE; + } + PowerMgmtConfig->Psi1Threshold = PSI1_THRESHOLD_DEFAULT; + PowerMgmtConfig->Psi2Threshold = PSI2_THRESHOLD_DEFAULT; + PowerMgmtConfig->Psi3Threshold = PSI3_THRESHOLD_DEFAULT; + + PowerMgmtConfig->FivrSscEnable = 1; + PowerMgmtConfig->FivrSscPercent = 62; + + /// + /// Initiate TxT policy + /// +#if defined(TXT_SUPPORT_FLAG) && (TXT_SUPPORT_FLAG == 1) + ZeroMem (TxtConfig, sizeof (TXT_CONFIG)); + CpuConfig->Txt = 0; + TxtConfig->SinitMemorySize = TXT_SINIT_MEMORY_SIZE; + TxtConfig->TxtHeapMemorySize = TXT_HEAP_MEMORY_SIZE; + TxtConfig->TxtDprMemoryBase = 0; + TxtConfig->TxtDprMemorySize = 0; + TxtConfig->BiosAcmBase = 0; + TxtConfig->BiosAcmSize = 0; + TxtConfig->McuUpdateDataAddr = 0; + TxtConfig->TgaSize = TXT_TGA_MEMORY_SIZE; + TxtConfig->TxtLcpPdBase = TXT_LCP_PD_BASE; + TxtConfig->TxtLcpPdSize = TXT_LCP_PD_SIZE; +#endif + /// + /// Initialize Overclocking Data + /// + OcConfig->CoreVoltageOffset = 0; + OcConfig->CoreVoltageOverride = 0; + OcConfig->CoreExtraTurboVoltage = 0; + OcConfig->CoreMaxOcTurboRatio = 0; + OcConfig->ClrVoltageOffset = 0; + OcConfig->ClrVoltageOverride = 0; + OcConfig->ClrExtraTurboVoltage = 0; + OcConfig->ClrMaxOcTurboRatio = 0; + OcConfig->SvidVoltageOverride = 0; + OcConfig->SvidEnable = 0; + OcConfig->FivrFaultsEnable = 0; + OcConfig->FivrEfficiencyEnable = 0; + OcConfig->CoreVoltageMode = 0; + OcConfig->ClrVoltageMode = 0; + OcConfig->OcSupport = 0; + OcConfig->BitReserved = 0; + + // + // Initialize Boot Guard data + // + BootGuardConfig->TpmType = TpmTypeMax; + BootGuardConfig->BypassTpmInit = FALSE; + BootGuardConfig->MeasuredBoot = FALSE; + BootGuardConfig->BootGuardSupport = FALSE; + BootGuardConfig->DisconnectAllTpms = FALSE; + BootGuardConfig->ByPassTpmEventLog = FALSE; + + //AMI_CHG + //UpdatePeiCpuPlatformPolicy (PeiServices, CpuPlatformPolicyPpi); //(AMI_CHG) + CallPeiCpuPolicyInitList(PeiServices, CpuPlatformPolicyPpi); // (AMI_CHG+) + + /// + /// Update the CPU Policy Ppi Descriptor + /// + CpuPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + CpuPlatformPolicyPpiDesc->Guid = &gPeiCpuPlatformPolicyPpiGuid; + CpuPlatformPolicyPpiDesc->Ppi = CpuPlatformPolicyPpi; + + /// + /// Install the CPU PEI Platform Policy PPI + /// + Status = (**PeiServices).InstallPpi (PeiServices, CpuPlatformPolicyPpiDesc); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.dxs b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.dxs new file mode 100644 index 0000000..1e93c04 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.dxs @@ -0,0 +1,41 @@ +/** @file + Dependency expression source file. + +@copyright + Copyright (c) 2010 - 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 "PeimDepex.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" +#endif + +#include EFI_PPI_DEPENDENCY (Variable) + +DEPENDENCY_START + PEI_READ_ONLY_VARIABLE_ACCESS_PPI_GUID +DEPENDENCY_END diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.h b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.h new file mode 100644 index 0000000..47a9f2b --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.h @@ -0,0 +1,55 @@ +/** @file + Header file for the CpuPeiPolicy PEIM. + +@copyright + Copyright (c) 2009 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _CPU_POLICY_INIT_PEI_H_ +#define _CPU_POLICY_INIT_PEI_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 "PfatDefinitions.h" +#include EFI_PPI_PRODUCER (CpuPlatformPolicy) +#include "CpuInitPeim.h" +#include "CpuRegs.h" +#include "CpuPlatformLib.h" +#include "PowerMgmtDefinitions.h" +#endif +//#include "CpuPlatformPolicyUpdatePeiLib.h" //(AMI_CHG) + +/// +/// Functions +/// +/** + This PEIM performs CPU PEI Platform Policy initialzation. + + @param[in] FfsHeader Pointer to Firmware File System file header. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The PPI is installed and initialized. + @retval EFI ERRORS The PPI is not successfully installed. +**/ +EFI_STATUS +EFIAPI +CpuPolicyInitPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ); +#endif diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.inf b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.inf new file mode 100644 index 0000000..1a07029 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyInitPei.inf @@ -0,0 +1,87 @@ +## @file +# Component description file for the CpuPolicyInitPei PEIM. +# +#@copyright +# Copyright (c) 2010 - 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 = CpuPolicyInitPei +FILE_GUID = 567F05DE-D174-48e4-A7C0-C19868A11F9B +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + CpuPolicyInitPei.h + CpuPolicyInitPei.c +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[includes.common] + . + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT) + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include/Library + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/CpuInit/Pei +# +# EDK II Glue Library utilizes some standard headers from EDK +# + $(EFI_SOURCE) + $(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/Pei/Include + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(PLATFORM_ECP_PACKAGE)/Include + $(PLATFORM_ECP_PACKAGE)/Library/OpensslLib + $(PLATFORM_ECP_PACKAGE)/Library/PeiCryptLib + +[libraries.common] + $(PROJECT_PCH_FAMILY)PpiLib + EdkFrameworkPpiLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGlueBaseMemoryLib + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + EdkIIGluePeiMemoryAllocationLib + EdkPpiLib + CpuPpiLib + PlatformPolicyUpdatePeiLib + OpensslLib + PeiCryptLib + CpuPlatformLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + DPX_SOURCE = CpuPolicyInitPei.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=CpuPolicyInitPeiEntryPoint + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -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__ \ + -D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.cif b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.cif new file mode 100644 index 0000000..c241162 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.cif @@ -0,0 +1,13 @@ +<component> + name = "Cpu Policy PEI" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\CpuPolicyInit\Pei" + RefName = "Cpu Policy Pei" +[files] +"CpuPolicyPei.sdl" +"CpuPolicyPei.mak" +"CpuPolicyInitPei.c" +"CpuPolicyInitPei.h" +"CpuPolicyInitPei.dxs" +"CpuPolicyInitPei.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.mak b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.mak new file mode 100644 index 0000000..3576f9e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.mak @@ -0,0 +1,139 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/Intel Haswell Cpu RC PKG/Cpu Policy PEI/CpuPolicyPei.mak 5 7/02/12 7:23a Davidhsieh $ +# +# $Revision: 5 $ +# +# $Date: 7/02/12 7:23a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/Intel Haswell Cpu RC PKG/Cpu Policy PEI/CpuPolicyPei.mak $ +# +# 5 7/02/12 7:23a Davidhsieh +# +# 4 5/22/12 4:36a Davidhsieh +# Add TXT_SUPPORT_FLAG define +# +# 3 5/14/12 2:20a Davidhsieh +# +# 2 2/23/12 2:46a Davidhsieh +# +# 1 2/07/12 3:56a Davidhsieh +# +# 2 9/21/11 11:22p Davidhsieh +# +# 1 5/06/11 6:06a Davidhsieh +# First release +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +EDK : CpuPolicyPei + +BUILD_CpuInitPei_DIR = $(BUILD_DIR)\$(CpuPolicyPei_DIR) + +$(BUILD_DIR)\CpuPolicyPei.mak : $(CpuPolicyPei_DIR)\CpuPolicyPei.cif $(BUILD_RULES) + $(CIF2MAK) $(CpuPolicyPei_DIR)\CpuPolicyPei.cif $(CIF2MAK_DEFAULTS) + +CpuPolicyPei : $(BUILD_DIR)\CpuPolicyPei.mak CpuPolicyPeiBin + +CpuPolicyPei_OBJECTS = \ + $(BUILD_CpuInitPei_DIR)\CpuPolicyInitPei.obj + +CpuPolicyPei_MY_INCLUDES= \ + $(EDK_INCLUDES) \ + /I$(PROJECT_CPU_ROOT)\ + /I$(PROJECT_CPU_ROOT)\Include \ + /I$(PROJECT_CPU_ROOT)\Include\Library \ + /I$(PROJECT_CPU_ROOT)\\Library \ + /I$(CpuInitPei_DIR) + +CpuPolicyPei_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=CpuPolicyInitPeiEntryPoint"\ + /D TXT_SUPPORT_FLAG=1 \ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_BASE_LIB__ \ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_PEI_SERVICES_TABLE_POINTER_LIB_MM7__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ + + +CpuPolicyPei_LIBS =\ + $(PchPlatformLib)\ + $(EfiRuntimeLib_LIB)\ + $(INTEL_PCH_PROTOCOL_LIB)\ + $(EFIRUNTIMELIB)\ + $(EDKFRAMEWORKPPILIB) \ + $(CPUIA32LIB)\ + $(EFIPROTOCOLLIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(IntelPchPpiLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGluePeiHobLib_LIB) \ + $(CpuGuidLib_LIB) \ + $(EdkIIGluePeiServicesLib_LIB) \ + $(EdkIIGluePeiReportStatusCodeLib_LIB) \ + $(PEIHOBLIB) \ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiDevicePathLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB) \ + $(EdkIIGlueBasePciExpressLib_LIB)\ + $(CPU_PPI_LIB)\ + $(PchPlatformPeiLib_LIB)\ + $(CpuPlatformLib_LIB)\ + $(EFISCRIPTLIB) + +CpuPolicyPeiBin : $(CpuPolicyPei_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\CpuPolicyPei.mak all\ + NAME=CpuPolicyPei\ + MAKEFILE=$(BUILD_DIR)\CpuPolicyPei.mak \ + "MY_INCLUDES=$(CpuPolicyPei_MY_INCLUDES)" \ + "MY_DEFINES=$(CpuPolicyPei_DEFINES)"\ + OBJECTS="$(CpuPolicyPei_OBJECTS)" \ + GUID=0ac2d35d-1c77-1033-a6f8-7ca55df7d0aa\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=PEIM \ + EDKIIModule=PEIM\ + DEPEX1=$(CpuPolicyPei_DIR)\CpuPolicyInitPei.dxs \ + DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 + +#--------------------------------------------------------------------------- +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.sdl b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.sdl new file mode 100644 index 0000000..947bdb1 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuPolicyInit/Pei/CpuPolicyPei.sdl @@ -0,0 +1,58 @@ +#**************************************************************************** +#**************************************************************************** +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 ** +#** ** +#** Phone (770)-246-8600 ** +#** ** +#**************************************************************************** +#**************************************************************************** +#**************************************************************************** +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/Intel Haswell Cpu RC PKG/Cpu Policy PEI/CpuPolicyPei.sdl 1 2/07/12 3:56a Davidhsieh $ +# +# $Revision: 1 $ +# +# $Date: 2/07/12 3:56a $ +# +#**************************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/Intel Haswell Cpu RC PKG/Cpu Policy PEI/CpuPolicyPei.sdl $ +# +# 1 2/07/12 3:56a Davidhsieh +# +# 1 5/06/11 6:06a Davidhsieh +# First release +# +# +#**************************************************************************** +TOKEN + Name = "CpuPeiPolicySupport" + Value = "1" + Help = "Main switch to enable Cpu Policy Pei support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +PATH + Name = "CpuPolicyPei_DIR" +End + +MODULE + Help = "Includes CpuPeiPolicy.mak to Project" + File = "CpuPolicyPei.mak" +End + +ELINK + Name = "$(BUILD_DIR)\CpuPolicyPei.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End + diff --git a/ReferenceCode/Haswell/SampleCode/CpuSampleCode.cif b/ReferenceCode/Haswell/SampleCode/CpuSampleCode.cif new file mode 100644 index 0000000..886b397 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/CpuSampleCode.cif @@ -0,0 +1,15 @@ +<component> + name = "CpuSampleCode" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\" + RefName = "CpuSampleCode" +[files] +"Include\AslUpdateLib.h" +"Include\PeiKscLib.h" +"Include\SmmIoLib.h" +"Include\KscLib.h" +"Include\acpibuild.dsc" +"Include\Cpu.h" +"Include\FlashMap.h" +"Include\BootGuardRevocationLib.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Include/AslUpdateLib.h b/ReferenceCode/Haswell/SampleCode/Include/AslUpdateLib.h new file mode 100644 index 0000000..eb9d1cf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/AslUpdateLib.h @@ -0,0 +1,178 @@ +/** @file + ASL dynamic update library definitions. + + This library provides dymanic update to various ASL structures. + + There may be different libraries for different environments (PEI, BS, RT, SMM). + Make sure you meet the requirements for the library (protocol dependencies, use + restrictions, etc). + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _ASL_UPDATE_LIB_H_ +#define _ASL_UPDATE_LIB_H_ + +/// +/// Include files +/// +#include "Tiano.h" +#include "Acpi.h" +#include "Acpi3_0.h" + +#include EFI_PROTOCOL_DEPENDENCY (AcpiSupport) +#include EFI_PROTOCOL_DEPENDENCY (AcpiTable) + +/// +/// AML parsing definitions +/// +#define AML_NAME_OP 0x08 +#define AML_BYTE_OP 0x0A +#define AML_WORD_OP 0x0B +#define AML_DWORD_OP 0x0C +#define AML_QWORD_OP 0x0E +#define AML_SCOPE_OP 0x10 +#define AML_BUFFER_OP 0x11 +#define AML_PACKAGE_OP 0x12 +#define AML_METHOD_OP 0x14 +#define AML_EXT_OP 0x5B +#define AML_OPREGION_OP 0x80 +#define AML_DEVICE_OP 0x82 +#define AML_PROCESSOR_OP 0x83 + +/// +/// Magic number definition for values to be updated +/// +#define UINT16_BIT_MAGIC_NUMBER 0xFFFF +#define UINT32_BIT_MAGIC_NUMBER 0xFFFFFFFF + +/// +/// ASL PSS package structure layout +/// +#pragma pack(1) +typedef struct { + UINT8 NameOp; ///< 12h ;First opcode is a NameOp. + UINT8 PackageLead; ///< 20h ;First opcode is a NameOp. + UINT8 NumEntries; ///< 06h ;First opcode is a NameOp. + UINT8 DwordPrefix1; ///< 0Ch + UINT32 CoreFrequency; ///< 00h + UINT8 DwordPrefix2; ///< 0Ch + UINT32 Power; ///< 00h + UINT8 DwordPrefix3; ///< 0Ch + UINT32 TransLatency; ///< 00h + UINT8 DwordPrefix4; ///< 0Ch + UINT32 BMLatency; ///< 00h + UINT8 DwordPrefix5; ///< 0Ch + UINT32 Control; ///< 00h + UINT8 DwordPrefix6; ///< 0Ch + UINT32 Status; ///< 00h +} PSS_PACKAGE_LAYOUT; +#pragma pack() + +/** + Initialize the ASL update library state. + This must be called prior to invoking other library functions. + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +InitializeAslUpdateLib ( + VOID + ); + +/** + This function locates an ACPI structure and updates it. + This function knows how to update operation regions and BUFA/BUFB resource structures. + + This function may not be implemented in all instantiations of this library. + + @param[in] AslSignature - The signature of Operation Region that we want to update. + @param[in] BaseAddress - Base address of IO trap. + @param[in] Length - Length of IO address. + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +UpdateAslCode ( + IN UINT32 AslSignature, + IN UINT16 BaseAddress, + IN UINT8 Length + ); + +/** + This function uses the ACPI support protocol to locate an ACPI table using the . + It is really only useful for finding tables that only have a single instance, + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc. + Matches are determined by finding the table with ACPI table that has + a matching signature and version. + + @param[in] TableId - Pointer to an ASCII string containing the Signature to match + @param[in] Table - Updated with a pointer to the table + @param[in] Handle - AcpiSupport protocol table handle for the table found + @param[in] Version - On input, the version of the table desired, + on output, the versions the table belongs to + (see AcpiSupport protocol for details) + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableBySignature ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ); + +/** + This function uses the ACPI support protocol to locate an ACPI SSDT table. + The table is located by searching for a matching OEM Table ID field. + Partial match searches are supported via the TableIdSize parameter. + + @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function + will consider it a match if the first TableIdSize bytes match + @param[in] Table - Updated with a pointer to the table + @param[in] Handle - AcpiSupport protocol table handle for the table found + @param[in] Version - See AcpiSupport protocol, GetAcpiTable function for use + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableByOemTableId ( + IN UINT8 *TableId, + IN UINT8 TableIdSize, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ); + +/** + This function calculates and updates an UINT8 checksum. + + @param[in] Buffer Pointer to buffer to checksum + @param[in] Size Number of bytes to checksum + @param[in] ChecksumOffset Offset to place the checksum result in + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFI_BOOTSERVICE +AcpiChecksum ( + IN VOID *Buffer, + IN UINTN Size, + IN UINTN ChecksumOffset + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Include/BootGuardRevocationLib.h b/ReferenceCode/Haswell/SampleCode/Include/BootGuardRevocationLib.h new file mode 100644 index 0000000..f7d0fbc --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/BootGuardRevocationLib.h @@ -0,0 +1,35 @@ +/** @file + Header file for Boot Guard revocation notification. + +@copyright + Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _BOOT_GUARD_REVOCATION_LIB_H_ +#define _BOOT_GUARD_REVOCATION_LIB_H_ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#endif + +/** + Provide a hook for OEM to deal with Boot Guard revocation flow. +**/ +VOID +EFIAPI +BootGuardOemRevocationHook ( + VOID + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Include/Cpu.h b/ReferenceCode/Haswell/SampleCode/Include/Cpu.h new file mode 100644 index 0000000..94b7e56 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/Cpu.h @@ -0,0 +1,63 @@ +/** @file + Various CPU-specific definitions. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _CPU_H_ +#define _CPU_H_ + +#define B_FAMILY_MODEL_STEPPING 0x00000FFF + +#define EFI_MSR_IA32_PERF_STS 0x198 +#define EFI_MSR_IA32_PERF_CTL 0x199 +#define EFI_MSR_IA32_CLOCK_MODULATION 0x19A +#define EFI_MSR_IA32_THERM_STATUS 0x19C + +#define B_BS_VID 0x0000003F +#define N_BS_VID 0 +#define B_BS_RATIO 0x00001F00 +#define N_BS_RATIO 8 + +/// +/// UINT64 workaround +/// +/// The MS compiler doesn't handle QWORDs very well. I'm breaking +/// them into DWORDs to circumvent the problems. Converting back +/// shouldn't be a big deal. +/// +#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() +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Include/FlashMap.h b/ReferenceCode/Haswell/SampleCode/Include/FlashMap.h new file mode 100644 index 0000000..b72df34 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/FlashMap.h @@ -0,0 +1,27 @@ +/** @file + File content auto-generated by FlashMap utility + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _FLASH_MAP_H_ +#define _FLASH_MAP_H_ + +/// +/// Please confirm following configuration from your platform setting. +/// +#define FLASH_REGION_MICROCODE_SIZE 0xffd90000 +#define FLASH_REGION_MICROCODE_BASE 0x00040000 +#endif ///< #ifndef _FLASH_MAP_H_ diff --git a/ReferenceCode/Haswell/SampleCode/Include/KscLib.h b/ReferenceCode/Haswell/SampleCode/Include/KscLib.h new file mode 100644 index 0000000..a428f77 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/KscLib.h @@ -0,0 +1,232 @@ +/** @file + KSC library functions and definitions. + + This library provides basic KSC interface. It is deemed simple enough and uses in + so few cases that there is not currently benefit to implementing a protocol. + If more consumers are added, it may be benefitial to implement as a protocol. + + There may be different libraries for different environments (PEI, BS, RT, SMM). + Make sure you meet the requirements for the library (protocol dependencies, use + restrictions, etc). + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _KSC_LIB_H_ +#define _KSC_LIB_H_ + +/// +/// Include files +/// +#include "Tiano.h" + +/// +/// Timeout if KSC command/data fails +/// +#define KSC_TIME_OUT 0x20000 + +/// +/// The Keyboard and System management Controller (KSC) implements a standard 8042 keyboard +/// controller interface at ports 0x60/0x64 and a ACPI compliant system management controller +/// at ports 0x62/0x66. Port 0x66 is the command and status port, port 0x62 is the data port. +/// +#define KSC_D_PORT 0x62 +#define KSC_C_PORT 0x66 + +/// +/// Status Port 0x62 +/// +#define KSC_S_OVR_TMP 0x80 ///< Current CPU temperature exceeds the threshold +#define KSC_S_SMI_EVT 0x40 ///< SMI event is pending +#define KSC_S_SCI_EVT 0x20 ///< SCI event is pending +#define KSC_S_BURST 0x10 ///< KSC is in burst mode or normal mode +#define KSC_S_CMD 0x08 ///< Byte in data register is command/data +#define KSC_S_IGN 0x04 ///< Ignored +#define KSC_S_IBF 0x02 ///< Input buffer is full/empty +#define KSC_S_OBF 0x01 ///< Output buffer is full/empty +/// +/// KSC commands that are issued to the KSC through the command port (0x66). +/// New commands and command parameters should only be written by the host when IBF=0. +/// Data read from the KSC data port is valid only when OBF=1. +/// +#define KSC_C_SMI_NOTIFY_ENABLE 0x04 ///< Enable SMI notifications to the host +#define KSC_C_SMI_NOTIFY_DISABLE 0x05 ///< SMI notifications are disabled and pending notifications cleared +#define KSC_C_QUERY_SYS_STATUS 0x06 ///< Returns 1 byte of information about the system status +#define KSC_B_SYS_STATUS_FAN 0x40 ///< Fan status (1 = ON) +#define KSC_B_SYS_STATUS_DOCK 0x20 ///< Dock status (1 = Docked) +#define KSC_B_SYS_STATUS_AC 0x10 ///< AC power (1 = AC powered) +#define KSC_B_SYS_STATUS_THERMAL 0x0F ///< CPU thermal state (0 ~ 9) +#define KSC_C_FAB_ID 0x0D ///< Get the board fab ID in the lower 3 bits +#define KSC_C_SYSTEM_POWER_OFF 0x22 ///< Turn off the system power +#define KSC_C_LAN_ON 0x46 ///< Turn on the power to LAN through EC/KSC +#define KSC_C_LAN_OFF 0x47 ///< Turn off the power to LAN through EC/KSC +#define KSC_C_GET_TEMP 0x50 ///< Returns the CPU temperature as read from the SMBus thermal sensor. +#define KSC_C_SET_CTEMP 0x58 ///< The next byte written to the data port will be the shutdown temperature +#define KSC_EC_PCH_SMBUS_EN 0x60 ///< EC PCH SMBus thermal monitoring Enable cmd +#define KSC_EC_PCH_SMBUS_DIS 0x61 ///< EC PCH SMBus thermal monitoring Disable cmd +#define KSC_TS_ON_DIMM_EN 0x6B ///< TS-on-DIMM thermal monitoring enable command +#define KSC_TS_ON_DIMM_DIS 0x6C ///< TS-on-DIMM thermal monitoring disable command +#define KSC_C_PCH_SMBUS_MSG_LENGTH 0x6D ///< PCH SMBus block read buffer length +#define KSC_C_PCH_SMBUS_PEC_EN 0x6E ///< PCH SMBus Packet Error Checking (PEC) Enable command. +#define KSC_C_PCH_SMBUS_PEC_DIS 0x76 ///< PCH SMBus Packet Error Checking (PEC) Disable command. +#define KSC_C_EC_SMBUS_HIGH_SPEED 0x75 ///< EC SMBus high speed mode command +#define KSC_EC_PCH_SMBUS_WRITE_EN 0x68 ///< EC PCH SMBus Write Enable cmd +#define KSC_EC_PCH_SMBUS_WRITE_DIS 0x69 ///< EC PCH SMBus Write Disable cmd +#define KSC_C_SMI_QUERY 0x70 ///< The host reads the data port to retrieve the notifications +#define KSC_C_SMI_TIMER 0x71 ///< Commands the KSC to generate a periodic SMI to the host +#define KSC_C_SMI_HOTKEY 0x72 ///< Get the scan code of hotkey pressed (CTRL + ALT + SHIFT + key) +#define KSC_C_READ_MEM 0x80 ///< Read the KSC memory +#define KSC_C_WRITE_MEM 0x81 ///< Write the KSC memory +#define KSC_C_DOCK_STATUS 0x8A ///< Get the dock status +#define KSC_B_DOCK_STATUS_ATTACH 0x01 ///< Dock status (1 = Attach) +#define KSC_C_KSC_REVISION 0x90 ///< Get the revision for the KSC +#define KSC_C_SMI_INJECT 0xBA ///< The next byte written to the data port will generate an immediate SMI +#define KSC_C_SMI_DISABLE 0xBC ///< SMI generation by the KSC is disabled +#define KSC_C_SMI_ENABLE 0xBD ///< SMI generation by the KSC is enabled +#define KSC_C_ACPI_ENABLE 0xAA ///< Enable ACPI mode +#define KSC_C_ACPI_DISABLE 0xAB ///< Disable ACPI mode +/// +/// KSC commands that are only valid if the EC has ACPI mode enabled. +/// Note that capacity and voltage are 16 bit values, thus you need to read them from +/// ACPI space with two reads (little Endian). +/// +#define KSC_VIRTUAL_BAT_STATUS 48 ///< Status of the virtual battery (present) +#define KSC_VIRTUAL_BAT_PRESENT_MASK 0x10 ///< Bit 4 is the indicator +#define KSC_REAL_BAT1_STATUS 50 ///< Status of the first real battery (present, charging) +#define KSC_REAL_BAT1_REMAINING_CAPACITY 89 ///< Remaining capacity in mWh +#define KSC_REAL_BAT1_RESOLUTION_VOLTAGE 93 ///< Full resolution voltage in mV +#define KSC_REAL_BAT2_STATUS 54 ///< Status of the second real battery (present, charging) +#define KSC_REAL_BAT2_REMAINING_CAPACITY 99 ///< Remaining capacity in mWh +#define KSC_REAL_BAT2_RESOLUTION_VOLTAGE 103 ///< Full resolution voltage in mV +#define KSC_REAL_BAT_PRESENT_MASK 0x8 ///< Bit 3 is the indicator +#define KSC_REAL_BAT_CHARGING_MASK 0x1 ///< Bit 1 is the indicator +/// +/// SMI notification code table, read through command KSC_C_SMI_QUERY +/// +#define KSC_N_SMI_NULL 0x00 ///< Null marks the end of the SMI notification queue +#define KSC_N_SMI_HOTKEY 0x20 ///< Hotkey pressed SMI +#define KSC_N_SMI_ACINSERTION 0x30 ///< AC insertion SMI +#define KSC_N_SMI_ACREMOVAL 0x31 ///< AC removal SMI +#define KSC_N_SMI_PWRSW 0x32 ///< Power switch press SMI +#define KSC_N_SMI_LID 0x33 ///< Lid switch change SMI +#define KSC_N_SMI_VB 0x34 ///< Virtual battery switch change SMI +#define KSC_N_SMI_THERM_0 0x60 ///< Thermal state 0 SMI +#define KSC_N_SMI_THERM_1 0x61 ///< Thermal state 1 SMI +#define KSC_N_SMI_THERM_2 0x62 ///< Thermal state 2 SMI +#define KSC_N_SMI_THERM_3 0x63 ///< Thermal state 3 SMI +#define KSC_N_SMI_THERM_4 0x64 ///< Thermal state 4 SMI +#define KSC_N_SMI_THERM_5 0x65 ///< Thermal state 5 SMI +#define KSC_N_SMI_THERM_6 0x66 ///< Thermal state 6 SMI +#define KSC_N_SMI_THERM_7 0x67 ///< Thermal state 7 SMI +#define KSC_N_SMI_THERM_8 0x68 ///< Thermal state 8 SMI +#define KSC_N_SMI_DOCKED 0x70 ///< Dock complete SMI +#define KSC_N_SMI_UNDOCKED 0x71 ///< Undock complete SMI +#define KSC_N_SMI_UNDOCKREQUEST 0x72 ///< Undocking request SMI +#define KSC_N_SMI_TIMER 0x80 ///< Timer wakeup SMI +/// +/// Hotkey scan code (CTRL + ALT + SHIFT + key) +/// +#define KSC_HK_ESC 0x01 ///< ESC +#define KSC_HK_1 0x02 ///< 1 ! +#define KSC_HK_2 0x03 ///< 2 @ +#define KSC_HK_3 0x04 ///< 3 # +#define KSC_HK_4 0x05 ///< 4 $ +#define KSC_HK_5 0x06 ///< 5 % +#define KSC_HK_6 0x07 ///< 6 ^ +#define KSC_HK_7 0x08 ///< 7 & +#define KSC_HK_8 0x09 ///< 8 * +#define KSC_HK_9 0x0A ///< 9 ( +#define KSC_HK_0 0x0B ///< 0 ) +#define KSC_HK_MINUS 0x0C ///< - _ +#define KSC_HK_ADD 0x0D ///< = + +#define KSC_HK_F1 0x3B ///< F1 +#define KSC_HK_F2 0x3C ///< F2 +#define KSC_HK_F3 0x3D ///< F3 +#define KSC_HK_F4 0x3E ///< F4 +#define KSC_HK_F5 0x3F ///< F5 +#define KSC_HK_F6 0x40 ///< F6 +#define KSC_HK_F7 0x41 ///< F7 +#define KSC_HK_F8 0x42 ///< F8 +#define KSC_HK_F9 0x43 ///< F9 +#define KSC_HK_F10 0x44 ///< F10 +#define KSC_HK_F11 0x57 ///< F11 +#define KSC_HK_F12 0x58 ///< F12 +/// +/// Function declarations +/// +/** + This function initializes the KSC library. + It must be called before using any of the other KSC library functions. + + @param[in] None. + + @retval EFI_SUCCESS - KscLib is successfully initialized. +**/ +EFI_STATUS +InitializeKscLib ( + VOID + ); +/** + Send a command to the Keyboard System Controller. + + @param[in] Command - Command byte to send + + @retval EFI_SUCCESS - Command success + @retval EFI_TIMEOUT - Command timeout + @retval Other - Command failed +**/ +EFI_STATUS +SendKscCommand ( + UINT8 Command + ); +/** + Sends data to Keyboard System Controller. + + @param[in] Data - Data byte to send + + @retval EFI_SUCCESS - Success + @retval EFI_TIMEOUT - Timeout + @retval Other - Failed +**/ +EFI_STATUS +SendKscData ( + UINT8 Data + ); +/** + Receives data from Keyboard System Controller. + + @param[in] Data - Data byte received + + @retval EFI_SUCCESS - Read success + @retval EFI_TIMEOUT - Read timeout + @retval Other - Read failed +**/ +EFI_STATUS +ReceiveKscData ( + UINT8 *Data + ); +/** + Receives status from Keyboard System Controller. + + @param[in] KscStatus - Status byte to receive + + @retval EFI_SUCCESS - Success + @retval Other - Failed +**/ +EFI_STATUS +ReceiveKscStatus ( + UINT8 *KscStatus + ); +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Include/PeiKscLib.h b/ReferenceCode/Haswell/SampleCode/Include/PeiKscLib.h new file mode 100644 index 0000000..76c3dfa --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/PeiKscLib.h @@ -0,0 +1,224 @@ +/** @file + KSC library functions and definitions. + + This library provides basic KSC interface. It is deemed simple enough and uses in + so few cases that there is not currently benefit to implementing a protocol. + If more consumers are added, it may be benefitial to implement as a protocol. + + There may be different libraries for different environments (PEI, BS, RT, SMM). + Make sure you meet the requirements for the library (protocol dependencies, use + restrictions, etc). + +@copyright + Copyright (c) 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _PEI_KSC_LIB_H_ +#define _PEI_KSC_LIB_H_ + +/// +/// Timeout if KSC command/data fails +/// +#define KSC_TIME_OUT 0x20000 + +/// +/// The Keyboard and System management Controller (KSC) implements a standard 8042 keyboard +/// controller interface at ports 0x60/0x64 and a ACPI compliant system management controller +/// at ports 0x62/0x66. Port 0x66 is the command and status port, port 0x62 is the data port. +/// +#define KSC_D_PORT 0x62 +#define KSC_C_PORT 0x66 + +/// +/// Status Port 0x62 +/// +#define KSC_S_OVR_TMP 0x80 ///< Current CPU temperature exceeds the threshold +#define KSC_S_SMI_EVT 0x40 ///< SMI event is pending +#define KSC_S_SCI_EVT 0x20 ///< SCI event is pending +#define KSC_S_BURST 0x10 ///< KSC is in burst mode or normal mode +#define KSC_S_CMD 0x08 ///< Byte in data register is command/data +#define KSC_S_IGN 0x04 ///< Ignored +#define KSC_S_IBF 0x02 ///< Input buffer is full/empty +#define KSC_S_OBF 0x01 ///< Output buffer is full/empty + +/// +/// KSC commands that are issued to the KSC through the command port (0x66). +/// New commands and command parameters should only be written by the host when IBF=0. +/// Data read from the KSC data port is valid only when OBF=1. +/// +#define KSC_C_SMI_NOTIFY_ENABLE 0x04 ///< Enable SMI notifications to the host +#define KSC_C_SMI_NOTIFY_DISABLE 0x05 ///< SMI notifications are disabled and pending notifications cleared +#define KSC_C_QUERY_SYS_STATUS 0x06 ///< Returns 1 byte of information about the system status +#define KSC_B_SYS_STATUS_FAN 0x40 ///< Fan status (1 = ON) +#define KSC_B_SYS_STATUS_DOCK 0x20 ///< Dock status (1 = Docked) +#define KSC_B_SYS_STATUS_AC 0x10 ///< AC power (1 = AC powered) +#define KSC_B_SYS_STATUS_THERMAL 0x0F ///< CPU thermal state (0 ~ 9) +#define KSC_C_FAB_ID 0x0D ///< Get the board fab ID in the lower 3 bits +#define KSC_B_BOARD_ID 0x0F ///< Board ID = [3:0] +#define KSC_C_SYSTEM_POWER_OFF 0x22 ///< Turn off the system power +#define KSC_C_LAN_ON 0x46 ///< Turn on the power to LAN through EC/KSC +#define KSC_C_LAN_OFF 0x47 ///< Turn off the power to LAN through EC/KSC +#define KSC_C_GET_DTEMP 0x50 ///< Returns the CPU temperature as read from the SMBus thermal sensor. +#define KSC_C_SET_CTEMP 0x58 ///< The next byte written to the data port will be the shutdown temperature +#define KSC_C_EN_DTEMP 0x5E ///< Commands KSC to begin reading Thermal Diode and comparing to Critical Temperature +#define KSC_C_DIS_DTEMP 0x5F ///< Commands KSC to stop reading Thermal Diode +#define KSC_C_SMI_QUERY 0x70 ///< The host reads the data port to retrieve the notifications +#define KSC_C_SMI_TIMER 0x71 ///< Commands the KSC to generate a periodic SMI to the host +#define KSC_C_SMI_HOTKEY 0x72 ///< Get the scan code of hotkey pressed (CTRL + ALT + SHIFT + key) +#define KSC_C_READ_MEM 0x80 ///< Read the KSC memory +#define KSC_C_WRITE_MEM 0x81 ///< Write the KSC memory +#define KSC_C_KSC_REVISION 0x90 ///< Get the revision for the KSC +#define KSC_C_SMI_INJECT 0xBA ///< The next byte written to the data port will generate an immediate SMI +#define KSC_C_SMI_DISABLE 0xBC ///< SMI generation by the KSC is disabled +#define KSC_C_SMI_ENABLE 0xBD ///< SMI generation by the KSC is enabled +#define KSC_C_ACPI_ENABLE 0xAA ///< Enable ACPI mode +#define KSC_C_ACPI_DISABLE 0xAB ///< Disable ACPI mode + +/// +/// SMI notification code table, read through command KSC_C_SMI_QUERY +/// +#define KSC_N_SMI_NULL 0x00 ///< Null marks the end of the SMI notification queue +#define KSC_N_SMI_HOTKEY 0x20 ///< Hotkey pressed SMI +#define KSC_N_SMI_ACINSERTION 0x30 ///< AC insertion SMI +#define KSC_N_SMI_ACREMOVAL 0x31 ///< AC removal SMI +#define KSC_N_SMI_PWRSW 0x32 ///< Power switch press SMI +#define KSC_N_SMI_LID 0x33 ///< Lid switch change SMI +#define KSC_N_SMI_VB 0x34 ///< Virtual battery switch change SMI +#define KSC_N_SMI_THERM_0 0x60 ///< Thermal state 0 SMI +#define KSC_N_SMI_THERM_1 0x61 ///< Thermal state 1 SMI +#define KSC_N_SMI_THERM_2 0x62 ///< Thermal state 2 SMI +#define KSC_N_SMI_THERM_3 0x63 ///< Thermal state 3 SMI +#define KSC_N_SMI_THERM_4 0x64 ///< Thermal state 4 SMI +#define KSC_N_SMI_THERM_5 0x65 ///< Thermal state 5 SMI +#define KSC_N_SMI_THERM_6 0x66 ///< Thermal state 6 SMI +#define KSC_N_SMI_THERM_7 0x67 ///< Thermal state 7 SMI +#define KSC_N_SMI_THERM_8 0x68 ///< Thermal state 8 SMI +#define KSC_N_SMI_DOCKED 0x70 ///< Dock complete SMI +#define KSC_N_SMI_UNDOCKED 0x71 ///< Undock complete SMI +#define KSC_N_SMI_UNDOCKREQUEST 0x72 ///< Undocking request SMI +#define KSC_N_SMI_TIMER 0x80 ///< Timer wakeup SMI + +/// +/// Hotkey scan code (CTRL + ALT + SHIFT + key) +/// +#define KSC_HK_ESC 0x01 ///< ESC +#define KSC_HK_1 0x02 ///< 1 ! +#define KSC_HK_2 0x03 ///< 2 @ +#define KSC_HK_3 0x04 ///< 3 # +#define KSC_HK_4 0x05 ///< 4 $ +#define KSC_HK_5 0x06 ///< 5 % +#define KSC_HK_6 0x07 ///< 6 ^ +#define KSC_HK_7 0x08 ///< 7 & +#define KSC_HK_8 0x09 ///< 8 * +#define KSC_HK_9 0x0A ///< 9 ( +#define KSC_HK_0 0x0B ///< 0 ) +#define KSC_HK_MINUS 0x0C ///< - _ +#define KSC_HK_ADD 0x0D ///< = + +#define KSC_HK_F1 0x3B ///< F1 +#define KSC_HK_F2 0x3C ///< F2 +#define KSC_HK_F3 0x3D ///< F3 +#define KSC_HK_F4 0x3E ///< F4 +#define KSC_HK_F5 0x3F ///< F5 +#define KSC_HK_F6 0x40 ///< F6 +#define KSC_HK_F7 0x41 ///< F7 +#define KSC_HK_F8 0x42 ///< F8 +#define KSC_HK_F9 0x43 ///< F9 +#define KSC_HK_F10 0x44 ///< F10 +#define KSC_HK_F11 0x57 ///< F11 +#define KSC_HK_F12 0x58 ///< F12 + +#include EFI_PPI_DEPENDENCY (CpuIo) +#include EFI_PPI_DEPENDENCY (Stall) + +/// +/// Function declarations +/// +EFI_STATUS +SendKscCommand ( + EFI_PEI_SERVICES **PeiServices, + PEI_CPU_IO_PPI *CpuIo, + PEI_STALL_PPI *StallPpi, + UINT8 Command + ); +/** + Sends command to Keyboard System Controller. + + @param[in] PeiServices - PEI Services + @param[in] CpiIo - Pointer to CPU IO protocol + @param[in] StallPpi - Pointer to Stall PPI + @param[in] Command - Command byte to send + + @retval EFI_SUCCESS - Command success + @retval EFI_DEVICE_ERROR - Command error + @retval EFI_TIMEOUT - Command timeout +**/ + +EFI_STATUS +SendKscData ( + EFI_PEI_SERVICES **PeiServices, + PEI_CPU_IO_PPI *CpuIo, + PEI_STALL_PPI *StallPpi, + UINT8 Data + ); +/** + Sends data to Keyboard System Controller. + + @param[in] PeiServices - PEI Services + @param[in] CpiIo - Pointer to CPU IO protocol + @param[in] StallPpi - Pointer to Stall PPI + @param[in] Data - Data byte to send + + @retval EFI_SUCCESS - Success + @retval EFI_DEVICE_ERROR - Error + @retval EFI_TIMEOUT - Command timeout +**/ + +EFI_STATUS +ReceiveKscData ( + EFI_PEI_SERVICES **PeiServices, + PEI_CPU_IO_PPI *CpuIo, + PEI_STALL_PPI *StallPpi, + UINT8 *Data + ); +/** + Receives data from Keyboard System Controller. + + @param[in] PeiServices - PEI Services + @param[in] CpiIo - Pointer to CPU IO protocol + @param[in] StallPpi - Pointer to Stall PPI + @param[in] Data - Data byte received + + @retval EFI_SUCCESS - Read success + @retval EFI_DEVICE_ERROR - Read error + @retval EFI_TIMEOUT - Command timeout +**/ + +EFI_STATUS +ReceiveKscStatus ( + EFI_PEI_SERVICES **PeiServices, + PEI_CPU_IO_PPI *CpuIo, + UINT8 *KscStatus + ); +/** + Receives status from Keyboard System Controller. + + @param[in] PeiServices - PEI Services + @param[in] CpiIo - Pointer to CPU IO protocol + @param[in] KscStatus - Status byte to receive + + @retval EFI_DEVICE_ERROR - Ksc library has not initialized yet or KSC not present + @retval EFI_SUCCESS - Get KSC status successfully +**/ + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Include/SmmIoLib.h b/ReferenceCode/Haswell/SampleCode/Include/SmmIoLib.h new file mode 100644 index 0000000..cc9eee9 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/SmmIoLib.h @@ -0,0 +1,265 @@ +/** @file + This library provides SMM functions for IO and PCI IO access. + These can be used to save size and simplify code. + All contents must be runtime and SMM safe. + +@copyright + Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _SMM_IO_LIB_H_ +#define _SMM_IO_LIB_H_ + +#include "EdkIIGlueDxe.h" +#include "Pci22.h" + +/// +/// Utility consumed protocols +/// +#include EFI_PROTOCOL_DEFINITION (SmmBase) + +/// +/// Global variables that must be defined and initialized to use this library +/// +extern EFI_SMM_SYSTEM_TABLE *mSmst; + +/// +/// Definitions +/// +#define ICH_ACPI_TIMER_MAX_VALUE 0x1000000 ///< The timer is 24 bit overflow +/// +/// Pci I/O related data structure deifinition +/// +typedef enum { + SmmPciWidthUint8 = 0, + SmmPciWidthUint16 = 1, + SmmPciWidthUint32 = 2, + SmmPciWidthUint64 = 3, + SmmPciWidthMaximum +} SMM_PCI_IO_WIDTH; + +#define SMM_PCI_ADDRESS(bus, dev, func, reg) \ + ((UINT64) ((((UINT32) bus) << 24) + (((UINT32) dev) << 16) + (((UINT32) func) << 8) + ((UINT32) reg))) + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT32 ExtendedRegister; +} SMM_PCI_IO_ADDRESS; + +/// +/// CPU I/O Access Functions +/// +/** + Do a one byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT8 +SmmIoRead8 ( + IN UINT16 Address + ); + +/** + Do a one byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite8 ( + IN UINT16 Address, + IN UINT8 Data + ); + +/** + Do a two byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT16 +SmmIoRead16 ( + IN UINT16 Address + ); + +/** + Do a two byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite16 ( + IN UINT16 Address, + IN UINT16 Data + ); + +/** + Do a four byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT32 +SmmIoRead32 ( + IN UINT16 Address + ); + +/** + Do a four byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite32 ( + IN UINT16 Address, + IN UINT32 Data + ); + +/** + Do a one byte Memory write + + @param[in] Dest - Memory address to write + @param[in] Data - Data to write + + @retval None +**/ +VOID +SmmMemWrite8 ( + IN UINT64 Dest, + IN UINT8 Data + ); + +/** + Do a one byte Memory read + + @param[in] Dest - Memory address to read + + @retval Data read +**/ +UINT8 +SmmMemRead8 ( + IN UINT64 Dest + ); + +/** + Do a two bytes Memory write + + @param[in] Dest - Memory address to write + @param[in] Data - Data to write + + @retval None +**/ +VOID +SmmMemWrite16 ( + IN UINT64 Dest, + IN UINT16 Data + ); + +/** + Do a two bytes Memory read + + @param[in] Dest - Memory address to read + + @retval Data read +**/ +UINT16 +SmmMemRead16 ( + IN UINT64 Dest + ); + +/** + Do a four bytes Memory write + + @param[in] Dest - Memory address to write + @param[in] Data - Data to write + + @retval None +**/ +VOID +SmmMemWrite32 ( + IN UINT64 Dest, + IN UINT32 Data + ); + +/** + Do a four bytes Memory read + + @param[in] Dest - Memory address to read + + @retval Data read +**/ +UINT32 +SmmMemRead32 ( + IN UINT64 Dest + ); + +/** + Do a four bytes Memory read, then AND with Data, then write back to the same address + + @param[in] Dest - Memory address to write + @param[in] Data - Data to do AND + + @retval None +**/ +VOID +SmmMemAnd32 ( + IN UINT64 Dest, + IN UINT32 Data + ); +/// +/// Pci Configuration Space access functions definition +/// +/** + Read value from the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgRead ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); +/** + Write value into the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgWrite ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Include/acpibuild.dsc b/ReferenceCode/Haswell/SampleCode/Include/acpibuild.dsc new file mode 100644 index 0000000..cc3fb3d --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Include/acpibuild.dsc @@ -0,0 +1,96 @@ +## @file +# Build description file for building ASL and ACT file types used in ACPI tables +# You should not put platform details, like how to build DSDT, SSDT, or how to +# package the ACPI tables into a data file in this build. This should be platform +# neutral code only. +# +#@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 +# + +[=============================================================================] +[Compile.Ia32.act,Compile.x64.act] +# +# Instructions to create ACPI table sections out of ACPI table C source files. +# + +#/*++ +# +# If it already exists, then include the dependency list file for this +# source file. If it doesn't exist, then this is a clean build and the +# dependency file will get created below and the source file will get +# compiled. Don't do any of this if NO_MAKEDEPS is defined. +# +#--*/ +!IF ("$(NO_MAKEDEPS)" == "") + +!IF EXIST($(DEST_DIR)\$(FILE).dep) +!INCLUDE $(DEST_DIR)\$(FILE).dep +!ENDIF + +# +# This is how to create the dependency file. +# +DEP_FILE = $(DEST_DIR)\$(FILE).dep + +$(DEP_FILE) : $(SOURCE_FILE_NAME) + $(MAKEDEPS) -ignorenotfound -f $(SOURCE_FILE_NAME) -q -target \ + $(DEST_DIR)\$(FILE).obj \ + -o $(DEP_FILE) $(INC) + +!ENDIF + +# +# Compile the file +# +$(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INC_DEPS) $(DEP_FILE) + $(CC) $(C_FLAGS) /TC $(SOURCE_FILE_NAME) + +# +# Link it +# +$(DEST_DIR)\$(FILE).exe : $(DEST_DIR)\$(FILE).obj + $(LINK) $(LINK_FLAGS_EXE) $(DEST_DIR)\$(FILE).obj /OUT:$(DEST_DIR)\$(FILE).exe /ENTRY:main + +# +# Strip out the ACPI table +# +$(DEST_DIR)\$(FILE).acpi : $(DEST_DIR)\$(FILE).exe + $(GENACPITABLE) $(DEST_DIR)\$(FILE).exe $(DEST_DIR)\$(FILE).acpi + +# +# Create a section from the ACPI table +# +$(DEST_DIR)\$(FILE).sec : $(DEST_DIR)\$(FILE).acpi + $(GENSECTION) -I $(DEST_DIR)\$(FILE).acpi -O $(DEST_DIR)\$(FILE).sec -S EFI_SECTION_RAW + +# +# Add it to the targets to build +# +SECTIONS = $(SECTIONS) $(DEST_DIR)\$(FILE).sec + +[=============================================================================] +[Compile.Ia32.asl,Compile.x64.asl] +# +# We run the ASL through the C Preprocessor to resolve definitions. +# +$(DEST_DIR)\$(FILE).asl : $(SOURCE_FILE_NAME) + $(CC) $(ASL_CPP_FLAGS) /nologo /C /EP /TC $(INC) -oa $(SOURCE_FILE_NAME) > $(DEST_DIR)\$(FILE).asl + +# +# Add it to the targets to build +# +ASL_FILES = $(ASL_FILES) $(DEST_DIR)\$(FILE).asl + diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c new file mode 100644 index 0000000..8adbe64 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.c @@ -0,0 +1,333 @@ +/** @file + Boot service DXE ASL update library implementation. + + These functions in this file can be called during DXE and cannot be called during runtime + or in SMM which should use a RT or SMM library. + + This library uses the ACPI Support protocol. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "AslUpdateLib.h" +#endif +/// +/// Function implemenations +/// +static EFI_ACPI_SUPPORT_PROTOCOL *mAcpiSupport = NULL; +static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL; + +/** + Initialize the ASL update library state. + This must be called prior to invoking other library functions. + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +InitializeAslUpdateLib ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Locate ACPI tables + /// + Status = gBS->LocateProtocol (&gEfiAcpiSupportGuid, NULL, (VOID **) &mAcpiSupport); + ASSERT_EFI_ERROR (Status); + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable); + return EFI_SUCCESS; +} + +/** + This procedure will update two kinds of asl code. + 1: Operating Region base address and length. + 2: Resource Consumption structures in device LDRC. + + @param[in] AslSignature - The signature of Operation Region that we want to update. + @param[in] BaseAddress - Base address of IO trap. + @param[in] Length - Length of IO address. + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +UpdateAslCode ( + IN UINT32 AslSignature, + IN UINT16 BaseAddress, + IN UINT8 Length + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_TABLE_VERSION Version; + UINT8 *CurrPtr; + UINT8 *Operation; + UINT32 *Signature; + UINT8 *DsdtPointer; + INTN Index; + UINTN Handle; + UINT16 AslLength; + + /// + /// Locate table with matching ID + /// + Index = 0; + AslLength = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) &Table, &Version, &Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while (Table->Signature != EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE); + + /// + /// Fix up the following ASL Code in DSDT: + /// (1) OperationRegion's IO Base Address and Length. + /// (2) Resource Consumption in LPC Device. + /// + CurrPtr = (UINT8 *) Table; + + /// + /// Loop through the ASL looking for values that we must fix up. + /// + for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) { + /// + /// Get a pointer to compare for signature + /// + Signature = (UINT32 *) DsdtPointer; + + /// + /// Check if this is the signature we are looking for + /// + if ((*Signature) == AslSignature) { + /// + /// Conditional match. For Region Objects, the Operator will always be the + /// byte immediately before the specific name. Therefore, subtract 1 to check + /// the Operator. + /// + Operation = DsdtPointer - 1; + + /// + /// If we have an operation region, update the base address and length + /// + if (*Operation == AML_OPREGION_OP) { + /// + /// Fixup the Base Address in OperationRegion. + /// + *(UINT16 *) (DsdtPointer + 6) = BaseAddress; + + /// + /// Fixup the Length in OperationRegion. + /// + *(DsdtPointer + 9) = Length; + } + + } else if ((*Signature) == EFI_SIGNATURE_32 ('L', 'D', 'R', 'C')) { + /// + /// Make sure it's device of LDRC and read the length + /// + if (*(DsdtPointer - 2) == AML_DEVICE_OP) { + AslLength = *(DsdtPointer - 1); + } else if (*(DsdtPointer - 3) == AML_DEVICE_OP) { + AslLength = *(UINT16 *) (DsdtPointer - 2); + AslLength = (AslLength & 0x0F) + ((AslLength & 0x0FF00) >> 4); + } + /// + /// Conditional match. Search _CSR in Device (LDRC). + /// + for (Operation = DsdtPointer; Operation <= DsdtPointer + AslLength; Operation++) { + /// + /// Get a pointer to compare for signature + /// + Signature = (UINT32 *) Operation; + + /// + /// Check if this is the signature we are looking for + /// + if ((*Signature) == EFI_SIGNATURE_32 ('_', 'C', 'R', 'S')) { + /// + /// Now look for an empty resource entry, fix the base address and length fields + /// + for (Index = 0; *(UINT16 *) (Operation + 9 + 8 * Index) != 0x0079; Index++) { + if (*(UINT16 *) (Operation + 11 + 8 * Index) == UINT16_BIT_MAGIC_NUMBER) { + /// + /// Fixup the Base Address and Length. + /// + *(UINT16 *) (Operation + 11 + 8 * Index) = BaseAddress; + *(UINT16 *) (Operation + 13 + 8 * Index) = BaseAddress; + *(Operation + 16 + 8 * Index) = Length; + + break; + } + } + } + } + + DsdtPointer = DsdtPointer + AslLength; + } + } + /// + /// Update the modified ACPI table + /// + Status = mAcpiTable->InstallAcpiTable ( + mAcpiTable, + Table, + Table->Length, + &Handle + ); + FreePool (Table); + + return EFI_SUCCESS; +} + +/** + This function uses the ACPI support protocol to locate an ACPI table. + It is really only useful for finding tables that only have a single instance, + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc. + + @param[in] Signature - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] Table - Updated with a pointer to the table + @param[in] Handle - AcpiSupport protocol table handle for the table found + @param[in] Version - The version of the table desired + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableBySignature ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + INTN Index; + EFI_ACPI_TABLE_VERSION DesiredVersion; + + DesiredVersion = *Version; + /// + /// Locate table with matching ID + /// + Index = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) Table, Version, Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while ((*Table)->Signature != Signature || !(*Version & DesiredVersion)); + + /// + /// If we found the table, there will be no error. + /// + return Status; +} + +/** + This function uses the ACPI support protocol to locate an ACPI SSDT table. + + @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header + @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function + will consider it a match if the first TableIdSize bytes match + @param[in] Table - Updated with a pointer to the table + @param[in] Handle - AcpiSupport protocol table handle for the table found + @param[in] Version - See AcpiSupport protocol, GetAcpiTable function for use + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +LocateAcpiTableByOemTableId ( + IN UINT8 *TableId, + IN UINT8 TableIdSize, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + INTN Index; + + /// + /// Locate table with matching ID + /// + Index = 0; + do { + Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) Table, Version, Handle); + if (Status == EFI_NOT_FOUND) { + break; + } + + ASSERT_EFI_ERROR (Status); + Index++; + } while (CompareMem (&(*Table)->OemTableId, TableId, TableIdSize)); + + /// + /// If we found the table, there will be no error. + /// + return Status; +} + +/** + This function calculates and updates an UINT8 checksum. + + @param[in] Buffer Pointer to buffer to checksum + @param[in] Size Number of bytes to checksum + @param[in] ChecksumOffset Offset to place the checksum result in + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +AcpiChecksum ( + IN VOID *Buffer, + IN UINTN Size, + IN UINTN ChecksumOffset + ) +{ + UINT8 Sum; + UINT8 *Ptr; + + Sum = 0; + /// + /// Initialize pointer + /// + Ptr = Buffer; + + /// + /// set checksum to 0 first + /// + Ptr[ChecksumOffset] = 0; + + /// + /// add all content of buffer + /// + while (Size--) { + Sum = (UINT8) (Sum + (*Ptr++)); + } + /// + /// set checksum + /// + Ptr = Buffer; + Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1); + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.inf b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.inf new file mode 100644 index 0000000..138e053 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/DxeAslUpdateLib.inf @@ -0,0 +1,46 @@ +## @file +# Component description file. +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + +[defines] +BASE_NAME = DxeAslUpdateLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + DxeAslUpdateLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.cif b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.cif new file mode 100644 index 0000000..5cfa2b1 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.cif @@ -0,0 +1,11 @@ +<component> + name = "PpmAslUpdateLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\AslUpdate\Dxe" + RefName = "PpmAslUpdateLib" +[files] +"PpmAslUpdateLib.sdl" +"PpmAslUpdateLib.mak" +"DxeAslUpdateLib.c" +"DxeAslUpdateLib.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.mak b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.mak new file mode 100644 index 0000000..adcce28 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : PpmAslUpdateLib + +$(BUILD_DIR)\PpmAslUpdateLib.lib : PpmAslUpdateLib + +PpmAslUpdateLib : $(BUILD_DIR)\PpmAslUpdateLib.mak PpmAslUpdateLibBin + +$(BUILD_DIR)\PpmAslUpdateLib.mak : $(PpmAslUpdateLib_DIR)\$(@B).cif $(PpmAslUpdateLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PpmAslUpdateLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PpmAslUpdateLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +PpmAslUpdateLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +PpmAslUpdateLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +PpmAslUpdateLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PpmAslUpdateLib.mak all \ + "MY_INCLUDES=$(PpmAslUpdateLib_INCLUDES)"\ + "MY_DEFINES=$(PpmAslUpdateLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.sdl new file mode 100644 index 0000000..0a74ab2 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/AslUpdate/Dxe/PpmAslUpdateLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = PpmAslUpdateLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable AslUpdateLib support in Project" +End + +MODULE + Help = "Includes PpmAslUpdateLib.mak to Project" + File = "PpmAslUpdateLib.mak" +End + +PATH + Name = "PpmAslUpdateLib_DIR" +End + +ELINK + Name = "PpmAslUpdateLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PpmAslUpdateLib.lib" + Parent = "PpmAslUpdateLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.c b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.c new file mode 100644 index 0000000..2a3ff51 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.c @@ -0,0 +1,34 @@ +/** @file + This file is SampleCode for Boot Guard revocation notification. + +@copyright + Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ + +#include "BootGuardRevocationLib.h" + +/** + Provide a hook for OEM to deal with Boot Guard revocation flow. +**/ +VOID +EFIAPI +BootGuardOemRevocationHook ( + VOID + ) +{ + + return; +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.cif b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.cif new file mode 100644 index 0000000..fdad18a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.cif @@ -0,0 +1,11 @@ +<component> + name = "BootGuardRevocationLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\BootGuardRevocationLib\Dxe" + RefName = "BootGuardRevocationLib" +[files] +"BootGuardRevocationLib.sdl" +"BootGuardRevocationLib.mak" +"BootGuardRevocationLib.c" +"BootGuardRevocationLib.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.inf b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.inf new file mode 100644 index 0000000..295dcf6 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.inf @@ -0,0 +1,73 @@ +## @file +# Provides services to display Boot Guard revocation notification. +# +#@copyright +# Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + +[defines] +BASE_NAME = BootGuardRevocationLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + BootGuardRevocationLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +# +# Edk II Glue Library, some hearder are included by R9 header so have to include +# + + $(EFI_SOURCE) + $(EFI_SOURCE)/Framework + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueBaseMemoryLib + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiLib + EdkFrameworkProtocolLib + +[nmake.common] + + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_LIB__
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.mak b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.mak new file mode 100644 index 0000000..2d3c433 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : BootGuardRevocationLib + +$(BUILD_DIR)\BootGuardRevocationLib.lib : BootGuardRevocationLib + +BootGuardRevocationLib : $(BUILD_DIR)\BootGuardRevocationLib.mak BootGuardRevocationLibBin + +$(BUILD_DIR)\BootGuardRevocationLib.mak : $(BootGuardRevocationLib_DIR)\$(@B).cif $(BootGuardRevocationLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(BootGuardRevocationLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +BootGuardRevocationLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +BootGuardRevocationLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +BootGuardRevocationLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +BootGuardRevocationLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\BootGuardRevocationLib.mak all \ + "MY_INCLUDES=$(BootGuardRevocationLib_INCLUDES)"\ + "MY_DEFINES=$(BootGuardRevocationLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.sdl new file mode 100644 index 0000000..b7405cf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardRevocationLib/Dxe/BootGuardRevocationLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = BootGuardRevocationLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable BootGuardRevocationLib support in Project" +End + +MODULE + Help = "Includes BootGuardRevocationLib.mak to Project" + File = "BootGuardRevocationLib.mak" +End + +PATH + Name = "BootGuardRevocationLib_DIR" +End + +ELINK + Name = "BootGuardRevocationLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\BootGuardRevocationLib.lib" + Parent = "BootGuardRevocationLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c new file mode 100644 index 0000000..ffb8480 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c @@ -0,0 +1,838 @@ +/** @file + This file is SampleCode for Boot Guard TPM event log. + +@copyright + Copyright (c) 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#include "EdkIIGluePeim.h" +#include "CpuAccess.h" +#endif + +#include <EfiTpm.h> +#include "BootGuardTpmEventLogLib.h" + +// +// Data structure definition +// +#pragma pack (1) + +#define BASE_4GB 0x0000000100000000ULL +// +// FIT definition +// +#define FIT_TABLE_TYPE_HEADER 0x0 +#define FIT_TABLE_TYPE_MICROCODE 0x1 +#define FIT_TABLE_TYPE_STARTUP_ACM 0x2 +#define FIT_TABLE_TYPE_BIOS_MODULE 0x7 +#define FIT_TABLE_TYPE_KEY_MANIFEST 0xB +#define FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST 0xC + +typedef struct { + UINT64 Address; + UINT8 Size[3]; + UINT8 Reserved; + UINT16 Version; + UINT8 Type : 7; + UINT8 Cv : 1; + UINT8 Chksum; +} FIRMWARE_INTERFACE_TABLE_ENTRY; + +// +// ACM definition +// +#define MMIO_ACM_STATUS (TXT_PUBLIC_BASE + R_CPU_BOOT_GUARD_ACM_STATUS) +#define ACM_KEY_HASH_MMIO_ADDR_0 0xFED30400 +#define ACM_KEY_HASH_MMIO_ADDR_1 (ACM_KEY_HASH_MMIO_ADDR_0 + 8) +#define ACM_KEY_HASH_MMIO_ADDR_2 (ACM_KEY_HASH_MMIO_ADDR_0 + 16) +#define ACM_KEY_HASH_MMIO_ADDR_3 (ACM_KEY_HASH_MMIO_ADDR_0 + 24) +#define ACM_PKCS_1_5_RSA_SIGNATURE_SIZE 256 +#define ACM_HEADER_FLAG_DEBUG_SIGNED BIT15 +#define ACM_NPW_SVN 0x2 + +typedef struct { + UINT32 ModuleType; + UINT32 HeaderLen; + UINT32 HeaderVersion; + UINT16 ChipsetId; + UINT16 Flags; + UINT32 ModuleVendor; + UINT32 Date; + UINT32 Size; + UINT16 AcmSvn; + UINT16 Reserved1; + UINT32 CodeControl; + UINT32 ErrorEntryPoint; + UINT32 GdtLimit; + UINT32 GdtBasePtr; + UINT32 SegSel; + UINT32 EntryPoint; + UINT8 Reserved2[64]; + UINT32 KeySize; + UINT32 ScratchSize; + UINT8 RsaPubKey[64 * 4]; + UINT32 RsaPubExp; + UINT8 RsaSig[256]; +} ACM_FORMAT; + +// +// Manifest definition +// +#define SHA256_DIGEST_SIZE 32 + +typedef struct { + UINT16 HashAlg; + UINT16 Size; + UINT8 HashBuffer[SHA256_DIGEST_SIZE]; +} HASH_STRUCTURE; + +#define RSA_PUBLIC_KEY_STRUCT_KEY_SIZE_DEFAULT 2048 +#define RSA_PUBLIC_KEY_STRUCT_KEY_LEN_DEFAULT (RSA_PUBLIC_KEY_STRUCT_KEY_SIZE_DEFAULT/8) + +typedef struct { + UINT8 Version; + UINT16 KeySize; + UINT32 Exponent; + UINT8 Modulus[RSA_PUBLIC_KEY_STRUCT_KEY_LEN_DEFAULT]; +} RSA_PUBLIC_KEY_STRUCT; + +#define RSASSA_SIGNATURE_STRUCT_KEY_SIZE_DEFAULT 2048 +#define RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT (RSASSA_SIGNATURE_STRUCT_KEY_SIZE_DEFAULT/8) +typedef struct { + UINT8 Version; + UINT16 KeySize; + UINT16 HashAlg; + UINT8 Signature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; +} RSASSA_SIGNATURE_STRUCT; + +typedef struct { + UINT8 Version; + UINT16 KeyAlg; + RSA_PUBLIC_KEY_STRUCT Key; + UINT16 SigScheme; + RSASSA_SIGNATURE_STRUCT Signature; +} KEY_SIGNATURE_STRUCT; + +#define BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID (*(UINT64 *)"__ACBP__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 HdrStructVersion; + UINT8 PMBPMVersion; + UINT8 BPSVN; + UINT8 ACMSVN; + UINT8 Reserved; + UINT16 NEMDataStack; +} BOOT_POLICY_MANIFEST_HEADER; + +#define IBB_SEGMENT_FLAG_IBB 0x0 +#define IBB_SEGMENT_FLAG_NON_IBB 0x1 +typedef struct { + UINT8 Reserved[2]; + UINT16 Flags; + UINT32 Base; + UINT32 Size; +} IBB_SEGMENT_ELEMENT; + +#define BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__IBBS__") +#define IBB_FLAG_AUTHORITY_MEASURE 0x4 + +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 Reserved1[2]; + UINT8 PbetValue; + UINT32 Flags; + UINT64 IbbMchBar; + UINT64 VtdBar; + UINT32 PmrlBase; + UINT32 PmrlLimit; + UINT64 Reserved2[2]; + HASH_STRUCTURE PostIbbHash; + UINT32 EntryPoint; + HASH_STRUCTURE Digest; + UINT8 SegmentCount; + IBB_SEGMENT_ELEMENT IbbSegment[1]; +} IBB_ELEMENT; + +#define BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__PMDA__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT16 PmDataSize; +} PLATFORM_MANUFACTURER_ELEMENT; + +#define BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__PMSG__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + KEY_SIGNATURE_STRUCT KeySignature; +} BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT; + +#define KEY_MANIFEST_STRUCTURE_ID (*(UINT64 *)"__KEYM__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 KeyManifestVersion; + UINT8 KmSvn; + UINT8 KeyManifestId; + HASH_STRUCTURE BpKey; + KEY_SIGNATURE_STRUCT KeyManifestSignature; +} KEY_MANIFEST_STRAUCTURE; + +// +// DetailPCR data +// +typedef struct { + UINT8 BpRstrLow; + UINT8 BpTypeLow; + UINT16 AcmSvn; + UINT8 AcmRsaSignature[ACM_PKCS_1_5_RSA_SIGNATURE_SIZE]; + UINT8 KmRsaSignature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; + UINT8 BpmRsaSignature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; + UINT8 IbbHash[SHA256_DIGEST_SIZE]; +} DETAIL_PCR_DATA; + +// +// AuthorityPCR data +// +typedef struct { + UINT8 BpRstrLow; + UINT8 BpTypeLow; + UINT16 AcmSvn; + UINT8 AcmKeyHash[SHA256_DIGEST_SIZE]; + UINT8 BpKeyHash[SHA256_DIGEST_SIZE]; + UINT8 BpmKeyHashFromKm[SHA256_DIGEST_SIZE]; + UINT8 VerifiedBoot; +} AUTHORITY_PCR_DATA; + +// +// Boot Policy Restrictions definition +// +typedef union { + struct { + UINT8 Facb : 1; + UINT8 Dcd : 1; + UINT8 Dbi : 1; + UINT8 Pbe : 1; + UINT8 Bbp : 1; + UINT8 Reserved : 2; + UINT8 BpInvd : 1; + } Bits; + UINT8 Data; +} BP_RSTR_LOW; + +// +// Boot Policy Type definition +// +typedef union { + struct { + UINT8 MeasuredBoot : 1; + UINT8 VerifiedBoot : 1; + UINT8 Hap : 1; + UINT8 Reserved : 5; + } Bits; + UINT8 Data; +} BP_TYPE_LOW; + +#pragma pack () + +// +// OEM_IMPLEMENTATION_BEGIN +// +// SHA calculation and TPM functions are OEM Core/Platform code depended, +// OEM can customize these empty functions for their specific. +// +// For the detail of SHA algorithm, please refer to FIPS PUB 180-2. +// For TPM event log, please refer to TCG EFI Protocol Specification. +// + +// +// Null-defined macro for passing EDK build +// +#define SHA_INIT +#define SHA_UPDATE +#define SHA_FINAL + +/** + Calculate SHA-1 Hash + + @param[in] Data Data to be hashed. + @param[in] Size Size of data. + @param[out] Digest SHA-1 digest value. +**/ +VOID +CreateSha1Hash ( + IN UINT8 *Data, + IN UINTN Size, + OUT UINT8 *Digest + ) +{ + VOID *Context; + + SHA_INIT (Context); + SHA_UPDATE (Context, Data, Size); + SHA_FINAL (Context, Digest); + + return; +} + +/** + Calculate SHA256 Hash + + @param[in] Data Data to be hashed. + @param[in] Size Size of data. + @param[out] Digest SHA256 digest value. +**/ +VOID +CreateSha256Hash ( + IN UINT8 *Data, + IN UINTN Size, + OUT UINT8 *Digest + ) +{ + VOID *Context; + + SHA_INIT (Context); + SHA_UPDATE (Context, Data, Size); + SHA_FINAL (Context, Digest); + + return; +} + +/** + Add a new entry to the Event Log. + + @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. + @param[in] NewEventData Pointer to the new event data. + + @retval EFI_SUCCESS The new event log entry was added. + @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. +**/ +EFI_STATUS +LogEvent ( + IN TCG_PCR_EVENT_HDR *NewEventHdr, + IN UINT8 *NewEventData + ) +{ + + return EFI_SUCCESS; +} +// +// OEM_IMPLEMENTATION_END +// + +/** + Find FIT Entry address data by type + + @param[in] Type FIT Entry type + + @return FIT entry address +**/ +VOID * +FindFitEntryData ( + IN UINT8 Type + ) +{ + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry; + UINT32 EntryNum; + UINT64 FitTableOffset; + UINT32 Index; + + FitTableOffset = *(UINT64 *)(UINTN)(BASE_4GB - 0x40); + FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *)(UINTN)FitTableOffset; + if (FitEntry[0].Address != *(UINT64 *)"_FIT_ ") { + return NULL; + } + if (FitEntry[0].Type != FIT_TABLE_TYPE_HEADER) { + return NULL; + } + EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; + for (Index = 0; Index < EntryNum; Index++) { + if (FitEntry[Index].Type == Type) { + return (VOID *)(UINTN)FitEntry[Index].Address; + } + } + + return NULL; +} + +/** + Find the address of ACM. + + @return A pointer to ACM. +**/ +VOID * +FindAcm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_STARTUP_ACM); +} + +/** + Find the address of Boot Policy Manifest. + + @return A pointer to Key Manifest data structure. +**/ +VOID * +FindBpm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST); +} + +/** + Find the address of Key Manifest. + + @return A pointer to Key Manifest data structure. +**/ +VOID * +FindKm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_KEY_MANIFEST); +} + +/** + Find BPM element by structureID + + @param[in] Bpm A pointer to BPM data structure. + @param[in] StructureId BPM element StructureID + + @return A pointer to BPM element data structure. +**/ +VOID * +FindBpmElement ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm, + IN UINT64 StructureId + ) +{ + BOOT_POLICY_MANIFEST_HEADER *BpmHeader; + IBB_ELEMENT *IbbElement; + PLATFORM_MANUFACTURER_ELEMENT *PmElement; + BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *BpmSignatureElement; + UINT8 *Buffer; + + Buffer = (UINT8 *)Bpm; + + BpmHeader = (BOOT_POLICY_MANIFEST_HEADER *)Buffer; + if (*(UINT64 *)BpmHeader->StructureId != BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(BOOT_POLICY_MANIFEST_HEADER); + + IbbElement = (IBB_ELEMENT *)Buffer; + if (*(UINT64 *)IbbElement->StructureId != BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(IBB_ELEMENT) + sizeof(IBB_SEGMENT_ELEMENT) * (IbbElement->SegmentCount - 1); + + PmElement = (PLATFORM_MANUFACTURER_ELEMENT *)Buffer; + while (*(UINT64 *)PmElement->StructureId == BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID) { + if (StructureId == BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(PLATFORM_MANUFACTURER_ELEMENT) + PmElement->PmDataSize; + PmElement = (PLATFORM_MANUFACTURER_ELEMENT *)Buffer; + } + + BpmSignatureElement = (BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *)Buffer; + if (*(UINT64 *)BpmSignatureElement->StructureId != BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + return NULL; +} + +/** + Find BPM IBB element + + @param[in] Bpm A pointer to BPM data structure. + + @return A pointer to BPM IBB element data structure. +**/ +VOID * +FindBpmIbb ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm + ) +{ + return FindBpmElement (Bpm, BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID); +} + +/** + Find BPM Signature element + + @param[in] Bpm BPM address + + @return BPM Signature element +**/ +VOID * +FindBpmSignature ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm + ) +{ + return FindBpmElement (Bpm, BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID); +} + +/** + Check if ACM is a NPW ACM. + + @retval TRUE It is a NPW ACM + @retval FALSE It is NOT a NPW ACM +**/ +BOOLEAN +IsNpwAcm ( + VOID + ) +{ + ACM_FORMAT *Acm; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + if (Acm == NULL) { + return FALSE; + } + + if (((Acm->Flags & ACM_HEADER_FLAG_DEBUG_SIGNED) == 0) && (Acm->AcmSvn < ACM_NPW_SVN)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Check if Boot Guard verifies the IBB. + + @retval TRUE It is VerifiedBoot + @retval FALSE It is NOT VerifiedBoot +**/ +BOOLEAN +IsVerifiedBoot ( + VOID + ) +{ + if ((AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & B_VERIFIED) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Check if Boot Guard measures IBB into TPM's PCRs. + + @retval TRUE It is MeasuredBoot + @retval FALSE It is NOT MeasuredBoot +**/ +BOOLEAN +IsMeasuredBoot ( + VOID + ) +{ + if ((AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & B_MEASURED) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Get the lower 8 bits of Boot Policy Restrictions + + @return The lower 8 bits of BP.RSTR +**/ +UINT8 +GetBpRstrLow ( + VOID + ) +{ + BP_RSTR_LOW BpRstr; + UINT32 AcmStatus; + UINT64 SacmInfo; + + AcmStatus = MmioRead32 (MMIO_ACM_STATUS); + SacmInfo = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO); + + BpRstr.Bits.Facb = (UINT8)((SacmInfo & BIT4) >> 4); + BpRstr.Bits.Dcd = (UINT8)((AcmStatus & BIT21) >> 21); + BpRstr.Bits.Dbi = (UINT8)((AcmStatus & BIT22) >> 22); + BpRstr.Bits.Pbe = (UINT8)((AcmStatus & BIT23) >> 23); + BpRstr.Bits.Bbp = (UINT8)((AcmStatus & BIT24) >> 24); + BpRstr.Bits.Reserved = 0; + BpRstr.Bits.BpInvd = 0; + + return BpRstr.Data; +} + +/** + Get the lower 8 bits of Boot Policy Type + + @return The lower 8 bits of BP.TYPE +**/ +UINT8 +GetBpTypeLow ( + VOID + ) +{ + BP_TYPE_LOW BpType; + UINT32 AcmStatus; + UINT64 SacmInfo; + + AcmStatus = MmioRead32 (MMIO_ACM_STATUS); + SacmInfo = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO); + + BpType.Bits.MeasuredBoot = (UINT8)((SacmInfo & BIT5) >> 5); + BpType.Bits.VerifiedBoot = (UINT8)((SacmInfo & BIT6) >> 6); + BpType.Bits.Hap = (UINT8)((AcmStatus & BIT20) >> 20); + BpType.Bits.Reserved = 0; + + return BpType.Data; +} + +/** + Calculate IBB Hash + + @param[in] BpmIbb A pointer to BPM IBB element data structure. + @param[out] Digest IBB digest value. +**/ +VOID +CreateIbbHash ( + IN IBB_ELEMENT *BpmIbb, + OUT UINT8 *Digest + ) +{ + VOID *Context; + UINTN Index; + + SHA_INIT (Context); + + for (Index = 0; Index < BpmIbb->SegmentCount; Index++) { + if (BpmIbb->IbbSegment[Index].Flags == IBB_SEGMENT_FLAG_IBB) { + SHA_UPDATE (Context, (VOID *)(UINTN)BpmIbb->IbbSegment[Index].Base, BpmIbb->IbbSegment[Index].Size); + } + } + + SHA_FINAL (Context, Digest); + + return; +} + +/** + Calculate DetailPCR extend value + + @param[out] Digest DetailPCR digest +**/ +VOID +CaculateDetailPCRExtendValue ( + OUT TCG_DIGEST *Digest + ) +{ + ACM_FORMAT *Acm; + KEY_MANIFEST_STRAUCTURE *Km; + BOOT_POLICY_MANIFEST_HEADER *Bpm; + IBB_ELEMENT *BpmIbb; + BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *BpmSignature; + DETAIL_PCR_DATA DetailPcrData; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + + Km = FindKm (); + ASSERT (Km != NULL); + + Bpm = FindBpm (); + ASSERT (Bpm != NULL); + + BpmIbb = FindBpmIbb (Bpm); + ASSERT (BpmIbb != NULL); + + BpmSignature = FindBpmSignature (Bpm); + ASSERT (BpmSignature != NULL); + + DetailPcrData.BpRstrLow = GetBpRstrLow (); + DetailPcrData.BpTypeLow = GetBpTypeLow (); + DetailPcrData.AcmSvn = Acm->AcmSvn; + CopyMem (&DetailPcrData.AcmRsaSignature, &Acm->RsaSig, sizeof(DetailPcrData.AcmRsaSignature)); + CopyMem (&DetailPcrData.KmRsaSignature, &Km->KeyManifestSignature.Signature.Signature, sizeof(DetailPcrData.KmRsaSignature)); + CopyMem (&DetailPcrData.BpmRsaSignature, &BpmSignature->KeySignature.Signature.Signature, sizeof(DetailPcrData.BpmRsaSignature)); + if (IsVerifiedBoot ()) { + CopyMem (&DetailPcrData.IbbHash, &BpmIbb->Digest.HashBuffer, sizeof(DetailPcrData.IbbHash)); + } else { + // + // Calculate IBB hash because it is NOT verified boot, the Digest from IBB can not be trust. + // + CreateIbbHash (BpmIbb, (UINT8 *)&DetailPcrData.IbbHash); + } + + CreateSha1Hash ((UINT8 *)&DetailPcrData, sizeof(DetailPcrData), (UINT8 *)Digest); +} + +/** + Calculate AuthorityPCR extend value + + @param[out] Digest AuthorityPCR digest +**/ +VOID +CaculateAuthorityPCRExtendValue ( + OUT TCG_DIGEST *Digest + ) +{ + ACM_FORMAT *Acm; + KEY_MANIFEST_STRAUCTURE *Km; + AUTHORITY_PCR_DATA AuthorityPcrData; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + + Km = FindKm (); + ASSERT (Km != NULL); + + AuthorityPcrData.BpRstrLow = GetBpRstrLow (); + AuthorityPcrData.BpTypeLow = GetBpTypeLow (); + AuthorityPcrData.AcmSvn = Acm->AcmSvn; + + // + // Get ACM Key hash + // + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[0] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_0); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[8] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_1); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[16] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_2); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[24] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_3); + + // + // Calculate BP Key hash + // + CreateSha256Hash ((UINT8 *)&Km->KeyManifestSignature.Key.Modulus, sizeof(Km->KeyManifestSignature.Key.Modulus), (UINT8 *)&AuthorityPcrData.BpKeyHash); + + CopyMem (&AuthorityPcrData.BpmKeyHashFromKm, &Km->BpKey.HashBuffer, sizeof(AuthorityPcrData.BpmKeyHashFromKm)); + if (IsVerifiedBoot ()) { + AuthorityPcrData.VerifiedBoot = 0; + } else { + AuthorityPcrData.VerifiedBoot = 1; + } + + CreateSha1Hash ((UINT8 *)&AuthorityPcrData, sizeof(AuthorityPcrData), (UINT8 *)Digest); +} + +/** + Check if we need AuthorityPCR measurement + + @retval TRUE Need AuthorityPCR measurement + @retval FALSE Do NOT need AuthorityPCR measurement +**/ +BOOLEAN +NeedAuthorityMeasure ( + VOID + ) +{ + BOOT_POLICY_MANIFEST_HEADER *Bpm; + IBB_ELEMENT *BpmIbb; + + Bpm = FindBpm (); + ASSERT (Bpm != NULL); + + BpmIbb = FindBpmIbb (Bpm); + ASSERT (BpmIbb != NULL); + + if ((BpmIbb->Flags & IBB_FLAG_AUTHORITY_MEASURE) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Create DetailPCR event log + + @param[in] TpmType TPM type +**/ +VOID +CreateDetailPcrEvent ( + IN TPM_TYPE TpmType + ) +{ + TCG_PCR_EVENT_HDR NewEventHdr; + + NewEventHdr.PCRIndex = 0; + NewEventHdr.EventType = EV_S_CRTM_CONTENTS; + CaculateDetailPCRExtendValue (&NewEventHdr.Digest); + + if (IsNpwAcm()) { + NewEventHdr.EventSize = sizeof ("Boot Guard Debug Measured S-CRTM"); + LogEvent (&NewEventHdr, "Boot Guard Debug Measured S-CRTM"); + } else { + NewEventHdr.EventSize = sizeof ("Boot Guard Measured S-CRTM"); + LogEvent (&NewEventHdr, "Boot Guard Measured S-CRTM"); + } +} + +/** + Create AuthorityPCR event log + + @param[in] TpmType TPM type +**/ +VOID +CreateAuthorityPcrEvent ( + IN TPM_TYPE TpmType + ) +{ + TCG_PCR_EVENT_HDR NewEventHdr; + + if (NeedAuthorityMeasure() && IsVerifiedBoot()) { + if (TpmType == dTpm12) { + NewEventHdr.PCRIndex = 6; + } else { + NewEventHdr.PCRIndex = 7; + } + NewEventHdr.EventType = EV_EFI_VARIABLE_DRIVER_CONFIG; + CaculateAuthorityPCRExtendValue (&NewEventHdr.Digest); + + if (IsNpwAcm()) { + NewEventHdr.EventSize = sizeof (L"Boot Guard Debug Measured S-CRTM"); + LogEvent (&NewEventHdr, (UINT8 *)L"Boot Guard Debug Measured S-CRTM"); + } else { + NewEventHdr.EventSize = sizeof (L"Boot Guard Measured S-CRTM"); + LogEvent (&NewEventHdr, (UINT8 *)L"Boot Guard Measured S-CRTM"); + } + } +} + +/** + Create Boot Guard TPM event log + + @param[in] TpmType Which type of TPM is available on system. +**/ +VOID +CreateTpmEventLog ( + IN TPM_TYPE TpmType + ) +{ + if (IsMeasuredBoot()) { + CreateDetailPcrEvent (TpmType); + CreateAuthorityPcrEvent (TpmType); + } +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif new file mode 100644 index 0000000..06d608a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif @@ -0,0 +1,11 @@ +<component> + name = "BootGuardTpmEventLogLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\BootGuardTpmEventLogLib" + RefName = "BootGuardTpmEventLogLib" +[files] +"BootGuardTpmEventLogLib.sdl" +"BootGuardTpmEventLogLib.mak" +"BootGuardTpmEventLogLib.c" +"BootGuardTpmEventLogLib.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h new file mode 100644 index 0000000..ca91990 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h @@ -0,0 +1,33 @@ +/** @file + Header file for Boot Guard TPM event log. + +@copyright + Copyright (c) 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _BOOT_GUARD_TPM_EVENT_LOG_LIB_H_ +#define _BOOT_GUARD_TPM_EVENT_LOG_LIB_H_ + +#include EFI_PPI_DEFINITION (CpuPlatformPolicy) + +/** + Create Boot Guard TPM event log + + @param[in] TpmType - Which type of TPM is available on system. +**/ +VOID +CreateTpmEventLog ( + IN TPM_TYPE TpmType + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak new file mode 100644 index 0000000..47a3d87 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : BootGuardTpmEventLogLib + +$(BUILD_DIR)\BootGuardTpmEventLogLib.lib : BootGuardTpmEventLogLib + +BootGuardTpmEventLogLib : $(BUILD_DIR)\BootGuardTpmEventLogLib.mak BootGuardTpmEventLogLibBin + +$(BUILD_DIR)\BootGuardTpmEventLogLib.mak : $(BootGuardTpmEventLogLib_DIR)\$(@B).cif $(BootGuardTpmEventLogLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(BootGuardTpmEventLogLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +BootGuardTpmEventLogLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +BootGuardTpmEventLogLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +BootGuardTpmEventLogLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +BootGuardTpmEventLogLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\BootGuardTpmEventLogLib.mak all \ + "MY_INCLUDES=$(BootGuardTpmEventLogLib_INCLUDES)"\ + "MY_DEFINES=$(BootGuardTpmEventLogLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl new file mode 100644 index 0000000..37c7417 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = BootGuardTpmEventLogLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable BootGuardTpmEventLogLib support in Project" +End + +MODULE + Help = "Includes BootGuardTpmEventLogLib.mak to Project" + File = "BootGuardTpmEventLogLib.mak" +End + +PATH + Name = "BootGuardTpmEventLogLib_DIR" +End + +ELINK + Name = "BootGuardTpmEventLogLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\BootGuardTpmEventLogLib.lib" + Parent = "BootGuardTpmEventLogLib_LIB" + InvokeOrder = AfterParent +End diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c new file mode 100644 index 0000000..05878cd --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c @@ -0,0 +1,71 @@ +/** @file + Digital Thermal Sensor (DTS) SMM Library. + This SMM Library configures and supports the DigitalThermalSensor features + for the platform. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#include "DTSHookLib.h" + +/** + Prepare data and protocol for Dts Hooe Lib + + @retval EFI_SUCCESS - Initialize complete +**/ +EFI_STATUS +InitializeDtsHookLib ( + VOID + ) +{ + /// + /// Nothing to do on CRB. + /// + return EFI_SUCCESS; +} + +/** + Platform may need to register some data to private data structure before generate + software SMI or SCI. +**/ +VOID +PlatformHookBeforeGenerateSCI ( + VOID + ) +{ + /// + /// Nothing to do on CRB. + /// +} + +/** + When system temperature out of specification, do platform specific programming to prevent + system damage. +**/ +VOID +PlatformEventOutOfSpec ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Handle critical event by shutting down via EC + /// + Status = InitializeKscLib (); + if (Status == EFI_SUCCESS) { + SendKscCommand (KSC_C_SYSTEM_POWER_OFF); + } +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.cif b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.cif new file mode 100644 index 0000000..6eddca3 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.cif @@ -0,0 +1,12 @@ +<component> + name = "DTSHookLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\DTSHookLib\Smm\" + RefName = "DTSHookLib" +[files] +"DTSHookLib.sdl" +"DTSHookLib.mak" +"DTSHookLib.inf" +"DTSHookLib.c" +"DTSHookLib.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.h b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.h new file mode 100644 index 0000000..7dfaa9b --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.h @@ -0,0 +1,27 @@ +/** @file + Defines and prototypes for the DigitalThermalSensor SMM driver + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _DTS_LIB_H_ +#define _DTS_LIB_H_ +/// +/// Include files +/// +#include "Tiano.h" +#include "KscLib.h" + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf new file mode 100644 index 0000000..f4011cf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf @@ -0,0 +1,49 @@ +## @file +# Component description file. +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + + +[defines] +BASE_NAME = DTSHookLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + DTSHookLib.c + DTSHookLib.h + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] + C_STD_INCLUDE= diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.mak b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.mak new file mode 100644 index 0000000..9b10b29 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(DTSHookLib_LIB) : DTSHookLib + +DTSHookLib : $(BUILD_DIR)\DTSHookLib.mak DTSHookLibBin + +$(BUILD_DIR)\DTSHookLib.mak : $(DTSHookLib_DIR)\$(@B).cif $(DTSHookLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(DTSHookLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +DTSHookLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\DTSHookLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(DTSHookLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.sdl new file mode 100644 index 0000000..e49c48f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = DTSHookLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable DTSHookLib support in Project" +End + +TOKEN + Name = "DTSHookLib_LIB" + Value = "$$(LIB_BUILD_DIR)\DTSHookLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes DTSHookLib.mak to Project" + File = "DTSHookLib.mak" +End + +PATH + Name = "DTSHookLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.c b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.c new file mode 100644 index 0000000..079482f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.c @@ -0,0 +1,228 @@ +/** @file + SMM KSC library implementation. + + These functions need to be SMM safe. + + These functions require the SMM IO library (SmmIoLib) to be present. + Caller must link those libraries and have the proper include path. + +@copyright + Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#include "KscLib.h" +#include "SmmIoLib.h" +#include "PchAccess.h" +#include "PchPlatformLib.h" + +BOOLEAN mSmmKscLibInitialized = FALSE; + +/// +/// Function implemenations +/// +/** + Initialize the library. + The SMM library only requires SMM IO library and has no initialization. + However, this must be called prior to use of any other KSC library functions + for future compatibility. + + @param[in] None. + + @retval EFI_SUCCESS - KscLib is successfully initialized. +**/ +EFI_STATUS +InitializeKscLib ( + VOID + ) +{ + EFI_STATUS Status; + + /// + /// Fail if EC doesn't exist. + /// + if (SmmIoRead8 (KSC_C_PORT) == 0xff) { + mSmmKscLibInitialized = FALSE; + Status = EFI_DEVICE_ERROR; + } else { + mSmmKscLibInitialized = TRUE; + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + Sends command to Keyboard System Controller. + + @param[in] Command - Command byte to send + + @retval EFI_SUCCESS - Command success + @retval EFI_DEVICE_ERROR - Command error +**/ +EFI_STATUS +SendKscCommand ( + UINT8 Command + ) +{ + UINTN Index; + UINT8 KscStatus; + + KscStatus = 0; + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + /// + /// Wait for KSC to be ready (with a timeout) + /// + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_IBF) != 0) && (Index < KSC_TIME_OUT)) { + PchPmTimerStall(15); + ReceiveKscStatus (&KscStatus); + Index++; + } + + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + /// + /// Send the KSC command + /// + SmmIoWrite8 (KSC_C_PORT, Command); + + return EFI_SUCCESS; +} + +/** + Receives status from Keyboard System Controller. + + @param[in] KscStatus - Status byte to receive + + @retval EFI_DEVICE_ERROR - Ksc library has not initialized yet or KSC not present + @retval EFI_SUCCESS - Get KSC status successfully +**/ +EFI_STATUS +ReceiveKscStatus ( + UINT8 *KscStatus + ) +{ + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + /// + /// Read and return the status + /// + *KscStatus = SmmIoRead8 (KSC_C_PORT); + + return EFI_SUCCESS; +} + +/** + Sends data to Keyboard System Controller. + + @param[in] Data - Data byte to send + + @retval EFI_SUCCESS - Success + @retval EFI_DEVICE_ERROR - Error +**/ +EFI_STATUS +SendKscData ( + UINT8 Data + ) +{ + UINTN Index; + UINT8 KscStatus; + + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + /// + /// Wait for KSC to be ready (with a timeout) + /// + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_IBF) != 0) && (Index < KSC_TIME_OUT)) { + PchPmTimerStall(15); + ReceiveKscStatus (&KscStatus); + Index++; + } + + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + /// + /// Send the data and return + /// + SmmIoWrite8 (KSC_D_PORT, Data); + + return EFI_SUCCESS; +} + +/** + Receives data from Keyboard System Controller. + + @param[in] Data - Data byte received + + @retval EFI_SUCCESS - Read success + @retval EFI_DEVICE_ERROR - Read error +**/ +EFI_STATUS +ReceiveKscData ( + UINT8 *Data + ) +{ + UINTN Index; + UINT8 KscStatus; + + /// + /// Verify if KscLib has been initialized, NOT if EC dose not exist. + /// + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + /// + /// Wait for KSC to be ready (with a timeout) + /// + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_OBF) == 0) && (Index < KSC_TIME_OUT)) { + PchPmTimerStall(15); + ReceiveKscStatus (&KscStatus); + Index++; + } + + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + /// + /// Read KSC data and return + /// + *Data = SmmIoRead8 (KSC_D_PORT); + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.cif b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.cif new file mode 100644 index 0000000..3ee7072 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.cif @@ -0,0 +1,11 @@ +<component> + name = "SmmKscLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\Ksc\Smm" + RefName = "SmmKscLib" +[files] +"SmmKscLib.sdl" +"SmmKscLib.mak" +"SmmKscLib.c" +"SmmKscLib.inf" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.inf b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.inf new file mode 100644 index 0000000..478ca1a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.inf @@ -0,0 +1,51 @@ +## @file +# Component description file. +# +#@copyright +# Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + + +[defines] +BASE_NAME = SmmKscLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + SmmKscLib.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library + +[libraries.common] + EdkFrameworkProtocolLib + PchPlatformLib + +[nmake.common] + C_STD_INCLUDE= diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.mak b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.mak new file mode 100644 index 0000000..ee3a5b0 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(SmmKscLib_LIB) : SmmKscLib + +SmmKscLib : $(BUILD_DIR)\SmmKscLib.mak SmmKscLibBin + +$(BUILD_DIR)\SmmKscLib.mak : $(SmmKscLib_DIR)\$(@B).cif $(SmmKscLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmmKscLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +SmmKscLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\SmmKscLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(SmmKscLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.sdl new file mode 100644 index 0000000..46ce94f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/Ksc/Smm/SmmKscLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = SmmKscLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable SmmKscLib support in Project" +End + +TOKEN + Name = "SmmKscLib_LIB" + Value = "$$(LIB_BUILD_DIR)\SmmKscLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes SmmKscLib.mak to Project" + File = "SmmKscLib.mak" +End + +PATH + Name = "SmmKscLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c new file mode 100644 index 0000000..9f1e19d --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c @@ -0,0 +1,169 @@ +/** @file + SMM I/O access utility implementation file, for Ia32 + +@copyright + Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ + +/// +/// Include files +/// +#include "SmmIoLib.h" + +/** + Do a one byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT8 +SmmIoRead8 ( + IN UINT16 Address + ) +{ + UINT8 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a one byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite8 ( + IN UINT16 Address, + IN UINT8 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Data + ); +} + +/** + Do a two byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT16 +SmmIoRead16 ( + IN UINT16 Address + ) +{ + UINT16 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a two byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite16 ( + IN UINT16 Address, + IN UINT16 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Data + ); +} + +/** + Do a four byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT32 +SmmIoRead32 ( + IN UINT16 Address + ) +{ + UINT32 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a four byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite32 ( + IN UINT16 Address, + IN UINT32 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Data + ); +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif new file mode 100644 index 0000000..ec8cae7 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif @@ -0,0 +1,12 @@ +<component> + name = "SmmIoLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\SmmIo" + RefName = "SmmIoLib" +[files] +"SmmIoLib.sdl" +"SmmIoLib.mak" +"SmmIoLib.inf" +"SmmIo.c" +"SmmPciIo.c" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf new file mode 100644 index 0000000..43045eb --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf @@ -0,0 +1,48 @@ +## @file +# Component description file. +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + + +[defines] +BASE_NAME = SmmIoLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + SmmIo.c + SmmPciIo.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak new file mode 100644 index 0000000..12b9d5e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(SmmIoLib_LIB) : SmmIoLib + +SmmIoLib : $(BUILD_DIR)\SmmIoLib.mak SmmIoLibBin + +$(BUILD_DIR)\SmmIoLib.mak : $(SmmIoLib_DIR)\$(@B).cif $(SmmIoLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmmIoLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +SmmIoLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\SmmIoLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(SmmIoLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl new file mode 100644 index 0000000..537a750 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = SmmIoLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable SmmIoLib support in Project" +End + +TOKEN + Name = "SmmIoLib_LIB" + Value = "$$(LIB_BUILD_DIR)\SmmIoLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes SmmIoLib.mak to Project" + File = "SmmIoLib.mak" +End + +PATH + Name = "SmmIoLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c new file mode 100644 index 0000000..f6fd18f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c @@ -0,0 +1,161 @@ +/** @file + SMM PCI config space I/O access utility implementation file, for Ia32 + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#include "SmmIoLib.h" + +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO_INTERFACE *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); + +/** + Read value from the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgRead ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO_INTERFACE *SmmCpuIo; + + ASSERT (mSmst); + + SmmCpuIo = &(mSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, FALSE, Width, Address, Buffer); +} + +/** + Write value into the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgWrite ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO_INTERFACE *SmmCpuIo; + + ASSERT (mSmst); + + SmmCpuIo = &(mSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, TRUE, Width, Address, Buffer); +} + +/** + Access a PCI config space address, including read and write + + @param[in] CpuIo - The cpu I/O accessing interface provided by EFI runtime sys table + @param[in] IsWrite - Indicates whether this operation is a write access or read + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value when this is a reading operation or the data + to be written when this is a writing one + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO_INTERFACE *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + PCI_CONFIG_ACCESS_CF8 PciCf8Data; + UINT64 PciDataReg; + + /// + /// PCI Config access are all 32-bit alligned, but by accessing the + /// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types + /// are possible on PCI. + /// + /// To read a byte of PCI config space you load 0xcf8 and + /// read 0xcfc, 0xcfd, 0xcfe, 0xcff + /// + /// The validation of passed in arguments "Address" will be checked in the + /// CPU IO functions, so we don't check them here + /// + if (Width >= SmmPciWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + PciCf8Data.Reg = Address->Register & 0xfc; + PciCf8Data.Func = Address->Function; + PciCf8Data.Dev = Address->Device; + PciCf8Data.Bus = Address->Bus; + PciCf8Data.Reserved = 0; + PciCf8Data.Enable = 1; + + Status = CpuIo->Io.Write (CpuIo, SmmPciWidthUint32, 0xcf8, 1, &PciCf8Data); + if (EFI_ERROR (Status)) { + return Status; + } + + PciDataReg = 0xcfc + (Address->Register & 0x03); + + if (IsWrite) { + /// + /// This is a Pci write operation, write data into (0xcfc + offset) + /// + Status = CpuIo->Io.Write (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + /// + /// This is a Pci Read operation, read returned data from (0xcfc + offset) + /// + Status = CpuIo->Io.Read (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} diff --git a/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.cif b/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.cif new file mode 100644 index 0000000..96d3f7b --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.cif @@ -0,0 +1,11 @@ +<component> + name = "CpuSampleCodeProtocolLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Protocol\" + RefName = "CpuSampleCodeProtocolLib" +[files] +"CpuSampleCodeProtocolLib.mak" +"CpuSampleCodeProtocolLib.sdl" +"TxtOneTouchOp\TxtOneTouchOp.c" +"TxtOneTouchOp\TxtOneTouchOp.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.mak b/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.mak new file mode 100644 index 0000000..f77edb4 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.mak @@ -0,0 +1,25 @@ +all : CpuSampleCodeProtocolLib + +$(CpuSampleCodeProtocolLib_LIB) : CpuSampleCodeProtocolLib + +CpuSampleCodeProtocolLib : $(BUILD_DIR)\CpuSampleCodeProtocolLib.mak CpuSampleCodeProtocolLibBin + +$(BUILD_DIR)\CpuSampleCodeProtocolLib.mak : $(CpuSampleCodeProtocolLib_DIR)\$(@B).cif $(CpuSampleCodeProtocolLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(CpuSampleCodeProtocolLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +CpuSampleCodeProtocolLib_INCLUDES=\ + $(EDK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(PROJECT_CPU_INCLUDES)\ + +CpuSampleCodeProtocolLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\CpuSampleCodeProtocolLib.mak all\ + "MY_INCLUDES=$(CpuSampleCodeProtocolLib_INCLUDES)" \ + TYPE=LIBRARY +!IF "$(x64_BUILD)"=="1" + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\ + /f $(BUILD_DIR)\CpuSampleCodeProtocolLib.mak all\ + "MY_INCLUDES=$(CpuSampleCodeProtocolLib_INCLUDES)" \ + TYPE=PEI_LIBRARY +!ENDIF
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.sdl b/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.sdl new file mode 100644 index 0000000..6662a1b --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Protocol/CpuSampleCodeProtocolLib.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = "CpuSampleCodeProtocolLib_SUPPORT" + Value = "1" + Help = "Main switch to enable CpuSampleCodeProtocolLib support in Project" + TokenType = Boolean + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "CpuSampleCodeProtocolLib_DIR" +End + +MODULE + Help = "Includes CpuSampleCodeProtocolLib.mak to Project" + File = "CpuSampleCodeProtocolLib.mak" +End + +TOKEN + Name = "CpuSampleCodeProtocolLib_LIB" + Value = "$$(LIB_BUILD_DIR)\CpuSampleCodeProtocolLib.lib" + TokenType = Expression + TargetMAK = Yes +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Protocol/TxtOneTouchOp/TxtOneTouchOp.c b/ReferenceCode/Haswell/SampleCode/Protocol/TxtOneTouchOp/TxtOneTouchOp.c new file mode 100644 index 0000000..3e6f982 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Protocol/TxtOneTouchOp/TxtOneTouchOp.c @@ -0,0 +1,32 @@ +/** @file + Txt specific PPI operation definition. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#endif +#include "TxtOneTouchOp.h" + +/// +/// Protocol GUID definition +/// +EFI_GUID gTxtOneTouchOpProtocolGuid = TXT_ONE_TOUCH_OP_PROTOCOL_GUID; + +/// +/// Protocol description +/// +EFI_GUID_STRING(&gTxtOneTouchOpProtocolGuid, "Txt One Touch OP Protocol", "Txt One Touch OP Protocol"); diff --git a/ReferenceCode/Haswell/SampleCode/Protocol/TxtOneTouchOp/TxtOneTouchOp.h b/ReferenceCode/Haswell/SampleCode/Protocol/TxtOneTouchOp/TxtOneTouchOp.h new file mode 100644 index 0000000..aaccb4e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Protocol/TxtOneTouchOp/TxtOneTouchOp.h @@ -0,0 +1,106 @@ +/** @file + Txt specific PPI operation definition. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _TXT_PPI_OPERATION_H_ +#define _TXT_PPI_OPERATION_H_ + +/// +/// EDK and EDKII have different GUID formats +/// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#define TXT_ONE_TOUCH_OP_PROTOCOL_GUID \ + { \ + 0xFA2338AD, 0x80DF, 0x49D0, 0x93, 0x96, 0xCF, 0x71, 0x45, 0xD0, 0x3A, 0x76 \ + } +#else +#define TXT_ONE_TOUCH_OP_PROTOCOL_GUID \ + { \ + 0xFA2338AD, 0x80DF, 0x49D0, \ + { \ + 0x93, 0x96, 0xCF, 0x71, 0x45, 0xD0, 0x3A, 0x76 \ + } \ + } +#endif +/// +/// Extern the GUID for protocol users. +/// +extern EFI_GUID gTxtOneTouchOpProtocolGuid; + +/// +/// Forward reference for ANSI C compatibility +/// +typedef struct _TXT_ONE_TOUCH_OP_PROTOCOL TXT_ONE_TOUCH_OP_PROTOCOL; + +/// +/// Member functions +/// +typedef +EFI_STATUS +(EFIAPI *TXT_PPI_EXEC_OPERATION)( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command + ); + +/* + +@brief + Extend PPI operation for TxT. + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + +*/ +typedef +EFI_STATUS +(EFIAPI *TXT_CONFIRMATION_DIALOG)( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command, + IN OUT BOOLEAN *Confirm + ); +/* + +@brief + Confirmation dialog for TxT PPI + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + @param[in] Confirm - User confirm + +*/ +typedef +EFI_STATUS +(EFIAPI *TXT_RESET_SYSTEM)( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command + ); + +/** + Reset system. + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + + @retval EFI_SUCCESS - Always return EFI_SUCCESS +**/ +struct _TXT_ONE_TOUCH_OP_PROTOCOL { + TXT_PPI_EXEC_OPERATION ExecuteOperation; + TXT_CONFIRMATION_DIALOG ConfirmationDialog; + TXT_RESET_SYSTEM ResetSystem; +}; + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.cif b/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.cif new file mode 100644 index 0000000..0bc0424 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.cif @@ -0,0 +1,20 @@ +<component> + name = "CpuRcSec" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\SecCore" + RefName = "CpuRcSec" +[files] +"CpuRcSec.mak" +"CpuRcSec.sdl" +"Sec\Ia32\Chipset.inc" +"Sec\Ia32\CpuRcSec.asm" +"Sec\Ia32\CrcSecPpi.c" +"Sec\Ia32\Flat32.asm" +"Sec\Ia32\Ia32.inc" +"Sec\Ia32\SecFlat32.inc" +"Sec\Ia32\Platform.inc" +"Sec\Ia32\ResetVec.asm" +"Sec\Ia32\ResetVec.raw" +"Sec\Ia32\SecCore.inc" +"Sec\Ia32\SecStartup.c" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.mak b/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.mak new file mode 100644 index 0000000..8f1b13f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.mak @@ -0,0 +1,27 @@ +# MAK file for the ModulePart:CPU SEC RC +CPU_RC_DEPENDANCIES = \ +$(CPU_RC_SEC_DIR)\Platform.inc \ +$(CPU_RC_SEC_DIR)\Chipset.inc \ +$(CPU_RC_SEC_DIR)\SecFlat32.inc + +$(BUILD_DIR)\CpuRcSec.obj : $(CPU_RC_SEC_DIR)\CpuRcSec.asm $(CPU_RC_DEPENDANCIES) + $(ASM) /c /nologo /coff /Sa /I$(BUILD_DIR) /Fo$@ $(CPU_RC_SEC_DIR)\CpuRcSec.asm + + +# Add its own include path to +MY_INC = \ +/ICore \ +/IEDK\Foundation\Framework\Ppi\SecPlatformInformation + +# Add CrcSecPpi.obj to CORE_PEIBin dependency list, so it will be linked with PEI CORE +CORE_PEIBin: $(BUILD_DIR)\CrcSecPpi.obj +# Add SecPlatformInformation.obj to CORE_PEIBin dependency list, so it will be linked with PEI CORE +CORE_PEIBin: $(BUILD_DIR)\SecPlatformInformation.obj + +# Add a description block for CrcSecPpi.OBJ for cross-module link +$(BUILD_DIR)\CrcSecPpi.OBJ : $(CPU_RC_SEC_DIR)\CrcSecPpi.c + $(CC) $(CFLAGS) $(MY_INC) /Fo$(BUILD_DIR)\CrcSecPpi.obj $(CPU_RC_SEC_DIR)\CrcSecPpi.c + +# Add a description block for SecPlatformInformation.OBJ +$(BUILD_DIR)\SecPlatformInformation.obj : $(EdkFrameworkPpiLib_DIR)\SECPLATFORMINFORMATION\SecPlatformInformation.c + $(CC) $(CFLAGS) $(EDK_INCLUDES) /D TIANO_RELEASE_VERSION=0x00080006 /Fo$(BUILD_DIR)\SecPlatformInformation.obj $(EdkFrameworkPpiLib_DIR)\SECPLATFORMINFORMATION\SecPlatformInformation.c diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.sdl b/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.sdl new file mode 100644 index 0000000..3c8a5b0 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/CpuRcSec.sdl @@ -0,0 +1,40 @@ +TOKEN + Name = "Intel_Haswell_SEC_RC_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +MODULE + Help = "Includes CpuRcSec.mak to Project" + File = "CpuRcSec.mak" +End + +ELINK + Name = "$(BUILD_DIR)\CpuRcSec.obj" + Parent = "ADDON_SEC_CORE_OBJ_FILES" + InvokeOrder = AfterParent +End + +PATH + Name = "CPU_RC_SEC_DIR" + Path = "ReferenceCode\Haswell\SampleCode\SecCore\Sec\Ia32" +End + +ELINK + Name = "GainestownSecRcEntry" + Parent = "SECCoreAtPowerOn" + Priority = 1000 + Help = "Gainestown RC" + InvokeOrder = AfterParent +End + +ELINK + Name = "CrcSecPlatformInformationPpi," + Parent = "PeiCoreInitialize" + InvokeOrder = AfterParent +End + diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Chipset.inc b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Chipset.inc new file mode 100644 index 0000000..ebd52ab --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Chipset.inc @@ -0,0 +1,107 @@ +;@file +; Chipset constants and macros +; +;@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 +; + +; +; APIC register +; +APICID EQU 0FEE00020h + +; +; Power Management I/O Registers +; +PCH_ACPI_BASE_ADDRESS EQU 0500h +ACPI_PM1_STS EQU 000h +ACPI_PM1_CNT EQU 004h + +; +; PCH RCBA base address +; +PCH_RCRB_BASE EQU 0FED1C000h +PCH_RCRB_BASE_REG EQU 8000F8F0h ; PCH Register B0:D31:RF0 +PCH_RCRB_GCS EQU 03410h +PCH_RCRB_RTC_CONF EQU 03400h +PCH_RCRB_RTC_CONF_UCMOS_EN EQU 04h +PCH_RCRB_HPET EQU 03404h +PCH_RCRB_HPET_DECODE EQU 080h + +; +; HPET compare register +; +HPET_COMP_1 EQU 0FED00108h +HPET_COMP_2 EQU 0FED0010Ch +HPET_COMP_3 EQU 0FED00128h +HPET_COMP_4 EQU 0FED00148h + +; +; MCH PCIe base address +; +;Need to match PcdPciExpressBaseAddress or PCIEX_BASE_ADDRESS +;CPU_HEC_BASE EQU 0E0000000h ; Must be X0000000 +;(AMI_CHG)> +CPU_HEC_BASE EQU MKF_PCIEX_BASE_ADDRESS ; Must be X0000000 +;<(AMI_CHG) +;CPU_HEC_SIZE EQU 000000000h ; 256M +;(AMI_CHG)> +CPU_HEC_SIZE EQU MKF_PCIEX_LENGTH_BIT_SETTING ; 64M, 128M, 256M +;<(AMI_CHG) +CPU_HEC_EN EQU 000000001h ; Enable +CPU0_HEC_PCI_ADDR EQU 080FF0150h +CPU1_HEC_PCI_ADDR EQU 080FE0150h + +PCI_LPC_BASE EQU 08000F800h + +GPIO_BASE_ADDRESS EQU 0800h +R_GPIO_USE_SEL2 EQU 030h +R_GPIO_IO_SEL2 EQU 034h +R_GPIO_LVL2 EQU 038h + +; +; PCI registers +; +PCH_LPC_PMBASE_PCI_ADDR EQU ((1Fh * 8 + 00h) * 1000h + 0040h + CPU_HEC_BASE) +PCH_LPC_ACPICNTL_PCI_ADDR EQU ((1Fh * 8 + 00h) * 1000h + 0044h + CPU_HEC_BASE) +PCH_LPC_GEN_PMCON_3_ADDR EQU ((1Fh * 8 + 00h) * 1000h + 00A4h + CPU_HEC_BASE) +PCH_LPC_RCRB_PCI_ADDR EQU ((1Fh * 8 + 00h) * 1000h + 00F0h + CPU_HEC_BASE) +PCH_LPC_BIOS_CNTL_PCI_ADDR EQU ((1Fh * 8 + 00h) * 1000h + 00DCh + CPU_HEC_BASE) +MCH_UNCERRMASK_PCI_ADDR EQU ((00h * 8 + 00h) * 1000h + 0108h + CPU_HEC_BASE) +MCH_SYRE_PCI_ADDR EQU ((10h * 8 + 00h) * 1000h + 0040h + CPU_HEC_BASE) + +SYRE_CPURST EQU 14 + +; +; PCIEXBAR constants for enable in bit [0] +; +ENABLE EQU 1 + +; +; PCIEXBAR constants for size in bit [2:1] +; +PCIEXBAR_64MB EQU 010b +PCIEXBAR_128MB EQU 001b +PCIEXBAR_256MB EQU 000b + +MMCFG_BASE EQU CPU_HEC_BASE ; 4GB-128MB +MMCFG_LENGTH_BIT_SETTING EQU CPU_HEC_SIZE ; 64M, 128M, 256M + +DMIBAR_REG EQU (068h + CPU_HEC_BASE) +DMI_BASE_ADDRESS EQU 0FED18000h + +MCHBAR_REG EQU (048h + CPU_HEC_BASE) +MCH_BASE_ADDRESS EQU 0FED10000h + diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/CpuRcSec.asm b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/CpuRcSec.asm new file mode 100644 index 0000000..1460ddf --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/CpuRcSec.asm @@ -0,0 +1,38 @@ + + INCLUDE Token.equ + INCLUDE Platform.inc + INCLUDE Ia32.inc + +CPU_HEC_BASE EQU MKF_PCIEX_BASE_ADDRESS ; Must defined before include Chipset.inc + INCLUDE Chipset.inc + + INCLUDE SecCore.inc + + .686p + .xmm + .model small + + extern FindMicrocode:NEAR32 + extern GainestownSecRcEntryEnd:NEAR32 + +STARTUP_SEG SEGMENT PARA PUBLIC USE32 'CODE' + ASSUME CS:STARTUP_SEG, DS:STARTUP_SEG + + INCLUDE SecFlat32.inc + +GainestownSecRcEntry PROC + + jmp ProtectedModeSECStart ; Jump to IvyBridge SEC sample code + +CallPeiCoreEntryPoint PROC + ; Set stack top pointer + mov esp, DATA_STACK_BASE_ADDRESS + DATA_STACK_SIZE + + jmp GainestownSecRcEntryEnd ; Exit the eLink +CallPeiCoreEntryPoint ENDP + +GainestownSecRcEntry ENDP + +STARTUP_SEG ENDS +END + diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/CrcSecPpi.c b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/CrcSecPpi.c new file mode 100644 index 0000000..28cc105 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/CrcSecPpi.c @@ -0,0 +1,233 @@ +/*++ + This file contains an 'Intel Peripheral Driver' 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 - 2008 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: + + CrcSecPpi.c + +Abstract: + + Install SecPlatformInformation PPI. + +--*/ + +//#include "Tiano.h" +//#include "PeiCore.h" +//#include "FlashMap.h" +//#include "EfiFirmwareFileSystem.h" +//#include "EfiFirmwareVolumeHeader.h" + +//#include EFI_PPI_DEFINITION (SecPlatformInformation) +#include "Tiano.h" +//#include <Core\Core_Pei\PeiCore.h> + +//#include "Efi.h" +//#include "Pei.h" + +#include "EfiCommonLib.h" +#include <Ppi\AmiEarlyBistPpi.h> +static EFI_GUID gAmiEarlyBistGuid = AMI_EARLY_BIST_PPI_GUID; + +#include "SecPlatformInformation.h" + +EFI_STATUS +SecPlatformInformation ( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + IN OUT SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { SecPlatformInformation }; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiSecPlatformInformationPpiGuid, + &mSecPlatformInformationPpi +}; + +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + IN OUT SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +/*++ + +Routine Description: + + Implementation of the PlatformInformation service in + EFI_SEC_PLATFORM_INFORMATION_PPI. + This function conveys state information out of the SEC phase into PEI. + +Arguments: + + PeiServices - Pointer to the PEI Services Table. + StructureSize - Pointer to the variable describing size of the input buffer. + PlatformInformationRecord - Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + +Returns: + + EFI_SUCCESS - The data was successfully returned. + EFI_BUFFER_TOO_SMALL - The buffer was too small. + +--*/ +{ + UINT32 *BIST; + UINT32 Size; + UINT32 Count; + AMI_EARLY_BIST_PPI *AmiEarlyPpi; + EFI_STATUS Status; + CPU_BIST PrivateBist; + + Status = (*PeiServices)->LocatePpi( + PeiServices, + &gAmiEarlyBistGuid, + 0, NULL, + &AmiEarlyPpi + ); + //Force BIST no error if PPI not found + if (Status != EFI_SUCCESS) { + Size = sizeof (UINT64); + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + PrivateBist.ApicId = 0; + PrivateBist.Bist = 0; + BIST = (UINT32*)&PrivateBist; + } else{ + Count = AmiEarlyPpi->NumBists; + Size = Count * sizeof (UINT64); + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + BIST = (UINT32 *) (&(AmiEarlyPpi->CpuBist)); + } + *StructureSize = Size; + EfiCommonLibCopyMem (PlatformInformationRecord, BIST, Size); + + return EFI_SUCCESS; + +/* + UINT32 *BIST; + UINT32 Size; + UINT32 Count; + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + Count = *(TopOfCar - 1); + Size = Count * sizeof (UINT64); + + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = Size; + BIST = (UINT32 *) ((UINT32) TopOfCar - sizeof (UINT32) - Size); + + EfiCommonLibCopyMem (PlatformInformationRecord, BIST, Size); + + return EFI_SUCCESS; +*/ +} + +//<AMI_PHDR_START> +//********************************************************************** +// +// Procedure: CrcSecPlatformInformationPpi +// +// Description: +// Install SecPlatformInformation PPI that Intel Ivybridge CPU reference code needs. +// (conveys state information out of the SEC phase into PEI) +// +// Input: +// IN EFI_FFS_FILE_HEADER *FfsHeader - pointer to the header of the current firmware file system +// IN EFI_PEI_SERVICES **PeiServices - pointer to the PeiServices Table +// +// Output: +// EFI_SUCCESS +// +// Notes: +// +//********************************************************************** +//<AMI_PHDR_END> +//PeiInitialize eLink + +EFI_STATUS EFIAPI CrcSecPlatformInformationPpi( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +){ + EFI_STATUS Status; + + // Install the NB Init Policy PPI + Status = (*PeiServices)->InstallPpi(PeiServices, &mPeiSecPlatformInformationPpi); + + return EFI_SUCCESS; +} + + +// VOID +// SecStartup ( +// IN UINT32 SizeOfRam, +// IN UINT32 BootFirmwareVolume, +// IN PEI_MAIN_ENTRY_POINT PeiCoreEntryPoint +// ) +/*++ + +Routine Description: + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + +Arguments: + + SizeOfRam - Size of the temporary memory available for use. + BootFirmwareVolume - Base address of the Boot Firmware Volume. + PeiCoreEntryPoint - Pointer to the entry point of the PEI core. + +Returns: + + This function never returns + +--*/ +// { +// EFI_PEI_STARTUP_DESCRIPTOR PeiStartup; +// +// PeiStartup.SizeOfCacheAsRam = SizeOfRam; +// PeiStartup.BootFirmwareVolume = BootFirmwareVolume; +// PeiStartup.DispatchTable = &mPeiSecPlatformInformationPpi; +// +// // +// // Transfer the control to the PEI core +// // +// (*PeiCoreEntryPoint) (&PeiStartup); +// +// // +// // Should not come here. +// // +// return ; +// } diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Flat32.asm b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Flat32.asm new file mode 100644 index 0000000..3b973d8 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Flat32.asm @@ -0,0 +1,1490 @@ +; +; 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 - 2013, Intel Corporation. All rights reserved.<BR> +; 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: +; +; Flat32.asm +; +; Abstract: +; +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector. +; +;------------------------------------------------------------------------------ + INCLUDE Platform.inc + INCLUDE Ia32.inc + INCLUDE Chipset.inc + INCLUDE SecCore.inc + +.686p +.xmm +.model small, c + +EXTRN SecStartup:NEAR + +; ECP porting +EXTRN PcdGet32 (PcdFlashMicrocodeFvBase):DWORD +EXTRN PcdGet32 (PcdFlashMicrocodeFvSize):DWORD +EXTRN PcdGet32 (PcdNemCodeCacheSize):DWORD +EXTRN PcdGet32 (PcdNemCodeCacheBase):DWORD +EXTRN PcdGet32 (PcdFlashAreaBaseAddress):DWORD +EXTRN PcdGet32 (PcdTemporaryRamBase):DWORD +EXTRN PcdGet32 (PcdTemporaryRamSize):DWORD +EXTRN PcdGet64 (PcdPciExpressBaseAddress):QWORD + +_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE + +;------------------------------------------------------------------------------ +; +; SEC "Security" Code module. +; +; Transition to non-paged flat-model protected mode from a +; hard-coded GDT that provides exactly two descriptors. +; This is a bare bones transition to protected mode only +; used for while in PEI and possibly DXE. +; +; IA32 specific cache as RAM modules +; +; After enabling protected mode, a far jump is executed to +; TransferToPEI using the newly loaded GDT. +; This code also enables the Cache-as-RAM +; +; RETURNS: none +; +; MMX Usage: +; MM0 = BIST State +; MM1 = Current Package Physical Info +; [7:0] = Cluster ID +; [15:8] = Total Prossor pacakge detected in system +; [16] = BAD CMOS Flag +; [17] = AuburnDale or ClarksField +; [0] = AuburnDale +; [1] = ClarksField +; [18] = Contain SEC reset flag +; CPU Only Reset Flag +; [19] = Contain SEC reset flag +; Power Good Reset Flag +; [23:20] = Reserved +; [31:24] = Reserved +; MM2 = store common MAX & MIN ratio +; MM3 = Patch Revision +; MM4 = Patch Pointer +; MM5 = Save time-stamp counter value high32bit +; MM6 = Save time-stamp counter value low32bit. +; MM7 = Used in CALL_MMX & RET_ESI micaro +; +;------------------------------------------------------------------------------ + +; Nehalem Reset Boot Flow Start + +align 4 +_ModuleEntryPoint PROC NEAR C PUBLIC + ; + ; Save BIST state in MM0 + ; + fninit ; clear any pending Floating point exceptions + movd mm0, eax + + ; + ; Save time-stamp counter value + ; rdtsc load 64bit time-stamp counter to EDX:EAX + ; + rdtsc + movd mm5, edx + movd mm6, eax +;---------------------------------------------------------------------------------------- +; "Merlin" support +;---------------------------------------------------------------------------------------- + xor eax, eax + mov es, ax + mov ax, cs + mov ds, ax + +;****************************************************************************** +; BEGIN WARM-START CHANGE +;****************************************************************************** +; +; PLATFORM-SPECIFIC EQUATES! +; These equates define an address which has the following requirements +; on the target platform: +; 1. After booting DOS, the memory is not used by other DOS applications +; or drivers (thus very platform/configuration specific). +; Minimum of roughly 8 bytes required. +; 2. The memory contents and address range are not affected by an INIT +; 3. By default, after booting DOS, the first 4 bytes at this address +; contain either 0 (cleared memory) or 0xFFFFFFFF. +; 4. After booting DOS, the memory is writable +; +; It's expected that a manual inspection (using ITP) is performed to ensure +; that the requirements are met. If the manual inspection fails, then a +; different address must be identified, the below two equates must be +; changed accordingly, and the platform firmware must be rebuilt. +; Note that simply changing the platform hardware configuration could +; break this firmware because drivers may be loaded differently in +; memory, potentially using the address arbitrarily chosen here. +; + ; + ; Check if value in magic address contains non-zero/non-FF value. + ; It should actually contain executable code, typically a jmp + ; instruction. + ; + mov ax, MAGIC_SEG + mov es, ax + mov al, BYTE PTR es:[MAGIC_ADDRESS_IN_SEG] + + ; Check for zero value + cmp al, 0EAh ; EA is the FAR JMP opcode that Merlin inserts + jz LegacyBiosWarmStart + + ; Check INIT# is asserted by port 0xCF9 + mov dx, 0CF9h + in al, dx + cmp al, 04h + jnz NotWarmStart + + ; + ; Issue hard reset due to client silicon limitations, CPU Only Reset is not supported. + ; + mov dx, 0CF9h + mov al, 06h + out dx, al + +LegacyBiosWarmStart: + + ; + ; Check APIC_BASE_MSR.BIT8 to see if we're the BSP + ; + mov cx, MSR_APIC_BASE + rdmsr + test ah, 1 + jz TightLoop + ; + ; We're the BSP, so jump to the magic address. + ; + DB 0EAh + DW MAGIC_ADDRESS_IN_SEG + DW MAGIC_SEG + + ; Not reached +NotWarmStart: + +;****************************************************************************** +; END WARM-START CHANGE +;****************************************************************************** + + ; + ; Enter Protected mode. + ; + STATUS_CODE (01h) ; BSP_PROTECTED_MODE_START + mov esi, OFFSET GdtDesc + DB 66h + lgdt fword ptr cs:[si] + mov eax, cr0 ; Get control register 0 + or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) + mov cr0, eax ; Activate protected mode + mov eax, cr4 ; Get control register 4 + or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + mov cr4, eax + + ; + ; Now we're in Protected16 + ; Set up the selectors for protected mode entry + ; + mov ax, SYS_DATA_SEL + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; + ; Go to Protected32 + ; + mov esi, offset NemInitLinearAddress + jmp fword ptr cs:[si] + +TightLoop: + cli + hlt + jmp TightLoop + +_ModuleEntryPoint ENDP +_TEXT_REALMODE ENDS + +_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE' + ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE + +CALL_MMX macro RoutineLabel + + local ReturnAddress + mov esi, offset ReturnAddress + movd mm7, esi ; save ReturnAddress into MM7 + jmp RoutineLabel +ReturnAddress: + +endm + +RET_ESI macro + + movd esi, mm7 ; restore ESP from MM7 + jmp esi + +endm + +CALL_EBP macro RoutineLabel + + local ReturnAddress + mov ebp, offset ReturnAddress + jmp RoutineLabel +ReturnAddress: + +endm + +RET_EBP macro + + jmp ebp ; restore ESP from EBP + +endm + +align 4 +ProtectedModeSECStart PROC NEAR PUBLIC + + STATUS_CODE (02h) + CALL_MMX EnableAccessCSR + + STATUS_CODE (03h) + CALL_EBP VeryEarlyMicrocodeUpdate + + STATUS_CODE (04h) + CALL_MMX DetectNumOfCPUSocket + + STATUS_CODE (05h) + CALL_MMX PlatformInitialization + + STATUS_CODE (06h) + CALL_MMX InitializeNEM + + STATUS_CODE (07h) + CALL_MMX EstablishStack + + STATUS_CODE (08h) + jmp CallPeiCoreEntryPoint + +ProtectedModeSECStart ENDP + +EnableAccessCSR PROC NEAR PRIVATE + ; + ; get Bus number from CPUID[1] EBX[31:24] + ; + + mov eax, 0Bh + mov ecx, 1 + cpuid + mov esi, eax + + mov eax, 1 ; bus 0 + cpuid + bswap ebx + movzx eax, bl + movzx ebx, bl + shl eax, BSPApicIDSaveStart ; Save current BSP APIC ID in MM1[31:24] + mov cx, si + shr bl, cl ; get Bus number in BL + or eax, ebx + movd mm1, eax ; save Bus number MM1[7:0] + + ; + ; Enable MM PCI-E Config Space + ; --cr-- use register symbol name; should upper 32 bit be cleared + ; + mov eax, 080000060h ; MCHBAR + mov dx, 0CF8h + out dx, eax + mov dx, 0CFCh + mov eax, 04h + out dx, eax + in eax, dx + or eax, MMCFG_BASE OR ENABLE + out dx, eax + + ; Clear reset flag + movd eax, mm1 + and eax, NOT BIT18+BIT19 + movd mm1, eax + + ; + ; Enable SPI prefetching and caching + ; + mov esi, PCH_LPC_BIOS_CNTL_PCI_ADDR ; Bus0:Dev31:Func0:RegDCh + and BYTE PTR es:[esi], NOT (11b SHL 2) + or BYTE PTR es:[esi], (10b SHL 2) ; D31:F0:RegDCh[3:2] = 10b + + RET_ESI + +EnableAccessCSR ENDP + +; STATUS_CODE (03h) +PlatformInitialization PROC NEAR PRIVATE + + ; + ; Program PCI Express base address + ; + + mov eax, 80000060h ; 0:0:0:60 + mov dx, 0CF8h + out dx, eax + mov dx, 0CFCh + ;using Pcd instead + ;mov eax, 0e0000000h OR 00h OR 1 +; mov eax, DWORD PTR PcdGet64 (PcdPciExpressBaseAddress) + mov eax, DWORD PTR PCIEXPRESS_BASE_ADDRESS + or eax, (PCIEX_LENGTH_BIT_SETTING OR 1) + out dx, eax + + ; + ; Enable Mch Bar + ; + mov esi, MCHBAR_REG + mov eax, (MCH_BASE_ADDRESS + 1) + mov Dword Ptr [esi], eax + + ; + ; Enable RCRB in PCH. + ; + mov esi, PCH_LPC_RCRB_PCI_ADDR + mov eax, PCH_RCRB_BASE + 1 + mov Dword Ptr [esi], eax + + ; + ; Configure GPIO to be able to initiate LVL change for GPIO48 for S3 resume time calculation. + ; + ; Enable GPIO BASE I/O registers + ; + mov eax, PCI_LPC_BASE + 48h + mov dx, 0CF8h + out dx, eax + mov eax, GPIO_BASE_ADDRESS + add dx, 4 + out dx, eax + + mov eax, PCI_LPC_BASE + 4Ch + mov dx, 0CF8h + out dx, eax + add dx, 4 + in al, dx + or al, BIT4 ; GPIOBASE Enable + out dx, al + + ;GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native + mov dx, GPIO_BASE_ADDRESS + R_GPIO_USE_SEL2 + in eax, dx + or eax, 010000h ;Enable GPIO48 + out dx, eax + + ;GP_IO_SEL2 Register -> 1 = Input 0 = Output (if Native Mode don't care) + mov dx, GPIO_BASE_ADDRESS + R_GPIO_IO_SEL2 + in eax, dx + and eax, 0FFFEFFFFh ;Configure GPIO48 as Output + out dx, eax + + mov dx, GPIO_BASE_ADDRESS + R_GPIO_LVL2 + in eax, dx + or eax, 010000h ;Configure GPIO48 as High + out dx, eax + + ; + ; Program and Enable ACPI PM Base. + ; + mov esi, PCH_LPC_PMBASE_PCI_ADDR + mov eax, PCH_ACPI_BASE_ADDRESS + 1 + mov Dword Ptr [esi], eax + mov esi, PCH_LPC_ACPICNTL_PCI_ADDR + or Dword Ptr [esi], 00000080h + + ; + ; PCH BIOS Spec Rev 0.5.0 Section 12.9 + ; Additional Programming Requirements for USB Support + ; Step 2.b + ; Clear RCBA + 3598h [0] to 0b + ; + mov esi, PCH_RCRB_BASE + 3598h + mov eax, 0 + mov Dword Ptr [esi], eax + + ; + ; Enable HPET decode in PCH. + ; + mov esi, PCH_RCRB_BASE + PCH_RCRB_HPET + mov eax, PCH_RCRB_HPET_DECODE + mov Dword Ptr [esi], eax + mov eax, Dword ptr [esi] + xor eax, eax + mov esi, HPET_COMP_1 + mov Dword Ptr [esi], eax + mov esi, HPET_COMP_2 + mov Dword ptr [esi], eax + + ; + ; Enable the upper 128-byte bank of RTC RAM. + ; + mov esi, PCH_RCRB_BASE + PCH_RCRB_RTC_CONF + mov eax, Dword Ptr [esi] + or eax, PCH_RCRB_RTC_CONF_UCMOS_EN + mov Dword Ptr [esi], eax + + ; + ; Choose Port80 Route + ; + mov esi, PCH_RCRB_BASE + PCH_RCRB_GCS + mov ebx, Dword Ptr [esi] + or bl, BIT5 + + ; + ; check SETUP option - PchPort80Route + ; 0 = LPC {Default]; 1 = PCI + ; +; mov al, CMOS_PCH_PORT80_OFFSET ; CMOS Offset = 17h +; mov dx, RTC_UPPER_INDEX +; out dx, al +; inc dx +; in al, dx +; test al, BIT0 +; jnz @F + and bl, NOT (BIT2) ; Port80h to LPC +;@@: + mov Dword Ptr [esi], ebx + + ; + ; Halt TCO Timer + ; + mov dx, 0468h + in ax, dx + or ax, BIT11 + out dx, ax + + ; + ; Clear the Second TO status bit + ; + mov dx, 0466h + in ax, dx + or ax, BIT1 + out dx, ax + + RET_ESI + +PlatformInitialization ENDP + +; STATUS_CODE (03h) +DetectNumOfCPUSocket PROC NEAR PRIVATE + + ; only one socket + movd eax, mm1 ; get MM1 value into EAX + mov ah, 01 + movd mm1, eax ; save CPU pkg count into MM1[15:8] + + RET_ESI + +DetectNumOfCPUSocket ENDP + +; STATUS_CODE (07h) +VeryEarlyMicrocodeUpdate PROC NEAR PRIVATE + +IF EARLY_MICROCODE_SUPPORT + mov ecx, IA32_BIOS_SIGN_ID + rdmsr ; CPU PatchID -> EDX + cmp edx, 0 ; If microcode has been updated + jnz luExit ; Skip if patch already loaded + + mov ecx, IA32_PLATFORM_ID ; To get Platform ID. + rdmsr + shr edx, 18 ; EDX[0-2] = Platform ID. + and dx, 07h ; DX = Platform ID. + mov si, dx ; Save Platform ID in FS. + mov eax, 01h ; To get CPU signature. + cpuid ; EAX = CPU signature. + mov cx, si ; CX = Platform ID + xor edx, edx + bts dx, cx ; EDX = Platform ID bit. + +; mov esi, PcdGet32 (PcdFlashMicrocodeFvBase) + mov esi, MICROCODE_FV_BASE_ADDRESS + + mov ebx, esi + mov bx, FVHEADER_LEN_OFF + movzx ebx, WORD PTR [ebx] + add esi, ebx + add si, FFSHEADER_LEN ; add FFS header + +; mov edi, PcdGet32 (PcdFlashMicrocodeFvBase) +; mov ebx, PcdGet32 (PcdFlashMicrocodeFvSize) + mov edi, MICROCODE_FV_BASE_ADDRESS + mov ebx, MICROCODE_FV_SIZE + add edi, ebx ;End addr of uCodes. + + ; EAX = CPU signature. + ; EDX = Platform ID bit. + ; ESI = Abs addr of contiguous uCode blocks. + ; EDI = Abs addr of contiguous uCode blocks end. + +luCheckPatch: + cmp (UpdateHeaderStruc PTR ds:[esi]).dProcessorSignature, eax;Sig matched? + jnz luCheckUnprogrammed ; No. + test (UpdateHeaderStruc PTR ds:[esi]).dProcessorFlags, edx;Platform matched? + jnz luFoundMatch ; Yes. + +luCheckUnprogrammed: + mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dDataSize + cmp ebx, 0FFFFFFFFh + je luUnprogrammed + cmp (UpdateHeaderStruc PTR ds:[esi]).dLoaderRevision, 1 + je luCheckExtdHdrs + +luUnprogrammed: + mov ebx, 1024 ; Unprogrammed space, 1KB checks + jmp luPoinToNextBlock ; for backword compatibility. + +luCheckExtdHdrs: + add ebx, SIZEOF(UpdateHeaderStruc) + cmp ebx, (UpdateHeaderStruc PTR ds:[esi]).dTotalSize + jae luTryNextPatch ; No extd hdrs. + + mov ecx, DWORD PTR ds:[esi + ebx] + jcxz luTryNextPatch ; No extd hdrs. (OK to use CX instead of ECX). + add ebx, 20 ; Point to the first Extd Sig. +luNextSig: + cmp eax, DWORD PTR ds:[esi + ebx] ;Sig matched? + jne lu_00 + test edx, DWORD PTR ds:[esi + ebx + 4] ;Platform matched? + jnz luFoundMatch +lu_00: + add ebx, 12 + loop luNextSig + +luTryNextPatch: + mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dTotalSize + or ebx, ebx + jnz luPoinToNextBlock ; Variable size uCode format. + mov ebx, BLOCK_LENGTH_BYTES ; Fixed size uCode format. + +; +; Add alignment check - begin +; + test ebx, 0400h + jz @F + add ebx, 0400h +@@: +; +; Add alignment check - end +; + +luPoinToNextBlock: + add esi, ebx + cmp esi, edi + jb luCheckPatch ; Check with all patches. + + ; Check possible multiple patch + movd eax, mm3 + movd esi, mm4 + or eax, eax + jnz luLoadPatch + jmp luExit ; No matching patch found. + +luFoundMatch: +; MM3 = Patch Revision +; MM4 = Patch Pointer + movd ebx, mm3 + cmp (UpdateHeaderStruc PTR ds:[esi]).dUpdateRevision, ebx + jb luTryNextPatch + + mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dUpdateRevision + +luStoreRevPtr: + movd mm3, ebx ; save Patch Revision + movd mm4, esi ; save Patch Pointer + jmp luTryNextPatch + +luLoadPatch: + mov ecx, IA32_BIOS_UPDT_TRIG + mov eax, esi ; EAX - Abs addr of uCode patch. + add eax, SIZEOF(UpdateHeaderStruc) ; EAX - Abs addr of uCode data. + xor edx, edx ; EDX:EAX - Abs addr of uCode data. + wrmsr ; Trigger uCode load. + +luExit: + +ENDIF + + RET_EBP +VeryEarlyMicrocodeUpdate ENDP + + +; STATUS_CODE (09h) +;************************************************************ +; Description: +; +; This function initializes the Cache for Data, Stack, and Code +; as specified in the BIOS Writer's Guide. +;************************************************************ +InitializeNEM PROC NEAR PRIVATE +IFDEF BOOT_GUARD_SUPPORT_FLAG + ; + ; Detect Boot Guard Boot + ; + mov ecx, MSR_BOOT_GUARD_SACM_INFO ; + rdmsr + and eax, 01h + jnz BootGuardNemSetup +ENDIF + + ; + ; Enable cache for use as stack and for caching code + ; The algorithm is specified in the processor BIOS writer's guide + ; + + ; + ; Ensure that the system is in flat 32 bit protected mode. + ; + ; Platform Specific - configured earlier + ; + ; Ensure that only one logical processor in the system is the BSP. + ; (Required step for clustered systems). + ; + ; Platform Specific - configured earlier + + ; Ensure all APs are in the Wait for SIPI state. + ; This includes all other logical processors in the same physical processor + ; as the BSP and all logical processors in other physical processors. + ; If any APs are awake, the BIOS must put them back into the Wait for + ; SIPI state by issuing a broadcast INIT IPI to all excluding self. + ; + mov edi, APIC_ICR_LO ; 0FEE00300h - Send INIT IPI to all excluding self + mov eax, ORAllButSelf + ORSelfINIT ; 0000C4500h + mov [edi], eax + +@@: + mov eax, [edi] + bt eax, 12 ; Check if send is in progress + jc @B ; Loop until idle + + ; + ; Load microcode update into BSP. + ; + ; Ensure that all variable-range MTRR valid flags are clear and + ; IA32_MTRR_DEF_TYPE MSR E flag is clear. Note: This is the default state + ; after hardware reset. + ; + ; Platform Specific - MTRR are usually in default state. + ; + + ; + ; Initialize all fixed-range and variable-range MTRR register fields to 0. + ; + mov ecx, IA32_MTRR_CAP ; get variable MTRR support + rdmsr + movzx ebx, al ; EBX = number of variable MTRR pairs + shl ebx, 2 ; *4 for Base/Mask pair and WORD size + add ebx, MtrrCountFixed * 2 ; EBX = size of Fixed and Variable MTRRs + + xor eax, eax ; Clear the low dword to write + xor edx, edx ; Clear the high dword to write + ;;;mov ebx, MtrrCount * 2 ; ebx <- sizeof MtrrInitTable +InitMtrrLoop: + add ebx, -2 + movzx ecx, WORD PTR cs:MtrrInitTable[ebx] ; ecx <- address of mtrr to zero + wrmsr + jnz InitMtrrLoop ; loop through the whole table + + ; + ; Configure the default memory type to un-cacheable (UC) in the + ; IA32_MTRR_DEF_TYPE MSR. + ; + mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index + rdmsr + and eax, NOT (00000CFFh) ; Clear the enable bits and def type UC. + wrmsr + + ; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB + ; based on the physical address size supported for this processor + ; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0] + ; + ; Examples: + ; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing + ; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing + ; + mov eax, 80000008h ; Address sizes leaf + cpuid + sub al, 32 + movzx eax, al + xor esi, esi + bts esi, eax + dec esi ; esi <- MTRR_PHYS_MASK_HIGH + + ; + ; Configure the DataStack region as write-back (WB) cacheable memory type + ; using the variable range MTRRs. + ; + + ; + ; Set the base address of the DataStack cache range + ; +; mov eax, PcdGet32 (PcdTemporaryRamBase) + mov eax, TEMPORARY_RAM_BASE_ADDRESS + or eax, MTRR_MEMORY_TYPE_WB + ; Load the write-back cache value + xor edx, edx ; clear upper dword + mov ecx, MTRR_PHYS_BASE_0 ; Load the MTRR index + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Set the mask for the DataStack cache range + ; Compute MTRR mask value: Mask = NOT (Size - 1) + ; +; mov eax, PcdGet32 (PcdTemporaryRamSize) + mov eax, TEMPORARY_RAM_SIZE + dec eax + not eax + or eax, MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + mov ecx, MTRR_PHYS_MASK_0 ; For proper addressing above 4GB + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Configure the BIOS code region as write-protected (WP) cacheable + ; memory type using a single variable range MTRR. + ; + ; Platform Specific - ensure region to cache meets MTRR requirements for + ; size and alignment. + ; + + ; + ; Save MM5 into ESP before program MTRR, because program MTRR will use MM5 as the local variable. + ; And, ESP is not initialized before CAR is enabled. So, it is safe ot use ESP here. + ; + movd esp, mm5 + + ; + ; Get total size of cache from PCD if it need fix value + ; +; mov eax, PcdGet32 (PcdNemCodeCacheSize) + mov eax, CODE_CACHE_SIZE + ; + ; Calculate NEM size + ; Determine LLC size by following RS - Haswell Processor Family BIOS Writer's Guide (BWG) 0.3.0 + ; Section 4.4.5 - The size of the code region and data region combined must not exceed the size + ; of the (Last Level Cache - 0.5MB). + ; + ; Determine Cache Parameter by CPUID Function 04h + ; + xor ecx, ecx + xor edi, edi + +Find_LLC_parameter: + mov ecx, edi + mov eax, 4 + cpuid + inc edi + and eax, 01Fh ; If EAX[4:0]=0, which indicates no more caches, then we can get LLC parameters + jnz Find_LLC_parameter + ; + ; LLC configuration is pointed to edi-2 + ; + dec edi + dec edi + mov ecx, edi + mov eax, 4 + cpuid + ; + ; Got LLC parameters + ; + ; This Cache Size in Bytes = (Ways + 1) * (Partitions + 1) * (Line_Size + 1) * (Sets + 1) + ; = (EBX[31:22] + 1) * (EBX[21:12] + 1) * (EBX[11:0] + 1) * (ECX + 1) + ; + mov eax, ecx + inc eax + mov edi, ebx + shr ebx, 22 + inc ebx + mul ebx + mov ebx, edi + and ebx, NOT 0FFC00FFFh + shr ebx, 12 + inc ebx + mul ebx + mov ebx, edi + and ebx, 0FFFh + inc ebx + mul ebx + ; + ; Maximum NEM size <= (Last Level Cache - 0.5MB) + ; + sub eax, 512*1024 +Got_NEM_size: + ; + ; Code cache size = Total NEM size - DataStack size + ; +; sub eax, PcdGet32 (PcdTemporaryRamSize) + sub eax, TEMPORARY_RAM_SIZE + ; + ; Set the base address of the CodeRegion cache range from PCD + ; PcdNemCodeCacheBase is set to the offset to flash base, + ; so add PcdFlashAreaBaseAddress to get the real code base address. + ; +; mov edi, PcdGet32 (PcdNemCodeCacheBase) +; add edi, PcdGet32 (PcdFlashAreaBaseAddress) + mov edi, CODE_CACHE_BASE_ADDRESS + add edi, FLASH_AREA_BASE_ADDRESS + + ; + ; Round up to page size + ; + mov ecx, eax ; Save + and ecx, 0FFFF0000h ; Number of pages in 64K + and eax, 0FFFFh ; Number of "less-than-page" bytes + jz Rounded + mov eax, 10000h ; Add the whole page size + +Rounded: + add eax, ecx ; eax - rounded up code cache size + + ; + ; Define "local" vars for this routine + ; Note that mm0 is used to store BIST result for BSP, + ; mm1 is used to store the number of processor and BSP APIC ID, + ; mm6 is used to save time-stamp counter value. + ; + CODE_SIZE_TO_CACHE TEXTEQU <mm3> + CODE_BASE_TO_CACHE TEXTEQU <mm4> + NEXT_MTRR_INDEX TEXTEQU <mm5> + NEXT_MTRR_SIZE TEXTEQU <mm2> + ; + ; Initialize "locals" + ; + sub ecx, ecx + movd NEXT_MTRR_INDEX, ecx ; Count from 0 but start from MTRR_PHYS_BASE_1 + + ; + ; Save remaining size to cache + ; + movd CODE_SIZE_TO_CACHE, eax ; Size of code cache region that must be cached + movd CODE_BASE_TO_CACHE, edi ; Base code cache address + +NextMtrr: + ; + ; Get remaining size to cache + ; + movd eax, CODE_SIZE_TO_CACHE + and eax, eax + jz CodeRegionMtrrdone ; 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 edi, CODE_BASE_TO_CACHE + bsf ecx, edi ; 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_PHYS_MASK_VALID ; Set valid bit + + ; + ; Program mask register + ; + mov ecx, MTRR_PHYS_MASK_1 ; setup variable mtrr + movd ebx, NEXT_MTRR_INDEX + add ecx, ebx + + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + wrmsr + ; + ; Program base register + ; + sub edx, edx + mov ecx, MTRR_PHYS_BASE_1 ; setup variable mtrr + add ecx, ebx ; ebx is still NEXT_MTRR_INDEX + + movd eax, CODE_BASE_TO_CACHE + or eax, MTRR_MEMORY_TYPE_WP ; set type to write protect + wrmsr + ; + ; Advance and loop + ; Reduce remaining size to cache + ; + movd ebx, CODE_SIZE_TO_CACHE + movd eax, NEXT_MTRR_SIZE + sub ebx, eax + movd CODE_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, CODE_BASE_TO_CACHE + movd eax, NEXT_MTRR_SIZE + add ebx, eax + ; + ; if carry happens, means NEM base + size over 4G + ; + jc CodeRegionMtrrdone + movd CODE_BASE_TO_CACHE, ebx + + jmp NextMtrr + +CodeRegionMtrrdone: + ; Program the variable MTRR's MASK register for WDB + ; (Write Data Buffer, used in MRC, must be WC type) + ; + mov ecx, MTRR_PHYS_MASK_1 + movd ebx, NEXT_MTRR_INDEX + add ecx, ebx + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID ; turn on the Valid flag + wrmsr + + ; + ; Program the variable MTRR's BASE register for WDB + ; + dec ecx + xor edx, edx + mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC + wrmsr + + ; + ; Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag. + ; + mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index + rdmsr + or eax, MTRR_DEF_TYPE_E ; Enable variable range MTRRs + wrmsr + + ; + ; Enable the logical processor's (BSP) cache: execute INVD and set + ; CR0.CD = 0, CR0.NW = 0. + ; + mov eax, cr0 + and eax, NOT (CR0_CACHE_DISABLE + CR0_NO_WRITE) + invd + mov cr0, eax + ; + ; Enable No-Eviction Mode Setup State by setting + ; NO_EVICT_MODE MSR 2E0h bit [0] = '1'. + ; + mov ecx, NO_EVICT_MODE + rdmsr + or eax, 1 + wrmsr + + ; + ; Restore MM5 from ESP after program MTRR + ; + movd mm5, esp + + ; + ; One location in each 64-byte cache line of the DataStack region + ; must be written to set all cache values to the modified state. + ; +; mov edi, PcdGet32 (PcdTemporaryRamBase) +; mov ecx, PcdGet32 (PcdTemporaryRamSize) + mov edi, TEMPORARY_RAM_BASE_ADDRESS + mov ecx, TEMPORARY_RAM_SIZE + shr ecx, 6 + mov eax, CACHE_INIT_VALUE +@@: + mov [edi], eax + sfence + add edi, 64 + loopd @b + + ; + ; Enable No-Eviction Mode Run State by setting + ; NO_EVICT_MODE MSR 2E0h bit [1] = '1'. + ; + mov ecx, NO_EVICT_MODE + rdmsr + or eax, 2 + wrmsr + +IFDEF BOOT_GUARD_SUPPORT_FLAG + jmp FinishedCacheConfig + + ; + ; Jump to here when Boot Guard boot and NEM is initialized by Boot Guard ACM + ; +BootGuardNemSetup: + ; + ; Finished with cache configuration + ; + ; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB + ; based on the physical address size supported for this processor + ; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0] + ; + ; Examples: + ; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing + ; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing + ; + mov eax, 80000008h ; Address sizes leaf + cpuid + sub al, 32 + movzx eax, al + xor esi, esi + bts esi, eax + dec esi ; esi <- MTRR_PHYS_MASK_HIGH + + ; + ; Configure the DataStack region as write-back (WB) cacheable memory type + ; using the variable range MTRRs. + ; + ; + ; Find available MTRR + ; + CALL_EBP FindFreeMtrr + + ; + ; Set the base address of the DataStack cache range + ; +; mov eax, PcdGet32 (PcdTemporaryRamBase) + mov eax, TEMPORARY_RAM_BASE_ADDRESS + or eax, MTRR_MEMORY_TYPE_WB + ; Load the write-back cache value + xor edx, edx ; clear upper dword + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Set the mask for the DataStack cache range + ; Compute MTRR mask value: Mask = NOT (Size - 1) + ; +; mov eax, PcdGet32 (PcdTemporaryRamSize) + mov eax, TEMPORARY_RAM_SIZE + dec eax + not eax + or eax, MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + inc ecx + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Program the variable MTRR's MASK register for WDB + ; (Write Data Buffer, used in MRC, must be WC type) + ; + + ; + ; Find available MTRR + ; + CALL_EBP FindFreeMtrr + +FoundAvailableMtrr: + ; + ; Program the variable MTRR's BASE register for WDB + ; + xor edx, edx + mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC + wrmsr + + inc ecx + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID ; turn on the Valid flag + wrmsr + + ; + ; One location in each 64-byte cache line of the DataStack region + ; must be written to set all cache values to the modified state. + ; +; mov edi, PcdGet32 (PcdTemporaryRamBase) +; mov ecx, PcdGet32 (PcdTemporaryRamSize) + mov edi, TEMPORARY_RAM_BASE_ADDRESS + mov ecx, TEMPORARY_RAM_SIZE + shr ecx, 6 + mov eax, CACHE_INIT_VALUE +@@: + mov [edi], eax + sfence + add edi, 64 + loopd @b +ENDIF + + ; + ; Finished with cache configuration + ; +FinishedCacheConfig: + + ; + ; Optionally Test the Region... + ; + + ; + ; Test area by writing and reading + ; + cld +; mov edi, PcdGet32 (PcdTemporaryRamBase) +; mov ecx, PcdGet32 (PcdTemporaryRamSize) + mov edi, TEMPORARY_RAM_BASE_ADDRESS + mov ecx, TEMPORARY_RAM_SIZE + shr ecx, 2 + mov eax, CACHE_TEST_VALUE +TestDataStackArea: + stosd + cmp eax, DWORD PTR [edi-4] + jnz DataStackTestFail + loop TestDataStackArea + jmp DataStackTestPass + + ; + ; Cache test failed + ; +DataStackTestFail: + STATUS_CODE (0D0h) + jmp $ + + ; + ; Configuration test failed + ; +ConfigurationTestFailed: + STATUS_CODE (0D1h) + jmp $ + +DataStackTestPass: + + ; + ; At this point you may continue normal execution. Typically this would include + ; reserving stack, initializing the stack pointer, etc. + ; + + ; + ; After memory initialization is complete, please follow the algorithm in the BIOS + ; Writer's Guide to properly transition to a normal system configuration. + ; The algorithm covers the required sequence to properly exit this mode. + ; + + RET_ESI + +InitializeNEM ENDP + +; STATUS_CODE (09h) +EstablishStack PROC NEAR PRIVATE + + ; + ; Enable STACK + ; + RET_ESI + +EstablishStack ENDP + +FindFreeMtrr PROC NEAR PRIVATE + mov ecx, MTRR_PHYS_MASK_0 + +@@: + rdmsr + test eax, 800h + jz FoundFreeMtrr + add ecx, 2 + cmp ecx, MTRR_PHYS_MASK_9 + jbe @b + ; + ; No available MTRR, halt system + ; + jmp $ + +FoundFreeMtrr: + dec ecx + + RET_EBP + +FindFreeMtrr ENDP + +; STATUS_CODE (0Bh) +CallPeiCoreEntryPoint PROC NEAR PRIVATE + ; + ; Set stack top pointer + ; +; mov esp, PcdGet32 (PcdTemporaryRamBase) +; add esp, PcdGet32 (PcdTemporaryRamSize) + mov esp, TEMPORARY_RAM_BASE_ADDRESS + add esp, TEMPORARY_RAM_SIZE + + ; + ; Push CPU count to stack first, then AP's (if there is one) + ; BIST status, and then BSP's + ; + + ; + ; Here work around for BIST + ; + ; Get number of BSPs + movd ecx, mm1 + movzx ecx, ch + + ; Save number of BSPs + push ecx + +GetSBSPBist: + ; Save SBSP BIST + movd eax, mm0 + push eax + + ; Save SBSP APIC ID + movd eax, mm1 + shr eax, BSPApicIDSaveStart ; Resume APIC ID + push eax + + ; Save Time-Stamp Counter + movd eax, mm5 + push eax + + movd eax, mm6 + push eax + +TransferToSecStartup: + + + + ; Switch to "C" code + STATUS_CODE (0Ch) + ; + ; Pass entry point of the PEI core + ; + mov edi, PEI_CORE_ENTRY_BASE ; 0FFFFFFE0h + push DWORD PTR ds:[edi] + + ; + ; Pass BFV into the PEI Core + ; + mov edi, FV_MAIN_BASE ; 0FFFFFFFCh + push DWORD PTR ds:[edi] + + ; ECPoverride: SecStartup entry point needs 4 parameters +; push PcdGet32 (PcdTemporaryRamBase) + push TEMPORARY_RAM_BASE_ADDRESS + + ; + ; Pass stack size into the PEI Core + ; +; push PcdGet32 (PcdTemporaryRamSize) + push TEMPORARY_RAM_SIZE + + ; + ; Pass Control into the PEI Core + ; + call SecStartup +CallPeiCoreEntryPoint ENDP + +StartUpAp PROC NEAR + + mov esi, HPET_COMP_2 + lock inc byte ptr [esi] + + DISABLE_CACHE +; +; Halt the AP and wait for the next SIPI +; +Ap_Halt: + cli +@@: + hlt + jmp @B + ret +StartUpAp ENDP + + +CheckValidCMOS PROC NEAR PRIVATE + ; + ; Check CMOS Status + ; + mov esi, PCH_LPC_GEN_PMCON_3_ADDR + mov eax, es:[esi] + + ; check PWR_FLR and RTC_PWR_STS status + and eax, BIT2 + BIT1 + + RET_EBP +CheckValidCMOS ENDP + +MtrrInitTable LABEL BYTE + DW MTRR_DEF_TYPE + DW MTRR_FIX_64K_00000 + DW MTRR_FIX_16K_80000 + DW MTRR_FIX_16K_A0000 + DW MTRR_FIX_4K_C0000 + DW MTRR_FIX_4K_C8000 + DW MTRR_FIX_4K_D0000 + DW MTRR_FIX_4K_D8000 + DW MTRR_FIX_4K_E0000 + DW MTRR_FIX_4K_E8000 + DW MTRR_FIX_4K_F0000 + DW MTRR_FIX_4K_F8000 + +MtrrCountFixed EQU (($ - MtrrInitTable) / 2) + + DW MTRR_PHYS_BASE_0 + DW MTRR_PHYS_MASK_0 + DW MTRR_PHYS_BASE_1 + DW MTRR_PHYS_MASK_1 + DW MTRR_PHYS_BASE_2 + DW MTRR_PHYS_MASK_2 + DW MTRR_PHYS_BASE_3 + DW MTRR_PHYS_MASK_3 + DW MTRR_PHYS_BASE_4 + DW MTRR_PHYS_MASK_4 + DW MTRR_PHYS_BASE_5 + DW MTRR_PHYS_MASK_5 + DW MTRR_PHYS_BASE_6 + DW MTRR_PHYS_MASK_6 + DW MTRR_PHYS_BASE_7 + DW MTRR_PHYS_MASK_7 + DW MTRR_PHYS_BASE_8 + DW MTRR_PHYS_MASK_8 + DW MTRR_PHYS_BASE_9 + DW MTRR_PHYS_MASK_9 +MtrrCount EQU (($ - MtrrInitTable) / 2) + +align 10h +PUBLIC BootGDTtable + +; +; GDT[0]: 0x00: Null entry, never used. +; +NULL_SEL EQU $ - GDT_BASE ; Selector [0] +GDT_BASE: +BootGDTtable DD 0 + DD 0 +; +; Linear data segment descriptor +; +LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 092h ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Linear code segment descriptor +; +LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Bh ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; System data segment descriptor +; +SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 + +; +; System code segment descriptor +; +SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Ah ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0Eh ; Changed from F000 to E000. + DB 09Bh ; present, ring 0, code, expand-up, writable + DB 00h ; byte-granular, 16-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 00h ; byte-granular, 16-bit + DB 0 + +; +; Spare segment descriptor +; +SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38] + DW 0 ; limit 0 + DW 0 ; base 0 + DB 0 + DB 0 ; present, ring 0, data, expand-up, writable + DB 0 ; page-granular, 32-bit + DB 0 +GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes + +GdtDesc: ; GDT descriptor +OffsetGDTDesc EQU $ - _ModuleEntryPoint + DW GDT_SIZE - 1 ; GDT limit + DD OFFSET BootGDTtable ; GDT base address + +NemInitLinearAddress LABEL FWORD +NemInitLinearOffset LABEL DWORD + DD OFFSET ProtectedModeSECStart ; Offset of our 32 bit code + DW LINEAR_CODE_SEL + +TopOfCar DD TEMPORARY_RAM_BASE_ADDRESS + TEMPORARY_RAM_SIZE + +_TEXT_PROTECTED_MODE ENDS +END diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Ia32.inc b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Ia32.inc new file mode 100644 index 0000000..d799a1e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Ia32.inc @@ -0,0 +1,164 @@ +;@file +; IA32 architecture MSRs +; +;@copyright +; Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved +; This software and associated documentation (if any) is furnished +; under a license and may only be used or copied in accordance +; with the terms of the license. Except as permitted by such +; license, no part of this software or documentation may be +; reproduced, stored in a retrieval system, or transmitted in any +; form or by any means without the express written consent of +; Intel Corporation. +; +; This file contains a 'Sample Driver' and is licensed as such +; under the terms of your license agreement with Intel or your +; vendor. This file may be modified by the user, subject to +; the additional terms of the license agreement +; + +IA32_MTRR_CAP EQU 0FEh +MTRR_PHYS_BASE_0 EQU 0200h +MTRR_PHYS_MASK_0 EQU 0201h +MTRR_PHYS_BASE_1 EQU 0202h +MTRR_PHYS_MASK_1 EQU 0203h +MTRR_PHYS_BASE_2 EQU 0204h +MTRR_PHYS_MASK_2 EQU 0205h +MTRR_PHYS_BASE_3 EQU 0206h +MTRR_PHYS_MASK_3 EQU 0207h +MTRR_PHYS_BASE_4 EQU 0208h +MTRR_PHYS_MASK_4 EQU 0209h +MTRR_PHYS_BASE_5 EQU 020Ah +MTRR_PHYS_MASK_5 EQU 020Bh +MTRR_PHYS_BASE_6 EQU 020Ch +MTRR_PHYS_MASK_6 EQU 020Dh +MTRR_PHYS_BASE_7 EQU 020Eh +MTRR_PHYS_MASK_7 EQU 020Fh +MTRR_PHYS_BASE_8 EQU 0210h +MTRR_PHYS_MASK_8 EQU 0211h +MTRR_PHYS_BASE_9 EQU 0212h +MTRR_PHYS_MASK_9 EQU 0213h +MTRR_FIX_64K_00000 EQU 0250h +MTRR_FIX_16K_80000 EQU 0258h +MTRR_FIX_16K_A0000 EQU 0259h +MTRR_FIX_4K_C0000 EQU 0268h +MTRR_FIX_4K_C8000 EQU 0269h +MTRR_FIX_4K_D0000 EQU 026Ah +MTRR_FIX_4K_D8000 EQU 026Bh +MTRR_FIX_4K_E0000 EQU 026Ch +MTRR_FIX_4K_E8000 EQU 026Dh +MTRR_FIX_4K_F0000 EQU 026Eh +MTRR_FIX_4K_F8000 EQU 026Fh +MTRR_DEF_TYPE EQU 02FFh + +MTRR_MEMORY_TYPE_UC EQU 00h +MTRR_MEMORY_TYPE_WC EQU 01h +MTRR_MEMORY_TYPE_WT EQU 04h +MTRR_MEMORY_TYPE_WP EQU 05h +MTRR_MEMORY_TYPE_WB EQU 06h + +MTRR_DEF_TYPE_E EQU 0800h +MTRR_DEF_TYPE_FE EQU 0400h +MTRR_PHYSMASK_VALID EQU 0800h + +; +; Define the high 32 bits of MTRR masking +; This should be read from CPUID EAX = 080000008h, EAX bits [7:0] +; But for most platforms this will be a fixed supported size so it is +; fixed to save space. +; +MTRR_PHYS_MASK_VALID EQU 0800h +MTRR_PHYS_MASK_HIGH EQU 00000000Fh ; For 36 bit addressing +;MTRR_PHYS_MASK_HIGH EQU 0000000FFh ; For 40 bit addressing + +IA32_MISC_ENABLE EQU 1A0h +FAST_STRING_ENABLE_BIT EQU 01h + +CR0_CACHE_DISABLE EQU 040000000h +CR0_NO_WRITE EQU 020000000h + +IA32_PLATFORM_ID EQU 017h +IA32_BIOS_UPDT_TRIG EQU 079h +IA32_BIOS_SIGN_ID EQU 08Bh +PLATFORM_INFO EQU 0CEh +NO_EVICT_MODE EQU 2E0h +NO_EVICTION_ENABLE_BIT EQU 01h + +; +; MSR definitions +; +MSR_IA32_PLATFORM_ID EQU 0017h +MSR_APIC_BASE EQU 001Bh +MSR_SOCKET_ID EQU 0039h +MSR_IA32_FEATURE_CONTROL EQU 003Ah +MSR_CLOCK_CST_CONFIG_CONTROL EQU 00E2h +MSR_CLOCK_FLEX_MAX EQU 0194h +MSR_IA32_PERF_STS EQU 0198h +MSR_IA32_PERF_CTL EQU 0199h +MSR_IA32_MISC_ENABLES EQU 01A0h +MSR_IA32_MC8_MISC2 EQU 0288h +MSR_IA32_MC7_CTL EQU 041Ch +MSR_BOOT_GUARD_SACM_INFO EQU 013Ah + +; +; Processor MSR definitions +; +MSR_BBL_CR_CTL3 EQU 011Eh ; L2 cache configuration MSR +B_MSR_BBL_CR_CTL3_L2_NOT_PRESENT EQU 23 ; L2 not present +B_MSR_BBL_CR_CTL3_L2_ENABLED EQU 8 ; L2 enabled +B_MSR_BBL_CR_CTL3_L2_HARDWARE_ENABLED EQU 0 ; L2 hardware enabled + +P6RatioBitsMask EQU 01Fh ; Bitmask for cpu ratio +P6_FREQ_LOCKED_BIT EQU 15d + +; +; Local APIC Register Equates +; +LOCAL_APIC_ID_REG EQU 0FEE00020h +APIC_ICR_HI EQU 0FEE00310h +APIC_ICR_LO EQU 0FEE00300h +ANDICRMask EQU 0FFF32000h ; AND mask for ICR Saving reserved bits +ORSelfINIT EQU 000004500h ; OR mask to send INIT IPI to itself +ORAllButSelf EQU 0000C0000h ; OR mask to set dest field = "All But Self" + +; +; Cache control macro +; +DISABLE_CACHE macro + mov eax, cr0 + or eax, CR0_CACHE_DISABLE + CR0_NO_WRITE + wbinvd + mov cr0, eax +endm + +ENABLE_CACHE macro + mov eax, cr0 + and eax, NOT (CR0_CACHE_DISABLE + CR0_NO_WRITE) + wbinvd + mov cr0, eax +endm + +VENDOR_ID_REG EQU 0 +PCI_REVISION_ID_REG EQU 8 +CPU_GENERIC_UNCORE_DEV EQU 0 +CPU_GENERIC_UNCORE_FUNC EQU 0 +CPU_LINK_1_DEV EQU 2 +CPU_LINK_1_FUNC EQU 4 + +B0_CPU_STEPPING EQU 10h + +BLOCK_LENGTH_BYTES EQU 2048 + +UpdateHeaderStruc STRUC + dHeaderVersion dd ? ; Header version# + dUpdateRevision dd ? ; Update revision# + dDate dd ? ; Date in binary (08/13/07 as 0x08132007) + dProcessorSignature dd ? ; CPU type, family, model, stepping + dChecksum dd ? ; Checksum + dLoaderRevision dd ? ; Update loader version# + dProcessorFlags dd ? ; Processor Flags + dDataSize dd ? ; Size of encrypted data + dTotalSize dd ? ; Total size of update in bytes + bReserved db 12 dup(?) ; 12 bytes reserved +UpdateHeaderStruc ENDS + diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Platform.inc b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Platform.inc new file mode 100644 index 0000000..b49f518 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/Platform.inc @@ -0,0 +1,196 @@ +;@file +; Platform Specific Definitions +; +;@copyright +; Copyright (c) 2011 - 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 +; + +;(AMI_CHG-)INCLUDE FlashMap.inc + +; Set "MINIMUM_BOOT_SUPPORT" flag allows BIOS boot as minimum feature in SEC phase. +MINIMUM_BOOT_SUPPORT EQU 0 ; ="0", Normal Boot; + ; ="1", Minimum Feature Boot +; "RESET_IN_SEC" flag allows BIOS doing RESET in SEC phase +RESET_IN_SEC EQU 0 ; ="0", RESET occurs in OemIohInit.c + ; ="1", RESET occurs in SEC phase + +EARLY_MICROCODE_SUPPORT EQU 1 +DETERMINISTIC_BSP_SUPPORT EQU 0 +DEBUG EQU 1 + +; +; IO port to access the upper 128-byte of RTC RAM +; +RTC_UPPER_INDEX EQU 072h +RTC_UPPER_DATA EQU 073h + +; +; Offset of data stored in the upper 128-byte of RTC RAM. +; +CMOS_CPU_BSP_SELECT EQU 010h ; BspSelection +CMOS_CPU_UP_MODE EQU 011h ; UpBootSelection + +; +; Cpu Ratio and Vid stored in the upper 128-byte of RTC RAM. +; +CMOS_CPU_RATIO_OFFSET EQU 012h ; ProcessorFlexibleRatio +CMOS_CPU_CORE_HT_OFFSET EQU 013h ; ProcessorHyperThreadingEnable & EnableCoresInSbsp & EnableCoresInNbsp + +; +; CPU Feature +; +CMOS_CPU_BIST_OFFSET EQU 015h ; ProcessorBistEnable +CMOS_CPU_VMX_OFFSET EQU 016h ; ProcessorVmxEnable + +; +; Port80 Selection +; +CMOS_PCH_PORT80_OFFSET EQU 017h ; PchPort80Route + +; +;Flash layout map +; +PEICODE_REGION_BASE_ADDRESS EQU FLASH_BASE +PEICODE_REGION_SIZE EQU FLASH_SIZE +PEICODE_REGION_SIZE_MASK EQU (NOT (PEICODE_REGION_SIZE - 1)) + +BIOS_REGION_UPDATABLE_STATUS EQU 0058h ; Offset +;---------------------------------------------------------------------------------------- +; "Merlin" support used equates +;---------------------------------------------------------------------------------------- +MAGIC_ADDRESS_IN_SEG EQU 0FFF0h +MAGIC_SEG EQU 0F000h + +; +; -- Equates for CAR initialization +; TileSize (must be a power of 2) +; +; Define the tile size +; The tile size and tile placement are critical to ensuring that no data loss occurs +; See BWG - chapter "Determining Tile Size" +; +TILE_SIZE EQU 000000000h + +; +; See BWG - chapter "Determining Cacheable Code Region Base Addresses and Ranges". +; +; Now FvRecovery is 6 blocks, so it is seperated into 2 parts to set MTRR: +; 1. base address = FFFA0000, length = 0x20000 +; 2. base address = FFFC0000, length = 0x40000 +; +; *** NOTE: If FvRecovery size changes, this code needs to be changed accordingly. +; Possible enhancement is to dynamically accomodate size changes. +; + +;(AMI_CHG)> +;-CODE_REGION_BASE_ADDRESS_PART1 EQU FLASH_REGION_FV_RECOVERY_BASE +;-CODE_REGION_SIZE_PART1 EQU (TILE_SIZE + (128*1024)) + +MIN_CODE_REGION_SIZE EQU 40000h +MIN_CODE_REGION_SIZE_MASK EQU (NOT (MIN_CODE_REGION_SIZE - 1)) +CODE_REGION_BASE_ADDRESS_PART1 EQU MKF_CODE_CACHE_BASE_ADDRESS AND 0ffff0000h +IF MKF_CODE_CACHE_SIZE lt 100000h + CODE_REGION_SIZE_PART1 EQU 100000h +ELSE + CODE_REGION_SIZE_PART1 EQU MKF_CODE_CACHE_SIZE +ENDIF + +CODE_REGION_SIZE_MASK_PART1 EQU (NOT (CODE_REGION_SIZE_PART1 - 1)) + +IF MKF_CODE_CACHE_PART2_BASE +;-CODE_REGION_BASE_ADDRESS_PART2 EQU CODE_REGION_BASE_ADDRESS_PART1 + CODE_REGION_SIZE_PART1 +;-CODE_REGION_SIZE_PART2 EQU (TILE_SIZE + (256*1024)) +CODE_REGION_BASE_ADDRESS_PART2 EQU MKF_CODE_CACHE_PART2_BASE +CODE_REGION_SIZE_PART2 EQU MKF_CODE_CACHE_PART2_SIZE +CODE_REGION_SIZE_MASK_PART2 EQU (NOT (CODE_REGION_SIZE_PART2 - 1)) +ENDIF + +IF MKF_WDB_REGION_BASE_ADDRESS +;-WDB_REGION_BASE_ADDRESS EQU 040000000h +;-WDB_REGION_SIZE EQU 01000h +WDB_REGION_BASE_ADDRESS EQU MKF_WDB_REGION_BASE_ADDRESS +WDB_REGION_SIZE EQU MKF_WDB_REGION_BASE_SIZE +WDB_REGION_SIZE_MASK EQU (NOT (WDB_REGION_SIZE - 1)) +ENDIF +;<(AMI_CHG) + +; +; See BWG - chapter "Determining Data Stack Base Address and Range" +; +;(AMI_CHG)> +;-;DATA_STACK_BASE_ADDRESS EQU (CODE_REGION_BASE_ADDRESS - TILE_SIZE - (16*1024 * 1024)) +;-DATA_STACK_BASE_ADDRESS EQU 0FFB00000h +;-DATA_STACK_SIZE EQU (64*1024) ; 10000h +DATA_STACK_BASE_ADDRESS EQU MKF_CAR_BASE_ADDRESS +DATA_STACK_SIZE EQU MKF_CAR_TOTAL_SIZE +DATA_STACK_SIZE_MASK EQU (NOT (DATA_STACK_SIZE - 1)) +TEMPORARY_RAM_BASE_ADDRESS EQU DATA_STACK_BASE_ADDRESS +TEMPORARY_RAM_SIZE EQU DATA_STACK_SIZE +;<(AMI_CHG) + +; +; Cache init and test values +; These are inverted to flip each bit at least once +; +CACHE_INIT_VALUE EQU 0A5A5A5A5h +CACHE_TEST_VALUE EQU (NOT CACHE_INIT_VALUE) + +PEI_CORE_ENTRY_BASE EQU 0FFFFFFE0h +FV_MAIN_BASE EQU 0FFFFFFFCh + +MAX_NR_BUS EQU 0FFh +MAX_NR_CPU_SOCKETS EQU 2 ; DP example, MP may have 4 or more + +; +; Support EDK1117 build - Sample BASE Address and Size insteads of PcdGet() +; +MICROCODE_FV_BASE_ADDRESS EQU 0FFF20000h ; PcdGet32 (PcdFlashMicrocodeFvBase) +MICROCODE_FV_SIZE EQU 40000h ; PcdGet32 (PcdFlashMicrocodeFvSize) +CODE_CACHE_BASE_ADDRESS EQU 0FFF80000h ; PcdGet32 (PcdNemCodeCacheBase) +CODE_CACHE_SIZE EQU 80000h ; PcdGet32 (PcdNemCodeCacheSize) +FLASH_AREA_BASE_ADDRESS EQU 0FF800000h ; PcdGet32 (PcdFlashAreaBaseAddress) +;(AMI_CHG)> +;TEMPORARY_RAM_BASE_ADDRESS EQU 0FEF00000h ; PcdGet32 (PcdTemporaryRamBase) +;TEMPORARY_RAM_SIZE EQU 2000h ; PcdGet32 (PcdTemporaryRamSize) +;<(AMI_CHG) +PCIEXPRESS_BASE_ADDRESS EQU 0E0000000h ; PcdGet64 (PcdPciExpressBaseAddress) + +BIT0 EQU 01h +BIT1 EQU 02h +BIT2 EQU 04h +BIT3 EQU 08h +BIT4 EQU 10h +BIT5 EQU 20h +BIT6 EQU 40h +BIT7 EQU 80h +BIT8 EQU 100h +BIT9 EQU 200h +BIT10 EQU 400h +BIT11 EQU 800h +BIT12 EQU 1000h +BIT13 EQU 2000h +BIT14 EQU 4000h +BIT15 EQU 8000h +BIT16 EQU 10000h +BIT17 EQU 20000h +BIT18 EQU 40000h +BIT19 EQU 80000h +BIT23 EQU 0800000h +BIT31 EQU 080000000h +; Bit definition in MM1 +BadCMOSDetected EQU (BIT0 shl 17) +BSPApicIDSaveStart EQU 24 diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/ResetVec.asm b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/ResetVec.asm new file mode 100644 index 0000000..54376e5 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/ResetVec.asm @@ -0,0 +1,108 @@ +; +; 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) 2006 - 2011, Intel Corporation. All rights reserved.<BR> +; 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: +; +; ResetVec.asm +; +; Abstract: +; +; Reset Vector Data structure +; This structure is located at 0xFFFFFFC0 +; +;------------------------------------------------------------------------------ + + .model tiny + .686p + .stack 0h + .code + +_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE + + ORG 0h +; +; FIT table pointer for LT-SX. +; +FitTablePointer DD 0eeeeeeeeh, 0eeeeeeeeh + + ORG 10h +; +; This is located at 0xFFFFFFD0h +; + mov di, "AP" + jmp ApStartup + + ORG 20h +; +; Pointer to the entry point of the PEI core +; It is located at 0xFFFFFFE0, and is fixed up by some build tool +; So if the value 8..1 appears in the final FD image, tool failure occurs. +; +PeiCoreEntryPoint DD 87654321h + +; +; This is the handler for all kinds of exceptions. Since it's for debugging +; purpose only, nothing except a deadloop would be done here. Developers could +; analyze the cause of the exception if a debugger had been attached. +; +InterruptHandler PROC + jmp $ + iret +InterruptHandler ENDP + + ORG 30h +; +; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte +; Execution starts here upon power-on/platform-reset. +; +ResetHandler: + nop + nop +ApStartup: + ; + ; Jmp Rel16 instruction + ; Use machine code directly in case of the assembler optimization + ; SEC entry point relatvie address will be fixed up by some build tool. + ; + + DB 0e9h + DW -3 + + + ORG 38h +; +; Ap reset vector segment address is at 0xFFFFFFF8 +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs +; +ApSegAddress dd 12345678h + + ORG 3ch +; +; BFV Base is at 0xFFFFFFFC +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs. +; +BfvBase DD 12345678h + +_TEXT_REALMODE ENDS + + END diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/ResetVec.raw b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/ResetVec.raw Binary files differnew file mode 100644 index 0000000..ca9dd3c --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/ResetVec.raw diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecCore.inc b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecCore.inc new file mode 100644 index 0000000..0129cc9 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecCore.inc @@ -0,0 +1,56 @@ +;@file +; SecCore constants and macros +; +;@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 +; + +; +; Set to 1 to enable debug +; +NO_EVICTION_MODE_DEBUG EQU 1 + +STATUS_CODE MACRO status +IF NO_EVICTION_MODE_DEBUG + mov al, status + out 080h, al +ENDIF +ENDM + +FVHEADER_LEN_OFF EQU 30h +FFSHEADER_LEN EQU 18h + +IMAGE_BASE_ADDRESS EQU 0FFFF0000h + +; +; Set to 1 to enable debug support for "Deterministic BSP selection" +; +AP_ENTRY_DELAY EQU 10h +AP_EXECUTION_DELAY EQU 1000h + +; +; Define the segment used for AP start-up +; It should be on the top of the recovery FV +; Seg = 0100h - (BlockNumber of Recovery FV) +; Here 0FCh = 0100h - 04h +; +AP_SEG EQU 0FFh + +; +; Commands defined in the AP SIPI code +; +AP_SIPI_COLLECT_MAX_RATIO EQU 001h +AP_SIPI_PROGRAM_MAX_RATIO EQU 002h +AP_SIPI_SWITCH_BSP EQU 003h diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc new file mode 100644 index 0000000..7b9dea4 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc @@ -0,0 +1,1024 @@ +; +; 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 - 2012, Intel Corporation. All rights reserved.<BR> +; 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: +; +; SecFlat32.inc +; +; Abstract: +; +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector. +; +;------------------------------------------------------------------------------ + +CALL_MMX macro RoutineLabel + + local ReturnAddress + mov esi, offset ReturnAddress + movd mm7, esi ; save ReturnAddress into MM7 + jmp RoutineLabel +ReturnAddress: + +endm + +RET_ESI macro + + movd esi, mm7 ; restore ESP from MM7 + jmp esi + +endm + +CALL_EBP macro RoutineLabel + + local ReturnAddress + mov ebp, offset ReturnAddress + jmp RoutineLabel +ReturnAddress: + +endm + +RET_EBP macro + + jmp ebp ; restore ESP from EBP + +endm + +align 4 +ProtectedModeSECStart PROC NEAR PUBLIC + STATUS_CODE (02h) + CALL_MMX EnableAccessCSR + +;(AMI_CHG+)> + STATUS_CODE (07h) + CALL_MMX VeryEarlyMicrocodeUpdate +;<(AMI_CHG+) + + CALL_MMX DetectNumOfCPUSocket + + STATUS_CODE (03h) +;(AMI_CHG+)> + ;-Things in PlatformInitialization are ready done in chipset part + ;-CALL_MMX PlatformInitialization +;<(AMI_CHG+) + STATUS_CODE (09h) + CALL_MMX InitializeNEM + + STATUS_CODE (0Bh) + jmp CallPeiCoreEntryPoint + +ProtectedModeSECStart ENDP + +EnableAccessCSR PROC NEAR PRIVATE + ; + ; get Bus number from CPUID[1] EBX[31:24] + ; + + mov eax, 0Bh + mov ecx, 1 + cpuid + mov esi, eax + + mov eax, 1 ; bus 0 + cpuid + bswap ebx + movzx eax, bl + movzx ebx, bl + shl eax, BSPApicIDSaveStart ; Save current BSP APIC ID in MM1[31:24] + mov cx, si + shr bl, cl ; get Bus number in BL + or eax, ebx + movd mm1, eax ; save Bus number MM1[7:0] + + ; + ; Enable MM PCI-E Config Space + ; --cr-- use register symbol name; should upper 32 bit be cleared + ; + mov eax, 080000060h ; MCHBAR + mov dx, 0CF8h + out dx, eax + mov dx, 0CFCh + mov eax, MMCFG_LENGTH_BIT_SETTING + out dx, eax + in eax, dx + or eax, MMCFG_BASE OR ENABLE + out dx, eax + + ; Clear reset flag + movd eax, mm1 + and eax, NOT BIT18+BIT19 + movd mm1, eax + RET_ESI + +EnableAccessCSR ENDP + +; STATUS_CODE (03h) +;PlatformInitialization PROC NEAR PRIVATE +; +; ; +; ; Program PCI Express base address +; ; +; +; mov eax, 80000060h ; 0:0:0:60 +; mov dx, 0CF8h +; out dx, eax +; mov dx, 0CFCh +; ;using Pcd instead +; ;mov eax, 0e0000000h OR 00h OR 1 +;; mov eax, DWORD PTR PcdGet64 (PcdPciExpressBaseAddress) +; mov eax, DWORD PTR PCIEXPRESS_BASE_ADDRESS +; or eax, (PCIEX_LENGTH_BIT_SETTING OR 1) +; out dx, eax +; +; ; +; ; Enable Mch Bar +; ; +; mov esi, MCHBAR_REG +; mov eax, (MCH_BASE_ADDRESS + 1) +; mov Dword Ptr [esi], eax +; +; ; +; ; Enable RCRB in PCH. +; ; +; mov esi, PCH_LPC_RCRB_PCI_ADDR +; mov eax, PCH_RCRB_BASE + 1 +; mov Dword Ptr [esi], eax +; +; ; +; ; Configure GPIO to be able to initiate LVL change for GPIO48 for S3 resume time calculation. +; ; +; ; Enable GPIO BASE I/O registers +; ; +; mov eax, PCI_LPC_BASE + 48h +; mov dx, 0CF8h +; out dx, eax +; mov eax, GPIO_BASE_ADDRESS +; add dx, 4 +; out dx, eax +; +; mov eax, PCI_LPC_BASE + 4Ch +; mov dx, 0CF8h +; out dx, eax +; add dx, 4 +; in al, dx +; or al, BIT4 ; GPIOBASE Enable +; out dx, al +; +; ;GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native +; mov dx, GPIO_BASE_ADDRESS + R_GPIO_USE_SEL2 +; in eax, dx +; or eax, 010000h ;Enable GPIO48 +; out dx, eax +; +; ;GP_IO_SEL2 Register -> 1 = Input 0 = Output (if Native Mode don't care) +; mov dx, GPIO_BASE_ADDRESS + R_GPIO_IO_SEL2 +; in eax, dx +; and eax, 0FFFEFFFFh ;Configure GPIO48 as Output +; out dx, eax +; +; mov dx, GPIO_BASE_ADDRESS + R_GPIO_LVL2 +; in eax, dx +; or eax, 010000h ;Configure GPIO48 as High +; out dx, eax +; +; ; +; ; Program and Enable ACPI PM Base. +; ; +; mov esi, PCH_LPC_PMBASE_PCI_ADDR +; mov eax, PCH_ACPI_BASE_ADDRESS + 1 +; mov Dword Ptr [esi], eax +; mov esi, PCH_LPC_ACPICNTL_PCI_ADDR +; or Dword Ptr [esi], 00000080h +; +; ; +; ; PCH BIOS Spec Rev 0.5.0 Section 12.9 +; ; Additional Programming Requirements for USB Support +; ; Step 2.b +; ; Clear RCBA + 3598h [0] to 0b +; ; +; mov esi, PCH_RCRB_BASE + 3598h +; mov eax, 0 +; mov Dword Ptr [esi], eax +; +; ; +; ; Enable HPET decode in PCH. +; ; +; mov esi, PCH_RCRB_BASE + PCH_RCRB_HPET +; mov eax, PCH_RCRB_HPET_DECODE +; mov Dword Ptr [esi], eax +; mov eax, Dword ptr [esi] +; xor eax, eax +; mov esi, HPET_COMP_1 +; mov Dword Ptr [esi], eax +; mov esi, HPET_COMP_2 +; mov Dword ptr [esi], eax +; +; ; +; ; Enable the upper 128-byte bank of RTC RAM. +; ; +; mov esi, PCH_RCRB_BASE + PCH_RCRB_RTC_CONF +; mov eax, Dword Ptr [esi] +; or eax, PCH_RCRB_RTC_CONF_UCMOS_EN +; mov Dword Ptr [esi], eax +; +; ; +; ; Choose Port80 Route +; ; +; mov esi, PCH_RCRB_BASE + PCH_RCRB_GCS +; mov ebx, Dword Ptr [esi] +; or bl, BIT5 +; +; ; +; ; check SETUP option - PchPort80Route +; ; 0 = LPC {Default]; 1 = PCI +; ; +;; mov al, CMOS_PCH_PORT80_OFFSET ; CMOS Offset = 17h +;; mov dx, RTC_UPPER_INDEX +;; out dx, al +;; inc dx +;; in al, dx +;; test al, BIT0 +;; jnz @F +; and bl, NOT (BIT2) ; Port80h to LPC +;;@@: +; mov Dword Ptr [esi], ebx +; +; ; +; ; Halt TCO Timer +; ; +; mov dx, 0468h +; in ax, dx +; or ax, BIT11 +; out dx, ax +; +; ; +; ; Clear the Second TO status bit +; ; +; mov dx, 0466h +; in ax, dx +; or ax, BIT1 +; out dx, ax +; +; RET_ESI +; +;PlatformInitialization ENDP + +; STATUS_CODE (03h) +DetectNumOfCPUSocket PROC NEAR PRIVATE + + ; only one socket + movd eax, mm1 ; get MM1 value into EAX + mov ah, 01 + movd mm1, eax ; save CPU pkg count into MM1[15:8] + + RET_ESI + +DetectNumOfCPUSocket ENDP + +; STATUS_CODE (07h) +VeryEarlyMicrocodeUpdate PROC NEAR PRIVATE +; (AMI_CHG+)> + public FindMicrocodeEnd + mov ecx,08bh + rdmsr + or dx,dx + jnz uc_exit + jmp FindMicrocode ;return to MicroCodeUpdateEnd +FindMicrocodeEnd:: + or eax, eax + jz uc_exit ;No microcode found: + + ;Update microcode + mov ecx, 79h + xor edx, edx + add eax, 48 ;eax = Update data + wrmsr ;Update microcode +uc_exit: + RET_ESI + +;-IF EARLY_MICROCODE_SUPPORT +;- mov ecx, IA32_BIOS_SIGN_ID +;- rdmsr ; CPU PatchID -> EDX +;- cmp edx, 0 ; If microcode has been updated +;- jnz luExit ; Skip if patch already loaded +;- +;- mov ecx, IA32_PLATFORM_ID ; To get Platform ID. +;- rdmsr +;- shr edx, 18 ; EDX[0-2] = Platform ID. +;- and dx, 07h ; DX = Platform ID. +;- mov si, dx ; Save Platform ID in FS. +;- mov eax, 01h ; To get CPU signature. +;- cpuid ; EAX = CPU signature. +;- mov cx, si ; CX = Platform ID +;- xor edx, edx +;- bts dx, cx ; EDX = Platform ID bit. +;- +; mov esi, PcdGet32 (PcdFlashMicrocodeFvBase) +;- mov esi, MICROCODE_FV_BASE_ADDRESS +;- +;- mov ebx, esi +;- mov bx, FVHEADER_LEN_OFF +;- movzx ebx, WORD PTR [ebx] +;- add esi, ebx +;- add si, FFSHEADER_LEN ; add FFS header +;- +;- mov edi, PcdGet32 (PcdFlashMicrocodeFvBase) +;- mov ebx, PcdGet32 (PcdFlashMicrocodeFvSize) +;- mov edi, MICROCODE_FV_BASE_ADDRESS +;- mov ebx, MICROCODE_FV_SIZE +;- add edi, ebx ;End addr of uCodes. +;- +;- ; EAX = CPU signature. +;- ; EDX = Platform ID bit. +;- ; ESI = Abs addr of contiguous uCode blocks. +;- ; EDI = Abs addr of contiguous uCode blocks end. +;- +;-luCheckPatch: +;- cmp (UpdateHeaderStruc PTR ds:[esi]).dProcessorSignature, eax;Sig matched? +;- jnz luCheckUnprogrammed ; No. +;- test (UpdateHeaderStruc PTR ds:[esi]).dProcessorFlags, edx;Platform matched? +;- jnz luFoundMatch ; Yes. +;- +;-luCheckUnprogrammed: +;- mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dDataSize +;- cmp ebx, 0FFFFFFFFh +;- je luUnprogrammed +;- cmp (UpdateHeaderStruc PTR ds:[esi]).dLoaderRevision, 1 +;- je luCheckExtdHdrs +;- +;-luUnprogrammed: +;- mov ebx, 1024 ; Unprogrammed space, 1KB checks +;- jmp luPoinToNextBlock ; for backword compatibility. +;- +;-luCheckExtdHdrs: +;- add ebx, SIZEOF(UpdateHeaderStruc) +;- cmp ebx, (UpdateHeaderStruc PTR ds:[esi]).dTotalSize +;- jae luTryNextPatch ; No extd hdrs. +;- +;- mov ecx, DWORD PTR ds:[esi + ebx] +;- jcxz luTryNextPatch ; No extd hdrs. (OK to use CX instead of ECX). +;- add ebx, 20 ; Point to the first Extd Sig. +;-luNextSig: +;- cmp eax, DWORD PTR ds:[esi + ebx] ;Sig matched? +;- jne lu_00 +;- test edx, DWORD PTR ds:[esi + ebx + 4] ;Platform matched? +;- jnz luFoundMatch +;-lu_00: +;- add ebx, 12 +;- loop luNextSig +;- +;-luTryNextPatch: +;- mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dTotalSize +;- or ebx, ebx +;- jnz luPoinToNextBlock ; Variable size uCode format. +;- mov ebx, BLOCK_LENGTH_BYTES ; Fixed size uCode format. + +; +; Add alignment check - begin +; +;- test ebx, 0400h +;- jz @F +;- add ebx, 0400h +;-@@: +; +; Add alignment check - end +; + +;-luPoinToNextBlock: +;- add esi, ebx +;- cmp esi, edi +;- jb luCheckPatch ; Check with all patches. +;- +;- ; Check possible multiple patch +;- movd eax, mm3 +;- movd esi, mm4 +;- or eax, eax +;- jnz luLoadPatch +;- jmp luExit ; No matching patch found. +;- +;-luFoundMatch: +;-; MM3 = Patch Revision +;-; MM4 = Patch Pointer +;- movd ebx, mm3 +;- cmp (UpdateHeaderStruc PTR ds:[esi]).dUpdateRevision, ebx +;- jb luTryNextPatch +;- +;- mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dUpdateRevision +;- +;-luStoreRevPtr: +;- movd mm3, ebx ; save Patch Revision +;- movd mm4, esi ; save Patch Pointer +;- jmp luTryNextPatch +;- +;-luLoadPatch: +;- mov ecx, IA32_BIOS_UPDT_TRIG +;- mov eax, esi ; EAX - Abs addr of uCode patch. +;- add eax, SIZEOF(UpdateHeaderStruc) ; EAX - Abs addr of uCode data. +;- xor edx, edx ; EDX:EAX - Abs addr of uCode data. +;- wrmsr ; Trigger uCode load. +;- +;-luExit: +;-ENDIF +;- +;- RET_EBP +;<(AMI_CHG+) +VeryEarlyMicrocodeUpdate ENDP +; STATUS_CODE (09h) +;************************************************************ +; Description: +; +; This function initializes the Cache for Data, Stack, and Code +; as specified in the BIOS Writer's Guide. +;************************************************************ +InitializeNEM PROC NEAR PRIVATE +IFDEF ANC_SUPPORT_FLAG + ; + ; Detect AnC Boot + ; + mov ecx, MSR_ANC_SACM_INFO ; + rdmsr + and eax, 01h + jnz AncNemSetup +ENDIF + + ; + ; Enable cache for use as stack and for caching code + ; The algorithm is specified in the processor BIOS writer's guide + ; + + ; + ; Ensure that the system is in flat 32 bit protected mode. + ; + ; Platform Specific - configured earlier + ; + ; Ensure that only one logical processor in the system is the BSP. + ; (Required step for clustered systems). + ; + ; Platform Specific - configured earlier + + ; Ensure all APs are in the Wait for SIPI state. + ; This includes all other logical processors in the same physical processor + ; as the BSP and all logical processors in other physical processors. + ; If any APs are awake, the BIOS must put them back into the Wait for + ; SIPI state by issuing a broadcast INIT IPI to all excluding self. + ; + mov edi, APIC_ICR_LO ; 0FEE00300h - Send INIT IPI to all excluding self + mov eax, ORAllButSelf + ORSelfINIT ; 0000C4500h + mov [edi], eax + +@@: + mov eax, [edi] + bt eax, 12 ; Check if send is in progress + jc @B ; Loop until idle + + ; + ; Load microcode update into BSP. + ; + ; Ensure that all variable-range MTRR valid flags are clear and + ; IA32_MTRR_DEF_TYPE MSR E flag is clear. Note: This is the default state + ; after hardware reset. + ; + ; Platform Specific - MTRR are usually in default state. + ; + + ; + ; Initialize all fixed-range and variable-range MTRR register fields to 0. + ; + mov ecx, IA32_MTRR_CAP ; get variable MTRR support + rdmsr + movzx ebx, al ; EBX = number of variable MTRR pairs + shl ebx, 2 ; *4 for Base/Mask pair and WORD size + add ebx, MtrrCountFixed * 2 ; EBX = size of Fixed and Variable MTRRs + + xor eax, eax ; Clear the low dword to write + xor edx, edx ; Clear the high dword to write + ;;;mov ebx, MtrrCount * 2 ; ebx <- sizeof MtrrInitTable +InitMtrrLoop: + add ebx, -2 + movzx ecx, WORD PTR cs:MtrrInitTable[ebx] ; ecx <- address of mtrr to zero + wrmsr + jnz InitMtrrLoop ; loop through the whole table + + ; + ; Configure the default memory type to un-cacheable (UC) in the + ; IA32_MTRR_DEF_TYPE MSR. + ; + mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index + rdmsr + and eax, NOT (00000CFFh) ; Clear the enable bits and def type UC. + wrmsr + + ; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB + ; based on the physical address size supported for this processor + ; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0] + ; + ; Examples: + ; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing + ; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing + ; + mov eax, 80000008h ; Address sizes leaf + cpuid + sub al, 32 + movzx eax, al + xor esi, esi + bts esi, eax + dec esi ; esi <- MTRR_PHYS_MASK_HIGH + + ; + ; Configure the DataStack region as write-back (WB) cacheable memory type + ; using the variable range MTRRs. + ; + + ; + ; Set the base address of the DataStack cache range + ; +; mov eax, PcdGet32 (PcdTemporaryRamBase) + mov eax, TEMPORARY_RAM_BASE_ADDRESS + or eax, MTRR_MEMORY_TYPE_WB + ; Load the write-back cache value + xor edx, edx ; clear upper dword + mov ecx, MTRR_PHYS_BASE_0 ; Load the MTRR index + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Set the mask for the DataStack cache range + ; Compute MTRR mask value: Mask = NOT (Size - 1) + ; +; mov eax, PcdGet32 (PcdTemporaryRamSize) + mov eax, TEMPORARY_RAM_SIZE + dec eax + not eax + or eax, MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + mov ecx, MTRR_PHYS_MASK_0 ; For proper addressing above 4GB + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Configure the BIOS code region as write-protected (WP) cacheable + ; memory type using a single variable range MTRR. + ; + ; Platform Specific - ensure region to cache meets MTRR requirements for + ; size and alignment. + ; + + ; + ; Set the base address of the CodeRegion cache range part 1 + ; + mov eax, CODE_REGION_BASE_ADDRESS_PART1 OR MTRR_MEMORY_TYPE_WP + ; Load the write-protected cache value + xor edx, edx ; clear upper dword + mov ecx, MTRR_PHYS_BASE_1 ; Load the MTRR index + wrmsr ; the value in MTRR_PHYS_BASE_1 + + ; + ; Set the mask for the CodeRegion cache range part 1 + ; + mov eax, CODE_REGION_SIZE_MASK_PART1 OR MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + mov ecx, MTRR_PHYS_MASK_1 ; Load the MTRR index + wrmsr ; the value in MTRR_PHYS_BASE_1 + +;(AMI_CHG)> +IF MKF_CODE_CACHE_PART2_BASE + ; + ; Set the base address of the CodeRegion cache range part 2 + ; + mov eax, CODE_REGION_BASE_ADDRESS_PART2 OR MTRR_MEMORY_TYPE_WP + ; Load the write-protected cache value + xor edx, edx ; clear upper dword +;- mov ecx, MTRR_PHYS_BASE_2 ; Load the MTRR index + inc ecx + wrmsr ; the value in MTRR_PHYS_BASE_2 + + ; + ; Set the mask for the CodeRegion cache range part 2 + ; + mov eax, CODE_REGION_SIZE_MASK_PART2 OR MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH +;- mov ecx, MTRR_PHYS_MASK_2 ; Load the MTRR index + inc ecx + wrmsr ; the value in MTRR_PHYS_BASE_1 +ENDIF + +IF MKF_WDB_REGION_BASE_ADDRESS + ; + ; Set the base address of the WDB range + ; + mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC + ; Load the write-combined cache value + xor edx, edx ; clear upper dword +;- mov ecx, MTRR_PHYS_BASE_3 ; Load the MTRR index + inc ecx + wrmsr ; the value in MTRR_PHYS_BASE_2 + + ; + ; Set the mask for the WDB range + ; + mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH +;- mov ecx, MTRR_PHYS_MASK_3 ; Load the MTRR index + inc ecx + wrmsr ; the value in MTRR_PHYS_BASE_1 +ENDIF +;<(AMI_CHG) + + ; + ; Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag. + ; + mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index + rdmsr + or eax, MTRR_DEF_TYPE_E ; Enable variable range MTRRs + wrmsr + + ; + ; Enable the logical processor's (BSP) cache: execute INVD and set + ; CR0.CD = 0, CR0.NW = 0. + ; + mov eax, cr0 + and eax, NOT (CR0_CACHE_DISABLE + CR0_NO_WRITE) + invd + mov cr0, eax + ; + ; Enable No-Eviction Mode Setup State by setting + ; NO_EVICT_MODE MSR 2E0h bit [0] = '1'. + ; + mov ecx, NO_EVICT_MODE + rdmsr + or eax, 1 + wrmsr + + ; + ; One location in each 64-byte cache line of the DataStack region + ; must be written to set all cache values to the modified state. + ; +; mov edi, PcdGet32 (PcdTemporaryRamBase) +; mov ecx, PcdGet32 (PcdTemporaryRamSize) + mov edi, TEMPORARY_RAM_BASE_ADDRESS + mov ecx, TEMPORARY_RAM_SIZE + shr ecx, 6 + mov eax, CACHE_INIT_VALUE +@@: + mov [edi], eax + sfence + add edi, 64 + loopd @b + + ; + ; Enable No-Eviction Mode Run State by setting + ; NO_EVICT_MODE MSR 2E0h bit [1] = '1'. + ; + mov ecx, NO_EVICT_MODE + rdmsr + or eax, 2 + wrmsr + +IFDEF ANC_SUPPORT_FLAG + jmp FinishedCacheConfig + + ; + ; Jump to here when AnC boot and NEM is initialized by AnC ACM + ; +AncNemSetup: + ; + ; Finished with cache configuration + ; + ; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB + ; based on the physical address size supported for this processor + ; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0] + ; + ; Examples: + ; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing + ; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing + ; + mov eax, 80000008h ; Address sizes leaf + cpuid + sub al, 32 + movzx eax, al + xor esi, esi + bts esi, eax + dec esi ; esi <- MTRR_PHYS_MASK_HIGH + + ; + ; Configure the DataStack region as write-back (WB) cacheable memory type + ; using the variable range MTRRs. + ; + ; + ; Find available MTRR + ; + CALL_EBP FindFreeMtrr + + ; + ; Set the base address of the DataStack cache range + ; +; mov eax, PcdGet32 (PcdTemporaryRamBase) + mov eax, TEMPORARY_RAM_BASE_ADDRESS + or eax, MTRR_MEMORY_TYPE_WB + ; Load the write-back cache value + xor edx, edx ; clear upper dword + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Set the mask for the DataStack cache range + ; Compute MTRR mask value: Mask = NOT (Size - 1) + ; +; mov eax, PcdGet32 (PcdTemporaryRamSize) + mov eax, TEMPORARY_RAM_SIZE + dec eax + not eax + or eax, MTRR_PHYS_MASK_VALID + ; turn on the Valid flag + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + inc ecx + wrmsr ; the value in MTRR_PHYS_BASE_0 + + ; + ; Program the variable MTRR's MASK register for WDB + ; (Write Data Buffer, used in MRC, must be WC type) + ; + + ; + ; Find available MTRR + ; + CALL_EBP FindFreeMtrr + +FoundAvailableMtrr: + ; + ; Program the variable MTRR's BASE register for WDB + ; + xor edx, edx + mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC + wrmsr + + inc ecx + mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH + mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID ; turn on the Valid flag + wrmsr + + ; + ; One location in each 64-byte cache line of the DataStack region + ; must be written to set all cache values to the modified state. + ; +; mov edi, PcdGet32 (PcdTemporaryRamBase) +; mov ecx, PcdGet32 (PcdTemporaryRamSize) + mov edi, TEMPORARY_RAM_BASE_ADDRESS + mov ecx, TEMPORARY_RAM_SIZE + shr ecx, 6 + mov eax, CACHE_INIT_VALUE +@@: + mov [edi], eax + sfence + add edi, 64 + loopd @b +ENDIF + + ; + ; Finished with cache configuration + ; +FinishedCacheConfig: + + ; + ; Optionally Test the Region... + ; + + ; + ; Test area by writing and reading + ; + cld +; mov edi, PcdGet32 (PcdTemporaryRamBase) +; mov ecx, PcdGet32 (PcdTemporaryRamSize) + mov edi, TEMPORARY_RAM_BASE_ADDRESS + mov ecx, TEMPORARY_RAM_SIZE + shr ecx, 2 + mov eax, CACHE_TEST_VALUE +TestDataStackArea: + stosd + cmp eax, DWORD PTR [edi-4] + jnz DataStackTestFail + loop TestDataStackArea + jmp DataStackTestPass + + ; + ; Cache test failed + ; +DataStackTestFail: + STATUS_CODE (0D0h) + jmp $ + + ; + ; Configuration test failed + ; +ConfigurationTestFailed: + STATUS_CODE (0D1h) + jmp $ + +DataStackTestPass: + + ; + ; At this point you may continue normal execution. Typically this would include + ; reserving stack, initializing the stack pointer, etc. + ; + + ; + ; After memory initialization is complete, please follow the algorithm in the BIOS + ; Writer's Guide to properly transition to a normal system configuration. + ; The algorithm covers the required sequence to properly exit this mode. + ; + + RET_ESI + +InitializeNEM ENDP + +; STATUS_CODE (09h) +;-EstablishStack PROC NEAR PRIVATE +;- +;- ; +;- ; Enable STACK +;- ; +;- RET_ESI +;- +;-EstablishStack ENDP +;- +;-FindFreeMtrr PROC NEAR PRIVATE +;- mov ecx, MTRR_PHYS_MASK_0 +;- +;-@@: +;- rdmsr +;- test eax, 800h +;- jz FoundFreeMtrr +;- add ecx, 2 +;- cmp ecx, MTRR_PHYS_MASK_9 +;- jbe @b +;- ; +;- ; No available MTRR, halt system +;- ; +;- jmp $ +;- +;-FoundFreeMtrr: +;- dec ecx +;- +;- RET_EBP +;- +;-FindFreeMtrr ENDP +;- +;-; STATUS_CODE (0Bh) +;-CallPeiCoreEntryPoint PROC NEAR PRIVATE +;- ; +;- ; Set stack top pointer +;- ; +;-; mov esp, PcdGet32 (PcdTemporaryRamBase) +;-; add esp, PcdGet32 (PcdTemporaryRamSize) +;- mov esp, TEMPORARY_RAM_BASE_ADDRESS +;- add esp, TEMPORARY_RAM_SIZE +;- +;- ; +;- ; Push CPU count to stack first, then AP's (if there is one) +;- ; BIST status, and then BSP's +;- ; +;- +;- ; +;- ; Here work around for BIST +;- ; +;- ; Get number of BSPs +;- movd ecx, mm1 +;- movzx ecx, ch +;- +;- ; Save number of BSPs +;- push ecx +;- +;-GetSBSPBist: +;- ; Save SBSP BIST +;- movd eax, mm0 +;- push eax +;- +;- ; Save SBSP APIC ID +;- movd eax, mm1 +;- shr eax, BSPApicIDSaveStart ; Resume APIC ID +;- push eax +;- +;- ; Save Time-Stamp Counter +;- movd eax, mm5 +;- push eax +;- +;- movd eax, mm6 +;- push eax +;- +;-TransferToSecStartup: +;- +;- +;- +;- ; Switch to "C" code +;- STATUS_CODE (0Ch) +;- ; +;- ; Pass entry point of the PEI core +;- ; +;- mov edi, PEI_CORE_ENTRY_BASE ; 0FFFFFFE0h +;- push DWORD PTR ds:[edi] +;- +;- ; +;- ; Pass BFV into the PEI Core +;- ; +;- mov edi, FV_MAIN_BASE ; 0FFFFFFFCh +;- push DWORD PTR ds:[edi] +;- +;- ; ECPoverride: SecStartup entry point needs 4 parameters +;-; push PcdGet32 (PcdTemporaryRamBase) +;- push TEMPORARY_RAM_BASE_ADDRESS +;- +;- ; +;- ; Pass stack size into the PEI Core +;- ; +;-; push PcdGet32 (PcdTemporaryRamSize) +;- push TEMPORARY_RAM_SIZE +;- +;- ; +;- ; Pass Control into the PEI Core +;- ; +;- call SecStartup +;-CallPeiCoreEntryPoint ENDP +;- +;-StartUpAp PROC NEAR +;- +;- mov esi, HPET_COMP_2 +;- lock inc byte ptr [esi] +;- +;- DISABLE_CACHE +;-; +;-; Halt the AP and wait for the next SIPI +;-; +;-Ap_Halt: +;- cli +;-@@: +;- hlt +;- jmp @B +;- ret +;-StartUpAp ENDP +;- +;- +;-CheckValidCMOS PROC NEAR PRIVATE +;- ; +;- ; Check CMOS Status +;- ; +;- mov esi, PCH_LPC_GEN_PMCON_3_ADDR +;- mov eax, es:[esi] +;- +;- ; check PWR_FLR and RTC_PWR_STS status +;- and eax, BIT2 + BIT1 +;- +;- RET_EBP +;-CheckValidCMOS ENDP + +MtrrInitTable LABEL BYTE + DW MTRR_DEF_TYPE + DW MTRR_FIX_64K_00000 + DW MTRR_FIX_16K_80000 + DW MTRR_FIX_16K_A0000 + DW MTRR_FIX_4K_C0000 + DW MTRR_FIX_4K_C8000 + DW MTRR_FIX_4K_D0000 + DW MTRR_FIX_4K_D8000 + DW MTRR_FIX_4K_E0000 + DW MTRR_FIX_4K_E8000 + DW MTRR_FIX_4K_F0000 + DW MTRR_FIX_4K_F8000 + +MtrrCountFixed EQU (($ - MtrrInitTable) / 2) + + DW MTRR_PHYS_BASE_0 + DW MTRR_PHYS_MASK_0 + DW MTRR_PHYS_BASE_1 + DW MTRR_PHYS_MASK_1 + DW MTRR_PHYS_BASE_2 + DW MTRR_PHYS_MASK_2 + DW MTRR_PHYS_BASE_3 + DW MTRR_PHYS_MASK_3 + DW MTRR_PHYS_BASE_4 + DW MTRR_PHYS_MASK_4 + DW MTRR_PHYS_BASE_5 + DW MTRR_PHYS_MASK_5 + DW MTRR_PHYS_BASE_6 + DW MTRR_PHYS_MASK_6 + DW MTRR_PHYS_BASE_7 + DW MTRR_PHYS_MASK_7 + DW MTRR_PHYS_BASE_8 + DW MTRR_PHYS_MASK_8 + DW MTRR_PHYS_BASE_9 + DW MTRR_PHYS_MASK_9 +MtrrCount EQU (($ - MtrrInitTable) / 2) diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecStartup.c b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecStartup.c new file mode 100644 index 0000000..9c6f19c --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecStartup.c @@ -0,0 +1,136 @@ +/** @file + SEC Startup function invoked after SEC Ram is started. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#include "Tiano.h" +#include "PeiCore.h" +#include "FlashMap.h" +#include "EfiFirmwareFileSystem.h" +#include "EfiFirmwareVolumeHeader.h" + +#include EFI_PPI_DEFINITION (SecPlatformInformation) + +/// +/// Define the Microcode FV base and size +/// So as to be used by Flat32.asm +/// Here the Microcode binary is embedded in a FFS within a FV +/// So the header should be taken into count to get the raw data +/// In FV header, the EFI_FV_BLOCK_MAP_ENTRY is an array with variable size +/// If the map is changed, it has to be adjusted as well. +/// +UINT32 MicrocodeStart = FLASH_REGION_NVSTORAGE_SUBREGION_MICROCODE_BASE + + sizeof (EFI_FFS_FILE_HEADER); +UINT32 MicrocodeEnd = FLASH_REGION_NVSTORAGE_SUBREGION_MICROCODE_BASE + + FLASH_REGION_NVSTORAGE_SUBREGION_MICROCODE_SIZE; + +extern UINT32 *TopOfCar; + +EFI_STATUS +SecPlatformInformation ( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + IN OUT SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { SecPlatformInformation }; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiSecPlatformInformationPpiGuid, + &mSecPlatformInformationPpi +}; + +/** + Implementation of the PlatformInformation service in + EFI_SEC_PLATFORM_INFORMATION_PPI. + This function conveys state information out of the SEC phase into PEI. + + @param[in] PeiServices - Pointer to the PEI Services Table. + @param[in] StructureSize - Pointer to the variable describing size of the input buffer. + @param[in] PlatformInformationRecord - Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS - The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL - The buffer was too small. +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + IN OUT SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + UINT32 *BIST; + UINT32 Size; + UINT32 Count; + + /// + /// The entries of BIST information, together with the number of them, + /// reside in the bottom of stack, left untouched by normal stack operation. + /// This routine copies the BIST information to the buffer pointed by + /// PlatformInformationRecord for output. + /// + Count = *(TopOfCar - 1); + Size = Count * sizeof (UINT64); + + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = Size; + BIST = (UINT32 *) ((UINT32) TopOfCar - sizeof (UINT32) - Size); + + EfiCommonLibCopyMem (PlatformInformationRecord, BIST, Size); + + return EFI_SUCCESS; +} + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] SizeOfRam - Size of the temporary memory available for use. + @param[in] BootFirmwareVolume - Base address of the Boot Firmware Volume. + @param[in] PeiCoreEntryPoint - Pointer to the entry point of the PEI core. + + @retval This function never returns +**/ +VOID +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 BootFirmwareVolume, + IN PEI_MAIN_ENTRY_POINT PeiCoreEntryPoint + ) +{ + EFI_PEI_STARTUP_DESCRIPTOR PeiStartup; + + PeiStartup.SizeOfCacheAsRam = SizeOfRam; + PeiStartup.BootFirmwareVolume = BootFirmwareVolume; + PeiStartup.DispatchTable = &mPeiSecPlatformInformationPpi; + + /// + /// Transfer the control to the PEI core + /// + (*PeiCoreEntryPoint)(&PeiStartup); + + /// + /// Should not come here. + /// + return; +} diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.c b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.c new file mode 100644 index 0000000..9c7efae --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.c @@ -0,0 +1,631 @@ +/** @file + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ +#include "TxtOneTouchDxe.h" + +TXT_ONE_TOUCH_OP_PROTOCOL mTxtOneTouchOpProtocol = { + TxtExecOperation, + TxtConfirmationDialog, + TxtResetState +}; + +EFI_TCG_PROTOCOL *mTcgProtocol; +TXT_ONE_TOUCH_SETUP mTxtVariable; + +/** + @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_HANDLE Handle; + + Handle = NULL; + ZeroMem (&mTxtVariable, sizeof (TXT_ONE_TOUCH_SETUP)); + + /// + /// Install the protocol + /// + Status = gBS->InstallProtocolInterface ( + &Handle, + &gTxtOneTouchOpProtocolGuid, + EFI_NATIVE_INTERFACE, + &mTxtOneTouchOpProtocol + ); + ASSERT_EFI_ERROR (Status); + + /// + /// Locate TcgProtocol + /// + mTcgProtocol = NULL; + Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &mTcgProtocol); + ASSERT_EFI_ERROR (Status); + + /// + /// Initiate the variable if it doesn't exist. + /// + if (ReadWriteVariable (&mTxtVariable, FALSE) != EFI_SUCCESS) { + ReadWriteVariable (&mTxtVariable, TRUE); + } + + return Status; +} + +/** + Read/Write variable for enable/disable TxT one + touch functions + + @param[in] VariableData - Point to Setup variable buffer + @param[in] WriteData - TRUE, write changes to Setup Variable. FALSE, not to write variable. + + @retval EFI_SUCCESS - Operation complete successful + @retval EFI_INVALID_PARAMETER - VariableData is NULL +**/ +EFI_STATUS +ReadWriteVariable ( + IN OUT TXT_ONE_TOUCH_SETUP *VariableData, + IN BOOLEAN WriteData + ) +{ + EFI_STATUS Status; + UINTN Size; + UINT32 VarAttrib; + + Status = EFI_SUCCESS; + Size = 0; + VarAttrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + + if (VariableData == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (WriteData == TRUE) { + /// + /// Write TxT variable + /// + Size = sizeof (TXT_ONE_TOUCH_SETUP); + + Status = gRT->SetVariable ( + TXT_ONE_TOUCH_VAR, + &gTxtOneTouchGuid, + VarAttrib, + Size, + VariableData + ); + } else { + /// + /// Read TxT variable + /// + Size = sizeof (TXT_ONE_TOUCH_SETUP); + + Status = gRT->GetVariable ( + TXT_ONE_TOUCH_VAR, + &gTxtOneTouchGuid, + NULL, + &Size, + VariableData + ); + } + + return Status; +} + +/** + Read TxT Maintenance flag + + @retval TRUE - TxT Maintenance Flag is TRUE + @retval FALSE - TxT Maintenance Flag is FALSE +**/ +BOOLEAN +CheckTxtMaintenanceFlag ( + VOID + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + /// + /// TBD. Need to read TPM NV index 0x50010000 + /// + /// + /// Read TxT variable first + /// + Status = ReadWriteVariable (&mTxtVariable, FALSE); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return mTxtVariable.NoTxtMaintenance; +} + +/** + Extend PPI operation for TxT. + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + + @retval EFI_SUCCESS - Execute the Command successful + @retval EFI_UNSUPPORTED - Command is not supported +**/ +EFI_STATUS +EFIAPI +TxtExecOperation ( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + /// + /// Read TxT variable first + /// + Status = ReadWriteVariable (&mTxtVariable, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Read variable for TxT One Touch function + /// The variable can be Setup variable + /// + switch (Command) { + case DISABLE_DEACTIVATE: + /// + /// Disable & Deactive TPM + /// Disable TxT + /// + mTxtVariable.TxtEnable = FALSE; + break; + + case ENABLE_VT: + /// + /// Enable VT + /// + mTxtVariable.VtEnable = TRUE; + break; + + case DISABLE_VT_TXT: + /// + /// Disable VT and TxT + /// + mTxtVariable.VtEnable = FALSE; + mTxtVariable.TxtEnable = FALSE; + break; + + case ENABLE_VTD: + /// + /// Enable VT-d + /// + mTxtVariable.VtdEnable = TRUE; + break; + + case DISABLE_VTD_TXT: + /// + /// Disable VT-d and TxT + /// + mTxtVariable.VtdEnable = FALSE; + break; + + case ENABLE_ACTTPM_VT_VTD_TXT_DISABLE_STM: + /// + /// Enable-Active TPM + /// Enable VT, VT-d and TxT + /// Disable STM + /// + TpmEnableActive (ENABLE_ACTIVATE); + /// + /// mTxtVariable.TpmEnable = TRUE; + /// mTxtVariable.TpmActive = TRUE; + /// + mTxtVariable.VtEnable = TRUE; + mTxtVariable.VtdEnable = TRUE; + mTxtVariable.TxtEnable = TRUE; + mTxtVariable.StmEnable = FALSE; + break; + + case ENABLE_ACTTPM_VT_VTD_TXT_STM: + /// + /// Enable-Active TPM + /// Enable VT, VT-d, TxT and STM + /// + TpmEnableActive (ENABLE_ACTIVATE); + /// + /// mTxtVariable.TpmEnable = TRUE; + /// mTxtVariable.TpmActive = TRUE; + /// + mTxtVariable.VtEnable = TRUE; + mTxtVariable.VtdEnable = TRUE; + mTxtVariable.TxtEnable = TRUE; + mTxtVariable.StmEnable = TRUE; + break; + + case DISABLE_STM: + /// + /// Disable STM + /// + mTxtVariable.StmEnable = FALSE; + break; + + case DISABLE_TXT_STM: + /// + /// Disable TxT and STM + /// + mTxtVariable.TxtEnable = FALSE; + mTxtVariable.StmEnable = FALSE; + break; + + case DISABLE_SENTER_VMX: + /// + /// Disable SENTER and VMX + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_VMX_SMX_ONLY: + /// + /// Enable VMX in SMX only + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_VMX_OUTSIDE_SMX: + /// + /// Enable VMX outside SMX Only + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_VMX: + /// + /// Enable VMX + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_SENTER_ONLY: + /// + /// Enable SENTER Only + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_SENTER_VMX_IN_SMX: + /// + /// Enable SENTER and VMX in SMX + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_SENTER_VMX_OUTSIDE_SMX: + /// + /// Enable SENTER and VMX outside SMX + /// + Status = EFI_UNSUPPORTED; + break; + + case ENABLE_SENTER_VMX: + /// + /// Enable SENTER and VMX + /// + Status = EFI_UNSUPPORTED; + break; + + case SET_NO_TXT_MAINTENANCE_FALSE: + /// + /// Set NoTxtMaintenance Flag FALSE + /// + mTxtVariable.NoTxtMaintenance = FALSE; + break; + + case SET_NO_TXT_MAINTENANCE_TRUE: + /// + /// Set NoTxtMaintenance Flag TRUE + /// + mTxtVariable.NoTxtMaintenance = TRUE; + break; + + default: + return EFI_UNSUPPORTED; + } + /// + /// Validate states + /// + Status = ValidateTxtStates (&mTxtVariable); + if (EFI_ERROR (Status)) { + Status = EFI_UNSUPPORTED; + } else { + /// + /// if settings are correct, write it to variable + /// + Status = ReadWriteVariable (&mTxtVariable, TRUE); + } + + return Status; +} + +/** + Confirmation dialog for TxT PPI + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + @param[in] Confirm - User confirm + + @retval EFI_SUCCESS - Execute the Command successful + @retval EFI_UNSUPPORTED - Command is not supported +**/ +EFI_STATUS +EFIAPI +TxtConfirmationDialog ( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command, + IN OUT BOOLEAN *Confirm + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + if (CheckTxtMaintenanceFlag ()) { + *Confirm = FALSE; + } + + switch (Command) { + case DISABLE_DEACTIVATE: + /// + /// Disable & Deactive TPM + /// Disable TxT + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Disable TxT\n\n\r" + ); + + break; + + case ENABLE_VT: + /// + /// Enable VT + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable VT\n\n\r" + ); + break; + + case DISABLE_VT_TXT: + /// + /// Disable VT and TxT + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Disable VT and TxT\n\n\r" + ); + break; + + case ENABLE_VTD: + /// + /// Enable VT-d + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable VT-d\n\n\r" + ); + break; + + case DISABLE_VTD_TXT: + /// + /// Disable VT-d and TxT + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Disable VT-d and TxT\n\n\r" + ); + break; + + case ENABLE_ACTTPM_VT_VTD_TXT_DISABLE_STM: + /// + /// Enable-Active TPM + /// Enable VT, VT-d and TxT + /// Disable STM + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable/Active TPM and Enable VT/VT-d/TxT, and Disable STM\n\n\r" + ); + break; + + case ENABLE_ACTTPM_VT_VTD_TXT_STM: + /// + /// Enable-Active TPM + /// Enable VT, VT-d, TxT and STM + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable/Active TPM and Enable VT/VT-d/TxT/STM\n\n\r" + ); + break; + + case DISABLE_STM: + /// + /// Disable STM + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Disable STM\n\n\r" + ); + break; + + case DISABLE_TXT_STM: + /// + /// Disable TxT and STM + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Disable TxT and STM\n\n\r" + ); + break; + + case DISABLE_SENTER_VMX: + /// + /// Disable SENTER and VMX + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Disable SENTER and VMX\n\n\r" + ); + break; + + case ENABLE_VMX_SMX_ONLY: + /// + /// Enable VMX in SMX only + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable VMX in SMX only\n\n\r" + ); + break; + + case ENABLE_VMX_OUTSIDE_SMX: + /// + /// Enable VMX outside SMX Only + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable VMX outside SMX Only\n\n\r" + ); + break; + + case ENABLE_VMX: + /// + /// Enable VMX + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable VMX\n\n\r" + ); + break; + + case ENABLE_SENTER_ONLY: + /// + /// Enable SENTER Only + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable SENTER only\n\n\r" + ); + break; + + case ENABLE_SENTER_VMX_IN_SMX: + /// + /// Enable SENTER and VMX in SMX + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable SENTER and VMX in SMX\n\n\r" + ); + break; + + case ENABLE_SENTER_VMX_OUTSIDE_SMX: + /// + /// Enable SENTER and VMX outside SMX + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable SENTER and VMX outside SMX\n\n\r" + ); + break; + + case ENABLE_SENTER_VMX: + /// + /// Enable SENTER and VMX + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Enable SENTER and VMX\n\n\r" + ); + break; + + case SET_NO_TXT_MAINTENANCE_FALSE: + /// + /// Set NoTxtMaintenance Flag FALSE + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Set TxT Maintenance Flag to FALSE\n\n\r" + ); + break; + + case SET_NO_TXT_MAINTENANCE_TRUE: + /// + /// Set NoTxtMaintenance Flag TRUE + /// + gST->ConOut->OutputString ( + gST->ConOut, + L"\nA configuration change was requested to Set TxT Maintenance Flag to TRUE\n\n\r" + ); + break; + + default: + return EFI_UNSUPPORTED; + } + + return Status; +} + +/** + Reset system. + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + + @retval EFI_SUCCESS - Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TxtResetState ( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command + ) +{ + EFI_STATUS Status; + PCH_RESET_PROTOCOL *PchReset; + + Status = gBS->LocateProtocol (&gPchResetProtocolGuid, NULL, (VOID **) &PchReset); + if (!EFI_ERROR (Status)) { + PchReset->Reset (PchReset, GlobalReset); + } else { + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); + } + + ASSERT (FALSE); + /// + /// Should not be here + /// + return EFI_SUCCESS; +} diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.cif b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.cif new file mode 100644 index 0000000..7e4a219 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.cif @@ -0,0 +1,14 @@ +<component> + name = "TxtOneTouch" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\TxtOneTouch\Dxe" + RefName = "TxtOneTouchDxe" +[files] +"TxtOneTouchDxe.sdl" +"TxtOneTouchDxe.dxs" +"TxtOneTouchDxe.mak" +"TxtOneTouchDxe.inf" +"TxtOneTouchDxe.c" +"TxtOneTouchDxe.h" +"TxtOneTouchOp.c" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.dxs b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.dxs new file mode 100644 index 0000000..2b37172 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.dxs @@ -0,0 +1,42 @@ +/** @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 (CpuPlatformPolicy) +#include EFI_PROTOCOL_CONSUMER (TcgService) +#endif + +DEPENDENCY_START + EFI_TCG_PROTOCOL_GUID AND + DXE_CPU_PLATFORM_POLICY_PROTOCOL_GUID +DEPENDENCY_END diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.h b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.h new file mode 100644 index 0000000..5722d40 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.h @@ -0,0 +1,158 @@ +/** @file + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _TXT_ONE_TOUCH_DXE_H_ +#define _TXT_ONE_TOUCH_DXE_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 "EdkIIGlueDxe.h" +#include EFI_GUID_DEFINITION (TxtOneTouch) +#include EFI_PROTOCOL_DEFINITION (TxtOneTouchOp) +#include EFI_PROTOCOL_DEFINITION (PchReset) +#include EFI_PROTOCOL_CONSUMER (TcgService) +#endif + +#define H2NL(x) (H2NS ((x) >> 16) | (H2NS ((x) & 0xffff) << 16)) +#define H2NS(x) ((((x) << 8) | ((x) >> 8)) & 0xffff) +#define TPM_PP_USER_ABORT ((TPM_RESULT) (-0x10)) +#define TPM_PP_BIOS_FAILURE ((TPM_RESULT) (-0x0f)) + +/// +/// TPM PPI Commands +/// +#define ENABLE 1 +#define ACTIVATE 3 +#define ENABLE_ACTIVATE 6 +#define DISABLE_DEACTIVATE 7 + +/// +/// Definitions +/// +#define TXT_ONE_TOUCH_VAR L"TxtOneTouch" +#pragma pack(push, 1) +typedef struct { + BOOLEAN NoTxtMaintenance; + BOOLEAN TpmEnable; + BOOLEAN TpmActive; + BOOLEAN VtEnable; + BOOLEAN VtdEnable; + BOOLEAN TxtEnable; + BOOLEAN StmEnable; + BOOLEAN VmxEnable; + BOOLEAN VmxInSmxEnable; + BOOLEAN VmxOutsideSmxEnable; + BOOLEAN SenterEnable; +} TXT_ONE_TOUCH_SETUP; +#pragma pack(pop) + +/** + Extend PPI operation for TxT. + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + + @retval EFI_SUCCESS - Execute the Command successful + @retval EFI_UNSUPPORTED - Command is not supported +**/ +EFI_STATUS +EFIAPI +TxtExecOperation ( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command + ); + +/** + Confirmation dialog for TxT PPI + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + @param[in] Confirm - User confirm + + @retval EFI_SUCCESS - Execute the Command successful + @retval EFI_UNSUPPORTED - Command is not supported +**/ +EFI_STATUS +EFIAPI +TxtConfirmationDialog ( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command, + IN OUT BOOLEAN *Confirm + ); + +/** + Reset system. + + @param[in] This - Point of TXT_ONE_TOUCH_OP_PROTOCOL + @param[in] Command - Operation value for TxT + + @retval EFI_SUCCESS - Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TxtResetState ( + IN TXT_ONE_TOUCH_OP_PROTOCOL *This, + IN UINT8 Command + ); + +/** + Enable/Active TPM + + @param[in] Command - The operation code for TxT One Touch function + + @retval EFI_SUCCESS - TPM command lunch success + @retval EFI_UNSUPPORTED - The Command is not supported + @retval EFI_DEVICE_ERROR - Faile to lunch TPM command +**/ +EFI_STATUS +TpmEnableActive ( + IN UINT8 Command + ); + +/** + Read/Write variable for enable/disable TxT one + touch functions + + @param[in] VariableData - Point to Setup variable buffer + @param[in] WriteData - TRUE, write changes to Setup Variable. FALSE, not to write variable. + + @retval EFI_SUCCESS - Operation complete successful + @retval EFI_INVALID_PARAMETER - VariableData is NULL +**/ +EFI_STATUS +ReadWriteVariable ( + IN OUT TXT_ONE_TOUCH_SETUP *VariableData, + IN BOOLEAN WriteData + ); + +/** + Verify the status of Chipset capaibility and Setup settings + + @param[in] Data - Point to TXT_ONE_TOUCH_SETUP + + @exception EFI_UNSUPPORTED - The system is not able to lunch TxT + @retval EFI_SUCCESS - The system is able to lunch TxT +**/ +EFI_STATUS +ValidateTxtStates ( + IN TXT_ONE_TOUCH_SETUP *Data + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.inf b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.inf new file mode 100644 index 0000000..5a7038b --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.inf @@ -0,0 +1,113 @@ +## @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 = TxtOneTouchDxe +FILE_GUID = 67791e00-0c05-4ae7-a921-fc4057221653 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + TxtOneTouchDxe.c + TxtOneTouchOp.c + TxtOneTouchDxe.h + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + . + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT) + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(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_SOURCE)/Foundation/Cpu/Pentium/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 + $(PROJECT_PCH_FAMILY)ProtocolLib + EdkIIGlueBaseLib + EdkIIGlueBaseMemoryLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeServicesTableLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiLib + EdkIIGlueDxeHobLib +# +# 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 = TxtOneTouchDxe.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/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.mak b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.mak new file mode 100644 index 0000000..7481ab7 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.mak @@ -0,0 +1,88 @@ +#/*++ +#Copyright (c) 2009 - 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: +# +# TxtPolicyInitDxeLib.mak +# +#Abstract: +# +# Make file for the TxtPolicyInitDxeLib component +# +#--*/ +all : TxtOneTouchDxe + +TxtOneTouchDxe : $(BUILD_DIR)\TxtOneTouchDxe.mak TxtOneTouchDxeBin + +$(BUILD_DIR)\TxtOneTouchDxe.mak : $(TxtOneTouchDxe_DIR)\$(@B).cif $(TxtOneTouchDxe_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(TxtOneTouchDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +TxtOneTouchDxeIncludes=\ + $(MISCFRAMEWORK_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + /I$(INTEL_PCH_DIR)\ + $(PROJECT_CPU_INCLUDES)\ + $(TXT_INCLUDES)\ + +TxtOneTouchDxeDefines=\ + $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=DriverEntry"\ + /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__ \ + +TxtOneTouchDxeLibs=\ + $(EFIGUIDLIB)\ + $(EDKFRAMEWORKPROTOCOLLIB)\ + $(EDKPROTOCOLLIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeServicesTableLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EdkIIGlueBaseTimerLibLocalApic_LIB)\ + $(EdkIIGlueDxeHobLib_LIB)\ + $(EdkIIGlueHiiLib_LIB)\ + $(EFIDRIVERLIB)\ + $(UEFIEFIIFRSUPPORTLIB)\ + $(EFISCRIPTLIB)\ + $(CpuProtocolLib_LIB)\ + $(CpuGuidLib_LIB)\ + $(CPUIA32LIB)\ + $(CpuSampleCodeProtocolLib_LIB)\ + $(INTEL_PCH_PROTOCOL_LIB) + +TxtOneTouchDxeBin : $(TxtOneTouchDxeLibs) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\TxtOneTouchDxe.mak all\ + "MY_INCLUDES=$(TxtOneTouchDxeIncludes)"\ + "MY_DEFINES=$(TxtOneTouchDxeDefines)"\ + "GUID=67791e00-0c05-4ae7-a921-fc4057221653"\ + "AFLAGS=$(AFLAGS) $(TxtOneTouchDxeIncludes)"\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(TxtOneTouchDxe_DIR)\TxtOneTouchDxe.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\ + COMPRESS=1\ diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.sdl b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.sdl new file mode 100644 index 0000000..541ccf4 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchDxe.sdl @@ -0,0 +1,28 @@ +TOKEN + Name = "TxtOneTouchSupport" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch" +End + +MODULE + Help = "Includes TxtOneTouchDxe.mak into project" + File = "TxtOneTouchDxe.mak" +End + +PATH + Name = "TxtOneTouchDxe_DIR" + Help = "TxT DXE Policy Init directory" +End + + +ELINK + Name = "$(BUILD_DIR)\TxtOneTouchDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchOp.c b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchOp.c new file mode 100644 index 0000000..860e90d --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/TxtOneTouch/Dxe/TxtOneTouchOp.c @@ -0,0 +1,178 @@ +/** @file + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#include "TxtOneTouchDxe.h" +#include "Tpm12.h" +#include "CpuIa32.h" + +extern EFI_TCG_PROTOCOL *mTcgProtocol; + +/** + Execute TPM command + + @param[in] TcgProtocol - Point to EFI_TCG_PROTOCOL + @param[in] Ordinal - TPM Command code + @param[in] AdditionalParameterSize - Size of additional parameters + @param[in] AdditionalParameters - Point to the buffer saves additional parameters + + @retval EFI_SUCCESS - TPM command lunch success + @retval TPM_PP_BIOS_FAILURE - BIOS fail to execute TPM command +**/ +TPM_RESULT +TpmCommandNoReturnData ( + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN TPM_COMMAND_CODE Ordinal, + IN UINTN AdditionalParameterSize, + IN VOID *AdditionalParameters + ) +{ + EFI_STATUS Status; + TPM_RQU_COMMAND_HDR *TpmRqu; + TPM_RSP_COMMAND_HDR TpmRsp; + UINT32 Size; + + TpmRqu = (TPM_RQU_COMMAND_HDR *) AllocatePool (sizeof (*TpmRqu) + AdditionalParameterSize); + if (TpmRqu == NULL) { + return TPM_PP_BIOS_FAILURE; + } + + TpmRqu->tag = H2NS (TPM_TAG_RQU_COMMAND); + Size = (UINT32) (sizeof (*TpmRqu) + AdditionalParameterSize); + TpmRqu->paramSize = H2NL (Size); + TpmRqu->ordinal = H2NL (Ordinal); + CopyMem (TpmRqu + 1, AdditionalParameters, AdditionalParameterSize); + + Status = TcgProtocol->PassThroughToTpm ( + TcgProtocol, + Size, + (UINT8 *) TpmRqu, + (UINT32) sizeof (TpmRsp), + (UINT8 *) &TpmRsp + ); + FreePool (TpmRqu); + if (EFI_ERROR (Status) || (TpmRsp.tag != H2NS (TPM_TAG_RSP_COMMAND))) { + return TPM_PP_BIOS_FAILURE; + } + + return H2NL (TpmRsp.returnCode); +} + +/** + Enable/Active TPM + + @param[in] Command - The operation code for TxT One Touch function + + @retval EFI_SUCCESS - TPM command lunch success + @retval EFI_UNSUPPORTED - The Command is not supported + @retval EFI_DEVICE_ERROR - Faile to lunch TPM command +**/ +EFI_STATUS +TpmEnableActive ( + IN UINT8 Command + ) +{ + TPM_RESULT TpmResponse; + EFI_STATUS Status; + BOOLEAN BoolVal; + + BoolVal = FALSE; + TpmResponse = 0; + Status = EFI_SUCCESS; + + switch (Command) { + case ENABLE: + TpmResponse = TpmCommandNoReturnData ( + mTcgProtocol, + TPM_ORD_PhysicalEnable, + 0, + NULL + ); + break; + + case ACTIVATE: + BoolVal = FALSE; + TpmResponse = TpmCommandNoReturnData ( + mTcgProtocol, + TPM_ORD_PhysicalSetDeactivated, + sizeof (BoolVal), + &BoolVal + ); + break; + + case ENABLE_ACTIVATE: + Status = TpmEnableActive (ENABLE); + if (Status == EFI_SUCCESS) { + Status = TpmEnableActive (ACTIVATE); + } + + return Status; + + default: + Status = EFI_UNSUPPORTED; + break; + } + + if (TpmResponse != 0) { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Verify the status of Chipset capaibility and Setup settings + + @param[in] Data - Point to TXT_ONE_TOUCH_SETUP + + @exception EFI_UNSUPPORTED - The system is not able to lunch TxT + @retval EFI_SUCCESS - The system is able to lunch TxT +**/ +EFI_STATUS +ValidateTxtStates ( + IN TXT_ONE_TOUCH_SETUP *Data + ) +{ + EFI_CPUID_REGISTER CpuidRegs; + + AsmCpuid ( + 1, + &CpuidRegs.RegEax, + &CpuidRegs.RegEbx, + &CpuidRegs.RegEcx, + &CpuidRegs.RegEdx + ); + + if (Data->VtEnable) { + /// + /// Check if VMX supported + /// + if ((CpuidRegs.RegEcx & 0x020) == 0) { + return EFI_UNSUPPORTED; + } + } + + if (Data->TxtEnable) { + /// + /// Check if TxT & VMX supported + /// + if ((CpuidRegs.RegEcx & 0x060) == 0) { + return EFI_UNSUPPORTED; + } + } + + return EFI_SUCCESS; +} |