Laszlo,

Minor comments included below.

Reviewed-by: Michael Kinney <michael.d.kin...@intel.com>

Mike

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Laszlo 
> Ersek
> Sent: Tuesday, November 3, 2015 1:01 PM
> To: edk2-de...@ml01.01.org
> Subject: [edk2] [PATCH v4 09/41] OvmfPkg: implement EFI_SMM_CONTROL2_PROTOCOL 
> with a DXE_RUNTIME_DRIVER
> 
> The EFI_SMM_COMMUNICATION_PROTOCOL implementation that is provided by the SMM 
> core depends on
> EFI_SMM_CONTROL2_PROTOCOL; see the
> mSmmControl2->Trigger() call in the SmmCommunicationCommunicate()
> mSmmControl2->function
> [MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c].
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Laszlo Ersek <ler...@redhat.com>
> ---
> 
> Notes:
>     v2:
>     - Set (APMC_EN|GBL_SMI_EN) in SMI_EN from the boot script at S3 resume.
>       Otherwise, because SMI_EN is cleared during warm reset,
>       SmmControl2DxeTrigger() would fail to trigger an SMI, and variable
>       access through the runtime services would fail.
> 
>       Set SMI_LOCK in GEN_PMCON_1 similarly.
> 
>  OvmfPkg/OvmfPkgIa32.dsc                   |   1 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                |   1 +
>  OvmfPkg/OvmfPkgX64.dsc                    |   1 +
>  OvmfPkg/OvmfPkgIa32.fdf                   |   1 +
>  OvmfPkg/OvmfPkgIa32X64.fdf                |   1 +
>  OvmfPkg/OvmfPkgX64.fdf                    |   1 +
>  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf |  65 ++++
>  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c   | 365 ++++++++++++++++++++
>  8 files changed, 436 insertions(+)
> 
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 
> d7bc38d..c71a2f4 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -675,4 +675,5 @@ [Components]
> 
>  !if $(SMM_REQUIRE) == TRUE
>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
>  !endif
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 
> e17cbe5..a1e8f0d 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -682,4 +682,5 @@ [Components.X64]
> 
>  !if $(SMM_REQUIRE) == TRUE
>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
>  !endif
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 
> a748fb3..1176629 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -680,4 +680,5 @@ [Components]
> 
>  !if $(SMM_REQUIRE) == TRUE
>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
>  !endif
> diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 
> 285720f..43c9c30 100644
> --- a/OvmfPkg/OvmfPkgIa32.fdf
> +++ b/OvmfPkg/OvmfPkgIa32.fdf
> @@ -357,6 +357,7 @@ [FV.DXEFV]
> 
>  !if $(SMM_REQUIRE) == TRUE
>  INF  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +INF  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
>  !endif
> 
>  
> ################################################################################
> diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 
> 02e8752..9446896 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.fdf
> +++ b/OvmfPkg/OvmfPkgIa32X64.fdf
> @@ -357,6 +357,7 @@ [FV.DXEFV]
> 
>  !if $(SMM_REQUIRE) == TRUE
>  INF  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +INF  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
>  !endif
> 
>  
> ################################################################################
> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 
> f04c36b..b272b76 100644
> --- a/OvmfPkg/OvmfPkgX64.fdf
> +++ b/OvmfPkg/OvmfPkgX64.fdf
> @@ -357,6 +357,7 @@ [FV.DXEFV]
> 
>  !if $(SMM_REQUIRE) == TRUE
>  INF  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +INF  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
>  !endif
> 
>  
> ################################################################################
> diff --git a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf 
> b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
> new file mode 100644
> index 0000000..bc66a27
> --- /dev/null
> +++ b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
> @@ -0,0 +1,65 @@
> +## @file
> +# A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the #
> +EFI_SMM_CONTROL2_PROTOCOL.
> +#
> +# We expect the PEI phase to have covered the following:
> +# - ensure that the underlying QEMU machine type be Q35
> +#   (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
> +# - ensure that the ACPI PM IO space be configured
> +#   (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
> +#
> +# Our own entry point is responsible for confirming the SMI feature and
> +for # configuring it.
> +#
> +# 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                      = SmmControl2Dxe
> +  FILE_GUID                      = 1206F7CA-A475-4624-A83E-E6FC9BB38E49
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010400
> +  ENTRY_POINT                    = SmmControl2DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the 
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmmControl2Dxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  IoLib
> +  PcdLib
> +  PciLib
> +  QemuFwCfgLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiS3SaveStateProtocolGuid   # PROTOCOL SOMETIMES_CONSUMED

Comment should be:      ## SOMETIMES_CONSUMES

> +  gEfiSmmControl2ProtocolGuid   # PROTOCOL ALWAYS_PRODUCED

Comment should be:      ## PRODUCES

> +
> +[FeaturePcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
> +
> +[Depex]
> +  TRUE
> diff --git a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c 
> b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
> new file mode 100644
> index 0000000..e895fd6
> --- /dev/null
> +++ b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
> @@ -0,0 +1,365 @@
> +/** @file
> +
> +  A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the
> + EFI_SMM_CONTROL2_PROTOCOL.
> +
> +  We expect the PEI phase to have covered the following:
> +  - ensure that the underlying QEMU machine type be Q35
> +    (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
> +  - ensure that the ACPI PM IO space be configured
> +    (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
> +
> +  Our own entry point is responsible for confirming the SMI feature and
> + for  configuring it.
> +
> +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>  Copyright (c) 2009 -
> + 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 <IndustryStandard/Q35MchIch9.h> #include <Library/DebugLib.h>
> +#include <Library/IoLib.h> #include <Library/PcdLib.h> #include
> +<Library/PciLib.h> #include <Library/QemuFwCfgLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Protocol/S3SaveState.h>
> +#include <Protocol/SmmControl2.h>
> +
> +//
> +// The absolute IO port address of the SMI Control and Enable Register.
> +It is // only used to carry information from the entry point function
> +to the // S3SaveState protocol installation callback, strictly before
> +the runtime // phase.
> +//
> +STATIC UINTN mSmiEnable;
> +
> +//
> +// Event signaled when an S3SaveState protocol interface is installed.
> +//
> +STATIC EFI_EVENT mS3SaveStateInstalled;
> +
> +/**
> +  Invokes SMI activation from either the preboot or runtime environment.
> +
> +  This function generates an SMI.
> +
> +  @param[in]     This                The EFI_SMM_CONTROL2_PROTOCOL instance.
> +  @param[in,out] CommandPort         The value written to the command port.
> +  @param[in,out] DataPort            The value written to the data port.
> +  @param[in]     Periodic            Optional mechanism to engender a 
> periodic
> +                                     stream.
> +  @param[in]     ActivationInterval  Optional parameter to repeat at this
> +                                     period one time or, if the Periodic
> +                                     Boolean is set, periodically.
> +
> +  @retval EFI_SUCCESS            The SMI/PMI has been engendered.
> +  @retval EFI_DEVICE_ERROR       The timing is unsupported.
> +  @retval EFI_INVALID_PARAMETER  The activation period is unsupported.
> +  @retval EFI_INVALID_PARAMETER  The last periodic activation has not been
> +                                 cleared.
> +  @retval EFI_NOT_STARTED        The SMM base service has not been 
> initialized.
> +**/
> +STATIC

Recommend removing use of STATIC

> +EFI_STATUS
> +EFIAPI
> +SmmControl2DxeTrigger (
> +  IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
> +  IN OUT UINT8                        *CommandPort       OPTIONAL,
> +  IN OUT UINT8                        *DataPort          OPTIONAL,
> +  IN BOOLEAN                          Periodic           OPTIONAL,
> +  IN UINTN                            ActivationInterval OPTIONAL
> +  )
> +{
> +  //
> +  // No support for queued or periodic activation.
> +  //
> +  if (Periodic || ActivationInterval > 0) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // The so-called "Advanced Power Management Status Port Register" is
> +in fact
> +  // a generic data passing register, between the caller and the SMI
> +  // dispatcher. The ICH9 spec calls it "scratchpad register" --
> +calling it
> +  // "status" elsewhere seems quite the misnomer. Status registers
> +usually
> +  // report about hardware status, while this register is fully
> +governed by
> +  // software.
> +  //
> +  // Write to the status register first, as this won't trigger the SMI
> +just
> +  // yet. Then write to the control register.
> +  //
> +  IoWrite8 (ICH9_APM_STS, DataPort    == NULL ? 0 : *DataPort);
> +  IoWrite8 (ICH9_APM_CNT, CommandPort == NULL ? 0 : *CommandPort);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Clears any system state that was created in response to the Trigger() call.
> +
> +  This function acknowledges and causes the deassertion of the SMI
> + activation  source.
> +
> +  @param[in] This                The EFI_SMM_CONTROL2_PROTOCOL instance.
> +  @param[in] Periodic            Optional parameter to repeat at this period
> +                                 one time
> +
> +  @retval EFI_SUCCESS            The SMI/PMI has been engendered.
> +  @retval EFI_DEVICE_ERROR       The source could not be cleared.
> +  @retval EFI_INVALID_PARAMETER  The service did not support the Periodic 
> input
> +                                 argument.
> +**/
> +STATIC

Recommend removing use of STATIC

> +EFI_STATUS
> +EFIAPI
> +SmmControl2DxeClear (
> +  IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
> +  IN BOOLEAN                          Periodic OPTIONAL
> +  )
> +{
> +  if (Periodic) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // The PI spec v1.4 explains that Clear() is only supposed to clear
> +software
> +  // status; it is not in fact responsible for deasserting the SMI. It
> +gives
> +  // two reasons for this: (a) many boards clear the SMI automatically
> +when
> +  // entering SMM, (b) if Clear() actually deasserted the SMI, then it
> +could
> +  // incorrectly suppress an SMI that was asynchronously asserted
> +between the
> +  // last return of the SMI handler and the call made to Clear().
> +  //
> +  // In fact QEMU automatically deasserts CPU_INTERRUPT_SMI in:
> +  // - x86_cpu_exec_interrupt() [target-i386/seg_helper.c], and
> +  // - kvm_arch_pre_run() [target-i386/kvm.c].
> +  //
> +  // So, nothing to do here.
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC EFI_SMM_CONTROL2_PROTOCOL mControl2 = {
> +  &SmmControl2DxeTrigger,
> +  &SmmControl2DxeClear,
> +  MAX_UINTN // MinimumTriggerPeriod -- we don't support periodic SMIs
> +};

Recommend removing use of STATIC
Global variable should be above function implementations

> +
> +//
> +// Forward declaration.
> +//
> +STATIC

Recommend removing use of STATIC

> +VOID
> +EFIAPI
> +OnS3SaveStateInstalled (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  );

Forward declarations should go before function implementations

> +
> +//
> +// Entry point of this driver.
> +//
> +EFI_STATUS
> +EFIAPI
> +SmmControl2DxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  UINT32     PmBase;
> +  UINT32     SmiEnableVal;
> +  EFI_STATUS Status;
> +
> +  //
> +  // This module should only be included if SMRAM support is required.
> +  //
> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> +
> +  //
> +  // Calculate the absolute IO port address of the SMI Control and
> + Enable  // Register. (As noted at the top, the PEI phase has left us
> + with a working  // ACPI PM IO space.)  //  PmBase = PciRead32
> + (POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE)) &
> +    ICH9_PMBASE_MASK;
> +  mSmiEnable = PmBase + ICH9_PMBASE_OFS_SMI_EN;
> +
> +  //
> +  // If APMC_EN is pre-set in SMI_EN, that's QEMU's way to tell us that
> + SMI  // support is not available. (For example due to KVM lacking it.)
> + Otherwise,  // this bit is clear after each reset.
> +  //
> +  SmiEnableVal = IoRead32 (mSmiEnable);  if ((SmiEnableVal &
> + ICH9_SMI_EN_APMC_EN) != 0) {
> +    DEBUG ((EFI_D_ERROR, "%a: this Q35 implementation lacks SMI\n",
> +      __FUNCTION__));
> +    goto FatalError;
> +  }
> +
> +  //
> +  // Otherwise, configure the board to inject an SMI when ICH9_APM_CNT
> + is  // written to. (See the Trigger() method above.)  //  SmiEnableVal
> + |= ICH9_SMI_EN_APMC_EN | ICH9_SMI_EN_GBL_SMI_EN;
> +  IoWrite32 (mSmiEnable, SmiEnableVal);
> +
> +  //
> +  // Prevent software from undoing the above (until platform reset).
> +  //
> +  PciOr16 (POWER_MGMT_REGISTER_Q35 (ICH9_GEN_PMCON_1),
> +    ICH9_GEN_PMCON_1_SMI_LOCK);
> +
> +  //
> +  // If we can clear GBL_SMI_EN now, that means QEMU's SMI support is
> + not  // appropriate.
> +  //
> +  IoWrite32 (mSmiEnable, SmiEnableVal &
> + ~(UINT32)ICH9_SMI_EN_GBL_SMI_EN);  if (IoRead32 (mSmiEnable) != 
> SmiEnableVal) {
> +    DEBUG ((EFI_D_ERROR, "%a: failed to lock down GBL_SMI_EN\n",
> +      __FUNCTION__));
> +    goto FatalError;
> +  }
> +
> +  if (QemuFwCfgS3Enabled ()) {
> +    VOID *Registration;
> +
> +    //
> +    // On S3 resume the above register settings have to be repeated. 
> Register a
> +    // protocol notify callback that, when boot script saving becomes
> +    // available, saves operations equivalent to the above to the boot 
> script.
> +    //
> +    Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
> +                    OnS3SaveStateInstalled, NULL /* Context */,
> +                    &mS3SaveStateInstalled);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((EFI_D_ERROR, "%a: CreateEvent: %r\n", __FUNCTION__, Status));
> +      goto FatalError;
> +    }
> +
> +    Status = gBS->RegisterProtocolNotify (&gEfiS3SaveStateProtocolGuid,
> +                    mS3SaveStateInstalled, &Registration);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((EFI_D_ERROR, "%a: RegisterProtocolNotify: %r\n", __FUNCTION__,
> +        Status));
> +      goto ReleaseEvent;
> +    }
> +
> +    //
> +    // Kick the event right now -- maybe the boot script is already saveable.
> +    //
> +    Status = gBS->SignalEvent (mS3SaveStateInstalled);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((EFI_D_ERROR, "%a: SignalEvent: %r\n", __FUNCTION__, Status));
> +      goto ReleaseEvent;
> +    }
> +  }
> +
> +  //
> +  // We have no pointers to convert to virtual addresses. The handle
> + itself  // doesn't matter, as protocol services are not accessible at 
> runtime.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
> +                  &gEfiSmmControl2ProtocolGuid, &mControl2,
> +                  NULL);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces: %r\n",
> +      __FUNCTION__, Status));
> +    goto ReleaseEvent;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +ReleaseEvent:
> +  if (mS3SaveStateInstalled != NULL) {
> +    gBS->CloseEvent (mS3SaveStateInstalled);
> +  }
> +
> +FatalError:
> +  //
> +  // 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);

Should not use internal macros.
If you need a CPU break point, then use BaseLib CpuBreakpoint ()
If you need a deadloop, then use BaseLib CpuDeadLoop ()

> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Notification callback for S3SaveState installation.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +
> +  @param[in] Context  The pointer to the notification function's context, 
> which
> +                      is implementation-dependent.
> +**/
> +STATIC

Recommend removing use of STATIC

> +VOID
> +EFIAPI
> +OnS3SaveStateInstalled (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState;
> +  UINT32                     SmiEnOrMask, SmiEnAndMask;
> +  UINT16                     GenPmCon1OrMask, GenPmCon1AndMask;
> +
> +  ASSERT (Event == mS3SaveStateInstalled);
> +
> +  Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid,
> +                  NULL /* Registration */, (VOID **)&S3SaveState);  if
> + (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  //
> +  // These operations were originally done, verified and explained in
> + the entry  // point function of the driver.
> +  //
> +  SmiEnOrMask  = ICH9_SMI_EN_APMC_EN | ICH9_SMI_EN_GBL_SMI_EN;
> + SmiEnAndMask = MAX_UINT32;  Status = S3SaveState->Write (
> +                          S3SaveState,
> +                          EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,
> +                          EfiBootScriptWidthUint32,
> +                          (UINT64)mSmiEnable,
> +                          &SmiEnOrMask,
> +                          &SmiEnAndMask
> +                          );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "%a: EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: %r\n",
> +      __FUNCTION__, Status));
> +    _ASSERT (FALSE);
> +  }
> +
> +  GenPmCon1OrMask  = ICH9_GEN_PMCON_1_SMI_LOCK;  GenPmCon1AndMask =
> + MAX_UINT16;  Status = S3SaveState->Write (
> +                          S3SaveState,
> +                          EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,
> +                          EfiBootScriptWidthUint16,
> +                          (UINT64)POWER_MGMT_REGISTER_Q35 (ICH9_GEN_PMCON_1),
> +                          &GenPmCon1OrMask,
> +                          &GenPmCon1AndMask
> +                          );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR,
> +      "%a: EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: %r\n", __FUNCTION__,
> +      Status));
> +    _ASSERT (FALSE);
> +  }
> +
> +  DEBUG ((EFI_D_VERBOSE, "%a: boot script fragment saved\n",
> +__FUNCTION__));
> +  gBS->CloseEvent (Event);
> +  mS3SaveStateInstalled = NULL;
> +}
> --
> 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

Reply via email to