From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web09.12624.1632611151004339490 for ; Sat, 25 Sep 2021 16:05:51 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: guo.dong@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10118"; a="285311472" X-IronPort-AV: E=Sophos;i="5.85,322,1624345200"; d="scan'208";a="285311472" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2021 16:05:50 -0700 X-IronPort-AV: E=Sophos;i="5.85,322,1624345200"; d="scan'208";a="586418276" Received: from gdong1-mobl1.amr.corp.intel.com ([10.255.67.241]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2021 16:05:49 -0700 From: "Guo Dong" To: devel@edk2.groups.io Cc: ray.ni@intel.com, maurice.ma@intel.com, benjamin.you@intel.com, Guo Dong Subject: [`edk2-devel][PATCH 2/8] UefiPayloadPkg: Add a common SMM control Runtime DXE module Date: Sat, 25 Sep 2021 16:05:24 -0700 Message-Id: <20210925230530.861-3-guo.dong@intel.com> X-Mailer: git-send-email 2.32.0.windows.2 In-Reply-To: <20210925230530.861-1-guo.dong@intel.com> References: <20210925230530.861-1-guo.dong@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 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 --- .../Include/Guid/SmmRegisterInfoGuid.h | 48 ++++ .../SmmControlRuntimeDxe.c | 252 ++++++++++++++++++ .../SmmControlRuntimeDxe.inf | 50 ++++ UefiPayloadPkg/UefiPayloadPkg.dec | 2 + 4 files changed, 352 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..bf908b24f2 --- /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=960xFF) 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..1558b17319 --- /dev/null +++ b/UefiPayloadPkg/SmmControlRuntimeDxe/SmmControlRuntimeDxe.c @@ -0,0 +1,252 @@ +/** @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 + Generates an SMI using the parameters passed in.=0D +=0D + @param This A pointer to an instance of=0D + EFI_SMM_CONTROL_PROTOCOL=0D + @param ArgumentBuffer The argument buffer=0D + @param ArgumentBufferSize The size of the argument buffer=0D + @param Periodic TRUE to indicate a periodical SMI=0D + @param ActivationInterval Interval of the periodical SMI=0D +=0D + @retval EFI_INVALID_PARAMETER Periodic is TRUE or ArgumentBufferSize > = 1=0D + @retval EFI_SUCCESS SMI generated=0D +=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_CONTROL_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 8f0a7e3f95..1705f28ec4 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