This mostly no-op runtime DXE driver produces the EFI_SMM_ACCESS2_PROTOCOL
and EFI_SMM_CONTROL2_PROTOCOL protocols, enabling the SMM core to be
loaded in the next patch.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---
 OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf |  55 ++++++++
 OvmfPkg/EmuSmmDxe/EmuSmmDxe.c   | 276 ++++++++++++++++++++++++++++++++++++++++
 OvmfPkg/OvmfPkgX64.dsc          |   5 +
 OvmfPkg/OvmfPkgX64.fdf          |   2 +
 4 files changed, 338 insertions(+)
 create mode 100644 OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf
 create mode 100644 OvmfPkg/EmuSmmDxe/EmuSmmDxe.c

diff --git a/OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf b/OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf
new file mode 100644
index 0000000..8cae943
--- /dev/null
+++ b/OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# This module emulates SMRAM by providing EFI_SMM_ACCESS2_PROTOCOL and
+# EFI_SMM_CONTROL2_PROTOCOL.
+#
+# Copyright (C) 2013, 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                      = EmuSmmDxe
+  FILE_GUID                      = C993C48A-9EEC-4BBD-93B0-276ED216CD11
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = EmuSmmDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  EmuSmmDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiSmmAccess2ProtocolGuid   # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmControl2ProtocolGuid  # PROTOCOL ALWAYS_PRODUCED
+
+[Guids]
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdEmuSmmAreaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdEmuSmmAreaSize
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/EmuSmmDxe/EmuSmmDxe.c b/OvmfPkg/EmuSmmDxe/EmuSmmDxe.c
new file mode 100644
index 0000000..92adccd
--- /dev/null
+++ b/OvmfPkg/EmuSmmDxe/EmuSmmDxe.c
@@ -0,0 +1,276 @@
+/** @file
+
+  This module emulates SMRAM by providing EFI_SMM_ACCESS2_PROTOCOL and
+  EFI_SMM_CONTROL2_PROTOCOL.
+
+  Copyright (C) 2013, 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 <Protocol/SmmAccess2.h>
+#include <Protocol/SmmControl2.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+
+STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2;
+
+
+/**
+  Opens the SMRAM area to be accessible by a boot-service 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[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The operation was successful.
+  @retval EFI_UNSUPPORTED   The system does not support opening and closing of
+                            SMRAM.
+  @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because it is
+                            locked.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+EmuSmmAccess2Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  //
+  // Normally we'd like to return EFI_UNSUPPORTED here (the PI spec allows it
+  // and our SMRAM is always visible), but the EFI_SMM_COMMUNICATION_PROTOCOL
+  // implementation in "MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c" really wants
+  // this function to succeed.
+  //
+  if (mAccess2.LockState) {
+    return EFI_DEVICE_ERROR;
+  }
+  mAccess2.OpenState = TRUE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The operation was successful.
+  @retval EFI_UNSUPPORTED   The system does not support opening and closing of
+                            SMRAM.
+  @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+EmuSmmAccess2Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  mAccess2.OpenState = FALSE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS      The device was successfully locked.
+  @retval EFI_UNSUPPORTED  The system does not support locking of SMRAM.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+EmuSmmAccess2Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  mAccess2.LockState = TRUE;
+  mAccess2.OpenState = FALSE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Queries the memory controller for the possible regions that will support
+  SMRAM.
+
+  @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+  @param[in,out] SmramMapSize   A pointer to the size, in bytes, of the
+                                SmramMemoryMap buffer.
+  @param[in,out] SmramMap       A pointer to the buffer in which firmware
+                                places the current memory map.
+
+  @retval EFI_SUCCESS           The chipset supported the given resource.
+  @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too small.  The
+                                current buffer size needed to hold the memory
+                                map is returned in SmramMapSize.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+EmuSmmAccess2GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  UINTN OrigSize;
+
+  OrigSize      = *SmramMapSize;
+  *SmramMapSize = sizeof *SmramMap; // 1 record
+  if (OrigSize < *SmramMapSize) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  SmramMap->PhysicalStart = PcdGet64 (PcdEmuSmmAreaBase);
+  SmramMap->CpuStart      = SmramMap->PhysicalStart;
+  SmramMap->PhysicalSize  = PcdGet32 (PcdEmuSmmAreaSize);
+  SmramMap->RegionState   = mAccess2.LockState ? EFI_SMRAM_LOCKED :
+                            mAccess2.OpenState ? EFI_SMRAM_OPEN :
+                            EFI_SMRAM_CLOSED;
+
+  ASSERT (SmramMap->PhysicalStart != 0);
+  DEBUG ((EFI_D_INFO, "EmuSmmAccess2GetCapabilities: "
+    "SMRAM Start=0x%Lx Size=0x%Lx\n",
+    SmramMap->PhysicalStart, SmramMap->PhysicalSize));
+  return EFI_SUCCESS;
+}
+
+
+STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
+  &EmuSmmAccess2Open,
+  &EmuSmmAccess2Close,
+  &EmuSmmAccess2Lock,
+  &EmuSmmAccess2GetCapabilities,
+  FALSE,                         // initial LockState
+  TRUE                           // initial OpenState
+};
+
+
+/**
+  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
+EFI_STATUS
+EFIAPI
+EmuSmmControl2Trigger (
+  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
+  )
+{
+  //
+  // The CommandPort and DataPort parameters allow the caller to trigger
+  // (dispatch) a specific SMI handler. We don't have anything like that in
+  // OvmfPkg.
+  //
+  // The only call to this function is made in SmmCommunicationCommunicate()
+  // [MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c], ie.
+  // EFI_SMM_COMMUNICATION_PROTOCOL.Communicate(), to enter SMM and get access
+  // to SMRAM. Since our emulated SMRAM is always visible (doesn't support
+  // closing or locking), we don't need to do anything here.
+  //
+  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
+EFI_STATUS
+EFIAPI
+EmuSmmControl2Clear (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
+  IN BOOLEAN                          Periodic OPTIONAL
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+STATIC EFI_SMM_CONTROL2_PROTOCOL mControl2 = {
+ &EmuSmmControl2Trigger,
+ &EmuSmmControl2Clear,
+ 100*1000                // MinimumTriggerPeriod, unit is 10ns; unused
+};
+
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+EmuSmmDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_HANDLE Handle;
+
+  if (PcdGet32 (PcdEmuSmmAreaSize) == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Handle = NULL;
+  return gBS->InstallMultipleProtocolInterfaces (&Handle,
+                &gEfiSmmAccess2ProtocolGuid, &mAccess2,
+                &gEfiSmmControl2ProtocolGuid, &mControl2,
+                NULL);
+}
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 8e32ad1..3919444 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -488,10 +488,15 @@
   #
   MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
   OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
 
   #
+  # SMM Support
+  #
+  OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf
+
+  #
   # ACPI Support
   #
   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
   OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
   OvmfPkg/AcpiTables/AcpiTables.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 9110266..42294e8 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -361,10 +361,12 @@ INF  
IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
 INF  IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf
 
 INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
 INF  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
 
+INF  OvmfPkg/EmuSmmDxe/EmuSmmDxe.inf
+
 INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
 INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
 INF  RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
 
 INF  RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf
-- 
1.8.3.1



------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to