From 9276e0d2b9847705c5fceda290641ddff7a79524 Mon Sep 17 00:00:00 2001
From: Michael Kubacki <michael.kubacki@microsoft.com>
Date: Tue, 7 Apr 2020 11:28:36 -0700
Subject: [PATCH] PrmPkg: Add initial PrmSamplePrintModule

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812

Adds a simple sample PRM module that demonstrates:
  1. How to write a PRM module
  2. How to use multiple PRM handlers in a module
  3. How to use a basic PRM OS service

Cc: Andrew Fish <afish@apple.com>
Cc: Kang Gao <kang.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Liu Yun <yun.y.liu@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Acked-by: Michael D Kinney <michael.d.kinney@intel.com>
Acked-by: Liming Gao <gaoliming@byosoft.com.cn>
Acked-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Ankit Sinha <ankit.sinha@intel.com>
---
 .../PrmSamplePrintModule.c                    | 157 ++++++++++++++++++
 .../PrmSamplePrintModule.inf                  |  39 +++++
 2 files changed, 196 insertions(+)
 create mode 100644 PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
 create mode 100644 PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf

diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
new file mode 100644
index 0000000000..85e8eb28a2
--- /dev/null
+++ b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
@@ -0,0 +1,157 @@
+/** @file
+
+  A sample PRM Module implementation. This PRM Module provides 3 PRM handlers that simply take a DEBUG print
+  function from the OS and invoke it with a debug message internal the PRM handler.
+
+  Copyright (c) Microsoft Corporation
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PrmModule.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+
+//
+// PRM Handler GUIDs
+//
+
+// {d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8}
+#define PRM_HANDLER_1_GUID {0xd5f2ad5f, 0xa347, 0x4d3e, {0x87, 0xbc, 0xc2, 0xce, 0x63, 0x02, 0x9c, 0xc8}}
+
+// {a9e7adc3-8cd0-429a-8915-10946ebde318}
+#define PRM_HANDLER_2_GUID  {0xa9e7adc3, 0x8cd0, 0x429a, {0x89, 0x15, 0x10, 0x94, 0x6e, 0xbd, 0xe3, 0x18}}
+
+// {b688c214-4081-4eeb-8d26-1eb5a3bcf11a}
+#define PRM_HANDLER_N_GUID {0xb688c214, 0x4081, 0x4eeb, {0x8d, 0x26, 0x1e, 0xb5, 0xa3, 0xbc, 0xf1, 0x1a}}
+
+/**
+  A sample Platform Runtime Mechanism (PRM) handler.
+
+  This sample handler currently uses the OS_SERVICES to write a debug message
+  indicating this is PRM handler 1.
+
+  @param[in]  ParameterBuffer     A pointer to the PRM handler parameter buffer
+  @param[in]  ContextBUffer       A pointer to the PRM handler context buffer
+
+  @retval EFI_STATUS              The PRM handler executed successfully.
+  @retval Others                  An error occurred in the PRM handler.
+
+**/
+EFI_STATUS
+PRM_EXPORT_API
+EFIAPI
+PrmHandler1 (
+  IN VOID                         *ParameterBuffer,
+  IN PRM_CONTEXT_BUFFER           *ContextBUffer
+  )
+{
+  PRM_OS_SERVICE_DEBUG_PRINT      OsServiceDebugPrint;
+
+  if (ParameterBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+  OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+  if (OsServiceDebugPrint == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  OsServiceDebugPrint ("PRM1 handler sample message!\n");
+
+  return EFI_SUCCESS;
+}
+
+/**
+  A sample Platform Runtime Mechanism (PRM) handler.
+
+  This sample handler currently uses the OS_SERVICES to write a debug message
+  indicating this is PRM handler 2.
+
+  @param[in]  ParameterBuffer    A pointer to the PRM handler parameter buffer
+  @param[in]  ContextBUffer      A pointer to the PRM handler context buffer
+
+  @retval EFI_STATUS             The PRM handler executed successfully.
+  @retval Others                 An error occurred in the PRM handler.
+
+**/
+EFI_STATUS
+PRM_EXPORT_API
+EFIAPI
+PrmHandler2 (
+  IN VOID                         *ParameterBuffer,
+  IN PRM_CONTEXT_BUFFER           *ContextBUffer
+  )
+{
+  PRM_OS_SERVICE_DEBUG_PRINT      OsServiceDebugPrint;
+
+  if (ParameterBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+  OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+  if (OsServiceDebugPrint == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  OsServiceDebugPrint ("PRM2 handler sample message!\n");
+
+  return EFI_SUCCESS;
+}
+
+/**
+  A sample Platform Runtime Mechanism (PRM) handler.
+
+  This sample handler currently uses the OS_SERVICES to write a debug message
+  indicating this is PRM handler N.
+
+  @param[in]  ParameterBuffer    A pointer to the PRM handler parameter buffer
+  @param[in]  ContextBUffer      A pointer to the PRM handler context buffer
+
+  @retval EFI_STATUS             The PRM handler executed successfully.
+  @retval Others                 An error occurred in the PRM handler.
+
+**/
+EFI_STATUS
+PRM_EXPORT_API
+EFIAPI
+PrmHandlerN (
+  IN VOID                         *ParameterBuffer,
+  IN PRM_CONTEXT_BUFFER           *ContextBUffer
+  )
+{
+  PRM_OS_SERVICE_DEBUG_PRINT      OsServiceDebugPrint;
+
+  if (ParameterBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+  OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+  if (OsServiceDebugPrint == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  OsServiceDebugPrint ("PRMN handler sample message!\n");
+
+  return EFI_SUCCESS;
+}
+
+//
+// Register the PRM export information for this PRM Module
+//
+PRM_MODULE_EXPORT (
+  PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1),
+  PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_2_GUID, PrmHandler2),
+  PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_N_GUID, PrmHandlerN)
+  );
+
+EFI_STATUS
+EFIAPI
+PrmSamplePrintModuleInit (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  EFI_SYSTEM_TABLE            *SystemTable
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
new file mode 100644
index 0000000000..d685bf888a
--- /dev/null
+++ b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
@@ -0,0 +1,39 @@
+## @file
+#  Sample PRM Driver
+#
+#  This driver simply uses an OS-provided debug message print service to write
+#  a debug message. Three PRM handlers are provided that each print a unique
+#  debug message.
+#
+#  Copyright (c) Microsoft Corporation
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PrmSamplePrintModule
+  FILE_GUID                      = 1652B3C2-A7A1-46AC-AF93-DD6DEE446669
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PrmSamplePrintModuleInit
+
+[Sources]
+  PrmSamplePrintModule.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Depex]
+  TRUE
+
+[BuildOptions.common]
+  MSFT:*_*_*_DLINK_FLAGS  = /DLL /SUBSYSTEM:CONSOLE