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 /Core/CPU/CpuSpSmi.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/CPU/CpuSpSmi.c')
-rw-r--r-- | Core/CPU/CpuSpSmi.c | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/Core/CPU/CpuSpSmi.c b/Core/CPU/CpuSpSmi.c new file mode 100644 index 0000000..bd4469d --- /dev/null +++ b/Core/CPU/CpuSpSmi.c @@ -0,0 +1,568 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1987-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.c 8 5/24/15 11:37p Davidhsieh $ +// +// $Revision: 8 $ +// +// $Date: 5/24/15 11:37p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.c $ +// +// 8 5/24/15 11:37p Davidhsieh +// [TAG] EIP215675 +// [Category] New Feature +// [Description] Smm Access Check feautre support +// [Files] Cpu.sdl, CpuDxe.c, CpuSpSmi.sdl, CpuSpsmi.c +// +// 7 10/08/13 3:10a Crystallee +// [TAG] EIP137873 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] CPU Security Configuration(MSR 4E0[0]) will be changed +// after S3 resume +// [RootCause] Didn't restore the Cpu MSR 4e0 while S3 resume. +// [Solution] Restore the Cpu MSR 0x4E0 while S3 resume. +// +// 6 1/24/13 10:45p Davidhsieh +// [TAG] EIP112381 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] TBoot S3 resume fail +// [RootCause] MSR 0x2e7 is not restored +// [Solution] Save and restore MSR 0x2e7 for S3 +// +// 5 12/18/12 9:23p Davidhsieh +// [TAG] None +// [Category] Improvement +// [Description] Check CPU before lock SMM_FEATURE_CONTROL MSR +// +// 4 12/09/12 10:35p Davidhsieh +// [TAG] None +// [Category] Improvement +// [Description] Lock SMM_FEATURE_CONTROL MSR +// +// 3 10/04/12 9:20a Davidhsieh +// Change the procedure of configuring MTRR +// +// 2 7/10/12 2:51a Davidhsieh +// [TAG] EIP93180 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] The "Event Kernel-Power 137" error event log shows while +// resumed from S3 +// [RootCause] The fixed and variable Mtrrs of BSP are not restored +// [Solution] Restore BPS's mtrss +// +// 1 2/07/12 4:00a Davidhsieh +// +// +//********************************************************************** + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: CpuSpSmi.C +// +// Description: Provide functions to CPU specific SMI +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include "CpuSpSmi.h" + +UINT64 ReadMsr (UINT32 Msr); +VOID WriteMsr(UINT32 Msr, UINT64 Value); + +UINTN MpMtrrSynchUpEntry (VOID); +VOID MpMtrrSynchUpExit (UINTN Cr4); + +EFI_GUID SwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID; + +EFI_SMM_SYSTEM_TABLE *mSmst; +EFI_SMM_BASE_PROTOCOL *pSmmBase; +EFI_SMM_SW_DISPATCH_PROTOCOL *gSwDispatch; + +// +// MSR table for S3 resume +// +EFI_MSR_VALUES mFixedMtrrValues[] = { + { MTRR_FIX_64K_00000, 0 }, + { MTRR_FIX_16K_80000, 0 }, + { MTRR_FIX_16K_A0000, 0 }, + { MTRR_FIX_4K_C0000, 0 }, + { MTRR_FIX_4K_C8000, 0 }, + { MTRR_FIX_4K_D0000, 0 }, + { MTRR_FIX_4K_D8000, 0 }, + { MTRR_FIX_4K_E0000, 0 }, + { MTRR_FIX_4K_E8000, 0 }, + { MTRR_FIX_4K_F0000, 0 }, + { MTRR_FIX_4K_F8000, 0 }, + { 0, 0 } +}; + +EFI_MSR_VALUES mVariableMtrrValues[] = { + { MTRR_PHYS_BASE_0, 0 }, + { MTRR_PHYS_MASK_0, 0 }, + { MTRR_PHYS_BASE_1, 0 }, + { MTRR_PHYS_MASK_1, 0 }, + { MTRR_PHYS_BASE_2, 0 }, + { MTRR_PHYS_MASK_2, 0 }, + { MTRR_PHYS_BASE_3, 0 }, + { MTRR_PHYS_MASK_3, 0 }, + { MTRR_PHYS_BASE_4, 0 }, + { MTRR_PHYS_MASK_4, 0 }, + { MTRR_PHYS_BASE_5, 0 }, + { MTRR_PHYS_MASK_5, 0 }, + { MTRR_PHYS_BASE_6, 0 }, + { MTRR_PHYS_MASK_6, 0 }, + { MTRR_PHYS_BASE_7, 0 }, + { MTRR_PHYS_MASK_7, 0 }, + { MTRR_PHYS_BASE_8, 0 }, + { MTRR_PHYS_MASK_8, 0 }, + { MTRR_PHYS_BASE_9, 0 }, + { MTRR_PHYS_MASK_9, 0 } +}; + +#define MiscMsrCount 1 + +EFI_MSR_VALUES mMiscMsrValues[] = { + { 0x2e7, 0 } +}; + +EFI_MSR_VALUES mSmmFeatureCtrl = { 0x4e0, 0}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SaveCpuMsr +// +// Description: This function saves the CPU MSRs for S3 resume usage. +// +// Input: DispatchHandle Handle to the Dispatcher +// DispatchContext SW SMM dispatcher context +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +SaveCpuMsr( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext + ) +{ + UINT32 i; + + if (Shr64(ReadMsr(0x17d),57) & 0x03){ + if (!(ReadMsr(mSmmFeatureCtrl.Index) && 0x01)) + WriteMsr(mSmmFeatureCtrl.Index, ReadMsr(mSmmFeatureCtrl.Index) | 0x01); + mSmmFeatureCtrl.Value = ReadMsr(mSmmFeatureCtrl.Index); + } + + //Save Fixed MTRR + for(i=0; i < NUM_OF_FIXED_MTRRS; i++) + { + mFixedMtrrValues[i].Value = ReadMsr(mFixedMtrrValues[i].Index); + } + + //Save variable MTRR + for (i = 0; i < ((UINT8)(ReadMsr(MSR_IA32_MTRR_CAP) & VCNT_MASK)); i++) + { + mVariableMtrrValues[i * 2].Value = ReadMsr(mVariableMtrrValues[i * 2].Index); + mVariableMtrrValues[i * 2 + 1].Value = ReadMsr(mVariableMtrrValues[i * 2 + 1].Index); + } + + mMiscMsrValues[0].Value = ReadMsr(mMiscMsrValues[0].Index); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RestoreMsrOnCpu +// +// Description: This function restores the CPU MSRs during S3 resume. +// +// Input: None +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +RestoreMsrOnCpu(IN VOID *data) +{ + UINT32 i; + UINTN Cr4; + + Cr4 = MpMtrrSynchUpEntry(); + + //Restore Fixed MTRR + for(i=0; i < NUM_OF_FIXED_MTRRS; i++) + { + WriteMsr(mFixedMtrrValues[i].Index, mFixedMtrrValues[i].Value ); + } + + //Restore variable MTRR + for (i = 0; i < ((UINT8)(ReadMsr(MSR_IA32_MTRR_CAP) & VCNT_MASK)); i++) + { + WriteMsr(mVariableMtrrValues[i * 2].Index, mVariableMtrrValues[i * 2].Value ); + WriteMsr(mVariableMtrrValues[i * 2 + 1].Index, mVariableMtrrValues[i * 2 + 1].Value ); + } + + MpMtrrSynchUpExit (Cr4); + + WriteMsr(mMiscMsrValues[0].Index, mMiscMsrValues[0].Value); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RestoreCpuMsr +// +// Description: This function restores the CPU MSRs during S3 resume. +// +// Input: DispatchHandle Handle to the Dispatcher +// DispatchContext SW SMM dispatcher context +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +RestoreCpuMsr( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext + ) +{ + UINT32 i; + UINTN Cr4; + + if (Shr64(ReadMsr(0x17d),57) & 0x03){ + if (!(ReadMsr(mSmmFeatureCtrl.Index) && 0x01)){ + WriteMsr(mSmmFeatureCtrl.Index, (mSmmFeatureCtrl.Value & ~0x01)); + WriteMsr(mSmmFeatureCtrl.Index, ReadMsr(mSmmFeatureCtrl.Index) | 0x01); + } + } + + for (i = 0; i < pSmst->NumberOfCpus; ++i) { + pSmst->SmmStartupThisAp(RestoreMsrOnCpu, i, NULL); + } + + Cr4 = MpMtrrSynchUpEntry(); + RestoreMsrOnCpu(NULL); + MpMtrrSynchUpExit (Cr4); +} + +#define SMRAM_CPU_DATA_VARIABLE_GUID \ + { \ + 0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \ + } + +#define SMRAM_CPU_DATA_VARIABLE L"SmramCpuDataVar" + +#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81 + +EFI_GUID mSmramCpuDataVariableGuid = SMRAM_CPU_DATA_VARIABLE_GUID; +BOOLEAN mLocked = FALSE; + +/** + Dispatch function for a Software SMI handler. + + @param DispatchHandle The handle of this dispatch function. + @param DispatchContext The pointer to the dispatch function's context. + The SwSmiInputValue field is filled in + by the software dispatch driver prior to + invoking this dispatch function. + The dispatch function will only be called + for input values for which it is registered. + + @return None + +**/ +VOID +EFIAPI +SmramSaveInfoHandler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext + ) +/** + +@brief + + Dispatch function for a Software SMI handler + + @param[in] DispatchHandle - The handle of this dispatch function. + @param[in] DispatchContext - The pointer to the dispatch function's context. + + +**/ +{ + EFI_STATUS Status; + UINT64 VarData[3]; + UINTN VarSize; + + if (!mLocked && IoRead8 (SW_SMI_IO_ADDRESS+1) == SMM_FROM_CPU_DRIVER_SAVE_INFO) { + VarSize = sizeof (VarData); + Status = pRS->GetVariable ( + SMRAM_CPU_DATA_VARIABLE, + &mSmramCpuDataVariableGuid, + NULL, + &VarSize, + VarData + ); + if (!EFI_ERROR (Status) && VarSize == sizeof (VarData)) { + MemCpy ( + (VOID *) (UINTN) (VarData[0]), + (VOID *) (UINTN) (VarData[1]), + (UINTN) (VarData[2]) + ); + } + + mLocked = TRUE; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CpuSmmFeatureEn +// +// Description: +// +// Input: DispatchHandle Handle to the Dispatcher +// DispatchContext SW SMM dispatcher context +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +CpuSmmFeatureEn( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext + ) +{ + + UINT64 MsrData; + + if (Shr64(ReadMsr(0x17d),58) & 0x01){ + if (!(ReadMsr(0x4e0) && 0x01)){ + MsrData = ReadMsr(0x4e0); + MsrData |= 0x4; + WriteMsr(0x4e0, MsrData); + } + } +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InSmmFunction +// +// Description: Called from InstallSmiHandler +// +// Input: +// +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InSmmFunction( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + EFI_STATUS Status; + EFI_HANDLE Handle; + + EFI_SMM_SW_DISPATCH_CONTEXT Save_CPU_MSR = {SW_SMI_SAVE_MSR}; + EFI_SMM_SW_DISPATCH_CONTEXT Restore_CPU_MSR = {SW_SMI_RESTORE_MSR}; + EFI_SMM_SW_DISPATCH_CONTEXT CpuDriverSaveInfo = { SMM_FROM_SMBASE_DRIVER }; + EFI_SMM_SW_DISPATCH_CONTEXT CpuSmmFeatureEnable = {SW_SMI_ENABLE_SMM_FEATURE}; + + Status = pBS->LocateProtocol(&SwDispatchProtocolGuid,NULL,&gSwDispatch); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR(Status); + return Status; + } + + Status = gSwDispatch->Register( + gSwDispatch, + SaveCpuMsr, + &Save_CPU_MSR, + &Handle + ); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR(Status); + return Status; + } + + Status = gSwDispatch->Register( + gSwDispatch, + RestoreCpuMsr, + &Restore_CPU_MSR, + &Handle + ); + + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR(Status); + return Status; + } + + Status = gSwDispatch->Register( + gSwDispatch, + SmramSaveInfoHandler, + &CpuDriverSaveInfo, + &Handle + ); + + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR(Status); + return Status; + } + + Status = gSwDispatch->Register( + gSwDispatch, + CpuSmmFeatureEn, + &CpuSmmFeatureEnable, + &Handle + ); + + Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase); + if (EFI_ERROR(Status)) { + return Status; + } + + /*Status = pBS->LocateProtocol (&gEfiSmmThunkProtocolGuid, NULL, &mSmmThunk); + if (EFI_ERROR(Status)) { + TRACE_IDESMM(((UINTN)TRACE_ALWAYS, "SMM Thunk Protocol not located.\n")); + } else { + TRACE_IDESMM(((UINTN)TRACE_ALWAYS, "SMM Thunk Protocol located.\n")); + }*/ + + pSmmBase->GetSmstLocation (pSmmBase, &mSmst); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NotInSmmFunction +// +// Description: If Not In Smm Function +// +// Input: +// +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS NotInSmmFunction( + ) +{ + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CpuSpSmiInit +// +// Description: Initializes CPU specific SMM Drivers. +// +// Input: +// +// Output: +// EFI_STATUS +// +// Modified: +// +// Referrals: +// +// Notes: +// Here is the control flow of this function: +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS CpuSpSmiInit( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + //EFI_STATUS Status; + + InitAmiLib(ImageHandle,SystemTable); + + //Status = pBS->LocateProtocol(&SwDispatchProtocolGuid,NULL,&gSwDispatch); + //if (EFI_ERROR(Status)) return Status; +//InitSmmHandler + + // return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NonSmmElinkFunctions); + + return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL); + + +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1987-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + |