/** @file SMM Chipset Services driver. It produces an instance of the SMM Chipset Services protocol to provide the chipset related functions which will be used by Kernel or Project code. These protocol functions should be used by calling the corresponding functions in SmmChipsetSvcLib to have the protocol size checking ;*************************************************************************** ;* Copyright (c) 2014 - 2020, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include #include #include #include #include #include #include // // Libraries // #include #include #include #include // // Consumer Protocols // #include #include #include #include #include #include #include // // Produced Protocols // #include #include #include #include //[-start-200114-IB16740000-modify]// for RC1023 modification //#include "Register/VirtualMsrcommon.h" #include //[-end-200114-IB16740000-modify]// #include #include // // Global variable // extern EFI_COMPONENT_NAME2_PROTOCOL gChipsetSvcSmmComponentName2; extern EFI_COMPONENT_NAME_PROTOCOL gChipsetSvcSmmComponentName; GLOBAL_REMOVE_IF_UNREFERENCED BIOSGUARD_HOB *mBiosGuardHobPtr; // // Driver Support EFI Version Protocol instance // GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gSmmChipsetSvcDriverSupportedEfiVersion = { sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), 0x0002001E }; H2O_IHISI_PROTOCOL *mH2OIhisi = NULL; H2O_SMM_CHIPSET_SERVICES_PROTOCOL *mSmmChipsetSvc = NULL; EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mSmmFwBlockService = NULL; EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL; BIOSGUARD_PROTOCOL *mBiosGuardProtocol; EFI_PHYSICAL_ADDRESS mBiosGuardMemAddress = 0; UINTN mBiosGuardMemSize = 0; #define ASSIGN_FUNCTION_ENTRY(ProtocolMember, FunctionEntry) \ if (mSmmChipsetSvc->Size >= (OFFSET_OF (H2O_SMM_CHIPSET_SERVICES_PROTOCOL, ProtocolMember) + sizeof (VOID*))) { \ mSmmChipsetSvc->ProtocolMember = FunctionEntry; \ } EFI_STATUS EFIAPI ResetSystem ( IN EFI_RESET_TYPE ResetType ); EFI_STATUS LegacyRegionAccessCtrl ( IN UINT32 Start, IN UINT32 Length, IN UINT32 Mode ); EFI_STATUS EFIAPI EnableFdWrites ( IN BOOLEAN EnableWrites ); EFI_STATUS SataComReset ( IN UINTN PortNumber ); /** The notification of gEfiSmmFwBlockServiceProtocolGuid protocol is installed @param[in] Protocol Points to the protocol's unique identifier. @param[in] Interface Points to the interface instance. @param[in] Handle The handle on which the interface was installed. @retval EFI_SUCCESS Locate gEfiSmmFwBlockServiceProtocolGuid protocol successful. @retval EFI_NOT_FOUND Cannot find gEfiSmmFwBlockServiceProtocolGuid instance. **/ STATIC EFI_STATUS SmmFwBlockNotify ( IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle ) { return gSmst->SmmLocateProtocol ( &gEfiSmmFwBlockServiceProtocolGuid, NULL, &mSmmFwBlockService ); } /** The notification of gEfiSmmVariableProtocolGuid protocol is installed @param[in] Protocol Points to the protocol's unique identifier. @param[in] Interface Points to the interface instance. @param[in] Handle The handle on which the interface was installed. @retval EFI_SUCCESS Locate gEfiSmmVariableProtocolGuid protocol successful. @retval EFI_NOT_FOUND Cannot find gEfiSmmVariableProtocolGuid instance. **/ STATIC EFI_STATUS SmmVariableNotify ( IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle ) { return gSmst->SmmLocateProtocol ( &gEfiSmmVariableProtocolGuid, NULL, &mSmmVariable ); } /** The notification of gH2OIhisiProtocolGuid protocol is installed @param[in] Protocol Points to the protocol's unique identifier. @param[in] Interface Points to the interface instance. @param[in] Handle The handle on which the interface was installed. @retval EFI_SUCCESS Locate gH2OIhisiProtocolGuid protocol successful. @retval EFI_NOT_FOUND Cannot find gH2OIhisiProtocolGuid instance. **/ STATIC EFI_STATUS SmmH2OIhisiNotify ( IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle ) { return gSmst->SmmLocateProtocol ( &gH2OIhisiProtocolGuid, NULL, &mH2OIhisi ); } /** The notification of gSmmBiosGuardProtocolGuid protocol is installed @param[in] Protocol Points to the protocol's unique identifier. @param[in] Interface Points to the interface instance. @param[in] Handle The handle on which the interface was installed. @retval EFI_SUCCESS Locate gSmmBiosGuardProtocolGuid protocol successful. @retval EFI_NOT_FOUND Cannot find gSmmBiosGuardProtocolGuid instance. **/ STATIC EFI_STATUS SmmBiosGuardNotify ( IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle ) { EFI_STATUS Status; Status = gSmst->SmmLocateProtocol ( &gSmmBiosGuardProtocolGuid, NULL, &mBiosGuardProtocol ); ASSERT_EFI_ERROR (Status); return Status; } /** The notification of gSmmBiosGuardProtocolGuid protocol is installed @param[in] Protocol Points to the protocol's unique identifier. @param[in] Interface Points to the interface instance. @param[in] Handle The handle on which the interface was installed. @retval EFI_SUCCESS Locate gSmmBiosGuardProtocolGuid protocol successful. @retval EFI_NOT_FOUND Cannot find gSmmBiosGuardProtocolGuid instance. **/ STATIC EFI_STATUS BiosGuardInitial ( VOID ) { SA_CONFIG_HOB *SaConfigHobPtr; UINT64 MsrValue; //[-start-200114-IB16740000-modify]// for RC1023 modification MSR_PLAT_FRMW_PROT_CTRL_REGISTER PlatFrmwProtCtrl; //[-end-200114-IB16740000-modify]// MEMORY_PLATFORM_DATA_HOB *MemInfoHob; UINT8 TotalDprSizeMB; mBiosGuardMemAddress = 0x00; mBiosGuardMemSize = 0; SaConfigHobPtr = NULL; MsrValue = 0x00; TotalDprSizeMB = 0; MemInfoHob = NULL; PlatFrmwProtCtrl.Uint64 = AsmReadMsr64 (MSR_PLAT_FRMW_PROT_CTRL); if (PlatFrmwProtCtrl.Bits.PfatLock == 1) { if (PlatFrmwProtCtrl.Bits.PfatEnable == 1) { SaConfigHobPtr = GetFirstGuidHob (&gSaConfigHobGuid); ASSERT (SaConfigHobPtr != NULL); if (SaConfigHobPtr == NULL) { return EFI_NOT_FOUND; } mBiosGuardHobPtr = GetFirstGuidHob (&gBiosGuardHobGuid); if (mBiosGuardHobPtr == NULL) { DEBUG ((DEBUG_ERROR, "BIOS Guard HOB not available\n")); return EFI_NOT_FOUND; } if (mBiosGuardHobPtr->BiosGuardModulePtr == (EFI_PHYSICAL_ADDRESS) NULL) { DEBUG ((DEBUG_ERROR, "BIOS Guard Module Pointer is NULL\n")); return EFI_NOT_FOUND; } MemInfoHob = (MEMORY_PLATFORM_DATA_HOB *) GetFirstGuidHob (&gSiMemoryPlatformDataGuid); if (MemInfoHob == NULL) { DEBUG ((DEBUG_ERROR, "MemInfoHob not available\n")); return EFI_NOT_FOUND; } TotalDprSizeMB += mBiosGuardHobPtr->BiosGuardMemSize; TotalDprSizeMB += SaConfigHobPtr->DprDirectory[EnumDprDirectoryTxt].Size; mBiosGuardMemAddress = (EFI_PHYSICAL_ADDRESS) ((UINT64)(MemInfoHob->Data.TsegBase - TotalDprSizeMB) << 20); mBiosGuardMemSize = (UINT32) LShiftU64 (mBiosGuardHobPtr->BiosGuardMemSize, 20); } } return EFI_SUCCESS; } EFI_STATUS EFIAPI ChipsetSvcSmmEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINT32 Size; EFI_HANDLE Handle; VOID *FwBlockRegistration; VOID *VariableRegistration; VOID *H2OIhisiRegistration; VOID *BiosGuardRegistration; Status = EFI_SUCCESS; Handle = NULL; // // Create an instance of the H2O SMM Chipset Services protocol. // Then install it on the image handle. // Size = sizeof (H2O_SMM_CHIPSET_SERVICES_PROTOCOL); if (Size < sizeof (UINT32)) { // must at least contain Size field. return EFI_INVALID_PARAMETER; } mSmmChipsetSvc = AllocateZeroPool (Size); if (mSmmChipsetSvc == NULL) { return EFI_OUT_OF_RESOURCES; } Status = gSmst->SmmLocateProtocol ( &gEfiSmmFwBlockServiceProtocolGuid, NULL, &mSmmFwBlockService ); if (EFI_ERROR (Status)) { Status = gSmst->SmmRegisterProtocolNotify ( &gEfiSmmFwBlockServiceProtocolGuid, SmmFwBlockNotify, &FwBlockRegistration ); } // // Locate SMM Variable Protocol // Status = gSmst->SmmLocateProtocol ( &gEfiSmmVariableProtocolGuid, NULL, (VOID **) &mSmmVariable ); if (EFI_ERROR (Status)) { Status = gSmst->SmmRegisterProtocolNotify ( &gEfiSmmVariableProtocolGuid, SmmVariableNotify, &VariableRegistration ); ASSERT_EFI_ERROR (Status); } Status = gSmst->SmmLocateProtocol ( &gH2OIhisiProtocolGuid, NULL, (VOID **) &mH2OIhisi ); if (EFI_ERROR (Status)) { Status = gSmst->SmmRegisterProtocolNotify ( &gH2OIhisiProtocolGuid, SmmH2OIhisiNotify, &H2OIhisiRegistration ); ASSERT_EFI_ERROR (Status); } Status = gSmst->SmmLocateProtocol ( &gSmmBiosGuardProtocolGuid, NULL, (VOID **)&mBiosGuardProtocol ); if (EFI_ERROR (Status)) { Status = gSmst->SmmRegisterProtocolNotify ( &gSmmBiosGuardProtocolGuid, SmmBiosGuardNotify, &BiosGuardRegistration ); ASSERT_EFI_ERROR (Status); } Status = BiosGuardInitial (); mSmmChipsetSvc->Size = Size; // // Now, populate functions based on Size. // ASSIGN_FUNCTION_ENTRY (EnableFdWrites, EnableFdWrites); ASSIGN_FUNCTION_ENTRY (LegacyRegionAccessCtrl, LegacyRegionAccessCtrl); ASSIGN_FUNCTION_ENTRY (ResetSystem, ResetSystem); ASSIGN_FUNCTION_ENTRY (SataComReset, SataComReset); ASSIGN_FUNCTION_ENTRY (IhisiFbtsGetPermission, IhisiFbtsGetPermission); ASSIGN_FUNCTION_ENTRY (IhisiFbtsGetOemFlashMap, IhisiFbtsGetOemFlashMap); ASSIGN_FUNCTION_ENTRY (IhisiFbtsDoBeforeWriteProcess, IhisiFbtsDoBeforeWriteProcess); ASSIGN_FUNCTION_ENTRY (IhisiFbtsDoAfterWriteProcess, IhisiFbtsDoAfterWriteProcess); ASSIGN_FUNCTION_ENTRY (IhisiFbtsDoBeforeReadProcess, IhisiFbtsDoBeforeReadProcess); ASSIGN_FUNCTION_ENTRY (IhisiFbtsDoAfterReadProcess, IhisiFbtsDoAfterReadProcess); ASSIGN_FUNCTION_ENTRY (IhisiFbtsApTerminated, IhisiFbtsApTerminated); ASSIGN_FUNCTION_ENTRY (IhisiFbtsNormalFlash, IhisiFbtsNormalFlash); ASSIGN_FUNCTION_ENTRY (IhisiFbtsPartialFlash, IhisiFbtsPartialFlash); ASSIGN_FUNCTION_ENTRY (IhisiFbtsOemComplete, IhisiFbtsOemComplete); ASSIGN_FUNCTION_ENTRY (IhisiFbtsShutdown, IhisiFbtsShutDown); ASSIGN_FUNCTION_ENTRY (IhisiFbtsReboot, IhisiFbtsReboot); ASSIGN_FUNCTION_ENTRY (IhisiFbtsApRequestDoNothing, IhisiFbtsApRequestDoNothing); ASSIGN_FUNCTION_ENTRY (IhisiFetsReboot, IhisiFetsReboot); ASSIGN_FUNCTION_ENTRY (IhisiFetsShutdown, IhisiFetsShutdown); ASSIGN_FUNCTION_ENTRY (IhisiOemExtCommunication, IhisiOemExtCommunication); ASSIGN_FUNCTION_ENTRY (IhisiOemExtDataWrite, IhisiOemExtDataWrite); ASSIGN_FUNCTION_ENTRY (IhisiOemExtDataRead, IhisiOemExtDataRead); Status = gSmst->SmmInstallProtocolInterface ( &Handle, &gH2OSmmChipsetServicesProtocolGuid, EFI_NATIVE_INTERFACE, mSmmChipsetSvc ); return Status; }