411 lines
14 KiB
C
411 lines
14 KiB
C
/** @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 <CsSvcIhisiFbts.h>
|
|
#include <CsSvcIhisiFets.h>
|
|
#include <CsSvcIhisiOemExtraDataCommunication.h>
|
|
#include <SaDataHob.h>
|
|
#include <CpuRegs.h>
|
|
#include <ChipsetSetupConfig.h>
|
|
#include <Library/BaseLib.h>
|
|
|
|
//
|
|
// Libraries
|
|
//
|
|
#include <Library/SmmServicesTableLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/HobLib.h>
|
|
//
|
|
// Consumer Protocols
|
|
//
|
|
#include <Protocol/DriverSupportedEfiVersion.h>
|
|
#include <Protocol/ComponentName2.h>
|
|
#include <Protocol/ComponentName.h>
|
|
#include <Protocol/SmmFwBlockService.h>
|
|
#include <Protocol/H2OIhisi.h>
|
|
#include <Protocol/BiosGuard.h>
|
|
#include <Protocol/SmmVariable.h>
|
|
//
|
|
// Produced Protocols
|
|
//
|
|
#include <Protocol/H2OSmmChipsetServices.h>
|
|
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
#include <CpuInitDataHob.h>
|
|
#include <SaConfigHob.h>
|
|
//[-start-200114-IB16740000-modify]// for RC1023 modification
|
|
//#include "Register/VirtualMsrcommon.h"
|
|
#include <Register/CommonMsr.h>
|
|
//[-end-200114-IB16740000-modify]//
|
|
#include <BiosGuard.h>
|
|
#include <MemInfoHob.h>
|
|
//
|
|
// 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;
|
|
}
|