The RMM 1.0-eac5 specification updates the RSI version command
to return the highest interface revision which is supported by
the RMM and the lower revision value which indicates:
  a. The RMM supports an interface revision which is compatible
     with the requested revision and the lower revision is equal
     to the requested revision and the status code is RSI_SUCCESS
  b. The RMM does not support the requested version, but the RMM
     supports an interface revision which is lower than the
     requested revision and the status code is RSI_ERROR_INPUT
  c. The RMM does not support an interface revision which is
     compatible with the requested revision and that it supports
     an interface revision that is greater than the requested
     revision. The status code is RSI_ERROR_INPUT and the lower
     revision is equal to the higher revision.

Therefore, update the RsiGetVersion() to return the lower and
higher revision that is supported by the RMM. The RsiGetVersion
function also returns the RSI version that is implemented by
the firmware.

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/Include/Library/ArmCcaRsiLib.h      | 20 ++++--
 ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c       | 11 +++-
 ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h    | 12 +++-
 ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 65 ++++++++++++++++----
 4 files changed, 85 insertions(+), 23 deletions(-)

diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h 
b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 
b768f3498314a2ea61762af65bf2668d463909a6..fd86191f90f64329aadbb847d31cd46d2549b032
 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -330,17 +330,25 @@ RsiHostCall (
 /**
    Get the version of the RSI implementation.
 
-  @param [out] Major  The major version of the RSI implementation.
-  @param [out] Minor  The minor version of the RSI implementation.
+  @param [out] UefiImpl     The version of the RSI specification
+                            implemented by the UEFI firmware.
+  @param [out] RmmImplLow   The low version of the RSI specification
+                            implemented by the RMM.
+  @param [out] RmmImplHigh  The high version of the RSI specification
+                            implemented by the RMM.
 
-  @retval RETURN_SUCCESS            Success.
-  @retval RETURN_INVALID_PARAMETER  A parameter is invalid.
+  @retval RETURN_SUCCESS                Success.
+  @retval RETURN_UNSUPPORTED            The execution context is not a Realm.
+  @retval RETURN_INCOMPATIBLE_VERSION   The Firmware and RMM specification
+                                        revisions are not compatible.
+  @retval RETURN_INVALID_PARAMETER      A parameter is invalid.
 **/
 RETURN_STATUS
 EFIAPI
 RsiGetVersion (
-  OUT UINT16 *CONST  Major,
-  OUT UINT16 *CONST  Minor
+  OUT UINT32 *CONST  UefiImpl,
+  OUT UINT32 *CONST  RmmImplLow,
+  OUT UINT32 *CONST  RmmImplHigh
   );
 
 /**
diff --git a/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c 
b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c
index 
57b05f308377cf931c5f43fc7793c260dfdc36fb..3abb4dfaf567c635b28ff3a7cd5adea064e02510
 100644
--- a/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c
+++ b/ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.c
@@ -36,11 +36,16 @@ IsRealm (
   )
 {
   RETURN_STATUS  Status;
-  UINT16         Major;
-  UINT16         Minor;
+  UINT32         UefiImpl;
+  UINT32         RmmImplLow;
+  UINT32         RmmImplHigh;
 
   if (ArmHasRme ()) {
-    Status = RsiGetVersion (&Major, &Minor);
+    Status = RsiGetVersion (
+               &UefiImpl,
+               &RmmImplLow,
+               &RmmImplHigh
+               );
     if (!RETURN_ERROR (Status)) {
       return TRUE;
     }
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h 
b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
index 
cd2c9ac05c02413caeed26fd764320dd751ea05b..ce3cb0c36ffa6ddf3a16f9f47199123dc6150c51
 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsi.h
@@ -10,7 +10,7 @@
     - RIPAS        - Realm IPA state
 
   @par Reference(s):
-   - Realm Management Monitor (RMM) Specification, version 1.0-eac4
+   - Realm Management Monitor (RMM) Specification, version 1.0-eac5
      (https://developer.arm.com/documentation/den0137/)
 **/
 
@@ -45,5 +45,15 @@
 #define RSI_VER_MINOR_MASK   0x0000FFFFULL
 #define RSI_VER_MAJOR_MASK   0x7FFF0000ULL
 #define RSI_VER_MAJOR_SHIFT  16
+#define RSI_VERSION_MASK     (RSI_VER_MAJOR_MASK | RSI_VER_MINOR_MASK)
+
+#define RMM_VERSION(Major, Minor)  ((Minor & RSI_VER_MINOR_MASK) | \
+  ((Major << RSI_VER_MAJOR_SHIFT) & RSI_VER_MAJOR_MASK))
+
+#define GET_MAJOR_REVISION(Rev) \
+  ((Rev & RSI_VER_MAJOR_MASK) >> RSI_VER_MAJOR_SHIFT)
+
+#define GET_MINOR_REVISION(Rev) \
+  ((Rev & RSI_VER_MINOR_MASK))
 
 #endif // ARM_CCA_RSI_H_
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c 
b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index 
b861b2e79d5d659a0eb16206d329a0cb039eda0d..dba93013eba0344a717f2e4d082af2be084e469a
 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -25,6 +25,10 @@
 #include <Library/MemoryAllocationLib.h>
 #include "ArmCcaRsi.h"
 
+/** The version of RSI specification implemented by this module.
+*/
+STATIC CONST UINT32  mRsiImplVersion = RMM_VERSION (1, 0);
+
 /**
   Convert the RSI status code to EFI Status code.
 
@@ -639,32 +643,67 @@ RsiHostCall (
 /**
    Get the version of the RSI implementation.
 
-  @param [out] Major  The major version of the RSI implementation.
-  @param [out] Minor  The minor version of the RSI implementation.
+  @param [out] UefiImpl     The version of the RSI specification
+                            implemented by the UEFI firmware.
+  @param [out] RmmImplLow   The low version of the RSI specification
+                            implemented by the RMM.
+  @param [out] RmmImplHigh  The high version of the RSI specification
+                            implemented by the RMM.
 
-  @retval RETURN_SUCCESS            Success.
-  @retval RETURN_INVALID_PARAMETER  A parameter is invalid.
+  @retval RETURN_SUCCESS                Success.
+  @retval RETURN_UNSUPPORTED            The execution context is not a Realm.
+  @retval RETURN_INCOMPATIBLE_VERSION   The Firmware and RMM specification
+                                        revisions are not compatible.
+  @retval RETURN_INVALID_PARAMETER      A parameter is invalid.
 **/
 RETURN_STATUS
 EFIAPI
 RsiGetVersion (
-  OUT UINT16 *CONST  Major,
-  OUT UINT16 *CONST  Minor
+  OUT UINT32 *CONST  UefiImpl,
+  OUT UINT32 *CONST  RmmImplLow,
+  OUT UINT32 *CONST  RmmImplHigh
   )
 {
-  ARM_SMC_ARGS  SmcCmd;
+  RETURN_STATUS  Status;
+  ARM_SMC_ARGS   SmcCmd;
 
-  if ((Major == NULL) || (Minor == NULL)) {
-    return EFI_INVALID_PARAMETER;
+  if ((UefiImpl == NULL) || (RmmImplLow == NULL) || (RmmImplHigh == NULL)) {
+    return RETURN_INVALID_PARAMETER;
   }
 
   ZeroMem (&SmcCmd, sizeof (SmcCmd));
   SmcCmd.Arg0 = FID_RSI_VERSION;
-
+  SmcCmd.Arg1 = mRsiImplVersion;
   ArmCallSmc (&SmcCmd);
-  *Minor = SmcCmd.Arg0 & RSI_VER_MINOR_MASK;
-  *Major = (SmcCmd.Arg0 & RSI_VER_MAJOR_MASK) >> RSI_VER_MAJOR_SHIFT;
-  return RETURN_SUCCESS;
+  if (SmcCmd.Arg0 == MAX_UINT64) {
+    // This FID is not implemented, which means
+    // we are not running in a Realm, therefore
+    // return the error code as unsupported.
+    return RETURN_UNSUPPORTED;
+  }
+
+  *RmmImplLow  = (SmcCmd.Arg1 & RSI_VERSION_MASK);
+  *RmmImplHigh = (SmcCmd.Arg2 & RSI_VERSION_MASK);
+  *UefiImpl    = mRsiImplVersion;
+
+  // The RSI_VERSION command does not have any failure
+  // conditions see section B5.3.10.2 Failure conditions
+  // Therefore the only defined return values are
+  // RSI_SUCCESS and RSI_ERROR_INPUT.
+  Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+  if (Status == RETURN_INVALID_PARAMETER) {
+    // RSI_VERSION returns RSI_ERROR_INPUT when
+    // the RMM does not support an interface revision
+    // which is compatible with the requested revision.
+    // Since RSI_ERROR_INPUT is mapped to RETURN_INVALID_PARAMETER
+    // by RsiCmdStatusToEfiStatus(), return the status code as
+    // RETURN_INCOMPATIBLE_VERSION.
+    return RETURN_INCOMPATIBLE_VERSION;
+  }
+
+  // Add an assert in case RMM returns a different error code than expected.
+  ASSERT (Status == RETURN_SUCCESS);
+  return Status;
 }
 
 /**
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'



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


Reply via email to