public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib
@ 2017-03-11  6:26 Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 01/12] OvmfPkg: introduce QemuFwCfgS3Lib class Laszlo Ersek
                   ` (12 more replies)
  0 siblings, 13 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel, Jordan Justen

This is version 2 of the series posted at
<https://lists.01.org/pipermail/edk2-devel/2017-February/007690.html>.

Changes in this version:
- pick up v1 R-b's from Jordan and Ard (patches 1-6)
- rename QemuFwCfgS3TransferOwnership to
  QemuFwCfgS3CallWhenBootScriptReady [Jordan]
- rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
- rename "Append" to "Callback" and "mAppend" to "mCallback" [Laszlo]
- rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
  QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
  QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
  QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
  respectively [Jordan]

Changes are noted per patch too.

Rebuilt at every stage and retested (like in v1).

Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Repo:     https://github.com/lersek/edk2.git
Branch:   fw_cfg_s3_v2

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>

Thanks
Laszlo

Laszlo Ersek (12):
  OvmfPkg: introduce QemuFwCfgS3Lib class
  OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance
  OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library
    instances
  ArmVirtPkg: resolve QemuFwCfgS3Lib
  OvmfPkg: resolve QemuFwCfgS3Lib
  ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib
  OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to
    libclass
  OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance
  OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance
  OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE fw_cfg instance
  OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib
  OvmfPkg/AcpiPlatformDxe: save fw_cfg boot script with QemuFwCfgS3Lib

 ArmVirtPkg/ArmVirtQemu.dsc                                        |   1 +
 ArmVirtPkg/ArmVirtQemuKernel.dsc                                  |   1 +
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                    |  17 -
 OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h                            |   2 +-
 OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf                       |   2 +-
 OvmfPkg/AcpiPlatformDxe/BootScript.c                              | 262 ++-----
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c                           |   8 +
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf              |   2 +-
 OvmfPkg/Include/Library/QemuFwCfgLib.h                            |  14 -
 OvmfPkg/Include/Library/QemuFwCfgS3Lib.h                          | 361 +++++++++
 OvmfPkg/Library/LockBoxLib/LockBoxDxe.c                           |   1 +
 OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf                      |   1 +
 OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h              |   1 +
 OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   1 +
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                       |  28 -
 OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf         |  43 ++
 OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf         |  46 ++
 OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf         |  44 ++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c                  | 110 +++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c               | 227 ++++++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c                   | 792 ++++++++++++++++++++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c                   |  86 +++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c                |  48 ++
 OvmfPkg/OvmfPkg.dec                                               |   4 +
 OvmfPkg/OvmfPkgIa32.dsc                                           |   3 +
 OvmfPkg/OvmfPkgIa32X64.dsc                                        |   3 +
 OvmfPkg/OvmfPkgX64.dsc                                            |   3 +
 OvmfPkg/PlatformPei/Platform.c                                    |   1 +
 OvmfPkg/PlatformPei/PlatformPei.inf                               |   1 +
 OvmfPkg/SmmControl2Dxe/SmiFeatures.c                              | 224 ++----
 OvmfPkg/SmmControl2Dxe/SmiFeatures.h                              |   5 +-
 OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c                           |   6 +-
 OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf                         |   1 +
 33 files changed, 1924 insertions(+), 425 deletions(-)
 create mode 100644 OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c
 create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c

-- 
2.9.3



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 01/12] OvmfPkg: introduce QemuFwCfgS3Lib class
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 02/12] OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance Laszlo Ersek
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

This library class will enable driver modules (a) to query whether S3
support was enabled on the QEMU command line, (b) to produce fw_cfg DMA
operations that are to be replayed at S3 resume time.

Declare the library class in OvmfPkg/OvmfPkg.dec, and add the library
class header under OvmfPkg/Include/Library/. At the moment, the only API
we expose is QemuFwCfgS3Enabled(), which we'll first migrate from
QemuFwCfgLib. Further interfaces will be added in later patches.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Suggested-by: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
---

Notes:
    v2:
    - no changes
    - pick up R-b from Jordan

 OvmfPkg/OvmfPkg.dec                      |  4 ++
 OvmfPkg/Include/Library/QemuFwCfgS3Lib.h | 39 ++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index a0c76a5bb448..3490f7ca7c07 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -35,6 +35,10 @@ [LibraryClasses]
   #
   QemuFwCfgLib|Include/Library/QemuFwCfgLib.h
 
+  ##  @libraryclass  S3 support for QEMU fw_cfg
+  #
+  QemuFwCfgS3Lib|Include/Library/QemuFwCfgS3Lib.h
+
   ##  @libraryclass  Rewrite the BootOrder NvVar based on QEMU's "bootorder"
   #                  fw_cfg file.
   #
diff --git a/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h b/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
new file mode 100644
index 000000000000..1c473610d11c
--- /dev/null
+++ b/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
@@ -0,0 +1,39 @@
+/** @file
+  S3 support for QEMU fw_cfg
+
+  This library class enables driver modules (a) to query whether S3 support was
+  enabled on the QEMU command line, (b) to produce fw_cfg DMA operations that
+  are to be replayed at S3 resume time.
+
+  Copyright (C) 2017, 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.
+**/
+
+#ifndef __FW_CFG_S3_LIB__
+#define __FW_CFG_S3_LIB__
+
+/**
+  Determine if S3 support is explicitly enabled.
+
+  @retval  TRUE   If S3 support is explicitly enabled. Other functions in this
+                  library may be called (subject to their individual
+                  restrictions).
+
+           FALSE  Otherwise. This includes unavailability of the firmware
+                  configuration interface. No other function in this library
+                  must be called.
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgS3Enabled (
+  VOID
+  );
+
+#endif
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 02/12] OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 01/12] OvmfPkg: introduce QemuFwCfgS3Lib class Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 03/12] OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library instances Laszlo Ersek
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

This library instance returns constant FALSE from QemuFwCfgS3Enabled(),
and all other library functions trigger assertion failures. It is suitable
for QEMU targets and machine types that never enable S3.

The QemuFwCfgS3Enabled() implementation is copied from
"ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c". Stubs for further
QemuFwCfgS3Lib APIs (with assertion failures, see above) will be added
later.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
---

Notes:
    v2:
    - no changes
    - pick up R-b from Jordan

 OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf | 39 ++++++++++++++++++++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c          | 39 ++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf b/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
new file mode 100644
index 000000000000..ba24a0b9d434
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
@@ -0,0 +1,39 @@
+## @file
+# Base Null library instance of the QemuFwCfgS3Lib class.
+#
+# This library instance returns constant FALSE from QemuFwCfgS3Enabled(), and
+# all other library functions trigger assertion failures. It is suitable for
+# QEMU targets and machine types that never enable S3.
+#
+# Copyright (C) 2017, 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                    = 1.25
+  BASE_NAME                      = BaseQemuFwCfgS3LibNull
+  FILE_GUID                      = EA7D2B69-D221-4950-9C2C-C38A65BCC96E
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QemuFwCfgS3Lib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 IPF EBC
+#
+
+[Sources]
+  QemuFwCfgS3Base.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
new file mode 100644
index 000000000000..bed9bf3dfb57
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
@@ -0,0 +1,39 @@
+/** @file
+  Base Null library instance of the QemuFwCfgS3Lib class.
+
+  This library instance returns constant FALSE from QemuFwCfgS3Enabled(), and
+  all other library functions trigger assertion failures. It is suitable for
+  QEMU targets and machine types that never enable S3.
+
+  Copyright (C) 2017, 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 <Library/QemuFwCfgS3Lib.h>
+
+/**
+  Determine if S3 support is explicitly enabled.
+
+  @retval  TRUE   If S3 support is explicitly enabled. Other functions in this
+                  library may be called (subject to their individual
+                  restrictions).
+
+           FALSE  Otherwise. This includes unavailability of the firmware
+                  configuration interface. No other function in this library
+                  must be called.
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgS3Enabled (
+  VOID
+  )
+{
+  return FALSE;
+}
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 03/12] OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library instances
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 01/12] OvmfPkg: introduce QemuFwCfgS3Lib class Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 02/12] OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 04/12] ArmVirtPkg: resolve QemuFwCfgS3Lib Laszlo Ersek
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

This patch introduces PeiQemuFwCfgS3LibFwCfg, a limited functionality
QemuFwCfgS3Lib instance, for PEI phase modules.

The patch also introduces DxeQemuFwCfgS3LibFwCfg, a full functionality
QemuFwCfgS3Lib instance, for DXE_DRIVER and DXE_RUNTIME_DRIVER modules.

These library instances share the QemuFwCfgS3Enabled() function. The
function actually uses fw_cfg; the implementation is copied from
"OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c".

The library instances will diverge in the following patches.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
---

Notes:
    v2:
    - no changes
    - pick up R-b from Jordan

 OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf | 38 ++++++++++++++++
 OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf | 41 +++++++++++++++++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c        | 48 ++++++++++++++++++++
 3 files changed, 127 insertions(+)

diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf b/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
new file mode 100644
index 000000000000..7016575f3dab
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
@@ -0,0 +1,38 @@
+## @file
+# Full functionality QemuFwCfgS3Lib instance, for DXE phase modules.
+#
+# Copyright (C) 2017, 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                    = 1.25
+  BASE_NAME                      = DxeQemuFwCfgS3LibFwCfg
+  FILE_GUID                      = C5DE76EB-E8DE-4057-A487-C5A09AB039AB
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QemuFwCfgS3Lib|DXE_DRIVER DXE_RUNTIME_DRIVER
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 IPF EBC
+#
+
+[Sources]
+  QemuFwCfgS3PeiDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  QemuFwCfgLib
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf b/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
new file mode 100644
index 000000000000..2593af8e5b4c
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
@@ -0,0 +1,41 @@
+## @file
+# Limited functionality QemuFwCfgS3Lib instance, for PEI phase modules.
+#
+# QemuFwCfgS3Enabled() queries S3 enablement via fw_cfg. Other library APIs
+# will report lack of support.
+#
+# Copyright (C) 2017, 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                    = 1.25
+  BASE_NAME                      = PeiQemuFwCfgS3LibFwCfg
+  FILE_GUID                      = DD8D28B4-C1DC-4CAF-BB93-074BE80DAE6D
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QemuFwCfgS3Lib|PEIM
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 IPF EBC
+#
+
+[Sources]
+  QemuFwCfgS3PeiDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  QemuFwCfgLib
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
new file mode 100644
index 000000000000..f87d6b8227cf
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
@@ -0,0 +1,48 @@
+/** @file
+  Shared code for the PEI fw_cfg and DXE fw_cfg instances of the QemuFwCfgS3Lib
+  class.
+
+  Copyright (C) 2017, 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 <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
+
+/**
+  Determine if S3 support is explicitly enabled.
+
+  @retval  TRUE   If S3 support is explicitly enabled. Other functions in this
+                  library may be called (subject to their individual
+                  restrictions).
+
+           FALSE  Otherwise. This includes unavailability of the firmware
+                  configuration interface. No other function in this library
+                  must be called.
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgS3Enabled (
+  VOID
+  )
+{
+  RETURN_STATUS        Status;
+  FIRMWARE_CONFIG_ITEM FwCfgItem;
+  UINTN                FwCfgSize;
+  UINT8                SystemStates[6];
+
+  Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
+  if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {
+    return FALSE;
+  }
+  QemuFwCfgSelectItem (FwCfgItem);
+  QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);
+  return (BOOLEAN) (SystemStates[3] & BIT7);
+}
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 04/12] ArmVirtPkg: resolve QemuFwCfgS3Lib
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (2 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 03/12] OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library instances Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 05/12] OvmfPkg: " Laszlo Ersek
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel

QemuFwCfgS3Enabled() in "ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c"
returns constant FALSE.

The same implementation is now available factored-out in
"OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c".

Resolve QemuFwCfgS3Lib to BaseQemuFwCfgS3LibNull.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---

Notes:
    v2:
    - no changes
    - pick up R-b from Jordan and Ard

 ArmVirtPkg/ArmVirtQemu.dsc       | 1 +
 ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 +
 2 files changed, 2 insertions(+)

diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 7b266b98b949..0bbbe4a7aa4a 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -51,6 +51,7 @@ [LibraryClasses.common]
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
   QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
 
   ArmPlatformLib|ArmVirtPkg/Library/ArmVirtPlatformLib/ArmVirtPlatformLib.inf
   ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index fd39c2802a85..71f16ed192de 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -51,6 +51,7 @@ [LibraryClasses.common]
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
   QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
 
   ArmPlatformLib|ArmVirtPkg/Library/ArmQemuRelocatablePlatformLib/ArmQemuRelocatablePlatformLib.inf
   ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 05/12] OvmfPkg: resolve QemuFwCfgS3Lib
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (3 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 04/12] ArmVirtPkg: resolve QemuFwCfgS3Lib Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 06/12] ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib Laszlo Ersek
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

QemuFwCfgS3Enabled() in "OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c"
queries the "etc/system-states" fw_cfg file.

The same implementation is now available factored-out in
"OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c". It is available to
PEIMs through the PeiQemuFwCfgS3LibFwCfg instance, and to DXE_DRIVER and
DXE_RUNTIME_DRIVER modules through the DxeQemuFwCfgS3LibFwCfg instance.

Resolve QemuFwCfgS3Lib accordingly.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
---

Notes:
    v2:
    - no changes
    - pick up R-b from Jordan

 OvmfPkg/OvmfPkgIa32.dsc    | 3 +++
 OvmfPkg/OvmfPkgIa32X64.dsc | 3 +++
 OvmfPkg/OvmfPkgX64.dsc     | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 0bce56bc8323..0796b0db816b 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -236,6 +236,7 @@ [LibraryClasses.common.PEIM]
 !endif
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -269,6 +270,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.UEFI_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -314,6 +316,7 @@ [LibraryClasses.common.DXE_DRIVER]
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.UEFI_APPLICATION]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 56f7ff9ad004..71ac62f023b5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -241,6 +241,7 @@ [LibraryClasses.common.PEIM]
 !endif
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -274,6 +275,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.UEFI_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -319,6 +321,7 @@ [LibraryClasses.common.DXE_DRIVER]
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.UEFI_APPLICATION]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index d0b0b0e1beb1..2ceb31d7ffd5 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -241,6 +241,7 @@ [LibraryClasses.common.PEIM]
 !endif
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -274,6 +275,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.UEFI_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -319,6 +321,7 @@ [LibraryClasses.common.DXE_DRIVER]
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
 
 [LibraryClasses.common.UEFI_APPLICATION]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 06/12] ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (4 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 05/12] OvmfPkg: " Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 07/12] OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to libclass Laszlo Ersek
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Ard Biesheuvel, Jordan Justen

At this point we're ready to retire QemuFwCfgS3Enabled() from the
QemuFwCfgLib class, together with its implementations in:

- ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
- OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c

Extend all modules that call the function with a new QemuFwCfgS3Lib class
dependency. Thanks to the previously added library class, instances, and
class resolutions, we can do this switch now as tightly as possible.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---

Notes:
    v2:
    - no changes
    - pick up R-b from Jordan and Ard

 OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf                       |  1 +
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf              |  1 +
 OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf                      |  1 +
 OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |  1 +
 OvmfPkg/PlatformPei/PlatformPei.inf                               |  1 +
 OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf                         |  1 +
 OvmfPkg/Include/Library/QemuFwCfgLib.h                            | 14 ----------
 OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h              |  1 +
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                    | 17 ------------
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c                           |  1 +
 OvmfPkg/Library/LockBoxLib/LockBoxDxe.c                           |  1 +
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                       | 28 --------------------
 OvmfPkg/PlatformPei/Platform.c                                    |  1 +
 OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c                           |  1 +
 14 files changed, 11 insertions(+), 59 deletions(-)

diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index bb5f14e0fc7a..42edc97b3da2 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -52,6 +52,7 @@ [LibraryClasses]
   UefiDriverEntryPoint
   HobLib
   QemuFwCfgLib
+  QemuFwCfgS3Lib
   MemoryAllocationLib
   BaseLib
   DxeServicesTableLib
diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
index e550ff5a4714..a9350540215d 100644
--- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
@@ -44,6 +44,7 @@ [LibraryClasses]
   MemoryAllocationLib
   OrderedCollectionLib
   QemuFwCfgLib
+  QemuFwCfgS3Lib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
 
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf b/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
index bedf1811e0b2..eb03f4f546bc 100644
--- a/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
@@ -40,6 +40,7 @@ [LibraryClasses]
   DebugLib
   UefiBootServicesTableLib
   QemuFwCfgLib
+  QemuFwCfgS3Lib
 
 [Protocols]
   gEfiLockBoxProtocolGuid    ## SOMETIMES_PRODUCES
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
index f9e35c955d4d..27789b7377bc 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -52,6 +52,7 @@ [LibraryClasses]
   PciLib
   NvVarsFileLib
   QemuFwCfgLib
+  QemuFwCfgS3Lib
   LoadLinuxLib
   QemuBootOrderLib
   UefiLib
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index fbaed3182dcf..53c6dd445a0e 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -58,6 +58,7 @@ [LibraryClasses]
   PeiServicesTablePointerLib
   PeimEntryPoint
   QemuFwCfgLib
+  QemuFwCfgS3Lib
   MtrrLib
   PcdLib
 
diff --git a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
index 31c80bd4448c..04b1ed0e4eb3 100644
--- a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
+++ b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
@@ -56,6 +56,7 @@ [LibraryClasses]
   PcdLib
   PciLib
   QemuFwCfgLib
+  QemuFwCfgS3Lib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
 
diff --git a/OvmfPkg/Include/Library/QemuFwCfgLib.h b/OvmfPkg/Include/Library/QemuFwCfgLib.h
index 2a1261327b01..596e3f25d5fe 100644
--- a/OvmfPkg/Include/Library/QemuFwCfgLib.h
+++ b/OvmfPkg/Include/Library/QemuFwCfgLib.h
@@ -179,19 +179,5 @@ QemuFwCfgFindFile (
   OUT  UINTN                 *Size
   );
 
-
-/**
-  Determine if S3 support is explicitly enabled.
-
-  @retval  TRUE   if S3 support is explicitly enabled.
-           FALSE  otherwise. This includes unavailability of the firmware
-                  configuration interface.
-**/
-BOOLEAN
-EFIAPI
-QemuFwCfgS3Enabled (
-  VOID
-  );
-
 #endif
 
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
index ec58efa5ef4a..97ffbb514825 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -48,6 +48,7 @@ Abstract:
 #include <Library/IoLib.h>
 #include <Library/NvVarsFileLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
 #include <Library/QemuBootOrderLib.h>
 
 #include <Protocol/Decompress.h>
diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 9dd5c911fc5c..fba1684af2b2 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -637,20 +637,3 @@ QemuFwCfgFindFile (
 
   return RETURN_NOT_FOUND;
 }
-
-
-/**
-  Determine if S3 support is explicitly enabled.
-
-  @retval TRUE   if S3 support is explicitly enabled.
-          FALSE  otherwise. This includes unavailability of the firmware
-                 configuration interface.
-**/
-BOOLEAN
-EFIAPI
-QemuFwCfgS3Enabled (
-  VOID
-  )
-{
-  return FALSE;
-}
diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
index 6a0ecd1ad962..76512534f5e0 100644
--- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
+++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
@@ -19,6 +19,7 @@
 #include <Library/BaseMemoryLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
 #include <Library/DxeServicesTableLib.h>
 #include <Library/PcdLib.h>
 #include <Library/OrderedCollectionLib.h>
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c b/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c
index 818646a275a9..3da9cd21e5c9 100644
--- a/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c
@@ -19,6 +19,7 @@
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
 #include <Protocol/LockBox.h>
 #include <LockBoxLib.h>
 
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 3dd55ba5042e..1bf725d8b7ae 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -368,31 +368,3 @@ QemuFwCfgFindFile (
 
   return RETURN_NOT_FOUND;
 }
-
-
-/**
-  Determine if S3 support is explicitly enabled.
-
-  @retval  TRUE   if S3 support is explicitly enabled.
-           FALSE  otherwise. This includes unavailability of the firmware
-                  configuration interface.
-**/
-BOOLEAN
-EFIAPI
-QemuFwCfgS3Enabled (
-  VOID
-  )
-{
-  RETURN_STATUS        Status;
-  FIRMWARE_CONFIG_ITEM FwCfgItem;
-  UINTN                FwCfgSize;
-  UINT8                SystemStates[6];
-
-  Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
-  if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {
-    return FALSE;
-  }
-  QemuFwCfgSelectItem (FwCfgItem);
-  QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);
-  return (BOOLEAN) (SystemStates[3] & BIT7);
-}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 0be86722e548..77a8a16c15b8 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -32,6 +32,7 @@
 #include <Library/PeimEntryPoint.h>
 #include <Library/PeiServicesLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
 #include <Library/ResourcePublicationLib.h>
 #include <Guid/MemoryTypeInformation.h>
 #include <Ppi/MasterBootMode.h>
diff --git a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
index f31646d73461..bb79fce0855b 100644
--- a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
+++ b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
@@ -32,6 +32,7 @@
 #include <Library/PcdLib.h>
 #include <Library/PciLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Protocol/S3SaveState.h>
 #include <Protocol/SmmControl2.h>
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 07/12] OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to libclass
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (5 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 06/12] ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 08/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance Laszlo Ersek
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

Introduce the following APIs:

- QemuFwCfgS3CallWhenBootScriptReady(): central function that registers a
  callback function, with a context parameter, for when ACPI S3 Boot
  Script opcodes can be produced. This function also allocates reserved
  memory for the opcodes to operate upon.

  The client module is supposed to produce the boot script fragment in the
  callback function.

- QemuFwCfgS3ScriptWriteBytes(), QemuFwCfgS3ScriptReadBytes(),
  QemuFwCfgS3ScriptSkipBytes(), QemuFwCfgS3ScriptCheckValue(): helper
  functions, available only to the above callback function, for composing
  the boot script fragment. QemuFwCfgS3ScriptSkipBytes() can double as a
  plain "select" whenever necessary.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - rename QemuFwCfgS3TransferOwnership to
      QemuFwCfgS3CallWhenBootScriptReady [Jordan]
    - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
      FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
    - rename "Append" to "Callback" [Laszlo]
    - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
      QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
      QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
      QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
      respectively [Jordan]

 OvmfPkg/Include/Library/QemuFwCfgS3Lib.h | 322 ++++++++++++++++++++
 1 file changed, 322 insertions(+)

diff --git a/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h b/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
index 1c473610d11c..76c8554cb706 100644
--- a/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
+++ b/OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
@@ -19,6 +19,8 @@
 #ifndef __FW_CFG_S3_LIB__
 #define __FW_CFG_S3_LIB__
 
+#include <Base.h>
+
 /**
   Determine if S3 support is explicitly enabled.
 
@@ -36,4 +38,324 @@ QemuFwCfgS3Enabled (
   VOID
   );
 
+
+/**
+  Prototype for the callback function that the client module provides.
+
+  In the callback function, the client module calls the
+  QemuFwCfgS3ScriptWriteBytes(), QemuFwCfgS3ScriptReadBytes(),
+  QemuFwCfgS3ScriptSkipBytes(), and QemuFwCfgS3ScriptCheckValue() functions.
+  Those functions produce ACPI S3 Boot Script opcodes that will perform fw_cfg
+  DMA operations, and will check any desired values that were read, during S3
+  resume.
+
+  The callback function is invoked when the production of ACPI S3 Boot Script
+  opcodes becomes possible. This may occur directly on the call stack of
+  QemuFwCfgS3CallWhenBootScriptReady() (see below), or after
+  QemuFwCfgS3CallWhenBootScriptReady() has successfully returned.
+
+  The callback function must not return if it fails -- in the general case,
+  there is noone to propagate any errors to. Therefore, on error, an error
+  message should be logged, and CpuDeadLoop() must be called.
+
+  @param[in,out] Context        Carries information from the client module
+                                itself (i.e., from the invocation of
+                                QemuFwCfgS3CallWhenBootScriptReady()) to the
+                                callback function.
+
+                                If Context points to dynamically allocated
+                                storage, then the callback function must
+                                release it.
+
+  @param[in,out] ScratchBuffer  Points to reserved memory, allocated by
+                                QemuFwCfgS3CallWhenBootScriptReady()
+                                internally.
+
+                                ScratchBuffer is typed and sized by the client
+                                module when it calls
+                                QemuFwCfgS3CallWhenBootScriptReady(). The
+                                client module defines a union type of
+                                structures for ScratchBuffer such that the
+                                union can hold client data for any desired
+                                fw_cfg DMA read and write operations, and value
+                                checking.
+
+                                The callback function casts ScratchBuffer to
+                                the union type described above. It passes union
+                                member sizes as NumberOfBytes to
+                                QemuFwCfgS3ScriptReadBytes() and
+                                QemuFwCfgS3ScriptWriteBytes(). It passes field
+                                addresses and sizes in structures in the union
+                                as ScratchData and ValueSize to
+                                QemuFwCfgS3ScriptCheckValue().
+
+                                ScratchBuffer is aligned at 8 bytes.
+**/
+typedef
+VOID (EFIAPI FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION) (
+  IN OUT VOID *Context,      OPTIONAL
+  IN OUT VOID *ScratchBuffer
+  );
+
+
+/**
+  Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for
+  when the production of ACPI S3 Boot Script opcodes becomes possible.
+
+  Take ownership of the client-provided Context, and pass it to the callback
+  function, when the latter is invoked.
+
+  Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon
+  that the client will produce in the callback function.
+
+  @param[in] Callback           FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke
+                                when the production of ACPI S3 Boot Script
+                                opcodes becomes possible. Callback() may be
+                                called immediately from
+                                QemuFwCfgS3CallWhenBootScriptReady().
+
+  @param[in,out] Context        Client-provided data structure for the
+                                Callback() callback function to consume.
+
+                                If Context points to dynamically allocated
+                                memory, then Callback() must release it.
+
+                                If Context points to dynamically allocated
+                                memory, and
+                                QemuFwCfgS3CallWhenBootScriptReady() returns
+                                successfully, then the caller of
+                                QemuFwCfgS3CallWhenBootScriptReady() must
+                                neither dereference nor even evaluate Context
+                                any longer, as ownership of the referenced area
+                                has been transferred to Callback().
+
+  @param[in] ScratchBufferSize  The size of the scratch buffer that will hold,
+                                in reserved memory, all client data read,
+                                written, and checked by the ACPI S3 Boot Script
+                                opcodes produced by Callback().
+
+  @retval RETURN_UNSUPPORTED       The library instance does not support this
+                                   function.
+
+  @retval RETURN_NOT_FOUND         The fw_cfg DMA interface to QEMU is
+                                   unavailable.
+
+  @retval RETURN_BAD_BUFFER_SIZE   ScratchBufferSize is too large.
+
+  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.
+
+  @retval RETURN_SUCCESS           Callback() has been installed, and the
+                                   ownership of Context has been transferred.
+                                   Reserved memory has been allocated for the
+                                   scratch buffer.
+
+                                   A successful invocation of
+                                   QemuFwCfgS3CallWhenBootScriptReady() cannot
+                                   be rolled back.
+
+  @return                          Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3CallWhenBootScriptReady (
+  IN     FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback,
+  IN OUT VOID                                 *Context,          OPTIONAL
+  IN     UINTN                                ScratchBufferSize
+  );
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and transfer data to it.
+
+  The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore
+  NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write
+  them to fw_cfg using DMA.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to write, expressed as INT32. If
+                                 FirmwareConfigItem is -1, no selection is
+                                 made, the write will occur to the currently
+                                 selected item, at its currently selected
+                                 offset. Otherwise, the specified item will be
+                                 selected, and the write will occur at offset
+                                 0.
+
+  @param[in] NumberOfBytes       Size of the data to restore in ScratchBuffer,
+                                 and to write from ScratchBuffer, during S3
+                                 resume. NumberOfBytes must not exceed
+                                 ScratchBufferSize, which was passed to
+                                 QemuFwCfgS3CallWhenBootScriptReady().
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is larger than
+                                    ScratchBufferSize.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptWriteBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  );
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and transfer data from it.
+
+  The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes
+  bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved
+  memory.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to read, expressed as INT32. If
+                                 FirmwareConfigItem is -1, no selection is
+                                 made, the read will occur from the currently
+                                 selected item, from its currently selected
+                                 offset. Otherwise, the specified item will be
+                                 selected, and the read will occur from offset
+                                 0.
+
+  @param[in] NumberOfBytes       Size of the data to read during S3 resume.
+                                 NumberOfBytes must not exceed
+                                 ScratchBufferSize, which was passed to
+                                 QemuFwCfgS3CallWhenBootScriptReady().
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is larger than
+                                    ScratchBufferSize.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptReadBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  );
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and increase its offset.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to advance the offset of, expressed as
+                                 INT32. If FirmwareConfigItem is -1, no
+                                 selection is made, and the offset for the
+                                 currently selected item is increased.
+                                 Otherwise, the specified item will be
+                                 selected, and the offset increment will occur
+                                 from offset 0.
+
+  @param[in] NumberOfBytes       The number of bytes to skip in the subject
+                                 fw_cfg item.
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is too large.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptSkipBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  );
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer.
+
+  If the check fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] ScratchData  Pointer to the UINT8, UINT16, UINT32 or UINT64 field
+                          in ScratchBuffer that should be checked. The caller
+                          is responsible for populating the field during S3
+                          resume, by calling QemuFwCfgS3ScriptReadBytes() ahead
+                          of QemuFwCfgS3ScriptCheckValue().
+
+                          ScratchData must point into ScratchBuffer, which was
+                          allocated, and passed to Callback(), by
+                          QemuFwCfgS3CallWhenBootScriptReady().
+
+                          ScratchData must be aligned at ValueSize bytes.
+
+  @param[in] ValueSize    One of 1, 2, 4 or 8, specifying the size of the field
+                          to check.
+
+  @param[in] ValueMask    The value read from ScratchData is binarily AND-ed
+                          with ValueMask, and the result is compared against
+                          Value. If the masked data equals Value, the check
+                          passes, and the boot script can proceed. Otherwise,
+                          the check fails, and the boot script hangs.
+
+  @param[in] Value        Refer to ValueMask.
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  ValueSize is invalid.
+
+  @retval RETURN_INVALID_PARAMETER  ValueMask or Value cannot be represented in
+                                    ValueSize bytes.
+
+  @retval RETURN_INVALID_PARAMETER  ScratchData is not aligned at ValueSize
+                                    bytes.
+
+  @retval RETURN_BAD_BUFFER_SIZE    The ValueSize bytes at ScratchData aren't
+                                    wholly contained in the ScratchBufferSize
+                                    bytes at ScratchBuffer.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptCheckValue (
+  IN VOID   *ScratchData,
+  IN UINT8  ValueSize,
+  IN UINT64 ValueMask,
+  IN UINT64 Value
+  );
+
 #endif
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 08/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (6 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 07/12] OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to libclass Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 09/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance Laszlo Ersek
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

In the Base Null instance:

- QemuFwCfgS3Enabled() returns constant FALSE. This is unique to the Base
  Null instance, and the function is already present in
  "QemuFwCfgS3Base.c".

- The QemuFwCfgS3CallWhenBootScriptReady() function must never be called
  (according to the documentation, given the above). This is also unique
  to the Base Null instance, so implement the function in
  "QemuFwCfgS3Base.c".

- Consequently, the QemuFwCfgS3ScriptWriteBytes(),
  QemuFwCfgS3ScriptReadBytes(), QemuFwCfgS3ScriptSkipBytes(), and
  QemuFwCfgS3ScriptCheckValue() functions must never be called either.
  This behavior is not unique to the Base Null instance (it will be shared
  with the PEI fw_cfg instance), so add these functions to
  "QemuFwCfgS3BasePei.c".

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - rename QemuFwCfgS3TransferOwnership to
      QemuFwCfgS3CallWhenBootScriptReady [Jordan]
    - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
      FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
    - rename "Append" to "Callback" [Laszlo]
    - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
      QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
      QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
      QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
      respectively [Jordan]

 OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf |   4 +
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c          |  71 ++++++
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c       | 227 ++++++++++++++++++++
 3 files changed, 302 insertions(+)

diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf b/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
index ba24a0b9d434..837fd70db6e5 100644
--- a/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
@@ -33,7 +33,11 @@ [Defines]
 
 [Sources]
   QemuFwCfgS3Base.c
+  QemuFwCfgS3BasePei.c
 
 [Packages]
   MdePkg/MdePkg.dec
   OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  DebugLib
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
index bed9bf3dfb57..7b71305d1267 100644
--- a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
@@ -16,6 +16,7 @@
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
+#include <Library/DebugLib.h>
 #include <Library/QemuFwCfgS3Lib.h>
 
 /**
@@ -37,3 +38,73 @@ QemuFwCfgS3Enabled (
 {
   return FALSE;
 }
+
+
+/**
+  Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for
+  when the production of ACPI S3 Boot Script opcodes becomes possible.
+
+  Take ownership of the client-provided Context, and pass it to the callback
+  function, when the latter is invoked.
+
+  Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon
+  that the client will produce in the callback function.
+
+  @param[in] Callback           FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke
+                                when the production of ACPI S3 Boot Script
+                                opcodes becomes possible. Callback() may be
+                                called immediately from
+                                QemuFwCfgS3CallWhenBootScriptReady().
+
+  @param[in,out] Context        Client-provided data structure for the
+                                Callback() callback function to consume.
+
+                                If Context points to dynamically allocated
+                                memory, then Callback() must release it.
+
+                                If Context points to dynamically allocated
+                                memory, and
+                                QemuFwCfgS3CallWhenBootScriptReady() returns
+                                successfully, then the caller of
+                                QemuFwCfgS3CallWhenBootScriptReady() must
+                                neither dereference nor even evaluate Context
+                                any longer, as ownership of the referenced area
+                                has been transferred to Callback().
+
+  @param[in] ScratchBufferSize  The size of the scratch buffer that will hold,
+                                in reserved memory, all client data read,
+                                written, and checked by the ACPI S3 Boot Script
+                                opcodes produced by Callback().
+
+  @retval RETURN_UNSUPPORTED       The library instance does not support this
+                                   function.
+
+  @retval RETURN_NOT_FOUND         The fw_cfg DMA interface to QEMU is
+                                   unavailable.
+
+  @retval RETURN_BAD_BUFFER_SIZE   ScratchBufferSize is too large.
+
+  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.
+
+  @retval RETURN_SUCCESS           Callback() has been installed, and the
+                                   ownership of Context has been transferred.
+                                   Reserved memory has been allocated for the
+                                   scratch buffer.
+
+                                   A successful invocation of
+                                   QemuFwCfgS3CallWhenBootScriptReady() cannot
+                                   be rolled back.
+
+  @return                          Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3CallWhenBootScriptReady (
+  IN     FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback,
+  IN OUT VOID                                 *Context,          OPTIONAL
+  IN     UINTN                                ScratchBufferSize
+  )
+{
+  ASSERT (FALSE);
+  return RETURN_UNSUPPORTED;
+}
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c
new file mode 100644
index 000000000000..674929e9d500
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c
@@ -0,0 +1,227 @@
+/** @file
+  Shared code for the Base Null and PEI fw_cfg instances of the QemuFwCfgS3Lib
+  class.
+
+  Copyright (C) 2017, 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 <Library/DebugLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and transfer data to it.
+
+  The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore
+  NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write
+  them to fw_cfg using DMA.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to write, expressed as INT32. If
+                                 FirmwareConfigItem is -1, no selection is
+                                 made, the write will occur to the currently
+                                 selected item, at its currently selected
+                                 offset. Otherwise, the specified item will be
+                                 selected, and the write will occur at offset
+                                 0.
+
+  @param[in] NumberOfBytes       Size of the data to restore in ScratchBuffer,
+                                 and to write from ScratchBuffer, during S3
+                                 resume. NumberOfBytes must not exceed
+                                 ScratchBufferSize, which was passed to
+                                 QemuFwCfgS3CallWhenBootScriptReady().
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is larger than
+                                    ScratchBufferSize.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptWriteBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  )
+{
+  ASSERT (FALSE);
+  return RETURN_UNSUPPORTED;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and transfer data from it.
+
+  The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes
+  bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved
+  memory.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to read, expressed as INT32. If
+                                 FirmwareConfigItem is -1, no selection is
+                                 made, the read will occur from the currently
+                                 selected item, from its currently selected
+                                 offset. Otherwise, the specified item will be
+                                 selected, and the read will occur from offset
+                                 0.
+
+  @param[in] NumberOfBytes       Size of the data to read during S3 resume.
+                                 NumberOfBytes must not exceed
+                                 ScratchBufferSize, which was passed to
+                                 QemuFwCfgS3CallWhenBootScriptReady().
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is larger than
+                                    ScratchBufferSize.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptReadBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  )
+{
+  ASSERT (FALSE);
+  return RETURN_UNSUPPORTED;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and increase its offset.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to advance the offset of, expressed as
+                                 INT32. If FirmwareConfigItem is -1, no
+                                 selection is made, and the offset for the
+                                 currently selected item is increased.
+                                 Otherwise, the specified item will be
+                                 selected, and the offset increment will occur
+                                 from offset 0.
+
+  @param[in] NumberOfBytes       The number of bytes to skip in the subject
+                                 fw_cfg item.
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is too large.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptSkipBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  )
+{
+  ASSERT (FALSE);
+  return RETURN_UNSUPPORTED;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer.
+
+  If the check fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] ScratchData  Pointer to the UINT8, UINT16, UINT32 or UINT64 field
+                          in ScratchBuffer that should be checked. The caller
+                          is responsible for populating the field during S3
+                          resume, by calling QemuFwCfgS3ScriptReadBytes() ahead
+                          of QemuFwCfgS3ScriptCheckValue().
+
+                          ScratchData must point into ScratchBuffer, which was
+                          allocated, and passed to Callback(), by
+                          QemuFwCfgS3CallWhenBootScriptReady().
+
+                          ScratchData must be aligned at ValueSize bytes.
+
+  @param[in] ValueSize    One of 1, 2, 4 or 8, specifying the size of the field
+                          to check.
+
+  @param[in] ValueMask    The value read from ScratchData is binarily AND-ed
+                          with ValueMask, and the result is compared against
+                          Value. If the masked data equals Value, the check
+                          passes, and the boot script can proceed. Otherwise,
+                          the check fails, and the boot script hangs.
+
+  @param[in] Value        Refer to ValueMask.
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  ValueSize is invalid.
+
+  @retval RETURN_INVALID_PARAMETER  ValueMask or Value cannot be represented in
+                                    ValueSize bytes.
+
+  @retval RETURN_INVALID_PARAMETER  ScratchData is not aligned at ValueSize
+                                    bytes.
+
+  @retval RETURN_BAD_BUFFER_SIZE    The ValueSize bytes at ScratchData aren't
+                                    wholly contained in the ScratchBufferSize
+                                    bytes at ScratchBuffer.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptCheckValue (
+  IN VOID   *ScratchData,
+  IN UINT8  ValueSize,
+  IN UINT64 ValueMask,
+  IN UINT64 Value
+  )
+{
+  ASSERT (FALSE);
+  return RETURN_UNSUPPORTED;
+}
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 09/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (7 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 08/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 10/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE " Laszlo Ersek
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

In the PEI fw_cfg instance:

- QemuFwCfgS3Enabled() queries S3 enablement via fw_cfg. This behavior is
  shared with the DXE fw_cfg instance, and the PEI fw_cfg instance already
  pulls in the function from "QemuFwCfgS3PeiDxe.c".

- If QemuFwCfgS3Enabled() returns TRUE, the client module is permitted to
  call QemuFwCfgS3CallWhenBootScriptReady(). However, in the PEI phase we
  have no support for capturing ACPI S3 Boot Script opcodes, hence we
  return RETURN_UNSUPPORTED unconditionally. This behavior is unique to
  the PEI fw_cfg instance, so add the function to "QemuFwCfgS3Pei.c".

- Consequently, the QemuFwCfgS3ScriptWriteBytes(),
  QemuFwCfgS3ScriptReadBytes(), QemuFwCfgS3ScriptSkipBytes(), and
  QemuFwCfgS3ScriptCheckValue() functions must never be called. (They
  could only be called from the client module's callback, but
  QemuFwCfgS3CallWhenBootScriptReady() will never install such callback in
  the PEI fw_cfg instance -- see above.)

  This behavior is not unique to the PEI fw_cfg instance (it is shared
  with the Base Null instance), so pull in these functions from
  "QemuFwCfgS3BasePei.c".

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - rename QemuFwCfgS3TransferOwnership to
      QemuFwCfgS3CallWhenBootScriptReady [Jordan]
    - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
      FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
    - rename "Append" to "Callback" [Laszlo]
    - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
      QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
      QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
      QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
      respectively [Jordan]

 OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf |  3 +
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c           | 86 ++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf b/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
index 2593af8e5b4c..890862076e81 100644
--- a/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
@@ -31,6 +31,8 @@ [Defines]
 #
 
 [Sources]
+  QemuFwCfgS3BasePei.c
+  QemuFwCfgS3Pei.c
   QemuFwCfgS3PeiDxe.c
 
 [Packages]
@@ -38,4 +40,5 @@ [Packages]
   OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
+  DebugLib
   QemuFwCfgLib
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c
new file mode 100644
index 000000000000..d447e36fc01c
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c
@@ -0,0 +1,86 @@
+/** @file
+  Limited functionality QemuFwCfgS3Lib instance, for PEI phase modules.
+
+  QemuFwCfgS3Enabled() queries S3 enablement via fw_cfg. Other library APIs
+  will report lack of support.
+
+  Copyright (C) 2017, 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 <Library/QemuFwCfgS3Lib.h>
+
+/**
+  Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for
+  when the production of ACPI S3 Boot Script opcodes becomes possible.
+
+  Take ownership of the client-provided Context, and pass it to the callback
+  function, when the latter is invoked.
+
+  Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon
+  that the client will produce in the callback function.
+
+  @param[in] Callback           FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke
+                                when the production of ACPI S3 Boot Script
+                                opcodes becomes possible. Callback() may be
+                                called immediately from
+                                QemuFwCfgS3CallWhenBootScriptReady().
+
+  @param[in,out] Context        Client-provided data structure for the
+                                Callback() callback function to consume.
+
+                                If Context points to dynamically allocated
+                                memory, then Callback() must release it.
+
+                                If Context points to dynamically allocated
+                                memory, and
+                                QemuFwCfgS3CallWhenBootScriptReady() returns
+                                successfully, then the caller of
+                                QemuFwCfgS3CallWhenBootScriptReady() must
+                                neither dereference nor even evaluate Context
+                                any longer, as ownership of the referenced area
+                                has been transferred to Callback().
+
+  @param[in] ScratchBufferSize  The size of the scratch buffer that will hold,
+                                in reserved memory, all client data read,
+                                written, and checked by the ACPI S3 Boot Script
+                                opcodes produced by Callback().
+
+  @retval RETURN_UNSUPPORTED       The library instance does not support this
+                                   function.
+
+  @retval RETURN_NOT_FOUND         The fw_cfg DMA interface to QEMU is
+                                   unavailable.
+
+  @retval RETURN_BAD_BUFFER_SIZE   ScratchBufferSize is too large.
+
+  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.
+
+  @retval RETURN_SUCCESS           Callback() has been installed, and the
+                                   ownership of Context has been transferred.
+                                   Reserved memory has been allocated for the
+                                   scratch buffer.
+
+                                   A successful invocation of
+                                   QemuFwCfgS3CallWhenBootScriptReady() cannot
+                                   be rolled back.
+
+  @return                          Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3CallWhenBootScriptReady (
+  IN     FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback,
+  IN OUT VOID                                 *Context,          OPTIONAL
+  IN     UINTN                                ScratchBufferSize
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 10/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE fw_cfg instance
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (8 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 09/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 11/12] OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib Laszlo Ersek
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

In the DXE fw_cfg instance:

- QemuFwCfgS3Enabled() queries S3 enablement via fw_cfg. This behavior is
  shared with the PEI fw_cfg instance, and the DXE fw_cfg instance already
  pulls in the function from "QemuFwCfgS3PeiDxe.c".

- If QemuFwCfgS3Enabled() returns TRUE, the client module is permitted to
  call QemuFwCfgS3CallWhenBootScriptReady().

  We provide a fully functional implementation for
  QemuFwCfgS3CallWhenBootScriptReady(). A protocol notify is installed at
  TPL_CALLBACK for EFI_S3_SAVE_STATE_PROTOCOL. If / once the protocol is
  available, the client module's Callback() function is called, which is
  expected to produce ACPI S3 Boot Script opcodes using the helper
  functions listed below. In QemuFwCfgS3CallWhenBootScriptReady(), we also
  allocate a reserved memory buffer, sized & typed by the client module,
  for the opcodes and (internally) the fw_cfg DMA operations to work upon,
  during S3 resume.

  This behavior is unique to the DXE fw_cfg instance. Thus, add the
  function to "QemuFwCfgS3Dxe.c".

- The QemuFwCfgS3ScriptWriteBytes(), QemuFwCfgS3ScriptReadBytes(),
  QemuFwCfgS3ScriptSkipBytes(), and QemuFwCfgS3ScriptCheckValue()
  functions are also implemented usefully, since the client module's
  Callback() function is expected to invoke them.

  Each of the first three functions produces MEM_WRITE, IO_WRITE, and
  MEM_POLL opcodes, to set up the DMA command in reserved memory, to start
  the DMA transfer, and to check the DMA result, respectively.

  The QemuFwCfgS3ScriptCheckValue() function produces a MEM_POLL opcode to
  validate an unsigned integer field in data that was read via
  QemuFwCfgS3ScriptReadBytes().

  This behavior is again unique to the DXE fw_cfg instance, so add the
  functions to "QemuFwCfgS3Dxe.c".

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - rename QemuFwCfgS3TransferOwnership to
      QemuFwCfgS3CallWhenBootScriptReady [Jordan]
    - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
      FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
    - rename "Append" to "Callback" and "mAppend" to "mCallback" [Laszlo]
    - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
      QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
      QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
      QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
      respectively [Jordan]

 OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf |   8 +
 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c           | 792 ++++++++++++++++++++
 2 files changed, 800 insertions(+)

diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf b/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
index 7016575f3dab..a0e4275cb8a5 100644
--- a/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
@@ -28,6 +28,7 @@ [Defines]
 #
 
 [Sources]
+  QemuFwCfgS3Dxe.c
   QemuFwCfgS3PeiDxe.c
 
 [Packages]
@@ -35,4 +36,11 @@ [Packages]
   OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
+  BaseLib
+  DebugLib
+  MemoryAllocationLib
   QemuFwCfgLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c
new file mode 100644
index 000000000000..0bd6cf939904
--- /dev/null
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c
@@ -0,0 +1,792 @@
+/** @file
+  Full functionality QemuFwCfgS3Lib instance, for DXE phase modules.
+
+  Copyright (C) 2017, 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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/S3SaveState.h>
+
+
+//
+// Event to signal when the S3SaveState protocol interface is installed.
+//
+STATIC EFI_EVENT mS3SaveStateInstalledEvent;
+
+//
+// Reference to the S3SaveState protocol interface, after it is installed.
+//
+STATIC EFI_S3_SAVE_STATE_PROTOCOL *mS3SaveState;
+
+//
+// The control structure is allocated in reserved memory, aligned at 8 bytes.
+// The client-requested ScratchBuffer will be allocated adjacently, also
+// aligned at 8 bytes.
+//
+#define RESERVED_MEM_ALIGNMENT 8
+
+STATIC FW_CFG_DMA_ACCESS *mDmaAccess;
+STATIC VOID              *mScratchBuffer;
+STATIC UINTN             mScratchBufferSize;
+
+//
+// Callback provided by the client, for appending ACPI S3 Boot Script opcodes.
+// To be called from S3SaveStateInstalledNotify().
+//
+STATIC FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *mCallback;
+
+
+/**
+  Event notification function for mS3SaveStateInstalledEvent.
+**/
+STATIC
+VOID
+EFIAPI
+S3SaveStateInstalledNotify (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (Event == mS3SaveStateInstalledEvent);
+
+  Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid,
+                  NULL /* Registration */, (VOID **)&mS3SaveState);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  ASSERT (mCallback != NULL);
+
+  DEBUG ((DEBUG_INFO, "%a: %a: DmaAccess@0x%Lx ScratchBuffer@[0x%Lx+0x%Lx]\n",
+    gEfiCallerBaseName, __FUNCTION__, (UINT64)(UINTN)mDmaAccess,
+    (UINT64)(UINTN)mScratchBuffer, (UINT64)mScratchBufferSize));
+  mCallback (Context, mScratchBuffer);
+
+  gBS->CloseEvent (mS3SaveStateInstalledEvent);
+  mS3SaveStateInstalledEvent = NULL;
+}
+
+
+/**
+  Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for
+  when the production of ACPI S3 Boot Script opcodes becomes possible.
+
+  Take ownership of the client-provided Context, and pass it to the callback
+  function, when the latter is invoked.
+
+  Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon
+  that the client will produce in the callback function.
+
+  @param[in] Callback           FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke
+                                when the production of ACPI S3 Boot Script
+                                opcodes becomes possible. Callback() may be
+                                called immediately from
+                                QemuFwCfgS3CallWhenBootScriptReady().
+
+  @param[in,out] Context        Client-provided data structure for the
+                                Callback() callback function to consume.
+
+                                If Context points to dynamically allocated
+                                memory, then Callback() must release it.
+
+                                If Context points to dynamically allocated
+                                memory, and
+                                QemuFwCfgS3CallWhenBootScriptReady() returns
+                                successfully, then the caller of
+                                QemuFwCfgS3CallWhenBootScriptReady() must
+                                neither dereference nor even evaluate Context
+                                any longer, as ownership of the referenced area
+                                has been transferred to Callback().
+
+  @param[in] ScratchBufferSize  The size of the scratch buffer that will hold,
+                                in reserved memory, all client data read,
+                                written, and checked by the ACPI S3 Boot Script
+                                opcodes produced by Callback().
+
+  @retval RETURN_UNSUPPORTED       The library instance does not support this
+                                   function.
+
+  @retval RETURN_NOT_FOUND         The fw_cfg DMA interface to QEMU is
+                                   unavailable.
+
+  @retval RETURN_BAD_BUFFER_SIZE   ScratchBufferSize is too large.
+
+  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.
+
+  @retval RETURN_SUCCESS           Callback() has been installed, and the
+                                   ownership of Context has been transferred.
+                                   Reserved memory has been allocated for the
+                                   scratch buffer.
+
+                                   A successful invocation of
+                                   QemuFwCfgS3CallWhenBootScriptReady() cannot
+                                   be rolled back.
+
+  @return                          Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3CallWhenBootScriptReady (
+  IN     FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback,
+  IN OUT VOID                                 *Context,          OPTIONAL
+  IN     UINTN                                ScratchBufferSize
+  )
+{
+  EFI_STATUS Status;
+  VOID       *Registration;
+
+  //
+  // Basic fw_cfg is certainly available, as we can only be here after a
+  // successful call to QemuFwCfgS3Enabled(). Check fw_cfg DMA availability.
+  //
+  ASSERT (QemuFwCfgIsAvailable ());
+  QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
+  if ((QemuFwCfgRead32 () & FW_CFG_F_DMA) == 0) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: fw_cfg DMA unavailable\n",
+      gEfiCallerBaseName, __FUNCTION__));
+    return RETURN_NOT_FOUND;
+  }
+
+  //
+  // Allocate a reserved buffer for the DMA access control structure and the
+  // client data together.
+  //
+  if (ScratchBufferSize >
+      MAX_UINT32 - (RESERVED_MEM_ALIGNMENT - 1) - sizeof *mDmaAccess) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: ScratchBufferSize too big: %Lu\n",
+      gEfiCallerBaseName, __FUNCTION__, (UINT64)ScratchBufferSize));
+    return RETURN_BAD_BUFFER_SIZE;
+  }
+  mDmaAccess = AllocateReservedPool ((RESERVED_MEM_ALIGNMENT - 1) +
+                 sizeof *mDmaAccess + ScratchBufferSize);
+  if (mDmaAccess == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: AllocateReservedPool(): out of resources\n",
+      gEfiCallerBaseName, __FUNCTION__));
+    return RETURN_OUT_OF_RESOURCES;
+  }
+  mDmaAccess = ALIGN_POINTER (mDmaAccess, RESERVED_MEM_ALIGNMENT);
+
+  //
+  // Set up a protocol notify for EFI_S3_SAVE_STATE_PROTOCOL. Forward the
+  // client's Context to the callback.
+  //
+  Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+                  S3SaveStateInstalledNotify, Context,
+                  &mS3SaveStateInstalledEvent);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: CreateEvent(): %r\n", gEfiCallerBaseName,
+      __FUNCTION__, Status));
+    goto FreeDmaAccess;
+  }
+  Status = gBS->RegisterProtocolNotify (&gEfiS3SaveStateProtocolGuid,
+                  mS3SaveStateInstalledEvent, &Registration);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: RegisterProtocolNotify(): %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    goto CloseEvent;
+  }
+
+  //
+  // Set the remaining global variables. For the alignment guarantee on
+  // mScratchBuffer, we rely on the fact that *mDmaAccess has a size that is an
+  // integral multiple of RESERVED_MEM_ALIGNMENT.
+  //
+  ASSERT (sizeof *mDmaAccess % RESERVED_MEM_ALIGNMENT == 0);
+  mScratchBuffer = mDmaAccess + 1;
+  mScratchBufferSize = ScratchBufferSize;
+  mCallback = Callback;
+
+  //
+  // Kick the event; EFI_S3_SAVE_STATE_PROTOCOL could be available already.
+  //
+  Status = gBS->SignalEvent (mS3SaveStateInstalledEvent);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: SignalEvent(): %r\n", gEfiCallerBaseName,
+      __FUNCTION__, Status));
+    goto NullGlobals;
+  }
+
+  return RETURN_SUCCESS;
+
+NullGlobals:
+  mScratchBuffer = NULL;
+  mScratchBufferSize = 0;
+  mCallback = NULL;
+
+CloseEvent:
+  gBS->CloseEvent (mS3SaveStateInstalledEvent);
+  mS3SaveStateInstalledEvent = NULL;
+
+FreeDmaAccess:
+  FreePool (mDmaAccess);
+  mDmaAccess = NULL;
+
+  return (RETURN_STATUS)Status;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and transfer data to it.
+
+  The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore
+  NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write
+  them to fw_cfg using DMA.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to write, expressed as INT32. If
+                                 FirmwareConfigItem is -1, no selection is
+                                 made, the write will occur to the currently
+                                 selected item, at its currently selected
+                                 offset. Otherwise, the specified item will be
+                                 selected, and the write will occur at offset
+                                 0.
+
+  @param[in] NumberOfBytes       Size of the data to restore in ScratchBuffer,
+                                 and to write from ScratchBuffer, during S3
+                                 resume. NumberOfBytes must not exceed
+                                 ScratchBufferSize, which was passed to
+                                 QemuFwCfgS3CallWhenBootScriptReady().
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is larger than
+                                    ScratchBufferSize.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptWriteBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  )
+{
+  UINTN      Count;
+  EFI_STATUS Status;
+  UINT64     AccessAddress;
+  UINT32     ControlPollData;
+  UINT32     ControlPollMask;
+
+  ASSERT (mDmaAccess != NULL);
+  ASSERT (mS3SaveState != NULL);
+
+  if (FirmwareConfigItem < -1 || FirmwareConfigItem > MAX_UINT16) {
+    return RETURN_INVALID_PARAMETER;
+  }
+  if (NumberOfBytes > mScratchBufferSize) {
+    return RETURN_BAD_BUFFER_SIZE;
+  }
+
+  //
+  // Set up a write[+select] fw_cfg DMA command.
+  //
+  mDmaAccess->Control = FW_CFG_DMA_CTL_WRITE;
+  if (FirmwareConfigItem != -1) {
+    mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT;
+    mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16;
+  }
+  mDmaAccess->Control = SwapBytes32 (mDmaAccess->Control);
+
+  //
+  // We ensured the following constraint via mScratchBufferSize in
+  // QemuFwCfgS3CallWhenBootScriptReady().
+  //
+  ASSERT (NumberOfBytes <= MAX_UINT32);
+  mDmaAccess->Length = SwapBytes32 ((UINT32)NumberOfBytes);
+
+  mDmaAccess->Address = SwapBytes64 ((UINTN)mScratchBuffer);
+
+  //
+  // Copy mDmaAccess and NumberOfBytes bytes from mScratchBuffer into the boot
+  // script. When executed at S3 resume, this opcode will restore all of them
+  // in-place.
+  //
+  Count = (UINTN)mScratchBuffer + NumberOfBytes - (UINTN)mDmaAccess;
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                     // This
+                           EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode
+                           EfiBootScriptWidthUint8,          // Width
+                           (UINT64)(UINTN)mDmaAccess,        // Address
+                           Count,                            // Count
+                           (VOID *)mDmaAccess                // Buffer
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  //
+  // Append an opcode that will write the address of the fw_cfg DMA command to
+  // the fw_cfg DMA address register, which consists of two 32-bit IO ports.
+  // The second (highest address, least significant) write will start the
+  // transfer.
+  //
+  AccessAddress = SwapBytes64 ((UINTN)mDmaAccess);
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                    // This
+                           EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
+                           EfiBootScriptWidthUint32,        // Width
+                           (UINT64)FW_CFG_IO_DMA_ADDRESS,   // Address
+                           (UINTN)2,                        // Count
+                           (VOID *)&AccessAddress           // Buffer
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  //
+  // The following opcode will wait until the Control word reads as zero
+  // (transfer complete). As timeout we use MAX_UINT64 * 100ns, which is
+  // approximately 58494 years.
+  //
+  ControlPollData = 0;
+  ControlPollMask = MAX_UINT32;
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                        // This
+                           EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,     // OpCode
+                           EfiBootScriptWidthUint32,            // Width
+                           (UINT64)(UINTN)&mDmaAccess->Control, // Address
+                           (VOID *)&ControlPollData,            // Data
+                           (VOID *)&ControlPollMask,            // DataMask
+                           MAX_UINT64                           // Delay
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and transfer data from it.
+
+  The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes
+  bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved
+  memory.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to read, expressed as INT32. If
+                                 FirmwareConfigItem is -1, no selection is
+                                 made, the read will occur from the currently
+                                 selected item, from its currently selected
+                                 offset. Otherwise, the specified item will be
+                                 selected, and the read will occur from offset
+                                 0.
+
+  @param[in] NumberOfBytes       Size of the data to read during S3 resume.
+                                 NumberOfBytes must not exceed
+                                 ScratchBufferSize, which was passed to
+                                 QemuFwCfgS3CallWhenBootScriptReady().
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is larger than
+                                    ScratchBufferSize.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptReadBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  )
+{
+  EFI_STATUS Status;
+  UINT64     AccessAddress;
+  UINT32     ControlPollData;
+  UINT32     ControlPollMask;
+
+  ASSERT (mDmaAccess != NULL);
+  ASSERT (mS3SaveState != NULL);
+
+  if (FirmwareConfigItem < -1 || FirmwareConfigItem > MAX_UINT16) {
+    return RETURN_INVALID_PARAMETER;
+  }
+  if (NumberOfBytes > mScratchBufferSize) {
+    return RETURN_BAD_BUFFER_SIZE;
+  }
+
+  //
+  // Set up a read[+select] fw_cfg DMA command.
+  //
+  mDmaAccess->Control = FW_CFG_DMA_CTL_READ;
+  if (FirmwareConfigItem != -1) {
+    mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT;
+    mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16;
+  }
+  mDmaAccess->Control = SwapBytes32 (mDmaAccess->Control);
+
+  //
+  // We ensured the following constraint via mScratchBufferSize in
+  // QemuFwCfgS3CallWhenBootScriptReady().
+  //
+  ASSERT (NumberOfBytes <= MAX_UINT32);
+  mDmaAccess->Length = SwapBytes32 ((UINT32)NumberOfBytes);
+
+  mDmaAccess->Address = SwapBytes64 ((UINTN)mScratchBuffer);
+
+  //
+  // Copy mDmaAccess into the boot script. When executed at S3 resume, this
+  // opcode will restore it in-place.
+  //
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                     // This
+                           EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode
+                           EfiBootScriptWidthUint8,          // Width
+                           (UINT64)(UINTN)mDmaAccess,        // Address
+                           sizeof *mDmaAccess,               // Count
+                           (VOID *)mDmaAccess                // Buffer
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  //
+  // Append an opcode that will write the address of the fw_cfg DMA command to
+  // the fw_cfg DMA address register, which consists of two 32-bit IO ports.
+  // The second (highest address, least significant) write will start the
+  // transfer.
+  //
+  AccessAddress = SwapBytes64 ((UINTN)mDmaAccess);
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                    // This
+                           EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
+                           EfiBootScriptWidthUint32,        // Width
+                           (UINT64)FW_CFG_IO_DMA_ADDRESS,   // Address
+                           (UINTN)2,                        // Count
+                           (VOID *)&AccessAddress           // Buffer
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  //
+  // The following opcode will wait until the Control word reads as zero
+  // (transfer complete). As timeout we use MAX_UINT64 * 100ns, which is
+  // approximately 58494 years.
+  //
+  ControlPollData = 0;
+  ControlPollMask = MAX_UINT32;
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                        // This
+                           EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,     // OpCode
+                           EfiBootScriptWidthUint32,            // Width
+                           (UINT64)(UINTN)&mDmaAccess->Control, // Address
+                           (VOID *)&ControlPollData,            // Data
+                           (VOID *)&ControlPollMask,            // DataMask
+                           MAX_UINT64                           // Delay
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
+  and increase its offset.
+
+  If the operation fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] FirmwareConfigItem  The UINT16 selector key of the firmware config
+                                 item to advance the offset of, expressed as
+                                 INT32. If FirmwareConfigItem is -1, no
+                                 selection is made, and the offset for the
+                                 currently selected item is increased.
+                                 Otherwise, the specified item will be
+                                 selected, and the offset increment will occur
+                                 from offset 0.
+
+  @param[in] NumberOfBytes       The number of bytes to skip in the subject
+                                 fw_cfg item.
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  FirmwareConfigItem is invalid.
+
+  @retval RETURN_BAD_BUFFER_SIZE    NumberOfBytes is too large.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptSkipBytes (
+  IN INT32 FirmwareConfigItem,
+  IN UINTN NumberOfBytes
+  )
+{
+  EFI_STATUS Status;
+  UINT64     AccessAddress;
+  UINT32     ControlPollData;
+  UINT32     ControlPollMask;
+
+  ASSERT (mDmaAccess != NULL);
+  ASSERT (mS3SaveState != NULL);
+
+  if (FirmwareConfigItem < -1 || FirmwareConfigItem > MAX_UINT16) {
+    return RETURN_INVALID_PARAMETER;
+  }
+  if (NumberOfBytes > MAX_UINT32) {
+    return RETURN_BAD_BUFFER_SIZE;
+  }
+
+  //
+  // Set up a skip[+select] fw_cfg DMA command.
+  //
+  mDmaAccess->Control = FW_CFG_DMA_CTL_SKIP;
+  if (FirmwareConfigItem != -1) {
+    mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT;
+    mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16;
+  }
+  mDmaAccess->Control = SwapBytes32 (mDmaAccess->Control);
+
+  mDmaAccess->Length = SwapBytes32 ((UINT32)NumberOfBytes);
+  mDmaAccess->Address = 0;
+
+  //
+  // Copy mDmaAccess into the boot script. When executed at S3 resume, this
+  // opcode will restore it in-place.
+  //
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                     // This
+                           EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode
+                           EfiBootScriptWidthUint8,          // Width
+                           (UINT64)(UINTN)mDmaAccess,        // Address
+                           sizeof *mDmaAccess,               // Count
+                           (VOID *)mDmaAccess                // Buffer
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  //
+  // Append an opcode that will write the address of the fw_cfg DMA command to
+  // the fw_cfg DMA address register, which consists of two 32-bit IO ports.
+  // The second (highest address, least significant) write will start the
+  // transfer.
+  //
+  AccessAddress = SwapBytes64 ((UINTN)mDmaAccess);
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                    // This
+                           EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
+                           EfiBootScriptWidthUint32,        // Width
+                           (UINT64)FW_CFG_IO_DMA_ADDRESS,   // Address
+                           (UINTN)2,                        // Count
+                           (VOID *)&AccessAddress           // Buffer
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  //
+  // The following opcode will wait until the Control word reads as zero
+  // (transfer complete). As timeout we use MAX_UINT64 * 100ns, which is
+  // approximately 58494 years.
+  //
+  ControlPollData = 0;
+  ControlPollMask = MAX_UINT32;
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                        // This
+                           EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,     // OpCode
+                           EfiBootScriptWidthUint32,            // Width
+                           (UINT64)(UINTN)&mDmaAccess->Control, // Address
+                           (VOID *)&ControlPollData,            // Data
+                           (VOID *)&ControlPollMask,            // DataMask
+                           MAX_UINT64                           // Delay
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer.
+
+  If the check fails during S3 resume, the boot script will hang.
+
+  This function may only be called from the client module's
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
+  QemuFwCfgS3CallWhenBootScriptReady() as Callback.
+
+  @param[in] ScratchData  Pointer to the UINT8, UINT16, UINT32 or UINT64 field
+                          in ScratchBuffer that should be checked. The caller
+                          is responsible for populating the field during S3
+                          resume, by calling QemuFwCfgS3ScriptReadBytes() ahead
+                          of QemuFwCfgS3ScriptCheckValue().
+
+                          ScratchData must point into ScratchBuffer, which was
+                          allocated, and passed to Callback(), by
+                          QemuFwCfgS3CallWhenBootScriptReady().
+
+                          ScratchData must be aligned at ValueSize bytes.
+
+  @param[in] ValueSize    One of 1, 2, 4 or 8, specifying the size of the field
+                          to check.
+
+  @param[in] ValueMask    The value read from ScratchData is binarily AND-ed
+                          with ValueMask, and the result is compared against
+                          Value. If the masked data equals Value, the check
+                          passes, and the boot script can proceed. Otherwise,
+                          the check fails, and the boot script hangs.
+
+  @param[in] Value        Refer to ValueMask.
+
+  @retval RETURN_SUCCESS            The opcodes were appended to the ACPI S3
+                                    Boot Script successfully. There is no way
+                                    to undo this action.
+
+  @retval RETURN_INVALID_PARAMETER  ValueSize is invalid.
+
+  @retval RETURN_INVALID_PARAMETER  ValueMask or Value cannot be represented in
+                                    ValueSize bytes.
+
+  @retval RETURN_INVALID_PARAMETER  ScratchData is not aligned at ValueSize
+                                    bytes.
+
+  @retval RETURN_BAD_BUFFER_SIZE    The ValueSize bytes at ScratchData aren't
+                                    wholly contained in the ScratchBufferSize
+                                    bytes at ScratchBuffer.
+
+  @return                           Error codes from underlying functions.
+**/
+EFIAPI
+RETURN_STATUS
+QemuFwCfgS3ScriptCheckValue (
+  IN VOID   *ScratchData,
+  IN UINT8  ValueSize,
+  IN UINT64 ValueMask,
+  IN UINT64 Value
+  )
+{
+  EFI_BOOT_SCRIPT_WIDTH Width;
+  EFI_STATUS            Status;
+
+  ASSERT (mS3SaveState != NULL);
+
+  switch (ValueSize) {
+  case 1:
+    Width = EfiBootScriptWidthUint8;
+    break;
+
+  case 2:
+    Width = EfiBootScriptWidthUint16;
+    break;
+
+  case 4:
+    Width = EfiBootScriptWidthUint32;
+    break;
+
+  case 8:
+    Width = EfiBootScriptWidthUint64;
+    break;
+
+  default:
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (ValueSize < 8 &&
+      (RShiftU64 (ValueMask, ValueSize * 8) > 0 ||
+       RShiftU64 (Value, ValueSize * 8) > 0)) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((UINTN)ScratchData % ValueSize > 0) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (((UINTN)ScratchData < (UINTN)mScratchBuffer) ||
+      ((UINTN)ScratchData > MAX_UINTN - ValueSize) ||
+      ((UINTN)ScratchData + ValueSize >
+       (UINTN)mScratchBuffer + mScratchBufferSize)) {
+    return RETURN_BAD_BUFFER_SIZE;
+  }
+
+  //
+  // The following opcode will wait "until" (*ScratchData & ValueMask) reads as
+  // Value, considering the least significant ValueSize bytes. As timeout we
+  // use MAX_UINT64 * 100ns, which is approximately 58494 years.
+  //
+  Status = mS3SaveState->Write (
+                           mS3SaveState,                    // This
+                           EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode
+                           Width,                           // Width
+                           (UINT64)(UINTN)ScratchData,      // Address
+                           (VOID *)&Value,                  // Data
+                           (VOID *)&ValueMask,              // DataMask
+                           MAX_UINT64                       // Delay
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
+      gEfiCallerBaseName, __FUNCTION__, Status));
+    return (RETURN_STATUS)Status;
+  }
+
+  return RETURN_SUCCESS;
+}
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 11/12] OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (9 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 10/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE " Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-11  6:26 ` [PATCH v2 12/12] OvmfPkg/AcpiPlatformDxe: " Laszlo Ersek
  2017-03-14 18:14 ` [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Jordan Justen
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

We cannot entirely eliminate the manual boot script building in this
driver, as it also programs lower-level chipset registers (SMI_EN,
GEN_PMCON_1) at S3 resume, not just registers exposed via fw_cfg.

We can nonetheless replace the manually built opcodes for the latter class
of registers with QemuFwCfgS3Lib function calls. We preserve the ordering
between the two sets of registers (low-level chipset first, fw_cfg
second).

This patch demonstrates that manual handling of S3SaveState protocol
installation can be combined with QemuFwCfgS3Lib, even without upsetting
the original order between boot script fragments. An S3SaveState notify
function running at TPL_CALLBACK can safely queue another S3SaveState
notify function at TPL_CALLBACK with QemuFwCfgS3CallWhenBootScriptReady().

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - rename QemuFwCfgS3TransferOwnership to
      QemuFwCfgS3CallWhenBootScriptReady [Jordan]
    - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
      FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
    - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
      QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
      QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
      QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
      respectively [Jordan]

 OvmfPkg/SmmControl2Dxe/SmiFeatures.h    |   5 +-
 OvmfPkg/SmmControl2Dxe/SmiFeatures.c    | 224 +++++++-------------
 OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c |   5 +-
 3 files changed, 77 insertions(+), 157 deletions(-)

diff --git a/OvmfPkg/SmmControl2Dxe/SmiFeatures.h b/OvmfPkg/SmmControl2Dxe/SmiFeatures.h
index 9d5f1dbcb57e..3f3a5d3ea9b1 100644
--- a/OvmfPkg/SmmControl2Dxe/SmiFeatures.h
+++ b/OvmfPkg/SmmControl2Dxe/SmiFeatures.h
@@ -37,13 +37,10 @@ NegotiateSmiFeatures (
 /**
   Append a boot script fragment that will re-select the previously negotiated
   SMI features during S3 resume.
-
-  @param[in] S3SaveState  The EFI_S3_SAVE_STATE_PROTOCOL instance to append to
-                          the S3 boot script with.
 **/
 VOID
 SaveSmiFeatures (
-  IN EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState
+  VOID
   );
 
 #endif
diff --git a/OvmfPkg/SmmControl2Dxe/SmiFeatures.c b/OvmfPkg/SmmControl2Dxe/SmiFeatures.c
index bd257f15d955..7c2cbd86ee62 100644
--- a/OvmfPkg/SmmControl2Dxe/SmiFeatures.c
+++ b/OvmfPkg/SmmControl2Dxe/SmiFeatures.c
@@ -18,6 +18,7 @@
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
 
 #include "SmiFeatures.h"
 
@@ -29,29 +30,26 @@
 
 //
 // Provides a scratch buffer (allocated in EfiReservedMemoryType type memory)
-// for the S3 boot script fragment to write to and read from. The buffer
-// captures a combined fw_cfg item selection + write command using the DMA
-// access method. Note that we don't trust the runtime OS to preserve the
-// contents of the buffer, the boot script will first rewrite it.
+// for the S3 boot script fragment to write to and read from.
 //
 #pragma pack (1)
-typedef struct {
-  FW_CFG_DMA_ACCESS Access;
-  UINT64            Features;
+typedef union {
+  UINT64 Features;
+  UINT8  FeaturesOk;
 } SCRATCH_BUFFER;
 #pragma pack ()
 
 //
 // These carry the selector keys of the "etc/smi/requested-features" and
 // "etc/smi/features-ok" fw_cfg files from NegotiateSmiFeatures() to
-// SaveSmiFeatures().
+// AppendFwCfgBootScript().
 //
 STATIC FIRMWARE_CONFIG_ITEM mRequestedFeaturesItem;
 STATIC FIRMWARE_CONFIG_ITEM mFeaturesOkItem;
 
 //
 // Carries the negotiated SMI features from NegotiateSmiFeatures() to
-// SaveSmiFeatures().
+// AppendFwCfgBootScript().
 //
 STATIC UINT64 mSmiFeatures;
 
@@ -168,157 +166,81 @@ FatalError:
 }
 
 /**
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib.
+**/
+STATIC
+VOID
+EFIAPI
+AppendFwCfgBootScript (
+  IN OUT VOID *Context,              OPTIONAL
+  IN OUT VOID *ExternalScratchBuffer
+  )
+{
+  SCRATCH_BUFFER *ScratchBuffer;
+  RETURN_STATUS  Status;
+
+  ScratchBuffer = ExternalScratchBuffer;
+
+  //
+  // Write the negotiated feature bitmap into "etc/smi/requested-features".
+  //
+  ScratchBuffer->Features = mSmiFeatures;
+  Status = QemuFwCfgS3ScriptWriteBytes (mRequestedFeaturesItem,
+             sizeof ScratchBuffer->Features);
+  if (RETURN_ERROR (Status)) {
+    goto FatalError;
+  }
+
+  //
+  // Read back "etc/smi/features-ok". This invokes the feature validation &
+  // lockdown. (The validation succeeded at first boot.)
+  //
+  Status = QemuFwCfgS3ScriptReadBytes (mFeaturesOkItem,
+             sizeof ScratchBuffer->FeaturesOk);
+  if (RETURN_ERROR (Status)) {
+    goto FatalError;
+  }
+
+  //
+  // If "etc/smi/features-ok" read as 1, we're good. Otherwise, hang the S3
+  // resume process.
+  //
+  Status = QemuFwCfgS3ScriptCheckValue (&ScratchBuffer->FeaturesOk,
+             sizeof ScratchBuffer->FeaturesOk, MAX_UINT8, 1);
+  if (RETURN_ERROR (Status)) {
+    goto FatalError;
+  }
+
+  DEBUG ((DEBUG_VERBOSE, "%a: SMI feature negotiation boot script saved\n",
+    __FUNCTION__));
+  return;
+
+FatalError:
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+
+/**
   Append a boot script fragment that will re-select the previously negotiated
   SMI features during S3 resume.
-
-  @param[in] S3SaveState  The EFI_S3_SAVE_STATE_PROTOCOL instance to append to
-                          the S3 boot script with.
 **/
 VOID
 SaveSmiFeatures (
-  IN EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState
+  VOID
   )
 {
-  SCRATCH_BUFFER *ScratchBuffer;
-  EFI_STATUS     Status;
-  UINT64         AccessAddress;
-  UINT32         ControlPollData;
-  UINT32         ControlPollMask;
-  UINT16         FeaturesOkItemAsUint16;
-  UINT8          FeaturesOkData;
-  UINT8          FeaturesOkMask;
+  RETURN_STATUS Status;
 
-  ScratchBuffer = AllocateReservedPool (sizeof *ScratchBuffer);
-  if (ScratchBuffer == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a: scratch buffer allocation failed\n",
-      __FUNCTION__));
-    goto FatalError;
-  }
-
-  //
-  // Populate the scratch buffer with a select + write fw_cfg DMA command that
-  // will write the negotiated feature bitmap into
-  // "etc/smi/requested-features".
-  //
-  ScratchBuffer->Access.Control = SwapBytes32 (
-                                    (UINT32)mRequestedFeaturesItem << 16 |
-                                    FW_CFG_DMA_CTL_SELECT |
-                                    FW_CFG_DMA_CTL_WRITE
-                                    );
-  ScratchBuffer->Access.Length = SwapBytes32 (
-                                   (UINT32)sizeof ScratchBuffer->Features);
-  ScratchBuffer->Access.Address = SwapBytes64 (
-                                    (UINTN)&ScratchBuffer->Features);
-  ScratchBuffer->Features       = mSmiFeatures;
-
-  //
-  // Copy the scratch buffer into the boot script. When replayed, this
-  // EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE will restore the current contents of the
-  // scratch buffer, in-place.
   //
-  Status = S3SaveState->Write (
-                          S3SaveState,                      // This
-                          EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode
-                          EfiBootScriptWidthUint8,          // Width
-                          (UINT64)(UINTN)ScratchBuffer,     // Address
-                          sizeof *ScratchBuffer,            // Count
-                          (VOID*)ScratchBuffer              // Buffer
-                          );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a:%d: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
-      __FUNCTION__, __LINE__, Status));
-    goto FatalError;
-  }
-
-  //
-  // Append an opcode that will write the address of the scratch buffer to the
-  // fw_cfg DMA address register, which consists of two 32-bit IO ports. The
-  // second (highest address, least significant) write will start the transfer.
+  // We are already running at TPL_CALLBACK, on the stack of
+  // OnS3SaveStateInstalled(). But that's okay, we can easily queue more
+  // notification functions while executing a notification function.
   //
-  AccessAddress = SwapBytes64 ((UINTN)&ScratchBuffer->Access);
-  Status = S3SaveState->Write (
-                          S3SaveState,                     // This
-                          EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
-                          EfiBootScriptWidthUint32,        // Width
-                          (UINT64)FW_CFG_IO_DMA_ADDRESS,   // Address
-                          (UINTN)2,                        // Count
-                          &AccessAddress                   // Buffer
-                          );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a:%d: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
-      __FUNCTION__, __LINE__, Status));
-    goto FatalError;
+  Status = QemuFwCfgS3CallWhenBootScriptReady (AppendFwCfgBootScript, NULL,
+             sizeof (SCRATCH_BUFFER));
+  if (RETURN_ERROR (Status)) {
+    ASSERT (FALSE);
+    CpuDeadLoop ();
   }
-
-  //
-  // The EFI_BOOT_SCRIPT_MEM_POLL_OPCODE will wait until the Control word reads
-  // as zero (transfer complete). As timeout we use MAX_UINT64 * 100ns, which
-  // is approximately 58494 years.
-  //
-  ControlPollData = 0;
-  ControlPollMask = MAX_UINT32;
-  Status = S3SaveState->Write (
-                     S3SaveState,                                   // This
-                     EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,               // OpCode
-                     EfiBootScriptWidthUint32,                      // Width
-                     (UINT64)(UINTN)&ScratchBuffer->Access.Control, // Address
-                     &ControlPollData,                              // Data
-                     &ControlPollMask,                              // DataMask
-                     MAX_UINT64                                     // Delay
-                     );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a:%d: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
-      __FUNCTION__, __LINE__, Status));
-    goto FatalError;
-  }
-
-  //
-  // Select the "etc/smi/features-ok" fw_cfg file, which invokes the feature
-  // validation & lockdown. (The validation succeeded at first boot.)
-  //
-  FeaturesOkItemAsUint16 = (UINT16)mFeaturesOkItem;
-  Status = S3SaveState->Write (
-                          S3SaveState,                     // This
-                          EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
-                          EfiBootScriptWidthUint16,        // Width
-                          (UINT64)FW_CFG_IO_SELECTOR,      // Address
-                          (UINTN)1,                        // Count
-                          &FeaturesOkItemAsUint16          // Buffer
-                          );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a:%d: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
-      __FUNCTION__, __LINE__, Status));
-    goto FatalError;
-  }
-
-  //
-  // Read the contents (one byte) of "etc/smi/features-ok". If the value is
-  // one, we're good. Otherwise, continue reading the data port: QEMU returns 0
-  // past the end of the fw_cfg item, so this will hang the resume process,
-  // which matches our intent.
-  //
-  FeaturesOkData = 1;
-  FeaturesOkMask = MAX_UINT8;
-  Status = S3SaveState->Write (
-                     S3SaveState,                    // This
-                     EFI_BOOT_SCRIPT_IO_POLL_OPCODE, // OpCode
-                     EfiBootScriptWidthUint8,        // Width
-                     (UINT64)(UINTN)FW_CFG_IO_DATA,  // Address
-                     &FeaturesOkData,                // Data
-                     &FeaturesOkMask,                // DataMask
-                     MAX_UINT64                      // Delay
-                     );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a:%d: EFI_BOOT_SCRIPT_IO_POLL_OPCODE: %r\n",
-      __FUNCTION__, __LINE__, Status));
-    goto FatalError;
-  }
-
-  DEBUG ((DEBUG_VERBOSE, "%a: ScratchBuffer@%p\n", __FUNCTION__,
-    (VOID *)ScratchBuffer));
-  return;
-
-FatalError:
-  ASSERT (FALSE);
-  CpuDeadLoop ();
 }
diff --git a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
index bb79fce0855b..e1cd3d02ac36 100644
--- a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
+++ b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c
@@ -378,14 +378,15 @@ OnS3SaveStateInstalled (
     CpuDeadLoop ();
   }
 
+  DEBUG ((DEBUG_VERBOSE, "%a: chipset boot script saved\n", __FUNCTION__));
+
   //
   // Append a boot script fragment that re-selects the negotiated SMI features.
   //
   if (mSmiFeatureNegotiation) {
-    SaveSmiFeatures (S3SaveState);
+    SaveSmiFeatures ();
   }
 
-  DEBUG ((EFI_D_VERBOSE, "%a: boot script fragment saved\n", __FUNCTION__));
   gBS->CloseEvent (Event);
   mS3SaveStateInstalled = NULL;
 }
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 12/12] OvmfPkg/AcpiPlatformDxe: save fw_cfg boot script with QemuFwCfgS3Lib
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (10 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 11/12] OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib Laszlo Ersek
@ 2017-03-11  6:26 ` Laszlo Ersek
  2017-03-14 18:14 ` [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Jordan Justen
  12 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-11  6:26 UTC (permalink / raw)
  To: edk2-devel-01; +Cc: Jordan Justen

Drop the explicit S3SaveState protocol and opcode management; instead,
create ACPI S3 Boot Script opcodes for the WRITE_POINTER commands with
QemuFwCfgS3Lib functions.

In this case, we have a dynamically allocated Context structure, hence the
patch demonstrates how the FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION takes
ownership of Context.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=394
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - rename QemuFwCfgS3TransferOwnership to
      QemuFwCfgS3CallWhenBootScriptReady [Jordan]
    - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
      FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
    - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
      QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
      QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
      QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
      respectively [Jordan]

 OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf          |   1 -
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf |   1 -
 OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h               |   2 +-
 OvmfPkg/AcpiPlatformDxe/BootScript.c                 | 262 +++++---------------
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c              |   7 +
 5 files changed, 64 insertions(+), 209 deletions(-)

diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index 42edc97b3da2..9a9b2e6bb2e5 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -61,7 +61,6 @@ [LibraryClasses]
 [Protocols]
   gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
   gEfiPciIoProtocolGuid                         # PROTOCOL SOMETIMES_CONSUMED
-  gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED
 
 [Guids]
   gEfiXenInfoGuid
diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
index a9350540215d..adc50cfd9f76 100644
--- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
@@ -51,7 +51,6 @@ [LibraryClasses]
 [Protocols]
   gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
   gEfiPciIoProtocolGuid                         # PROTOCOL SOMETIMES_CONSUMED
-  gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED
 
 [Guids]
   gRootBridgesConnectedEventGroupGuid
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
index 0f035a0d5751..83b981ee005d 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
@@ -115,7 +115,7 @@ SaveCondensedWritePointerToS3Context (
 
 EFI_STATUS
 TransferS3ContextToBootScript (
-  IN CONST S3_CONTEXT *S3Context
+  IN S3_CONTEXT *S3Context
   );
 
 #endif
diff --git a/OvmfPkg/AcpiPlatformDxe/BootScript.c b/OvmfPkg/AcpiPlatformDxe/BootScript.c
index bff42ad8b9b0..a7d2f9e38f57 100644
--- a/OvmfPkg/AcpiPlatformDxe/BootScript.c
+++ b/OvmfPkg/AcpiPlatformDxe/BootScript.c
@@ -15,7 +15,7 @@
 
 #include <Library/MemoryAllocationLib.h>
 #include <Library/QemuFwCfgLib.h>
-#include <Protocol/S3SaveState.h>
+#include <Library/QemuFwCfgS3Lib.h>
 
 #include "AcpiPlatform.h"
 
@@ -53,19 +53,11 @@ struct S3_CONTEXT {
 
 //
 // Scratch buffer, allocated in EfiReservedMemoryType type memory, for the ACPI
-// S3 Boot Script opcodes to work on. We use the buffer to compose and to
-// replay several fw_cfg select+skip and write operations, using the DMA access
-// method. The fw_cfg operations will implement the actions dictated by
-// CONDENSED_WRITE_POINTER objects.
+// S3 Boot Script opcodes to work on.
 //
 #pragma pack (1)
-typedef struct {
-  FW_CFG_DMA_ACCESS Access;       // filled in from
-                                  //   CONDENSED_WRITE_POINTER.PointerItem,
-                                  //   CONDENSED_WRITE_POINTER.PointerSize,
-                                  //   CONDENSED_WRITE_POINTER.PointerOffset
-  UINT64            PointerValue; // filled in from
-                                  //   CONDENSED_WRITE_POINTER.PointerValue
+typedef union {
+  UINT64 PointerValue; // filled in from CONDENSED_WRITE_POINTER.PointerValue
 } SCRATCH_BUFFER;
 #pragma pack ()
 
@@ -197,220 +189,78 @@ SaveCondensedWritePointerToS3Context (
 
 
 /**
-  Translate and append the information from an S3_CONTEXT object to the ACPI S3
-  Boot Script.
-
-  The effects of a successful call to this function cannot be undone.
-
-  @param[in] S3Context  The S3_CONTEXT object to translate to ACPI S3 Boot
-                        Script opcodes.
-
-  @retval EFI_OUT_OF_RESOURCES  Out of memory.
-
-  @retval EFI_SUCCESS           The translation of S3Context to ACPI S3 Boot
-                                Script opcodes has been successful.
-
-  @return                       Error codes from underlying functions.
+  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib.
 **/
-EFI_STATUS
-TransferS3ContextToBootScript (
-  IN CONST S3_CONTEXT *S3Context
+STATIC
+VOID
+EFIAPI
+AppendFwCfgBootScript (
+  IN OUT VOID *Context,              OPTIONAL
+  IN OUT VOID *ExternalScratchBuffer
   )
 {
-  EFI_STATUS                 Status;
-  EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState;
-  SCRATCH_BUFFER             *ScratchBuffer;
-  FW_CFG_DMA_ACCESS          *Access;
-  UINT64                     BigEndianAddressOfAccess;
-  UINT32                     ControlPollData;
-  UINT32                     ControlPollMask;
-  UINTN                      Index;
+  S3_CONTEXT     *S3Context;
+  SCRATCH_BUFFER *ScratchBuffer;
+  UINTN          Index;
 
-  //
-  // If the following protocol lookup fails, it shall not happen due to an
-  // unexpected DXE driver dispatch order.
-  //
-  // Namely, this function is only invoked on QEMU. Therefore it is only
-  // reached after Platform BDS signals gRootBridgesConnectedEventGroupGuid
-  // (see OnRootBridgesConnected() in "EntryPoint.c"). Hence, because
-  // TransferS3ContextToBootScript() is invoked in BDS, all DXE drivers,
-  // including S3SaveStateDxe (producing EFI_S3_SAVE_STATE_PROTOCOL), have been
-  // dispatched by the time we get here. (S3SaveStateDxe is not expected to
-  // have any stricter-than-TRUE DEPEX -- not a DEPEX that gets unblocked only
-  // within BDS anyway.)
-  //
-  // Reaching this function also depends on QemuFwCfgS3Enabled(). That implies
-  // S3SaveStateDxe has not exited immediately due to S3 being disabled. Thus
-  // EFI_S3_SAVE_STATE_PROTOCOL can only be missing for genuinely unforeseeable
-  // reasons.
-  //
-  Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid,
-                  NULL /* Registration */, (VOID **)&S3SaveState);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a: LocateProtocol(): %r\n", __FUNCTION__, Status));
-    return Status;
-  }
+  S3Context = Context;
+  ScratchBuffer = ExternalScratchBuffer;
 
-  ScratchBuffer = AllocateReservedPool (sizeof *ScratchBuffer);
-  if (ScratchBuffer == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Set up helper variables that we'll use identically for all
-  // CONDENSED_WRITE_POINTER elements.
-  //
-  Access = &ScratchBuffer->Access;
-  BigEndianAddressOfAccess = SwapBytes64 ((UINTN)Access);
-  ControlPollData = 0;
-  ControlPollMask = MAX_UINT32;
-
-  //
-  // For each CONDENSED_WRITE_POINTER, we need six ACPI S3 Boot Script opcodes:
-  // (1) restore an FW_CFG_DMA_ACCESS object in reserved memory that selects
-  //     the writeable fw_cfg file PointerFile (through PointerItem), and skips
-  //     to PointerOffset in it,
-  // (2) call QEMU with the FW_CFG_DMA_ACCESS object,
-  // (3) wait for the select+skip to finish,
-  // (4) restore a SCRATCH_BUFFER object in reserved memory that writes
-  //     PointerValue (base address of the allocated / downloaded PointeeFile,
-  //     plus PointeeOffset), of size PointerSize, into the fw_cfg file
-  //     selected in (1), at the offset sought to in (1),
-  // (5) call QEMU with the FW_CFG_DMA_ACCESS object,
-  // (6) wait for the write to finish.
-  //
-  // EFI_S3_SAVE_STATE_PROTOCOL does not allow rolling back opcode additions,
-  // therefore we treat any failure here as fatal.
-  //
   for (Index = 0; Index < S3Context->Used; ++Index) {
     CONST CONDENSED_WRITE_POINTER *Condensed;
+    RETURN_STATUS                 Status;
 
     Condensed = &S3Context->WritePointers[Index];
 
-    //
-    // (1) restore an FW_CFG_DMA_ACCESS object in reserved memory that selects
-    //     the writeable fw_cfg file PointerFile (through PointerItem), and
-    //     skips to PointerOffset in it,
-    //
-    Access->Control = SwapBytes32 ((UINT32)Condensed->PointerItem << 16 |
-                        FW_CFG_DMA_CTL_SELECT | FW_CFG_DMA_CTL_SKIP);
-    Access->Length = SwapBytes32 (Condensed->PointerOffset);
-    Access->Address = 0;
-    Status = S3SaveState->Write (
-                            S3SaveState,                      // This
-                            EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode
-                            EfiBootScriptWidthUint8,          // Width
-                            (UINT64)(UINTN)Access,            // Address
-                            sizeof *Access,                   // Count
-                            Access                            // Buffer
-                            );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a: Index %Lu opcode 1: %r\n", __FUNCTION__,
-        (UINT64)Index, Status));
+    Status = QemuFwCfgS3ScriptSkipBytes (Condensed->PointerItem,
+               Condensed->PointerOffset);
+    if (RETURN_ERROR (Status)) {
       goto FatalError;
     }
 
-    //
-    // (2) call QEMU with the FW_CFG_DMA_ACCESS object,
-    //
-    Status = S3SaveState->Write (
-                            S3SaveState,                     // This
-                            EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
-                            EfiBootScriptWidthUint32,        // Width
-                            (UINT64)FW_CFG_IO_DMA_ADDRESS,   // Address
-                            (UINTN)2,                        // Count
-                            &BigEndianAddressOfAccess        // Buffer
-                            );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a: Index %Lu opcode 2: %r\n", __FUNCTION__,
-        (UINT64)Index, Status));
-      goto FatalError;
-    }
-
-    //
-    // (3) wait for the select+skip to finish,
-    //
-    Status = S3SaveState->Write (
-                            S3SaveState,                     // This
-                            EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode
-                            EfiBootScriptWidthUint32,        // Width
-                            (UINT64)(UINTN)&Access->Control, // Address
-                            &ControlPollData,                // Data
-                            &ControlPollMask,                // DataMask
-                            MAX_UINT64                       // Delay
-                            );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a: Index %Lu opcode 3: %r\n", __FUNCTION__,
-        (UINT64)Index, Status));
-      goto FatalError;
-    }
-
-    //
-    // (4) restore a SCRATCH_BUFFER object in reserved memory that writes
-    //     PointerValue (base address of the allocated / downloaded
-    //     PointeeFile, plus PointeeOffset), of size PointerSize, into the
-    //     fw_cfg file selected in (1), at the offset sought to in (1),
-    //
-    Access->Control = SwapBytes32 (FW_CFG_DMA_CTL_WRITE);
-    Access->Length = SwapBytes32 (Condensed->PointerSize);
-    Access->Address = SwapBytes64 ((UINTN)&ScratchBuffer->PointerValue);
     ScratchBuffer->PointerValue = Condensed->PointerValue;
-    Status = S3SaveState->Write (
-                            S3SaveState,                      // This
-                            EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode
-                            EfiBootScriptWidthUint8,          // Width
-                            (UINT64)(UINTN)ScratchBuffer,     // Address
-                            sizeof *ScratchBuffer,            // Count
-                            ScratchBuffer                     // Buffer
-                            );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a: Index %Lu opcode 4: %r\n", __FUNCTION__,
-        (UINT64)Index, Status));
-      goto FatalError;
-    }
-
-    //
-    // (5) call QEMU with the FW_CFG_DMA_ACCESS object,
-    //
-    Status = S3SaveState->Write (
-                            S3SaveState,                     // This
-                            EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode
-                            EfiBootScriptWidthUint32,        // Width
-                            (UINT64)FW_CFG_IO_DMA_ADDRESS,   // Address
-                            (UINTN)2,                        // Count
-                            &BigEndianAddressOfAccess        // Buffer
-                            );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a: Index %Lu opcode 5: %r\n", __FUNCTION__,
-        (UINT64)Index, Status));
-      goto FatalError;
-    }
-
-    //
-    // (6) wait for the write to finish.
-    //
-    Status = S3SaveState->Write (
-                            S3SaveState,                     // This
-                            EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode
-                            EfiBootScriptWidthUint32,        // Width
-                            (UINT64)(UINTN)&Access->Control, // Address
-                            &ControlPollData,                // Data
-                            &ControlPollMask,                // DataMask
-                            MAX_UINT64                       // Delay
-                            );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a: Index %Lu opcode 6: %r\n", __FUNCTION__,
-        (UINT64)Index, Status));
+    Status = QemuFwCfgS3ScriptWriteBytes (-1, Condensed->PointerSize);
+    if (RETURN_ERROR (Status)) {
       goto FatalError;
     }
   }
 
-  DEBUG ((DEBUG_VERBOSE, "%a: boot script fragment saved, ScratchBuffer=%p\n",
-    __FUNCTION__, (VOID *)ScratchBuffer));
-  return EFI_SUCCESS;
+  DEBUG ((DEBUG_VERBOSE, "%a: boot script fragment saved\n", __FUNCTION__));
+
+  ReleaseS3Context (S3Context);
+  return;
 
 FatalError:
   ASSERT (FALSE);
   CpuDeadLoop ();
-  return Status;
+}
+
+
+/**
+  Translate and append the information from an S3_CONTEXT object to the ACPI S3
+  Boot Script.
+
+  The effects of a successful call to this function cannot be undone.
+
+  @param[in] S3Context  The S3_CONTEXT object to translate to ACPI S3 Boot
+                        Script opcodes. If the function returns successfully,
+                        the caller must set the S3Context pointer -- originally
+                        returned by AllocateS3Context() -- immediately to NULL,
+                        because the ownership of S3Context has been transfered.
+
+  @retval EFI_SUCCESS The translation of S3Context to ACPI S3 Boot Script
+                      opcodes has been successfully executed or queued.
+
+  @return             Error codes from underlying functions.
+**/
+EFI_STATUS
+TransferS3ContextToBootScript (
+  IN S3_CONTEXT *S3Context
+  )
+{
+  RETURN_STATUS Status;
+
+  Status = QemuFwCfgS3CallWhenBootScriptReady (AppendFwCfgBootScript,
+             S3Context, sizeof (SCRATCH_BUFFER));
+  return (EFI_STATUS)Status;
 }
diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
index 76512534f5e0..7bb2e3f21821 100644
--- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
+++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
@@ -848,6 +848,13 @@ InstallQemuFwCfgTables (
   //
   if (S3Context != NULL) {
     Status = TransferS3ContextToBootScript (S3Context);
+    if (EFI_ERROR (Status)) {
+      goto UninstallAcpiTables;
+    }
+    //
+    // Ownership of S3Context has been transfered.
+    //
+    S3Context = NULL;
   }
 
 UninstallAcpiTables:
-- 
2.9.3



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib
  2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
                   ` (11 preceding siblings ...)
  2017-03-11  6:26 ` [PATCH v2 12/12] OvmfPkg/AcpiPlatformDxe: " Laszlo Ersek
@ 2017-03-14 18:14 ` Jordan Justen
  2017-03-14 20:56   ` Laszlo Ersek
  12 siblings, 1 reply; 15+ messages in thread
From: Jordan Justen @ 2017-03-14 18:14 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel-01; +Cc: Ard Biesheuvel

Series Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

On 2017-03-10 22:26:39, Laszlo Ersek wrote:
> This is version 2 of the series posted at
> <https://lists.01.org/pipermail/edk2-devel/2017-February/007690.html>.
> 
> Changes in this version:
> - pick up v1 R-b's from Jordan and Ard (patches 1-6)
> - rename QemuFwCfgS3TransferOwnership to
>   QemuFwCfgS3CallWhenBootScriptReady [Jordan]
> - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
>   FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
> - rename "Append" to "Callback" and "mAppend" to "mCallback" [Laszlo]
> - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
>   QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
>   QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
>   QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
>   respectively [Jordan]
> 
> Changes are noted per patch too.
> 
> Rebuilt at every stage and retested (like in v1).
> 
> Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=394
> Repo:     https://github.com/lersek/edk2.git
> Branch:   fw_cfg_s3_v2
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> 
> Thanks
> Laszlo
> 
> Laszlo Ersek (12):
>   OvmfPkg: introduce QemuFwCfgS3Lib class
>   OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance
>   OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library
>     instances
>   ArmVirtPkg: resolve QemuFwCfgS3Lib
>   OvmfPkg: resolve QemuFwCfgS3Lib
>   ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib
>   OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to
>     libclass
>   OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance
>   OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance
>   OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE fw_cfg instance
>   OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib
>   OvmfPkg/AcpiPlatformDxe: save fw_cfg boot script with QemuFwCfgS3Lib
> 
>  ArmVirtPkg/ArmVirtQemu.dsc                                        |   1 +
>  ArmVirtPkg/ArmVirtQemuKernel.dsc                                  |   1 +
>  ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                    |  17 -
>  OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h                            |   2 +-
>  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf                       |   2 +-
>  OvmfPkg/AcpiPlatformDxe/BootScript.c                              | 262 ++-----
>  OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c                           |   8 +
>  OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf              |   2 +-
>  OvmfPkg/Include/Library/QemuFwCfgLib.h                            |  14 -
>  OvmfPkg/Include/Library/QemuFwCfgS3Lib.h                          | 361 +++++++++
>  OvmfPkg/Library/LockBoxLib/LockBoxDxe.c                           |   1 +
>  OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf                      |   1 +
>  OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h              |   1 +
>  OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   1 +
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                       |  28 -
>  OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf         |  43 ++
>  OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf         |  46 ++
>  OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf         |  44 ++
>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c                  | 110 +++
>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c               | 227 ++++++
>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c                   | 792 ++++++++++++++++++++
>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c                   |  86 +++
>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c                |  48 ++
>  OvmfPkg/OvmfPkg.dec                                               |   4 +
>  OvmfPkg/OvmfPkgIa32.dsc                                           |   3 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                                        |   3 +
>  OvmfPkg/OvmfPkgX64.dsc                                            |   3 +
>  OvmfPkg/PlatformPei/Platform.c                                    |   1 +
>  OvmfPkg/PlatformPei/PlatformPei.inf                               |   1 +
>  OvmfPkg/SmmControl2Dxe/SmiFeatures.c                              | 224 ++----
>  OvmfPkg/SmmControl2Dxe/SmiFeatures.h                              |   5 +-
>  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c                           |   6 +-
>  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf                         |   1 +
>  33 files changed, 1924 insertions(+), 425 deletions(-)
>  create mode 100644 OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c
>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
> 
> -- 
> 2.9.3
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib
  2017-03-14 18:14 ` [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Jordan Justen
@ 2017-03-14 20:56   ` Laszlo Ersek
  0 siblings, 0 replies; 15+ messages in thread
From: Laszlo Ersek @ 2017-03-14 20:56 UTC (permalink / raw)
  To: Jordan Justen, edk2-devel-01; +Cc: Ard Biesheuvel

On 03/14/17 19:14, Jordan Justen wrote:
> Series Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

Thank you, pushed as 6ac97ad31edb..805762252733.

The next series that I'll post will comply with the updated multi-line
function call syntax, codified in
<https://bugzilla.tianocore.org/show_bug.cgi?id=425>.

Thanks
Laszlo

> On 2017-03-10 22:26:39, Laszlo Ersek wrote:
>> This is version 2 of the series posted at
>> <https://lists.01.org/pipermail/edk2-devel/2017-February/007690.html>.
>>
>> Changes in this version:
>> - pick up v1 R-b's from Jordan and Ard (patches 1-6)
>> - rename QemuFwCfgS3TransferOwnership to
>>   QemuFwCfgS3CallWhenBootScriptReady [Jordan]
>> - rename FW_CFG_BOOT_SCRIPT_APPEND_FUNCTION to
>>   FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION [Jordan]
>> - rename "Append" to "Callback" and "mAppend" to "mCallback" [Laszlo]
>> - rename QemuFwCfgS3WriteBytes, QemuFwCfgS3ReadBytes,
>>   QemuFwCfgS3SkipBytes, and QemuFwCfgS3CheckValue to
>>   QemuFwCfgS3ScriptWriteBytes, QemuFwCfgS3ScriptReadBytes,
>>   QemuFwCfgS3ScriptSkipBytes, and QemuFwCfgS3ScriptCheckValue,
>>   respectively [Jordan]
>>
>> Changes are noted per patch too.
>>
>> Rebuilt at every stage and retested (like in v1).
>>
>> Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=394
>> Repo:     https://github.com/lersek/edk2.git
>> Branch:   fw_cfg_s3_v2
>>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>
>> Thanks
>> Laszlo
>>
>> Laszlo Ersek (12):
>>   OvmfPkg: introduce QemuFwCfgS3Lib class
>>   OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance
>>   OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library
>>     instances
>>   ArmVirtPkg: resolve QemuFwCfgS3Lib
>>   OvmfPkg: resolve QemuFwCfgS3Lib
>>   ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib
>>   OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to
>>     libclass
>>   OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance
>>   OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance
>>   OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE fw_cfg instance
>>   OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib
>>   OvmfPkg/AcpiPlatformDxe: save fw_cfg boot script with QemuFwCfgS3Lib
>>
>>  ArmVirtPkg/ArmVirtQemu.dsc                                        |   1 +
>>  ArmVirtPkg/ArmVirtQemuKernel.dsc                                  |   1 +
>>  ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                    |  17 -
>>  OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h                            |   2 +-
>>  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf                       |   2 +-
>>  OvmfPkg/AcpiPlatformDxe/BootScript.c                              | 262 ++-----
>>  OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c                           |   8 +
>>  OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf              |   2 +-
>>  OvmfPkg/Include/Library/QemuFwCfgLib.h                            |  14 -
>>  OvmfPkg/Include/Library/QemuFwCfgS3Lib.h                          | 361 +++++++++
>>  OvmfPkg/Library/LockBoxLib/LockBoxDxe.c                           |   1 +
>>  OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf                      |   1 +
>>  OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h              |   1 +
>>  OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   1 +
>>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c                       |  28 -
>>  OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf         |  43 ++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf         |  46 ++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf         |  44 ++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c                  | 110 +++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c               | 227 ++++++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c                   | 792 ++++++++++++++++++++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c                   |  86 +++
>>  OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c                |  48 ++
>>  OvmfPkg/OvmfPkg.dec                                               |   4 +
>>  OvmfPkg/OvmfPkgIa32.dsc                                           |   3 +
>>  OvmfPkg/OvmfPkgIa32X64.dsc                                        |   3 +
>>  OvmfPkg/OvmfPkgX64.dsc                                            |   3 +
>>  OvmfPkg/PlatformPei/Platform.c                                    |   1 +
>>  OvmfPkg/PlatformPei/PlatformPei.inf                               |   1 +
>>  OvmfPkg/SmmControl2Dxe/SmiFeatures.c                              | 224 ++----
>>  OvmfPkg/SmmControl2Dxe/SmiFeatures.h                              |   5 +-
>>  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.c                           |   6 +-
>>  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf                         |   1 +
>>  33 files changed, 1924 insertions(+), 425 deletions(-)
>>  create mode 100644 OvmfPkg/Include/Library/QemuFwCfgS3Lib.h
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c
>>  create mode 100644 OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
>>
>> -- 
>> 2.9.3
>>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-03-14 20:56 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-11  6:26 [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 01/12] OvmfPkg: introduce QemuFwCfgS3Lib class Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 02/12] OvmfPkg/QemuFwCfgS3Lib: add initial Base Null library instance Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 03/12] OvmfPkg/QemuFwCfgS3Lib: add initial PEI and DXE fw_cfg library instances Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 04/12] ArmVirtPkg: resolve QemuFwCfgS3Lib Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 05/12] OvmfPkg: " Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 06/12] ArmVirtPkg, OvmfPkg: retire QemuFwCfgS3Enabled() from QemuFwCfgLib Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 07/12] OvmfPkg/QemuFwCfgS3Lib: add boot script opcode generation APIs to libclass Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 08/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for Base Null instance Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 09/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for PEI fw_cfg instance Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 10/12] OvmfPkg/QemuFwCfgS3Lib: implement opcode APIs for DXE " Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 11/12] OvmfPkg/SmmControl2Dxe: save fw_cfg boot script with QemuFwCfgS3Lib Laszlo Ersek
2017-03-11  6:26 ` [PATCH v2 12/12] OvmfPkg/AcpiPlatformDxe: " Laszlo Ersek
2017-03-14 18:14 ` [PATCH v2 00/12] ArmVirtPkg, OvmfPkg: factor out QemuFwCfgS3Lib Jordan Justen
2017-03-14 20:56   ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox