On 11/05/15 16:45, Kinney, Michael D wrote: > Laszlo, > > Thanks for the details. Your implementation looks good. > > I will discuss this further with Jiewen to see if it makes sense to provide > additional implementations of this PPI that could be shared by multiple > platforms.
I greatly appreciate your flexibility. Thank you! Laszlo > > Thanks, > > Mike > >> -----Original Message----- >> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of >> Laszlo Ersek >> Sent: Thursday, November 05, 2015 3:15 AM >> To: Kinney, Michael D; edk2-de...@ml01.01.org >> Cc: Justen, Jordan L >> Subject: Re: [edk2] [PATCH v4 07/41] OvmfPkg: add PEIM for providing TSEG- >> as-SMRAM during PEI >> >> On 11/05/15 02:32, Kinney, Michael D wrote: >>> Laszlo, >>> >>> For the EFI_PEI_COMMUNICATION_PPI, is there a reason you are not using >>> UefiCpuPkg\PiSmmCommunication\PiSmmCommunicationPei.inf to produce >> that PPI? >> >> Yes. >> >> When I wrote this patch originally on April 27th and the days after, >> there was no EFI_PEI_COMMUNICATION_PPI implementation in edk2; neither >> were plans known to add one. >> >> In addition, we had discussed the behavior of SmmLockBoxPeiLib at >> length, in an off-list thread that you had been CC'd on. Please search >> your archives for the message with the following metadata, and the >> sub-thread rooted in it: >> >> Message-ID: <553f96cc.9050...@redhat.com> >> Date: Tue, 28 Apr 2015 16:18:52 +0200 >> From: Laszlo Ersek <ler...@redhat.com> >> To: Yao, Jiewen <jiewen....@intel.com> >> CC: Justen, Jordan L <jordan.l.jus...@intel.com>, >> Zimmer, Vincent <vincent.zim...@intel.com>, >> Kinney, Michael D <michael.d.kin...@intel.com>, >> Paolo Bonzini <pbonz...@redhat.com>, >> Gerd Hoffmann <kra...@redhat.com>, >> Michael S. Tsirkin <m...@redhat.com> >> Subject: Re: open-sourcing Intel's "IA32FamilyCpuPkg/PiSmmCpuDxeSmm" >> >> In that message, I asked: >> >>> In the whitepaper entitled "A Tour Beyond BIOS: Implementing S3 Resume >>> with EDKII", page 25 says, under the heading "PEI Instance": >>> >>> The PEI instance of SmmLockboxLib has two ways to communicate with >>> the LockBox in SMRAM. >>> >>> 1) It uses the SMM_COMMUNICATION PPI to communicate the SmmLockbox >>> service provider, similar as DXE instance. >>> 2) When the PEI instance is used before SMM ready, the >>> SMM_COMMUNICATION PPI will return EFI_NOT_STARTED. In this case, >>> PEI SmmLockBoxLib needs to search the SMRAM region directly to >>> find LockBox content. >>> >>> The question is why a platform would choose option (1), ever. >>> >>> Namely, option (1) depends on additional drivers: >>> - SMM_COMMUNICATION_PPI that actually works >>> - (which might further depend on PEI_SMM_CONTROL_PPI) >>> - a PEIM driver that implements the privileged (SMM) half of lockbox >>> >>> Whereas, option (2) is much simpler for the platform. It just needs to >>> provide a minimal SMM_COMMUNICATION_PPI where it always returns >>> EFI_NOT_STARTED. Then the lockbox library will do everything (and >>> depend only on PEI_SMM_ACCESS_PPI). >>> >>> So, the question is: why would a platform ever pick (1), given that it >>> is much more work to implement, for (as far as I can see) no benefit? >> >> And Jiewen replied (the same day), >> >>> Ah, I see. The only reason is that: A PEIM might need to restore >>> lockbox data *before* SMM rebase happen. Then it has to use #2. >>> >>> A PEIM might need to restore lockbox data *after* SMM rebase happen. >>> Then it has to use #1. (Scanning SMRAM does not work at that moment, >>> which is enforced by SMRR) >> >> I couldn't see any grounds from Jiewen's answer to abandon option (2). >> Option (2) actually worked, plus it was actually the *only* possibility >> to make SmmLockboxLib work in OVMF (see above). >> >> I would like to stick with this approach. >> >> Thanks >> Laszlo >> >>> >>> Thanks, >>> >>> Mike >>> >>>> -----Original Message----- >>>> From: Laszlo Ersek [mailto:ler...@redhat.com] >>>> Sent: Tuesday, November 03, 2015 1:01 PM >>>> To: edk2-de...@ml01.01.org >>>> Cc: Kinney, Michael D; Justen, Jordan L >>>> Subject: [PATCH v4 07/41] OvmfPkg: add PEIM for providing TSEG-as- >> SMRAM >>>> during PEI >>>> >>>> "MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf" is the >> library >>>> instance that implements the LockBoxLib library class with SMRAM access >>>> for the PEI phase. >>>> >>>> Introduce a PEIM that produces the EFI_PEI_SMM_COMMUNICATION_PPI >> and >>>> PEI_SMM_ACCESS_PPI interfaces, enabling SmmLockBoxPeiLib to work. >>>> >>>> Said library instance can parse and access LockBox data itself (without >>>> additional LockBox drivers) if the >>>> EFI_PEI_SMM_COMMUNICATION_PPI.Communicate() function returns >>>> EFI_NOT_STARTED to it. However it requires that >>>> EFI_PEI_SMM_COMMUNICATION_PPI exist at least. Also, >>>> PEI_SMM_ACCESS_PPI >>>> must exist and work. >>>> >>>> The load / installation order of S3Resume2Pei and SmmAccessPei is >>>> indifferent. SmmAccessPei produces the GUIDed HOB during its installation >>>> (which happens during PEI), but S3Resume2Pei accesses the HOB only >> when >>>> the DXE IPL calls its S3RestoreConfig2 PPI member, as last act of PEI. >>>> >>>> MCH_SMRAM_D_LCK and MCH_ESMRAMC_T_EN are masked out the way >>>> they are, in >>>> SmmAccessPeiEntryPoint() and SmramAccessOpen() respectively, in order >> to >>>> prevent VS20xx from warning about the (otherwise fully intentional) >>>> truncation in the UINT8 casts. (Warnings reported by Michael Kinney.) >>>> >>>> Cc: Michael Kinney <michael.d.kin...@intel.com> >>>> Cc: Jordan Justen <jordan.l.jus...@intel.com> >>>> Contributed-under: TianoCore Contribution Agreement 1.0 >>>> Signed-off-by: Laszlo Ersek <ler...@redhat.com> >>>> --- >>>> >>>> Notes: >>>> v3: >>>> - update bit-neg expressions to silence VS20xx warnings [Mike] >>>> >>>> OvmfPkg/OvmfPkgIa32.dsc | 6 + >>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 + >>>> OvmfPkg/OvmfPkgX64.dsc | 6 + >>>> OvmfPkg/OvmfPkgIa32.fdf | 3 + >>>> OvmfPkg/OvmfPkgIa32X64.fdf | 3 + >>>> OvmfPkg/OvmfPkgX64.fdf | 3 + >>>> OvmfPkg/SmmAccess/SmmAccessPei.inf | 70 +++ >>>> OvmfPkg/SmmAccess/SmramInternal.h | 89 ++++ >>>> OvmfPkg/SmmAccess/SmmAccessPei.c | 446 ++++++++++++++++++++ >>>> OvmfPkg/SmmAccess/SmramInternal.c | 188 +++++++++ >>>> 10 files changed, 820 insertions(+) >>>> >>>> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc >>>> index c6850ff..0b729ca 100644 >>>> --- a/OvmfPkg/OvmfPkgIa32.dsc >>>> +++ b/OvmfPkg/OvmfPkgIa32.dsc >>>> @@ -445,6 +445,12 @@ [Components] >>>> <LibraryClasses> >>>> PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf >>>> } >>>> +!if $(SMM_REQUIRE) == TRUE >>>> + OvmfPkg/SmmAccess/SmmAccessPei.inf { >>>> + <LibraryClasses> >>>> + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf >>>> + } >>>> +!endif >>>> >>>> # >>>> # DXE Phase modules >>>> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc >>>> index dd65bf9..7f672d9 100644 >>>> --- a/OvmfPkg/OvmfPkgIa32X64.dsc >>>> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc >>>> @@ -451,6 +451,12 @@ [Components.IA32] >>>> <LibraryClasses> >>>> PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf >>>> } >>>> +!if $(SMM_REQUIRE) == TRUE >>>> + OvmfPkg/SmmAccess/SmmAccessPei.inf { >>>> + <LibraryClasses> >>>> + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf >>>> + } >>>> +!endif >>>> >>>> [Components.X64] >>>> # >>>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc >>>> index 0de3c85..986c019 100644 >>>> --- a/OvmfPkg/OvmfPkgX64.dsc >>>> +++ b/OvmfPkg/OvmfPkgX64.dsc >>>> @@ -450,6 +450,12 @@ [Components] >>>> <LibraryClasses> >>>> PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf >>>> } >>>> +!if $(SMM_REQUIRE) == TRUE >>>> + OvmfPkg/SmmAccess/SmmAccessPei.inf { >>>> + <LibraryClasses> >>>> + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf >>>> + } >>>> +!endif >>>> >>>> # >>>> # DXE Phase modules >>>> diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf >>>> index 44e4a92..650dab1 100644 >>>> --- a/OvmfPkg/OvmfPkgIa32.fdf >>>> +++ b/OvmfPkg/OvmfPkgIa32.fdf >>>> @@ -171,6 +171,9 @@ [FV.PEIFV] >>>> INF OvmfPkg/PlatformPei/PlatformPei.inf >>>> INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf >>>> INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf >>>> +!if $(SMM_REQUIRE) == TRUE >>>> +INF OvmfPkg/SmmAccess/SmmAccessPei.inf >>>> +!endif >>>> >>>> >>>> >> ################################################################# >>>> ############### >>>> >>>> diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf >>>> index 67bfbe7..5830401 100644 >>>> --- a/OvmfPkg/OvmfPkgIa32X64.fdf >>>> +++ b/OvmfPkg/OvmfPkgIa32X64.fdf >>>> @@ -171,6 +171,9 @@ [FV.PEIFV] >>>> INF OvmfPkg/PlatformPei/PlatformPei.inf >>>> INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf >>>> INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf >>>> +!if $(SMM_REQUIRE) == TRUE >>>> +INF OvmfPkg/SmmAccess/SmmAccessPei.inf >>>> +!endif >>>> >>>> >>>> >> ################################################################# >>>> ############### >>>> >>>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf >>>> index 6624789..9dd6171 100644 >>>> --- a/OvmfPkg/OvmfPkgX64.fdf >>>> +++ b/OvmfPkg/OvmfPkgX64.fdf >>>> @@ -171,6 +171,9 @@ [FV.PEIFV] >>>> INF OvmfPkg/PlatformPei/PlatformPei.inf >>>> INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf >>>> INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf >>>> +!if $(SMM_REQUIRE) == TRUE >>>> +INF OvmfPkg/SmmAccess/SmmAccessPei.inf >>>> +!endif >>>> >>>> >>>> >> ################################################################# >>>> ############### >>>> >>>> diff --git a/OvmfPkg/SmmAccess/SmmAccessPei.inf >>>> b/OvmfPkg/SmmAccess/SmmAccessPei.inf >>>> new file mode 100644 >>>> index 0000000..94eb6c9 >>>> --- /dev/null >>>> +++ b/OvmfPkg/SmmAccess/SmmAccessPei.inf >>>> @@ -0,0 +1,70 @@ >>>> +## @file >>>> +# A PEIM with the following responsibilities: >>>> +# >>>> +# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, >>>> +# - provide a simple EFI_PEI_SMM_COMMUNICATION_PPI (always >> returning >>>> +# EFI_NOT_STARTED), >>>> +# - verify & configure the Q35 TSEG in the entry point, >>>> +# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, >> and >>>> expose >>>> +# it via the gEfiAcpiVariableGuid GUIDed HOB. >>>> +# >>>> +# Copyright (C) 2013, 2015, Red Hat, Inc. >>>> +# >>>> +# This program and the accompanying materials are licensed and made >>>> available >>>> +# under the terms and conditions of the BSD License which accompanies >> this >>>> +# distribution. The full text of the license may be found at >>>> +# http://opensource.org/licenses/bsd-license.php >>>> +# >>>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>>> BASIS, WITHOUT >>>> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >>>> IMPLIED. >>>> +# >>>> +## >>>> + >>>> +[Defines] >>>> + INF_VERSION = 0x00010005 >>>> + BASE_NAME = SmmAccessPei >>>> + FILE_GUID = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066 >>>> + MODULE_TYPE = PEIM >>>> + VERSION_STRING = 1.0 >>>> + ENTRY_POINT = SmmAccessPeiEntryPoint >>>> + >>>> +# >>>> +# The following information is for reference only and not required by the >>>> build tools. >>>> +# >>>> +# VALID_ARCHITECTURES = IA32 X64 >>>> +# >>>> + >>>> +[Sources] >>>> + SmmAccessPei.c >>>> + SmramInternal.c >>>> + >>>> +[Packages] >>>> + MdeModulePkg/MdeModulePkg.dec >>>> + MdePkg/MdePkg.dec >>>> + OvmfPkg/OvmfPkg.dec >>>> + >>>> +[Guids] >>>> + gEfiAcpiVariableGuid >>>> + >>>> +[LibraryClasses] >>>> + BaseMemoryLib >>>> + DebugLib >>>> + HobLib >>>> + IoLib >>>> + PcdLib >>>> + PciLib >>>> + PeiServicesLib >>>> + PeimEntryPoint >>>> + >>>> +[FeaturePcd] >>>> + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire >>>> + >>>> +[FixedPcd] >>>> + gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes >>>> + >>>> +[Ppis] >>>> + gEfiPeiSmmCommunicationPpiGuid # PPI ALWAYS_PRODUCED >>>> + gPeiSmmAccessPpiGuid # PPI ALWAYS_PRODUCED >>>> + >>>> +[Depex] >>>> + TRUE >>>> diff --git a/OvmfPkg/SmmAccess/SmramInternal.h >>>> b/OvmfPkg/SmmAccess/SmramInternal.h >>>> new file mode 100644 >>>> index 0000000..4e9ac05 >>>> --- /dev/null >>>> +++ b/OvmfPkg/SmmAccess/SmramInternal.h >>>> @@ -0,0 +1,89 @@ >>>> +/** @file >>>> + >>>> + Functions and types shared by the SMM accessor PEI and DXE modules. >>>> + >>>> + Copyright (C) 2015, Red Hat, Inc. >>>> + >>>> + This program and the accompanying materials are licensed and made >>>> available >>>> + under the terms and conditions of the BSD License which accompanies >> this >>>> + distribution. The full text of the license may be found at >>>> + http://opensource.org/licenses/bsd-license.php >>>> + >>>> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>>> BASIS, WITHOUT >>>> + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >>>> IMPLIED. >>>> + >>>> +**/ >>>> + >>>> +#include <Pi/PiMultiPhase.h> >>>> + >>>> +// >>>> +// We'll have two SMRAM ranges. >>>> +// >>>> +// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to >> be >>>> +// filled in by the CPU SMM driver during normal boot, for the PEI >> instance >>>> of >>>> +// the LockBox library (which will rely on the object during S3 resume). >>>> +// >>>> +// The other SMRAM range is the main one, for the SMM core and the >> SMM >>>> drivers. >>>> +// >>>> +typedef enum { >>>> + DescIdxSmmS3ResumeState = 0, >>>> + DescIdxMain = 1, >>>> + DescIdxCount = 2 >>>> +} DESCRIPTOR_INDEX; >>>> + >>>> +/** >>>> + Read the MCH_SMRAM and ESMRAMC registers, and update the >> LockState >>>> and >>>> + OpenState fields in the PEI_SMM_ACCESS_PPI / >>>> EFI_SMM_ACCESS2_PROTOCOL object, >>>> + from the D_LCK and T_EN bits. >>>> + >>>> + PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member >>>> functions can rely on >>>> + the LockState and OpenState fields being up-to-date on entry, and they >>>> need >>>> + to restore the same invariant on exit, if they touch the bits in >>>> question. >>>> + >>>> + @param[out] LockState Reflects the D_LCK bit on output; TRUE iff >> SMRAM >>>> is >>>> + locked. >>>> + @param[out] OpenState Reflects the inverse of the T_EN bit on output; >>>> TRUE >>>> + iff SMRAM is open. >>>> +**/ >>>> +VOID >>>> +GetStates ( >>>> + OUT BOOLEAN *LockState, >>>> + OUT BOOLEAN *OpenState >>>> + ); >>>> + >>>> +// >>>> +// The functions below follow the PEI_SMM_ACCESS_PPI and >>>> +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices >> and >>>> This >>>> +// pointers are removed (TSEG doesn't depend on them), and so is the >>>> +// DescriptorIndex parameter (TSEG doesn't support range-wise locking). >>>> +// >>>> +// The LockState and OpenState members that are common to both >>>> +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken >> and >>>> updated in >>>> +// isolation from the rest of the (non-shared) members. >>>> +// >>>> + >>>> +EFI_STATUS >>>> +SmramAccessOpen ( >>>> + OUT BOOLEAN *LockState, >>>> + OUT BOOLEAN *OpenState >>>> + ); >>>> + >>>> +EFI_STATUS >>>> +SmramAccessClose ( >>>> + OUT BOOLEAN *LockState, >>>> + OUT BOOLEAN *OpenState >>>> + ); >>>> + >>>> +EFI_STATUS >>>> +SmramAccessLock ( >>>> + OUT BOOLEAN *LockState, >>>> + IN OUT BOOLEAN *OpenState >>>> + ); >>>> + >>>> +EFI_STATUS >>>> +SmramAccessGetCapabilities ( >>>> + IN BOOLEAN LockState, >>>> + IN BOOLEAN OpenState, >>>> + IN OUT UINTN *SmramMapSize, >>>> + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap >>>> + ); >>>> diff --git a/OvmfPkg/SmmAccess/SmmAccessPei.c >>>> b/OvmfPkg/SmmAccess/SmmAccessPei.c >>>> new file mode 100644 >>>> index 0000000..8de4e4f >>>> --- /dev/null >>>> +++ b/OvmfPkg/SmmAccess/SmmAccessPei.c >>>> @@ -0,0 +1,446 @@ >>>> +/** @file >>>> + >>>> + A PEIM with the following responsibilities: >>>> + >>>> + - verify & configure the Q35 TSEG in the entry point, >>>> + - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, >>>> + - provide a simple EFI_PEI_SMM_COMMUNICATION_PPI (always >> returning >>>> + EFI_NOT_STARTED), >>>> + - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, >> and >>>> expose >>>> + it via the gEfiAcpiVariableGuid GUID HOB. >>>> + >>>> + This PEIM runs from RAM, so we can write to variables with static >> storage >>>> + duration. >>>> + >>>> + Copyright (C) 2013, 2015, Red Hat, Inc.<BR> >>>> + Copyright (c) 2010, Intel Corporation. All rights reserved.<BR> >>>> + >>>> + This program and the accompanying materials are licensed and made >>>> available >>>> + under the terms and conditions of the BSD License which accompanies >> this >>>> + distribution. The full text of the license may be found at >>>> + http://opensource.org/licenses/bsd-license.php >>>> + >>>> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>>> BASIS, WITHOUT >>>> + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >>>> IMPLIED. >>>> + >>>> +**/ >>>> + >>>> +#include <Guid/AcpiS3Context.h> >>>> +#include <Library/BaseMemoryLib.h> >>>> +#include <Library/DebugLib.h> >>>> +#include <Library/HobLib.h> >>>> +#include <Library/IoLib.h> >>>> +#include <Library/PcdLib.h> >>>> +#include <Library/PciLib.h> >>>> +#include <Library/PeiServicesLib.h> >>>> +#include <Ppi/SmmAccess.h> >>>> +#include <Ppi/SmmCommunication.h> >>>> + >>>> +#include <OvmfPlatforms.h> >>>> + >>>> +#include "SmramInternal.h" >>>> + >>>> +// >>>> +// EFI_PEI_SMM_COMMUNICATION_PPI implementation. >>>> +// >>>> + >>>> +/** >>>> + Communicates with a registered handler. >>>> + >>>> + This function provides a service to send and receive messages from a >>>> + registered UEFI service. >>>> + >>>> + @param[in] This The EFI_PEI_SMM_COMMUNICATION_PPI >>>> instance. >>>> + @param[in] CommBuffer A pointer to the buffer to convey into >>>> SMRAM. >>>> + @param[in] CommSize The size of the data buffer being passed >>>> in.On >>>> + exit, the size of data being returned. >>>> Zero if >>>> + the handler does not wish to reply with >>>> any >>>> + data. >>>> + >>>> + @retval EFI_SUCCESS The message was successfully posted. >>>> + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. >>>> +**/ >>>> +STATIC >>>> +EFI_STATUS >>>> +EFIAPI >>>> +SmmCommunicate ( >>>> + IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This, >>>> + IN OUT VOID *CommBuffer, >>>> + IN OUT UINTN *CommSize >>>> + ) >>>> +{ >>>> + // >>>> + // This return status is not documented, but it causes >>>> + // "MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c" to >> look >>>> for the >>>> + // LockBox in SMRAM itself. It allows us to avoid implementing >>>> + // EFI_PEI_SMM_COMMUNICATION_PPI with real functionality, plus we >> can >>>> + // completely skip PEI_SMM_CONTROL_PPI (which the former would >>>> arguably rely >>>> + // on). >>>> + // >>>> + return EFI_NOT_STARTED; >>>> +} >>>> + >>>> +STATIC EFI_PEI_SMM_COMMUNICATION_PPI mCommunication = { >>>> + &SmmCommunicate >>>> +}; >>>> + >>>> + >>>> +// >>>> +// PEI_SMM_ACCESS_PPI implementation. >>>> +// >>>> + >>>> +/** >>>> + Opens the SMRAM area to be accessible by a PEIM driver. >>>> + >>>> + This function "opens" SMRAM so that it is visible while not inside of >> SMM. >>>> + The function should return EFI_UNSUPPORTED if the hardware does not >>>> support >>>> + hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the >>>> SMRAM >>>> + configuration is locked. >>>> + >>>> + @param PeiServices General purpose services available to >>>> every >>>> + PEIM. >>>> + @param This The pointer to the SMM Access Interface. >>>> + @param DescriptorIndex The region of SMRAM to Open. >>>> + >>>> + @retval EFI_SUCCESS The region was successfully opened. >>>> + @retval EFI_DEVICE_ERROR The region could not be opened because >>>> locked >>>> + by chipset. >>>> + @retval EFI_INVALID_PARAMETER The descriptor index was out of >> bounds. >>>> + >>>> +**/ >>>> +STATIC >>>> +EFI_STATUS >>>> +EFIAPI >>>> +SmmAccessPeiOpen ( >>>> + IN EFI_PEI_SERVICES **PeiServices, >>>> + IN PEI_SMM_ACCESS_PPI *This, >>>> + IN UINTN DescriptorIndex >>>> + ) >>>> +{ >>>> + if (DescriptorIndex >= DescIdxCount) { >>>> + return EFI_INVALID_PARAMETER; >>>> + } >>>> + >>>> + // >>>> + // According to current practice, DescriptorIndex is not considered at >>>> all, >>>> + // beyond validating it. >>>> + // >>>> + return SmramAccessOpen (&This->LockState, &This->OpenState); >>>> +} >>>> + >>>> +/** >>>> + Inhibits access to the SMRAM. >>>> + >>>> + This function "closes" SMRAM so that it is not visible while outside of >> SMM. >>>> + The function should return EFI_UNSUPPORTED if the hardware does not >>>> support >>>> + hiding of SMRAM. >>>> + >>>> + @param PeiServices General purpose services available to >>>> every >>>> + PEIM. >>>> + @param This The pointer to the SMM Access >>>> Interface. >>>> + @param DescriptorIndex The region of SMRAM to Close. >>>> + >>>> + @retval EFI_SUCCESS The region was successfully closed. >>>> + @retval EFI_DEVICE_ERROR The region could not be closed because >>>> + locked by chipset. >>>> + @retval EFI_INVALID_PARAMETER The descriptor index was out of >>>> bounds. >>>> + >>>> +**/ >>>> +STATIC >>>> +EFI_STATUS >>>> +EFIAPI >>>> +SmmAccessPeiClose ( >>>> + IN EFI_PEI_SERVICES **PeiServices, >>>> + IN PEI_SMM_ACCESS_PPI *This, >>>> + IN UINTN DescriptorIndex >>>> + ) >>>> +{ >>>> + if (DescriptorIndex >= DescIdxCount) { >>>> + return EFI_INVALID_PARAMETER; >>>> + } >>>> + >>>> + // >>>> + // According to current practice, DescriptorIndex is not considered at >>>> all, >>>> + // beyond validating it. >>>> + // >>>> + return SmramAccessClose (&This->LockState, &This->OpenState); >>>> +} >>>> + >>>> +/** >>>> + Inhibits access to the SMRAM. >>>> + >>>> + This function prohibits access to the SMRAM region. This function is >>>> usually >>>> + implemented such that it is a write-once operation. >>>> + >>>> + @param PeiServices General purpose services available to >>>> every >>>> + PEIM. >>>> + @param This The pointer to the SMM Access >>>> Interface. >>>> + @param DescriptorIndex The region of SMRAM to Close. >>>> + >>>> + @retval EFI_SUCCESS The region was successfully locked. >>>> + @retval EFI_DEVICE_ERROR The region could not be locked because >> at >>>> + least one range is still open. >>>> + @retval EFI_INVALID_PARAMETER The descriptor index was out of >> bounds. >>>> + >>>> +**/ >>>> +STATIC >>>> +EFI_STATUS >>>> +EFIAPI >>>> +SmmAccessPeiLock ( >>>> + IN EFI_PEI_SERVICES **PeiServices, >>>> + IN PEI_SMM_ACCESS_PPI *This, >>>> + IN UINTN DescriptorIndex >>>> + ) >>>> +{ >>>> + if (DescriptorIndex >= DescIdxCount) { >>>> + return EFI_INVALID_PARAMETER; >>>> + } >>>> + >>>> + // >>>> + // According to current practice, DescriptorIndex is not considered at >>>> all, >>>> + // beyond validating it. >>>> + // >>>> + return SmramAccessLock (&This->LockState, &This->OpenState); >>>> +} >>>> + >>>> +/** >>>> + Queries the memory controller for the possible regions that will support >>>> + SMRAM. >>>> + >>>> + @param PeiServices General purpose services available to >>>> every >>>> + PEIM. >>>> + @param This The pointer to the SmmAccessPpi Interface. >>>> + @param SmramMapSize The pointer to the variable containing >> size >>>> of >>>> + the buffer to contain the description >>>> + information. >>>> + @param SmramMap The buffer containing the data describing >> the >>>> + Smram region descriptors. >>>> + >>>> + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient >>>> buffer. >>>> + @retval EFI_SUCCESS The user provided a sufficiently-sized >>>> buffer. >>>> + >>>> +**/ >>>> +STATIC >>>> +EFI_STATUS >>>> +EFIAPI >>>> +SmmAccessPeiGetCapabilities ( >>>> + IN EFI_PEI_SERVICES **PeiServices, >>>> + IN PEI_SMM_ACCESS_PPI *This, >>>> + IN OUT UINTN *SmramMapSize, >>>> + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap >>>> + ) >>>> +{ >>>> + return SmramAccessGetCapabilities (This->LockState, This->OpenState, >>>> + SmramMapSize, SmramMap); >>>> +} >>>> + >>>> +// >>>> +// LockState and OpenState will be filled in by the entry point. >>>> +// >>>> +STATIC PEI_SMM_ACCESS_PPI mAccess = { >>>> + &SmmAccessPeiOpen, >>>> + &SmmAccessPeiClose, >>>> + &SmmAccessPeiLock, >>>> + &SmmAccessPeiGetCapabilities >>>> +}; >>>> + >>>> + >>>> +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { >>>> + { >>>> + EFI_PEI_PPI_DESCRIPTOR_PPI, >>>> + &gEfiPeiSmmCommunicationPpiGuid, &mCommunication >>>> + }, >>>> + { >>>> + EFI_PEI_PPI_DESCRIPTOR_PPI | >> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, >>>> + &gPeiSmmAccessPpiGuid, &mAccess >>>> + } >>>> +}; >>>> + >>>> + >>>> +// >>>> +// Utility functions. >>>> +// >>>> +STATIC >>>> +UINT8 >>>> +CmosRead8 ( >>>> + IN UINT8 Index >>>> + ) >>>> +{ >>>> + IoWrite8 (0x70, Index); >>>> + return IoRead8 (0x71); >>>> +} >>>> + >>>> +STATIC >>>> +UINT32 >>>> +GetSystemMemorySizeBelow4gb ( >>>> + VOID >>>> + ) >>>> +{ >>>> + UINT32 Cmos0x34; >>>> + UINT32 Cmos0x35; >>>> + >>>> + Cmos0x34 = CmosRead8 (0x34); >>>> + Cmos0x35 = CmosRead8 (0x35); >>>> + >>>> + return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB; >>>> +} >>>> + >>>> + >>>> +// >>>> +// Entry point of this driver. >>>> +// >>>> +EFI_STATUS >>>> +EFIAPI >>>> +SmmAccessPeiEntryPoint ( >>>> + IN EFI_PEI_FILE_HANDLE FileHandle, >>>> + IN CONST EFI_PEI_SERVICES **PeiServices >>>> + ) >>>> +{ >>>> + UINT16 HostBridgeDevId; >>>> + UINT8 EsmramcVal; >>>> + UINT8 RegMask8; >>>> + UINT32 TopOfLowRam, TopOfLowRamMb; >>>> + EFI_STATUS Status; >>>> + UINTN SmramMapSize; >>>> + EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount]; >>>> + VOID *GuidHob; >>>> + >>>> + // >>>> + // This module should only be included if SMRAM support is required. >>>> + // >>>> + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); >>>> + >>>> + // >>>> + // Verify if we're running on a Q35 machine type. >>>> + // >>>> + HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID); >>>> + if (HostBridgeDevId != INTEL_Q35_MCH_DEVICE_ID) { >>>> + DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; >>>> only " >>>> + "DID=0x%04x (Q35) is supported\n", __FUNCTION__, HostBridgeDevId, >>>> + INTEL_Q35_MCH_DEVICE_ID)); >>>> + goto WrongConfig; >>>> + } >>>> + >>>> + // >>>> + // Confirm if QEMU supports SMRAM. >>>> + // >>>> + // With no support for it, the ESMRAMC (Extended System Management >>>> RAM >>>> + // Control) register reads as zero. If there is support, the >>>> cache-enable >>>> + // bits are hard-coded as 1 by QEMU. >>>> + // >>>> + EsmramcVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC)); >>>> + RegMask8 = MCH_ESMRAMC_SM_CACHE | MCH_ESMRAMC_SM_L1 | >>>> MCH_ESMRAMC_SM_L2; >>>> + if ((EsmramcVal & RegMask8) != RegMask8) { >>>> + DEBUG ((EFI_D_ERROR, "%a: this Q35 implementation lacks SMRAM\n", >>>> + __FUNCTION__)); >>>> + goto WrongConfig; >>>> + } >>>> + >>>> + TopOfLowRam = GetSystemMemorySizeBelow4gb (); >>>> + ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0); >>>> + TopOfLowRamMb = TopOfLowRam >> 20; >>>> + >>>> + // >>>> + // Some of the following registers are no-ops for QEMU at the moment, >> but >>>> it >>>> + // is recommended to set them correctly, since the ESMRAMC that we >>>> ultimately >>>> + // care about is in the same set of registers. >>>> + // >>>> + // First, we disable the integrated VGA, and set both the GTT Graphics >>>> Memory >>>> + // Size and the Graphics Mode Select memory pre-allocation fields to >> zero. >>>> + // This takes just one write to the Graphics Control Register. >>>> + // >>>> + PciWrite16 (DRAMC_REGISTER_Q35 (MCH_GGC), MCH_GGC_IVD); >>>> + >>>> + // >>>> + // Set Top of Low Usable DRAM. >>>> + // >>>> + PciWrite16 (DRAMC_REGISTER_Q35 (MCH_TOLUD), >>>> + (UINT16)(TopOfLowRamMb << MCH_TOLUD_MB_SHIFT)); >>>> + >>>> + // >>>> + // Given the zero graphics memory sizes configured above, set the >>>> + // graphics-related stolen memory bases to the same as TOLUD. >>>> + // >>>> + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_GBSM), >>>> + TopOfLowRamMb << MCH_GBSM_MB_SHIFT); >>>> + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_BGSM), >>>> + TopOfLowRamMb << MCH_BGSM_MB_SHIFT); >>>> + >>>> + // >>>> + // Set TSEG Memory Base. >>>> + // >>>> + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_TSEGMB), >>>> + (TopOfLowRamMb - FixedPcdGet8 (PcdQ35TsegMbytes)) << >>>> MCH_TSEGMB_MB_SHIFT); >>>> + >>>> + // >>>> + // Set TSEG size, and disable TSEG visibility outside of SMM. Note that >> the >>>> + // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility >>>> is >>>> + // *restricted* to SMM. >>>> + // >>>> + EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK; >>>> + EsmramcVal |= FixedPcdGet8 (PcdQ35TsegMbytes) == 8 ? >>>> MCH_ESMRAMC_TSEG_8MB : >>>> + FixedPcdGet8 (PcdQ35TsegMbytes) == 2 ? >>>> MCH_ESMRAMC_TSEG_2MB : >>>> + MCH_ESMRAMC_TSEG_1MB; >>>> + EsmramcVal |= MCH_ESMRAMC_T_EN; >>>> + PciWrite8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), EsmramcVal); >>>> + >>>> + // >>>> + // TSEG should be closed (see above), but unlocked, initially. Set >>>> G_SMRAME >>>> + // (Global SMRAM Enable) too, as both D_LCK and T_EN depend on it. >>>> + // >>>> + PciAndThenOr8 (DRAMC_REGISTER_Q35 (MCH_SMRAM), >>>> + (UINT8)((~(UINT32)MCH_SMRAM_D_LCK) & 0xff), >>>> MCH_SMRAM_G_SMRAME); >>>> + >>>> + // >>>> + // Create the GUID HOB and point it to the first SMRAM range. >>>> + // >>>> + GetStates (&mAccess.LockState, &mAccess.OpenState); >>>> + SmramMapSize = sizeof SmramMap; >>>> + Status = SmramAccessGetCapabilities (mAccess.LockState, >>>> mAccess.OpenState, >>>> + &SmramMapSize, SmramMap); >>>> + ASSERT_EFI_ERROR (Status); >>>> + >>>> + DEBUG_CODE_BEGIN (); >>>> + { >>>> + UINTN Count; >>>> + UINTN Idx; >>>> + >>>> + Count = SmramMapSize / sizeof SmramMap[0]; >>>> + DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n", >>>> __FUNCTION__, >>>> + (INT32)Count)); >>>> + DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n", >>>> "PhysicalStart(0x)", >>>> + "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)")); >>>> + for (Idx = 0; Idx < Count; ++Idx) { >>>> + DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n", >>>> + SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize, >>>> + SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState)); >>>> + } >>>> + } >>>> + DEBUG_CODE_END (); >>>> + >>>> + GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid, >>>> + sizeof SmramMap[DescIdxSmmS3ResumeState]); >>>> + if (GuidHob == NULL) { >>>> + return EFI_OUT_OF_RESOURCES; >>>> + } >>>> + >>>> + CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState], >>>> + sizeof SmramMap[DescIdxSmmS3ResumeState]); >>>> + >>>> + // >>>> + // We're done. The next step should succeed, but even if it fails, we >>>> can't >>>> + // roll back the above BuildGuidHob() allocation, because PEI doesn't >>>> support >>>> + // releasing memory. >>>> + // >>>> + return PeiServicesInstallPpi (mPpiList); >>>> + >>>> +WrongConfig: >>>> + // >>>> + // We really don't want to continue in this case. >>>> + // >>>> + // _ASSERT() is never compiled out, and it respects >> PcdDebugPropertyMask >>>> (ie. >>>> + // prevent further execution with CPU breakpoint vs. dead loop). >>>> + // >>>> + _ASSERT (FALSE); >>>> + return EFI_UNSUPPORTED; >>>> +} >>>> diff --git a/OvmfPkg/SmmAccess/SmramInternal.c >>>> b/OvmfPkg/SmmAccess/SmramInternal.c >>>> new file mode 100644 >>>> index 0000000..c3267ca >>>> --- /dev/null >>>> +++ b/OvmfPkg/SmmAccess/SmramInternal.c >>>> @@ -0,0 +1,188 @@ >>>> +/** @file >>>> + >>>> + Functions and types shared by the SMM accessor PEI and DXE modules. >>>> + >>>> + Copyright (C) 2015, Red Hat, Inc. >>>> + >>>> + This program and the accompanying materials are licensed and made >>>> available >>>> + under the terms and conditions of the BSD License which accompanies >> this >>>> + distribution. The full text of the license may be found at >>>> + http://opensource.org/licenses/bsd-license.php >>>> + >>>> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>>> BASIS, WITHOUT >>>> + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >>>> IMPLIED. >>>> + >>>> +**/ >>>> + >>>> +#include <Guid/AcpiS3Context.h> >>>> +#include <IndustryStandard/Q35MchIch9.h> >>>> +#include <Library/DebugLib.h> >>>> +#include <Library/PciLib.h> >>>> + >>>> +#include "SmramInternal.h" >>>> + >>>> +/** >>>> + Read the MCH_SMRAM and ESMRAMC registers, and update the >> LockState >>>> and >>>> + OpenState fields in the PEI_SMM_ACCESS_PPI / >>>> EFI_SMM_ACCESS2_PROTOCOL object, >>>> + from the D_LCK and T_EN bits. >>>> + >>>> + PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member >>>> functions can rely on >>>> + the LockState and OpenState fields being up-to-date on entry, and they >>>> need >>>> + to restore the same invariant on exit, if they touch the bits in >>>> question. >>>> + >>>> + @param[out] LockState Reflects the D_LCK bit on output; TRUE iff >> SMRAM >>>> is >>>> + locked. >>>> + @param[out] OpenState Reflects the inverse of the T_EN bit on output; >>>> TRUE >>>> + iff SMRAM is open. >>>> +**/ >>>> +VOID >>>> +GetStates ( >>>> + OUT BOOLEAN *LockState, >>>> + OUT BOOLEAN *OpenState >>>> +) >>>> +{ >>>> + UINT8 SmramVal, EsmramcVal; >>>> + >>>> + SmramVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_SMRAM)); >>>> + EsmramcVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC)); >>>> + >>>> + *LockState = !!(SmramVal & MCH_SMRAM_D_LCK); >>>> + *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN); >>>> +} >>>> + >>>> +// >>>> +// The functions below follow the PEI_SMM_ACCESS_PPI and >>>> +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices >> and >>>> This >>>> +// pointers are removed (TSEG doesn't depend on them), and so is the >>>> +// DescriptorIndex parameter (TSEG doesn't support range-wise locking). >>>> +// >>>> +// The LockState and OpenState members that are common to both >>>> +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken >> and >>>> updated in >>>> +// isolation from the rest of the (non-shared) members. >>>> +// >>>> + >>>> +EFI_STATUS >>>> +SmramAccessOpen ( >>>> + OUT BOOLEAN *LockState, >>>> + OUT BOOLEAN *OpenState >>>> + ) >>>> +{ >>>> + // >>>> + // Open TSEG by clearing T_EN. >>>> + // >>>> + PciAnd8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), >>>> + (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff)); >>>> + >>>> + GetStates (LockState, OpenState); >>>> + if (!*OpenState) { >>>> + return EFI_DEVICE_ERROR; >>>> + } >>>> + return EFI_SUCCESS; >>>> +} >>>> + >>>> +EFI_STATUS >>>> +SmramAccessClose ( >>>> + OUT BOOLEAN *LockState, >>>> + OUT BOOLEAN *OpenState >>>> + ) >>>> +{ >>>> + // >>>> + // Close TSEG by setting T_EN. >>>> + // >>>> + PciOr8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), >> MCH_ESMRAMC_T_EN); >>>> + >>>> + GetStates (LockState, OpenState); >>>> + if (*OpenState) { >>>> + return EFI_DEVICE_ERROR; >>>> + } >>>> + return EFI_SUCCESS; >>>> +} >>>> + >>>> +EFI_STATUS >>>> +SmramAccessLock ( >>>> + OUT BOOLEAN *LockState, >>>> + IN OUT BOOLEAN *OpenState >>>> + ) >>>> +{ >>>> + if (*OpenState) { >>>> + return EFI_DEVICE_ERROR; >>>> + } >>>> + >>>> + // >>>> + // Close & lock TSEG by setting T_EN and D_LCK. >>>> + // >>>> + PciOr8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), >> MCH_ESMRAMC_T_EN); >>>> + PciOr8 (DRAMC_REGISTER_Q35 (MCH_SMRAM), MCH_SMRAM_D_LCK); >>>> + >>>> + GetStates (LockState, OpenState); >>>> + if (*OpenState || !*LockState) { >>>> + return EFI_DEVICE_ERROR; >>>> + } >>>> + return EFI_SUCCESS; >>>> +} >>>> + >>>> +EFI_STATUS >>>> +SmramAccessGetCapabilities ( >>>> + IN BOOLEAN LockState, >>>> + IN BOOLEAN OpenState, >>>> + IN OUT UINTN *SmramMapSize, >>>> + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap >>>> + ) >>>> +{ >>>> + UINTN OriginalSize; >>>> + UINT32 TsegMemoryBaseMb, TsegMemoryBase; >>>> + UINT64 CommonRegionState; >>>> + UINT8 TsegSizeBits; >>>> + >>>> + OriginalSize = *SmramMapSize; >>>> + *SmramMapSize = DescIdxCount * sizeof *SmramMap; >>>> + if (OriginalSize < *SmramMapSize) { >>>> + return EFI_BUFFER_TOO_SMALL; >>>> + } >>>> + >>>> + // >>>> + // Read the TSEG Memory Base register. >>>> + // >>>> + TsegMemoryBaseMb = PciRead32 (DRAMC_REGISTER_Q35 >> (MCH_TSEGMB)); >>>> + TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) >> << >>>> 20; >>>> + >>>> + // >>>> + // Precompute the region state bits that will be set for all regions. >>>> + // >>>> + CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : >>>> EFI_SMRAM_CLOSED) | >>>> + (LockState ? EFI_SMRAM_LOCKED : 0) | >>>> + EFI_CACHEABLE; >>>> + >>>> + // >>>> + // The first region hosts an SMM_S3_RESUME_STATE object. It is located >> at >>>> the >>>> + // start of TSEG. We round up the size to whole pages, and we report it >> as >>>> + // EFI_ALLOCATED, so that the SMM_CORE stays away from it. >>>> + // >>>> + SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = >> TsegMemoryBase; >>>> + SmramMap[DescIdxSmmS3ResumeState].CpuStart = >> TsegMemoryBase; >>>> + SmramMap[DescIdxSmmS3ResumeState].PhysicalSize = >>>> + EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof >>>> (SMM_S3_RESUME_STATE))); >>>> + SmramMap[DescIdxSmmS3ResumeState].RegionState = >>>> + CommonRegionState | EFI_ALLOCATED; >>>> + >>>> + // >>>> + // Get the TSEG size bits from the ESMRAMC register. >>>> + // >>>> + TsegSizeBits = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC)) & >>>> + MCH_ESMRAMC_TSEG_MASK; >>>> + >>>> + // >>>> + // The second region is the main one, following the first. >>>> + // >>>> + SmramMap[DescIdxMain].PhysicalStart = >>>> + SmramMap[DescIdxSmmS3ResumeState].PhysicalStart + >>>> + SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; >>>> + SmramMap[DescIdxMain].CpuStart = >>>> SmramMap[DescIdxMain].PhysicalStart; >>>> + SmramMap[DescIdxMain].PhysicalSize = >>>> + (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB : >>>> + TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB : >>>> + SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; >>>> + SmramMap[DescIdxMain].RegionState = CommonRegionState; >>>> + >>>> + return EFI_SUCCESS; >>>> +} >>>> -- >>>> 1.8.3.1 >>>> >>> >> >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.01.org >> https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel