From 2ce7e221e70214b094e2e54d0e6dc9491a742dd3 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Fri, 3 Jan 2014 19:57:26 +0000
Subject: [PATCH] OvmfPkg: QemuFwCfgLib: extract stateful implementation

The current implementation of QemuFwCfgLib is:
- stateful
- implicitly initialized in the library constructor.

OVMF's SEC runs from read-only memory/flash. When the library is linked
into a SEC binary (which currently never happens), the
"mQemuFwCfgSupported" global variable becomes read-only, making the
library non-functional.

Extract the stateful, implicitly initialized library implementation into a
separate file, making room for a stateless, explicitly queried
implementation that's usable in SEC. Restrict the stateful implementation
to the current, non-SEC clients.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15045 6f19259b-4bc3-4df7-8a09-765794883524
---
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c   | 74 ---------------
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf |  6 +-
 .../Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c    | 92 +++++++++++++++++++
 3 files changed, 97 insertions(+), 75 deletions(-)
 create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c

diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 985b383c26..3c5963f31b 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -22,8 +22,6 @@
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
-STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
-
 
 /**
   Reads an 8-bit I/O port fifo into a block of memory.
@@ -78,26 +76,6 @@ IoWriteFifo8 (
   );
 
 
-/**
-  Returns a boolean indicating if the firmware configuration interface
-  is available or not.
-
-  This function may change fw_cfg state.
-
-  @retval    TRUE   The interface is available
-  @retval    FALSE  The interface is not available
-
-**/
-BOOLEAN
-EFIAPI
-QemuFwCfgIsAvailable (
-  VOID
-  )
-{
-  return InternalQemuFwCfgIsAvailable ();
-}
-
-
 /**
   Selects a firmware configuration item for reading.
   
@@ -265,39 +243,6 @@ QemuFwCfgRead64 (
 }
 
 
-RETURN_STATUS
-EFIAPI
-QemuFwCfgInitialize (
-  VOID
-  )
-{
-  UINT32 Signature;
-  UINT32 Revision;
-
-  //
-  // Enable the access routines while probing to see if it is supported.
-  //
-  mQemuFwCfgSupported = TRUE;
-
-  QemuFwCfgSelectItem (QemuFwCfgItemSignature);
-  Signature = QemuFwCfgRead32 ();
-  DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));
-  QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
-  Revision = QemuFwCfgRead32 ();
-  DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));
-  if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
-      (Revision < 1)
-     ) {
-    DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));
-    mQemuFwCfgSupported = FALSE;
-    return RETURN_SUCCESS;
-  }
-
-  DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n"));
-  return RETURN_SUCCESS;
-}
-
-
 /**
   Find the configuration item corresponding to the firmware configuration file.
 
@@ -349,22 +294,3 @@ QemuFwCfgFindFile (
 
   return RETURN_NOT_FOUND;
 }
-
-
-/**
-  Returns a boolean indicating if the firmware configuration interface is
-  available for library-internal purposes.
-
-  This function never changes fw_cfg state.
-
-  @retval    TRUE   The interface is available internally.
-  @retval    FALSE  The interface is not available internally.
-**/
-BOOLEAN
-EFIAPI
-InternalQemuFwCfgIsAvailable (
-  VOID
-  )
-{
-  return mQemuFwCfgSupported;
-}
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
index e6910c76bb..071737edef 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
@@ -1,5 +1,8 @@
 ## @file
 #
+#  Stateful, implicitly initialized fw_cfg library.
+#
+#  Copyright (C) 2013, Red Hat, Inc.
 #  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
@@ -18,7 +21,7 @@
   FILE_GUID                      = fdd53716-31e1-4acc-9007-8bd5d877c96f
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = QemuFwCfgLib
+  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
 
   CONSTRUCTOR                    = QemuFwCfgInitialize
 
@@ -30,6 +33,7 @@
 
 [Sources]
   QemuFwCfgLib.c
+  QemuFwCfgPeiDxe.c
 
 [Sources.IA32]
   Ia32/IoLibExAsm.asm
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
new file mode 100644
index 0000000000..f693cff29e
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
@@ -0,0 +1,92 @@
+/** @file
+
+  Stateful and implicitly initialized fw_cfg library implementation.
+
+  Copyright (C) 2013, Red Hat, Inc.
+  Copyright (c) 2011 - 2013, 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 <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
+
+
+/**
+  Returns a boolean indicating if the firmware configuration interface
+  is available or not.
+
+  This function may change fw_cfg state.
+
+  @retval    TRUE   The interface is available
+  @retval    FALSE  The interface is not available
+
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgIsAvailable (
+  VOID
+  )
+{
+  return InternalQemuFwCfgIsAvailable ();
+}
+
+
+RETURN_STATUS
+EFIAPI
+QemuFwCfgInitialize (
+  VOID
+  )
+{
+  UINT32 Signature;
+  UINT32 Revision;
+
+  //
+  // Enable the access routines while probing to see if it is supported.
+  //
+  mQemuFwCfgSupported = TRUE;
+
+  QemuFwCfgSelectItem (QemuFwCfgItemSignature);
+  Signature = QemuFwCfgRead32 ();
+  DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));
+  QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
+  Revision = QemuFwCfgRead32 ();
+  DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));
+  if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
+      (Revision < 1)
+     ) {
+    DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));
+    mQemuFwCfgSupported = FALSE;
+    return RETURN_SUCCESS;
+  }
+
+  DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n"));
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Returns a boolean indicating if the firmware configuration interface is
+  available for library-internal purposes.
+
+  This function never changes fw_cfg state.
+
+  @retval    TRUE   The interface is available internally.
+  @retval    FALSE  The interface is not available internally.
+**/
+BOOLEAN
+EFIAPI
+InternalQemuFwCfgIsAvailable (
+  VOID
+  )
+{
+  return mQemuFwCfgSupported;
+}