]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg: prepare 32bit ARM build of StandaloneMmPkg
authorEtienne Carriere <etienne.carriere@linaro.org>
Mon, 9 Aug 2021 15:19:43 +0000 (17:19 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 11 Aug 2021 11:32:32 +0000 (11:32 +0000)
Changes in ArmPkg to prepare building StandaloneMm firmware for
32bit Arm architectures.

Adds ArmmmuStandaloneMmLib library to the list of the standard
components build for ArmPkg on when ARM architectures.

Changes path of source file AArch64/ArmMmuStandaloneMmLib.c
and compile it for both 32bit and 64bit architectures.

Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
ArmPkg/ArmPkg.dec
ArmPkg/ArmPkg.dsc
ArmPkg/Library/StandaloneMmMmuLib/AArch64/ArmMmuStandaloneMmLib.c [deleted file]
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c [new file with mode: 0644]
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf

index 214b2f5892174a19fdefec798bd37386c7766d4f..6ed51edd0340605639d4b34f77bdb59dca1827be 100644 (file)
   # hardware coherency (i.e., no virtualization or cache coherent DMA)\r
   gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043\r
 \r
-[PcdsFeatureFlag.AARCH64]\r
+[PcdsFeatureFlag.AARCH64, PcdsFeatureFlag.ARM]\r
   ## Used to select method for requesting services from S-EL1.<BR><BR>\r
   #   TRUE  - Selects FF-A calls for communication between S-EL0 and SPMC.<BR>\r
   #   FALSE - Selects SVC calls for communication between S-EL0 and SPMC.<BR>\r
index 926986cf7fbb938ac9abfb20332b6db355e74998..8abe3713c829cbe81842c52de6982e7cbef5c323 100644 (file)
 [Components.AARCH64]\r
   ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf\r
   ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf\r
+\r
+[Components.AARCH64, Components.ARM]\r
   ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf\r
diff --git a/ArmPkg/Library/StandaloneMmMmuLib/AArch64/ArmMmuStandaloneMmLib.c b/ArmPkg/Library/StandaloneMmMmuLib/AArch64/ArmMmuStandaloneMmLib.c
deleted file mode 100644 (file)
index dd014be..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/** @file\r
-  File managing the MMU for ARMv8 architecture in S-EL0\r
-\r
-  Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-  @par Reference(s):\r
-  - [1] SPM based on the MM interface.\r
-        (https://trustedfirmware-a.readthedocs.io/en/latest/components/\r
-         secure-partition-manager-mm.html)\r
-  - [2] Arm Firmware Framework for Armv8-A, DEN0077A, version 1.0\r
-        (https://developer.arm.com/documentation/den0077/a)\r
-**/\r
-\r
-#include <Uefi.h>\r
-#include <IndustryStandard/ArmMmSvc.h>\r
-#include <IndustryStandard/ArmFfaSvc.h>\r
-\r
-#include <Library/ArmLib.h>\r
-#include <Library/ArmMmuLib.h>\r
-#include <Library/ArmSvcLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-\r
-/** Send memory permission request to target.\r
-\r
-  @param [in, out]  SvcArgs     Pointer to SVC arguments to send. On\r
-                                return it contains the response parameters.\r
-  @param [out]      RetVal      Pointer to return the response value.\r
-\r
-  @retval EFI_SUCCESS           Request successfull.\r
-  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
-  @retval EFI_NOT_READY         Callee is busy or not in a state to handle\r
-                                this request.\r
-  @retval EFI_UNSUPPORTED       This function is not implemented by the\r
-                                callee.\r
-  @retval EFI_ABORTED           Message target ran into an unexpected error\r
-                                and has aborted.\r
-  @retval EFI_ACCESS_DENIED     Access denied.\r
-  @retval EFI_OUT_OF_RESOURCES  Out of memory to perform operation.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-SendMemoryPermissionRequest (\r
-  IN OUT  ARM_SVC_ARGS *SvcArgs,\r
-     OUT  INT32        *RetVal\r
-  )\r
-{\r
-  if ((SvcArgs == NULL) || (RetVal == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  ArmCallSvc (SvcArgs);\r
-  if (FeaturePcdGet (PcdFfaEnable)) {\r
-    // Get/Set memory attributes is an atomic call, with\r
-    // StandaloneMm at S-EL0 being the caller and the SPM\r
-    // core being the callee. Thus there won't be a\r
-    // FFA_INTERRUPT or FFA_SUCCESS response to the Direct\r
-    // Request sent above. This will have to be considered\r
-    // for other Direct Request calls which are not atomic\r
-    // We therefore check only for Direct Response by the\r
-    // callee.\r
-    if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64) {\r
-      // A Direct Response means FF-A success\r
-      // Now check the payload for errors\r
-      // The callee sends back the return value\r
-      // in Arg3\r
-      *RetVal = SvcArgs->Arg3;\r
-    } else {\r
-      // If Arg0 is not a Direct Response, that means we\r
-      // have an FF-A error. We need to check Arg2 for the\r
-      // FF-A error code.\r
-      // See [2], Table 10.8: FFA_ERROR encoding.\r
-      *RetVal = SvcArgs->Arg2;\r
-      switch (*RetVal) {\r
-        case ARM_FFA_SPM_RET_INVALID_PARAMETERS:\r
-          return EFI_INVALID_PARAMETER;\r
-\r
-        case ARM_FFA_SPM_RET_DENIED:\r
-          return EFI_ACCESS_DENIED;\r
-\r
-        case ARM_FFA_SPM_RET_NOT_SUPPORTED:\r
-          return EFI_UNSUPPORTED;\r
-\r
-        case ARM_FFA_SPM_RET_BUSY:\r
-          return EFI_NOT_READY;\r
-\r
-        case ARM_FFA_SPM_RET_ABORTED:\r
-          return EFI_ABORTED;\r
-\r
-        default:\r
-          // Undefined error code received.\r
-          ASSERT (0);\r
-          return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  } else {\r
-    *RetVal = SvcArgs->Arg0;\r
-  }\r
-\r
-  // Check error response from Callee.\r
-  if ((*RetVal & BIT31) != 0) {\r
-    // Bit 31 set means there is an error returned\r
-    // See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 and\r
-    // Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.\r
-    switch (*RetVal) {\r
-      case ARM_SVC_SPM_RET_NOT_SUPPORTED:\r
-        return EFI_UNSUPPORTED;\r
-\r
-      case ARM_SVC_SPM_RET_INVALID_PARAMS:\r
-        return EFI_INVALID_PARAMETER;\r
-\r
-      case ARM_SVC_SPM_RET_DENIED:\r
-        return EFI_ACCESS_DENIED;\r
-\r
-      case ARM_SVC_SPM_RET_NO_MEMORY:\r
-        return EFI_OUT_OF_RESOURCES;\r
-\r
-      default:\r
-        // Undefined error code received.\r
-        ASSERT (0);\r
-        return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/** Request the permission attributes of a memory region from S-EL0.\r
-\r
-  @param [in]   BaseAddress          Base address for the memory region.\r
-  @param [out]  MemoryAttributes     Pointer to return the memory attributes.\r
-\r
-  @retval EFI_SUCCESS             Request successfull.\r
-  @retval EFI_INVALID_PARAMETER   A parameter is invalid.\r
-  @retval EFI_NOT_READY           Callee is busy or not in a state to handle\r
-                                  this request.\r
-  @retval EFI_UNSUPPORTED         This function is not implemented by the\r
-                                  callee.\r
-  @retval EFI_ABORTED             Message target ran into an unexpected error\r
-                                  and has aborted.\r
-  @retval EFI_ACCESS_DENIED       Access denied.\r
-  @retval EFI_OUT_OF_RESOURCES    Out of memory to perform operation.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-GetMemoryPermissions (\r
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  OUT UINT32                    *MemoryAttributes\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  INT32         Ret;\r
-  ARM_SVC_ARGS  SvcArgs;\r
-\r
-  if (MemoryAttributes == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  // Prepare the message parameters.\r
-  // See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64.\r
-  ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));\r
-  if (FeaturePcdGet (PcdFfaEnable)) {\r
-    // See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.\r
-    SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;\r
-    SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;\r
-    SvcArgs.Arg2 = 0;\r
-    SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;\r
-    SvcArgs.Arg4 = BaseAddress;\r
-  } else {\r
-    SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;\r
-    SvcArgs.Arg1 = BaseAddress;\r
-    SvcArgs.Arg2 = 0;\r
-    SvcArgs.Arg3 = 0;\r
-  }\r
-\r
-  Status = SendMemoryPermissionRequest (&SvcArgs, &Ret);\r
-  if (EFI_ERROR (Status)) {\r
-    *MemoryAttributes = 0;\r
-    return Status;\r
-  }\r
-\r
-  *MemoryAttributes = Ret;\r
-  return Status;\r
-}\r
-\r
-/** Set the permission attributes of a memory region from S-EL0.\r
-\r
-  @param [in]  BaseAddress     Base address for the memory region.\r
-  @param [in]  Length          Length of the memory region.\r
-  @param [in]  Permissions     Memory access controls attributes.\r
-\r
-  @retval EFI_SUCCESS             Request successfull.\r
-  @retval EFI_INVALID_PARAMETER   A parameter is invalid.\r
-  @retval EFI_NOT_READY           Callee is busy or not in a state to handle\r
-                                  this request.\r
-  @retval EFI_UNSUPPORTED         This function is not implemented by the\r
-                                  callee.\r
-  @retval EFI_ABORTED             Message target ran into an unexpected error\r
-                                  and has aborted.\r
-  @retval EFI_ACCESS_DENIED       Access denied.\r
-  @retval EFI_OUT_OF_RESOURCES    Out of memory to perform operation.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-RequestMemoryPermissionChange (\r
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN  UINT64                    Length,\r
-  IN  UINT32                    Permissions\r
-  )\r
-{\r
-  INT32         Ret;\r
-  ARM_SVC_ARGS  SvcArgs;\r
-\r
-  // Prepare the message parameters.\r
-  // See [1], Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.\r
-  ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));\r
-  if (FeaturePcdGet (PcdFfaEnable)) {\r
-    // See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.\r
-    SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;\r
-    SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;\r
-    SvcArgs.Arg2 = 0;\r
-    SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;\r
-    SvcArgs.Arg4 = BaseAddress;\r
-    SvcArgs.Arg5 = EFI_SIZE_TO_PAGES (Length);\r
-    SvcArgs.Arg6 = Permissions;\r
-  } else {\r
-    SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;\r
-    SvcArgs.Arg1 = BaseAddress;\r
-    SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length);\r
-    SvcArgs.Arg3 = Permissions;\r
-  }\r
-\r
-  return SendMemoryPermissionRequest (&SvcArgs, &Ret);\r
-}\r
-\r
-EFI_STATUS\r
-ArmSetMemoryRegionNoExec (\r
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN  UINT64                    Length\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINT32 MemoryAttributes;\r
-  UINT32 CodePermission;\r
-\r
-  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
-  if (!EFI_ERROR (Status)) {\r
-    CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;\r
-    return RequestMemoryPermissionChange (\r
-             BaseAddress,\r
-             Length,\r
-             MemoryAttributes | CodePermission\r
-             );\r
-  }\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ArmClearMemoryRegionNoExec (\r
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN  UINT64                    Length\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINT32 MemoryAttributes;\r
-  UINT32 CodePermission;\r
-\r
-  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
-  if (!EFI_ERROR (Status)) {\r
-    CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;\r
-    return RequestMemoryPermissionChange (\r
-             BaseAddress,\r
-             Length,\r
-             MemoryAttributes & ~CodePermission\r
-             );\r
-  }\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ArmSetMemoryRegionReadOnly (\r
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN  UINT64                    Length\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINT32 MemoryAttributes;\r
-  UINT32 DataPermission;\r
-\r
-  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
-  if (!EFI_ERROR (Status)) {\r
-    DataPermission = SET_MEM_ATTR_DATA_PERM_RO << SET_MEM_ATTR_DATA_PERM_SHIFT;\r
-    return RequestMemoryPermissionChange (\r
-             BaseAddress,\r
-             Length,\r
-             MemoryAttributes | DataPermission\r
-             );\r
-  }\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ArmClearMemoryRegionReadOnly (\r
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN  UINT64                    Length\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINT32 MemoryAttributes;\r
-  UINT32 PermissionRequest;\r
-\r
-  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
-  if (!EFI_ERROR (Status)) {\r
-    PermissionRequest = SET_MEM_ATTR_MAKE_PERM_REQUEST (SET_MEM_ATTR_DATA_PERM_RW,\r
-                                                        MemoryAttributes);\r
-    return RequestMemoryPermissionChange (\r
-             BaseAddress,\r
-             Length,\r
-             PermissionRequest\r
-             );\r
-  }\r
-  return Status;\r
-}\r
diff --git a/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c b/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c
new file mode 100644 (file)
index 0000000..20f873e
--- /dev/null
@@ -0,0 +1,327 @@
+/** @file\r
+  File managing the MMU for ARMv8 architecture in S-EL0\r
+\r
+  Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>\r
+  Copyright (c) 2021, Linaro Limited\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+  @par Reference(s):\r
+  - [1] SPM based on the MM interface.\r
+        (https://trustedfirmware-a.readthedocs.io/en/latest/components/\r
+         secure-partition-manager-mm.html)\r
+  - [2] Arm Firmware Framework for Armv8-A, DEN0077A, version 1.0\r
+        (https://developer.arm.com/documentation/den0077/a)\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <IndustryStandard/ArmMmSvc.h>\r
+#include <IndustryStandard/ArmFfaSvc.h>\r
+\r
+#include <Library/ArmLib.h>\r
+#include <Library/ArmMmuLib.h>\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+/** Send memory permission request to target.\r
+\r
+  @param [in, out]  SvcArgs     Pointer to SVC arguments to send. On\r
+                                return it contains the response parameters.\r
+  @param [out]      RetVal      Pointer to return the response value.\r
+\r
+  @retval EFI_SUCCESS           Request successfull.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_NOT_READY         Callee is busy or not in a state to handle\r
+                                this request.\r
+  @retval EFI_UNSUPPORTED       This function is not implemented by the\r
+                                callee.\r
+  @retval EFI_ABORTED           Message target ran into an unexpected error\r
+                                and has aborted.\r
+  @retval EFI_ACCESS_DENIED     Access denied.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory to perform operation.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+SendMemoryPermissionRequest (\r
+  IN OUT  ARM_SVC_ARGS *SvcArgs,\r
+     OUT  INT32        *RetVal\r
+  )\r
+{\r
+  if ((SvcArgs == NULL) || (RetVal == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ArmCallSvc (SvcArgs);\r
+  if (FeaturePcdGet (PcdFfaEnable)) {\r
+    // Get/Set memory attributes is an atomic call, with\r
+    // StandaloneMm at S-EL0 being the caller and the SPM\r
+    // core being the callee. Thus there won't be a\r
+    // FFA_INTERRUPT or FFA_SUCCESS response to the Direct\r
+    // Request sent above. This will have to be considered\r
+    // for other Direct Request calls which are not atomic\r
+    // We therefore check only for Direct Response by the\r
+    // callee.\r
+    if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP) {\r
+      // A Direct Response means FF-A success\r
+      // Now check the payload for errors\r
+      // The callee sends back the return value\r
+      // in Arg3\r
+      *RetVal = SvcArgs->Arg3;\r
+    } else {\r
+      // If Arg0 is not a Direct Response, that means we\r
+      // have an FF-A error. We need to check Arg2 for the\r
+      // FF-A error code.\r
+      // See [2], Table 10.8: FFA_ERROR encoding.\r
+      *RetVal = SvcArgs->Arg2;\r
+      switch (*RetVal) {\r
+        case ARM_FFA_SPM_RET_INVALID_PARAMETERS:\r
+          return EFI_INVALID_PARAMETER;\r
+\r
+        case ARM_FFA_SPM_RET_DENIED:\r
+          return EFI_ACCESS_DENIED;\r
+\r
+        case ARM_FFA_SPM_RET_NOT_SUPPORTED:\r
+          return EFI_UNSUPPORTED;\r
+\r
+        case ARM_FFA_SPM_RET_BUSY:\r
+          return EFI_NOT_READY;\r
+\r
+        case ARM_FFA_SPM_RET_ABORTED:\r
+          return EFI_ABORTED;\r
+\r
+        default:\r
+          // Undefined error code received.\r
+          ASSERT (0);\r
+          return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+  } else {\r
+    *RetVal = SvcArgs->Arg0;\r
+  }\r
+\r
+  // Check error response from Callee.\r
+  if ((*RetVal & BIT31) != 0) {\r
+    // Bit 31 set means there is an error returned\r
+    // See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 and\r
+    // Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.\r
+    switch (*RetVal) {\r
+      case ARM_SVC_SPM_RET_NOT_SUPPORTED:\r
+        return EFI_UNSUPPORTED;\r
+\r
+      case ARM_SVC_SPM_RET_INVALID_PARAMS:\r
+        return EFI_INVALID_PARAMETER;\r
+\r
+      case ARM_SVC_SPM_RET_DENIED:\r
+        return EFI_ACCESS_DENIED;\r
+\r
+      case ARM_SVC_SPM_RET_NO_MEMORY:\r
+        return EFI_OUT_OF_RESOURCES;\r
+\r
+      default:\r
+        // Undefined error code received.\r
+        ASSERT (0);\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/** Request the permission attributes of a memory region from S-EL0.\r
+\r
+  @param [in]   BaseAddress          Base address for the memory region.\r
+  @param [out]  MemoryAttributes     Pointer to return the memory attributes.\r
+\r
+  @retval EFI_SUCCESS             Request successfull.\r
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid.\r
+  @retval EFI_NOT_READY           Callee is busy or not in a state to handle\r
+                                  this request.\r
+  @retval EFI_UNSUPPORTED         This function is not implemented by the\r
+                                  callee.\r
+  @retval EFI_ABORTED             Message target ran into an unexpected error\r
+                                  and has aborted.\r
+  @retval EFI_ACCESS_DENIED       Access denied.\r
+  @retval EFI_OUT_OF_RESOURCES    Out of memory to perform operation.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetMemoryPermissions (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  OUT UINT32                    *MemoryAttributes\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  INT32         Ret;\r
+  ARM_SVC_ARGS  SvcArgs;\r
+\r
+  if (MemoryAttributes == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Prepare the message parameters.\r
+  // See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64.\r
+  ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));\r
+  if (FeaturePcdGet (PcdFfaEnable)) {\r
+    // See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.\r
+    SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;\r
+    SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;\r
+    SvcArgs.Arg2 = 0;\r
+    SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES;\r
+    SvcArgs.Arg4 = BaseAddress;\r
+  } else {\r
+    SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES;\r
+    SvcArgs.Arg1 = BaseAddress;\r
+    SvcArgs.Arg2 = 0;\r
+    SvcArgs.Arg3 = 0;\r
+  }\r
+\r
+  Status = SendMemoryPermissionRequest (&SvcArgs, &Ret);\r
+  if (EFI_ERROR (Status)) {\r
+    *MemoryAttributes = 0;\r
+    return Status;\r
+  }\r
+\r
+  *MemoryAttributes = Ret;\r
+  return Status;\r
+}\r
+\r
+/** Set the permission attributes of a memory region from S-EL0.\r
+\r
+  @param [in]  BaseAddress     Base address for the memory region.\r
+  @param [in]  Length          Length of the memory region.\r
+  @param [in]  Permissions     Memory access controls attributes.\r
+\r
+  @retval EFI_SUCCESS             Request successfull.\r
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid.\r
+  @retval EFI_NOT_READY           Callee is busy or not in a state to handle\r
+                                  this request.\r
+  @retval EFI_UNSUPPORTED         This function is not implemented by the\r
+                                  callee.\r
+  @retval EFI_ABORTED             Message target ran into an unexpected error\r
+                                  and has aborted.\r
+  @retval EFI_ACCESS_DENIED       Access denied.\r
+  @retval EFI_OUT_OF_RESOURCES    Out of memory to perform operation.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+RequestMemoryPermissionChange (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length,\r
+  IN  UINT32                    Permissions\r
+  )\r
+{\r
+  INT32         Ret;\r
+  ARM_SVC_ARGS  SvcArgs;\r
+\r
+  // Prepare the message parameters.\r
+  // See [1], Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.\r
+  ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));\r
+  if (FeaturePcdGet (PcdFfaEnable)) {\r
+    // See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.\r
+    SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;\r
+    SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;\r
+    SvcArgs.Arg2 = 0;\r
+    SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES;\r
+    SvcArgs.Arg4 = BaseAddress;\r
+    SvcArgs.Arg5 = EFI_SIZE_TO_PAGES (Length);\r
+    SvcArgs.Arg6 = Permissions;\r
+  } else {\r
+    SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES;\r
+    SvcArgs.Arg1 = BaseAddress;\r
+    SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length);\r
+    SvcArgs.Arg3 = Permissions;\r
+  }\r
+\r
+  return SendMemoryPermissionRequest (&SvcArgs, &Ret);\r
+}\r
+\r
+EFI_STATUS\r
+ArmSetMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32 MemoryAttributes;\r
+  UINT32 CodePermission;\r
+\r
+  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
+  if (!EFI_ERROR (Status)) {\r
+    CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;\r
+    return RequestMemoryPermissionChange (\r
+             BaseAddress,\r
+             Length,\r
+             MemoryAttributes | CodePermission\r
+             );\r
+  }\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ArmClearMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32 MemoryAttributes;\r
+  UINT32 CodePermission;\r
+\r
+  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
+  if (!EFI_ERROR (Status)) {\r
+    CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;\r
+    return RequestMemoryPermissionChange (\r
+             BaseAddress,\r
+             Length,\r
+             MemoryAttributes & ~CodePermission\r
+             );\r
+  }\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ArmSetMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32 MemoryAttributes;\r
+  UINT32 DataPermission;\r
+\r
+  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
+  if (!EFI_ERROR (Status)) {\r
+    DataPermission = SET_MEM_ATTR_DATA_PERM_RO << SET_MEM_ATTR_DATA_PERM_SHIFT;\r
+    return RequestMemoryPermissionChange (\r
+             BaseAddress,\r
+             Length,\r
+             MemoryAttributes | DataPermission\r
+             );\r
+  }\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ArmClearMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32 MemoryAttributes;\r
+  UINT32 PermissionRequest;\r
+\r
+  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);\r
+  if (!EFI_ERROR (Status)) {\r
+    PermissionRequest = SET_MEM_ATTR_MAKE_PERM_REQUEST (SET_MEM_ATTR_DATA_PERM_RW,\r
+                                                        MemoryAttributes);\r
+    return RequestMemoryPermissionChange (\r
+             BaseAddress,\r
+             Length,\r
+             PermissionRequest\r
+             );\r
+  }\r
+  return Status;\r
+}\r
index 6c71fe00237b9322c2e759638ad29551fbb1f2da..ff20e5898051c135969cdc5019325c7eb20c63d5 100644 (file)
   LIBRARY_CLASS                  = StandaloneMmMmuLib\r
   PI_SPECIFICATION_VERSION       = 0x00010032\r
 \r
-[Sources.AARCH64]\r
-  AArch64/ArmMmuStandaloneMmLib.c\r
+[Sources]\r
+  ArmMmuStandaloneMmLib.c\r
 \r
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
   MdePkg/MdePkg.dec\r
 \r
-[FeaturePcd.AARCH64]\r
+[FeaturePcd.ARM, FeaturePcd.AARCH64]\r
   gArmTokenSpaceGuid.PcdFfaEnable\r
 \r
 [LibraryClasses]\r