alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/ChipsetSvcSmm/ChipsetSvcSmm.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;
}