From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web10.10216.1634917618991189270 for ; Fri, 22 Oct 2021 08:46:59 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: guo.dong@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10145"; a="209428360" X-IronPort-AV: E=Sophos;i="5.87,173,1631602800"; d="scan'208";a="209428360" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Oct 2021 08:46:41 -0700 X-IronPort-AV: E=Sophos;i="5.87,173,1631602800"; d="scan'208";a="445333059" Received: from gdong1-mobl1.amr.corp.intel.com ([10.212.41.65]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Oct 2021 08:46:40 -0700 From: "Guo Dong" To: devel@edk2.groups.io Cc: Guo Dong , Ray Ni , Maurice Ma , Benjamin You Subject: [`edk2-devel][PATCH V3 2/8] UefiPayloadPkg: Add a common SMM control Runtime DXE module Date: Fri, 22 Oct 2021 08:46:21 -0700 Message-Id: <20211022154627.1607-3-guo.dong@intel.com> X-Mailer: git-send-email 2.32.0.windows.2 In-Reply-To: <20211022154627.1607-1-guo.dong@intel.com> References: <20211022154627.1607-1-guo.dong@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Guo Dong This module consumes SMM Registers HOB (SMI_GBL_EN and SMI_APM_EN) to install SMM control 2 protocol gEfiSmmControl2ProtocolGuid. The protocol activate() would set SMI_GBL_EN and SMI_APM_EN and trigger SMI by writing to IO port 0xB3 and 0xB2. Signed-off-by: Guo Dong Cc: Ray Ni Cc: Maurice Ma Cc: Benjamin You Reviewed-by: Ray Ni Reviewed-by: Benjamin You --- .../Include/Guid/SmmRegisterInfoGuid.h | 48 ++++ .../SmmControlRuntimeDxe.c | 256 ++++++++++++++++++ .../SmmControlRuntimeDxe.inf | 50 ++++ UefiPayloadPkg/UefiPayloadPkg.dec | 2 + 4 files changed, 356 insertions(+) create mode 100644 UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h create mode 100644 UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDx= e.c create mode 100644 UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDx= e.inf diff --git a/UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h b/UefiPayloa= dPkg/Include/Guid/SmmRegisterInfoGuid.h new file mode 100644 index 0000000000..8a1d3d7486 --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h @@ -0,0 +1,48 @@ +/** @file=0D + This file defines the SMM info hob structure.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef PAYLOAD_SMM_REGISTER_INFO_GUID_H_=0D +#define PAYLOAD_SMM_REGISTER_INFO_GUID_H_=0D +=0D +#include =0D +=0D +///=0D +/// SMM Information GUID=0D +///=0D +extern EFI_GUID gSmmRegisterInfoGuid;=0D +=0D +///=0D +/// Reuse ACPI definition=0D +/// AddressSpaceId(0xC0-0xFF) is defined by OEM for MSR and other spaces=0D +///=0D +typedef EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE PLD_GENERIC_ADDRESS;=0D +=0D +#define REGISTER_ID_SMI_GBL_EN 1=0D +#define REGISTER_ID_SMI_GBL_EN_LOCK 2=0D +#define REGISTER_ID_SMI_EOS 3=0D +#define REGISTER_ID_SMI_APM_EN 4=0D +#define REGISTER_ID_SMI_APM_STS 5=0D +=0D +#pragma pack(1)=0D +typedef struct {=0D + UINT64 Id;=0D + UINT64 Value;=0D + PLD_GENERIC_ADDRESS Address;=0D +} PLD_GENERIC_REGISTER;=0D +=0D +typedef struct {=0D + UINT16 Revision;=0D + UINT16 Reserved;=0D + UINT32 Count;=0D + PLD_GENERIC_REGISTER Registers[0];=0D +} PLD_SMM_REGISTERS;=0D +=0D +=0D +#pragma pack()=0D +=0D +#endif=0D diff --git a/UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.c b/U= efiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.c new file mode 100644 index 0000000000..6dd91e2601 --- /dev/null +++ b/UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.c @@ -0,0 +1,256 @@ +/** @file=0D + This module produces the SMM Control2 Protocol=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#define SMM_DATA_PORT 0xB3=0D +#define SMM_CONTROL_PORT 0xB2=0D +=0D +typedef struct {=0D + UINT8 GblBitOffset;=0D + UINT8 ApmBitOffset;=0D + UINT32 Address;=0D +} SMM_CONTROL2_REG;=0D +=0D +SMM_CONTROL2_REG mSmiCtrlReg;=0D +=0D +/**=0D + Invokes SMI activation from either the preboot or runtime environment.=0D +=0D + This function generates an SMI.=0D +=0D + @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instanc= e.=0D + @param[in,out] CommandPort The value written to the command port= .=0D + @param[in,out] DataPort The value written to the data port.=0D + @param[in] Periodic Optional mechanism to engender a peri= odic stream.=0D + @param[in] ActivationInterval Optional parameter to repeat at this = period one=0D + time or, if the Periodic Boolean is s= et, periodically.=0D +=0D + @retval EFI_SUCCESS The SMI has been engendered.=0D + @retval EFI_DEVICE_ERROR The timing is unsupported.=0D + @retval EFI_INVALID_PARAMETER The activation period is unsupported.=0D + @retval EFI_INVALID_PARAMETER The last periodic activation has not been= cleared.=0D + @retval EFI_NOT_STARTED The MM base service has not been initiali= zed.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +Activate (=0D + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,=0D + IN OUT UINT8 *CommandPort OPTIONAL,=0D + IN OUT UINT8 *DataPort OPTIONAL,=0D + IN BOOLEAN Periodic OPTIONAL,=0D + IN EFI_SMM_PERIOD ActivationInterval OPTIONAL=0D + )=0D +{=0D + UINT32 SmiEn;=0D + UINT32 SmiEnableBits;=0D +=0D + if (Periodic) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + SmiEn =3D IoRead32 (mSmiCtrlReg.Address);=0D + SmiEnableBits =3D (1 << mSmiCtrlReg.GblBitOffset) | (1 << mSmiCtrlReg.Ap= mBitOffset);=0D + if ((SmiEn & SmiEnableBits) !=3D SmiEnableBits) {=0D + //=0D + // Set the "global SMI enable" bit and APM bit=0D + //=0D + IoWrite32 (mSmiCtrlReg.Address, SmiEn | SmiEnableBits);=0D + }=0D +=0D + IoWrite8 (SMM_DATA_PORT, DataPort =3D=3D NULL ? 0 : *DataPort);=0D + IoWrite8 (SMM_CONTROL_PORT, CommandPort =3D=3D NULL ? 0 : *CommandPort);= =0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Clears an SMI.=0D +=0D + @param This Pointer to an instance of EFI_SMM_CONTROL2_PROTOCOL=0D + @param Periodic TRUE to indicate a periodical SMI=0D +=0D + @return Return value from SmmClear ()=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +Deactivate (=0D + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,=0D + IN BOOLEAN Periodic=0D + )=0D +{=0D + if (Periodic) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Temporarily do nothing here=0D + //=0D + return EFI_SUCCESS;=0D +}=0D +=0D +///=0D +/// SMM COntrol2 Protocol instance=0D +///=0D +EFI_SMM_CONTROL2_PROTOCOL mSmmControl2 =3D {=0D + Activate,=0D + Deactivate,=0D + 0=0D +};=0D +=0D +/**=0D + Get specified SMI register based on given register ID=0D +=0D + @param[in] SmmRegister SMI related register array from bootloader=0D + @param[in] Id The register ID to get.=0D +=0D + @retval NULL The register is not found or the format is not = expected.=0D + @return smi register=0D +=0D +**/=0D +PLD_GENERIC_REGISTER *=0D +GetSmmCtrlRegById (=0D + IN PLD_SMM_REGISTERS *SmmRegister,=0D + IN UINT32 Id=0D + )=0D +{=0D + UINT32 Index;=0D + PLD_GENERIC_REGISTER *PldReg;=0D +=0D + PldReg =3D NULL;=0D + for (Index =3D 0; Index < SmmRegister->Count; Index++) {=0D + if (SmmRegister->Registers[Index].Id =3D=3D Id) {=0D + PldReg =3D &SmmRegister->Registers[Index];=0D + break;=0D + }=0D + }=0D +=0D + if (PldReg =3D=3D NULL) {=0D + DEBUG ((DEBUG_INFO, "Register %d not found.\n", Id));=0D + return NULL;=0D + }=0D +=0D + //=0D + // Checking the register if it is expected.=0D + //=0D + if ((PldReg->Address.AccessSize !=3D EFI_ACPI_3_0_DWORD) ||=0D + (PldReg->Address.Address =3D=3D 0) ||=0D + (PldReg->Address.RegisterBitWidth !=3D 1) ||=0D + (PldReg->Address.AddressSpaceId !=3D EFI_ACPI_3_0_SYSTEM_IO) ||=0D + (PldReg->Value !=3D 1)) {=0D + DEBUG ((DEBUG_INFO, "Unexpected SMM register.\n"));=0D + DEBUG ((DEBUG_INFO, "AddressSpaceId=3D 0x%x\n", PldReg->Address.Addres= sSpaceId));=0D + DEBUG ((DEBUG_INFO, "RegBitWidth =3D 0x%x\n", PldReg->Address.Regist= erBitWidth));=0D + DEBUG ((DEBUG_INFO, "RegBitOffset =3D 0x%x\n", PldReg->Address.Regist= erBitOffset));=0D + DEBUG ((DEBUG_INFO, "AccessSize =3D 0x%x\n", PldReg->Address.Access= Size));=0D + DEBUG ((DEBUG_INFO, "Address =3D 0x%lx\n",PldReg->Address.Addres= s ));=0D + return NULL;=0D + }=0D + return PldReg;=0D +}=0D +=0D +=0D +/**=0D + Fixup data pointers so that the services can be called in virtual mode.= =0D +=0D + @param[in] Event The event registered.=0D + @param[in] Context Event context.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +SmmControlVirtualAddressChangeEvent (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + )=0D +{=0D + EfiConvertPointer (0x0, (VOID **) &(mSmmControl2.Trigger));=0D + EfiConvertPointer (0x0, (VOID **) &(mSmmControl2.Clear));=0D +}=0D +=0D +=0D +/**=0D + This function installs EFI_SMM_CONTROL2_PROTOCOL.=0D +=0D + @param ImageHandle Handle for the image of this driver=0D + @param SystemTable Pointer to the EFI System Table=0D +=0D + @retval EFI_UNSUPPORTED There's no Intel ICH on this platform=0D + @return The status returned from InstallProtocolInterface().=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SmmControlEntryPoint (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_HOB_GUID_TYPE *GuidHob;=0D + PLD_SMM_REGISTERS *SmmRegister;=0D + PLD_GENERIC_REGISTER *SmiGblEnReg;=0D + PLD_GENERIC_REGISTER *SmiApmEnReg;=0D + EFI_EVENT Event;=0D +=0D + GuidHob =3D GetFirstGuidHob (&gSmmRegisterInfoGuid);=0D + if (GuidHob =3D=3D NULL) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + SmmRegister =3D (PLD_SMM_REGISTERS *) (GET_GUID_HOB_DATA(GuidHob));=0D + SmiGblEnReg =3D GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_GBL_EN);= =0D + if (SmiGblEnReg =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "SMI global enable reg not found.\n"));=0D + return EFI_NOT_FOUND;=0D + }=0D + mSmiCtrlReg.Address =3D (UINT32)SmiGblEnReg->Address.Address;=0D + mSmiCtrlReg.GblBitOffset =3D SmiGblEnReg->Address.RegisterBitOffset;=0D +=0D + SmiApmEnReg =3D GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_APM_EN);= =0D + if (SmiApmEnReg =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "SMI APM enable reg not found.\n"));=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + if (SmiApmEnReg->Address.Address !=3D mSmiCtrlReg.Address) {=0D + DEBUG ((DEBUG_ERROR, "SMI APM EN and SMI GBL EN are expected to have s= ame register base\n"));=0D + DEBUG ((DEBUG_ERROR, "APM:0x%x, GBL:0x%x\n", SmiApmEnReg->Address.Addr= ess, mSmiCtrlReg.Address));=0D + return EFI_UNSUPPORTED;=0D + }=0D + mSmiCtrlReg.ApmBitOffset =3D SmiApmEnReg->Address.RegisterBitOffset;=0D +=0D + //=0D + // Install our protocol interfaces on the device's handle=0D + //=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &ImageHandle,=0D + &gEfiSmmControl2ProtocolGuid,=0D + &mSmmControl2,=0D + NULL=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + Status =3D gBS->CreateEventEx (=0D + EVT_NOTIFY_SIGNAL,=0D + TPL_NOTIFY,=0D + SmmControlVirtualAddressChangeEvent,=0D + NULL,=0D + &gEfiEventVirtualAddressChangeGuid,=0D + &Event=0D + );=0D + return Status;=0D +}=0D diff --git a/UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.inf b= /UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.inf new file mode 100644 index 0000000000..f0c2a4586b --- /dev/null +++ b/UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.inf @@ -0,0 +1,50 @@ +## @file=0D +# SMM Control runtime DXE Module=0D +#=0D +# Provides the ability to generate a software SMI.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SmmControlRuntimeDxe=0D + FILE_GUID =3D C3099578-F815-4a96-84A3-FC593760181D= =0D + MODULE_TYPE =3D DXE_RUNTIME_DRIVER=0D + VERSION_STRING =3D 1.0=0D + ENTRY_POINT =3D SmmControlEntryPoint=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64=0D +#=0D +=0D +[Sources]=0D + SmmControlRuntimeDxe.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + UefiPayloadPkg/UefiPayloadPkg.dec=0D +=0D +[LibraryClasses]=0D + UefiDriverEntryPoint=0D + DebugLib=0D + UefiBootServicesTableLib=0D + UefiRuntimeLib=0D + PcdLib=0D + IoLib=0D + HobLib=0D +=0D +[Guids]=0D + gSmmRegisterInfoGuid=0D + gEfiEventVirtualAddressChangeGuid=0D +=0D +[Protocols]=0D + gEfiSmmControl2ProtocolGuid ## PRODUCES=0D +=0D +[Depex]=0D + TRUE=0D diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayload= Pkg.dec index e5e8db8863..4f93d3e671 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -37,6 +37,8 @@ gUefiSerialPortInfoGuid =3D { 0x6c6872fe, 0x56a9, 0x4403, { 0xbb, 0x98,= 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1 } }=0D gLoaderMemoryMapInfoGuid =3D { 0xa1ff7424, 0x7a1a, 0x478e, { 0xa9, 0xe4,= 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32 } }=0D =0D + gSmmRegisterInfoGuid =3D { 0xaa9bd7a7, 0xcafb, 0x4499, { 0xa4, 0xa9,= 0xb, 0x34, 0x6b, 0x40, 0xa6, 0x22 } }=0D +=0D [Ppis]=0D gEfiPayLoadHobBasePpiGuid =3D { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6,= 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} }=0D =0D --=20 2.32.0.windows.2