ArmMonitorLib provides an abstraction for invoking monitor calls
using a SMC or HVC conduit based on the value configured in the
PCD PcdMonitorConduitHvc.

The monitor call conduit is fixed for a platform firmware in
most scenarios. For a normal virtual machine guest firmware,
the default conduit is HVC. However, for Arm CCA the Realm
code must use SMC as the conduit.

To have a common code base for Guest/Virtual firmware to be used
by both normal VMs and Realm VMs, the firmware must dynamically
detect the conduit to be used.

Some VMMs like kvmtool setup the PSCI conduit to be used in the
device tree it hands off to the firmware. Therefore, introduce
an ArmVirt instance of ArmMontorLib that parses this device tree
to read the PSCI conduit value and issues monitor calls using
the appropriate conduit.

Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org>
Cc: Leif Lindholm <quic_llind...@quicinc.com>
Cc: Gerd Hoffmann <kra...@redhat.com>
Signed-off-by: Sami Mujawar <sami.muja...@arm.com>
---
 ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c   | 119 
++++++++++++++++++++
 ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf |  37 ++++++
 2 files changed, 156 insertions(+)

diff --git a/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c 
b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c
new file mode 100644
index 
0000000000000000000000000000000000000000..a13bec36b3537a2348e7883c29c5beb6e55dc64b
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.c
@@ -0,0 +1,119 @@
+/** @file
+  Arm Monitor Library.
+
+  Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/ArmHvcLib.h>
+#include <Library/ArmMonitorLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/FdtClient.h>
+
+/**
+  An enum representing the PSCI conduits for issuing monitor calls.
+*/
+typedef enum PsciConduit {
+  PsciConduitHvc,   // < HVC conduit
+  PsciConduitSmc,   // < SMC conduit
+  PsciConduitMax
+} PSCI_CONDUIT;
+
+/**
+  A variable that stores the PSCI conduit to be used.
+*/
+STATIC PSCI_CONDUIT  mArmPsciConduit = PsciConduitMax;
+
+/** Monitor call.
+
+  An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
+  depending on the conduit. The library constructor for ArmVirtMonitorLib
+  determines the conduit by parsing the Device Tree handed off by the VMM
+  and initialising mArmPsciConduit.
+
+  @param [in,out]  Args    Arguments for the HVC/SMC.
+**/
+VOID
+EFIAPI
+ArmMonitorCall (
+  IN OUT ARM_MONITOR_ARGS  *Args
+  )
+{
+  switch (mArmPsciConduit) {
+    case PsciConduitHvc:
+      ArmCallHvc ((ARM_HVC_ARGS *)Args);
+      break;
+    case PsciConduitSmc:
+      ArmCallSmc ((ARM_SMC_ARGS *)Args);
+      break;
+    default:
+      ASSERT (0);
+      CpuDeadLoop ();
+  }
+}
+
+/** Constructor for ArmVirtMonitorLib.
+
+  The library constructor for ArmVirtMonitorLib determines the conduit
+  by parsing the Device Tree handed off by the VMM and initialising
+  mArmPsciConduit, which can then be used to select the appropriate
+  conduit for invoking the monitor call.
+
+  @retval RETURN_SUCCESS    The constructor always returns RETURN_SUCCESS.
+  @retval RETURN_NOT_FOUND  An entry for the PSCI conduit was not found in
+                            the platform device tree.
+**/
+RETURN_STATUS
+EFIAPI
+ArmVirtMonitorLibConstructor (
+  VOID
+  )
+{
+  RETURN_STATUS        Status;
+  FDT_CLIENT_PROTOCOL  *FdtClient;
+  CONST VOID           *Prop;
+
+  Status = gBS->LocateProtocol (
+                  &gFdtClientProtocolGuid,
+                  NULL,
+                  (VOID **)&FdtClient
+                  );
+  if (RETURN_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  Status = FdtClient->FindCompatibleNodeProperty (
+                        FdtClient,
+                        "arm,psci-0.2",
+                        "method",
+                        &Prop,
+                        NULL
+                        );
+  if (RETURN_ERROR (Status)) {
+    return Status;
+  }
+
+  if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
+    mArmPsciConduit = PsciConduitHvc;
+  } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
+    mArmPsciConduit = PsciConduitSmc;
+  } else {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Unknown PSCI method \"%a\"\n",
+      __func__,
+      Prop
+      ));
+    return RETURN_NOT_FOUND;
+  }
+
+  return RETURN_SUCCESS;
+}
diff --git a/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf 
b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
new file mode 100644
index 
0000000000000000000000000000000000000000..d90f92d5faff96de9cd0433c1de18b0168b42592
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
@@ -0,0 +1,37 @@
+## @file
+#  Arm Virt Monitor Library
+#
+#  Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = ArmVirtMonitorLib
+  FILE_GUID                      = 3E464134-890D-4C3F-A559-D0FE2803E332
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmMonitorLib|DXE_DRIVER DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = ArmVirtMonitorLibConstructor
+
+[Sources]
+  ArmVirtMonitorLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmHvcLib
+  ArmSmcLib
+  DebugLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gFdtClientProtocolGuid                                ## CONSUMES
+
+[Depex]
+  gFdtClientProtocolGuid
+
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117678): https://edk2.groups.io/g/devel/message/117678
Mute This Topic: https://groups.io/mt/105483416/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to