]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmMmuLib: Add MMU Library suitable for use in S-EL0.
authorAchin Gupta <achin.gupta@arm.com>
Tue, 27 Nov 2018 10:43:57 +0000 (16:13 +0530)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 27 Nov 2018 12:06:06 +0000 (13:06 +0100)
The Standalone MM environment runs in S-EL0 in AArch64 on ARM Standard
Platforms. Privileged firmware e.g. ARM Trusted Firmware sets up its
architectural context including the initial translation tables for the
S-EL1/EL0 translation regime. The MM environment will still request ARM
TF to change the memory attributes of memory regions during
initialization.

The Standalone MM image is a FV that encapsulates the MM foundation
and drivers. These are PE-COFF images with data and text segments.
To initialise the MM environment, Arm Trusted Firmware has to create
translation tables with sane default attributes for the memory
occupied by the FV. This library sends SVCs to ARM Trusted Firmware
to request memory permissions change for data and text segments.

This patch adds a simple MMU library suitable for execution in S-EL0 and
requesting memory permissions change operations from Arm Trusted Firmware.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sughosh Ganu <sughosh.ganu@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
ArmPkg/ArmPkg.dec
ArmPkg/ArmPkg.dsc
ArmPkg/Include/Library/StandaloneMmMmuLib.h [new file with mode: 0644]
ArmPkg/Library/StandaloneMmMmuLib/Aarch64/ArmMmuStandaloneMmLib.c [new file with mode: 0644]
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf [new file with mode: 0644]

index 0db7aa9d301c8de922ba58d629f7021249201760..d99eb6769ff1a443576893bf36d05dc701fbd288 100644 (file)
@@ -42,6 +42,7 @@
   ArmMtlLib|ArmPlatformPkg/Include/Library/ArmMtlLib.h\r
   ArmSvcLib|Include/Library/ArmSvcLib.h\r
   OpteeLib|Include/Library/OpteeLib.h\r
+  StandaloneMmMmuLib|Include/Library/StandaloneMmMmuLib.h\r
 \r
 [Guids.common]\r
   gArmTokenSpaceGuid       = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }\r
index 810caaff629f445afd926e1b549045aa26e0b704..acf679651ddf06b9942a247612dfd1713260435a 100644 (file)
   ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf\r
   ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf\r
   ArmPkg/Library/ArmExceptionLib/ArmRelocateExceptionLib.inf\r
+  ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf\r
 \r
   ArmPkg/Drivers/CpuDxe/CpuDxe.inf\r
   ArmPkg/Drivers/CpuPei/CpuPei.inf\r
diff --git a/ArmPkg/Include/Library/StandaloneMmMmuLib.h b/ArmPkg/Include/Library/StandaloneMmMmuLib.h
new file mode 100644 (file)
index 0000000..1f7653d
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+\r
+  Copyright (c) 2018, ARM Ltd. All rights reserved.\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __STANDALONEMM_MMU_LIB__\r
+#define __STANDALONEMM_MMU_LIB__\r
+\r
+EFI_STATUS\r
+ArmSetMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+EFI_STATUS\r
+ArmClearMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+EFI_STATUS\r
+ArmSetMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+EFI_STATUS\r
+ArmClearMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+#endif /* __STANDALONEMM_MMU_LIB__ */\r
diff --git a/ArmPkg/Library/StandaloneMmMmuLib/Aarch64/ArmMmuStandaloneMmLib.c b/ArmPkg/Library/StandaloneMmMmuLib/Aarch64/ArmMmuStandaloneMmLib.c
new file mode 100644 (file)
index 0000000..3095d71
--- /dev/null
@@ -0,0 +1,185 @@
+/** @file\r
+*  File managing the MMU for ARMv8 architecture in S-EL0\r
+*\r
+*  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.\r
+*\r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <IndustryStandard/ArmMmSvc.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/DebugLib.h>\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetMemoryPermissions (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  OUT UINT32                    *MemoryAttributes\r
+  )\r
+{\r
+  ARM_SVC_ARGS  GetMemoryPermissionsSvcArgs = {0};\r
+\r
+  GetMemoryPermissionsSvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;\r
+  GetMemoryPermissionsSvcArgs.Arg1 = BaseAddress;\r
+  GetMemoryPermissionsSvcArgs.Arg2 = 0;\r
+  GetMemoryPermissionsSvcArgs.Arg3 = 0;\r
+\r
+  ArmCallSvc (&GetMemoryPermissionsSvcArgs);\r
+  if (GetMemoryPermissionsSvcArgs.Arg0 == ARM_SVC_SPM_RET_INVALID_PARAMS) {\r
+    *MemoryAttributes = 0;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *MemoryAttributes = GetMemoryPermissionsSvcArgs.Arg0;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+RequestMemoryPermissionChange (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length,\r
+  IN  UINTN                     Permissions\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ARM_SVC_ARGS  ChangeMemoryPermissionsSvcArgs = {0};\r
+\r
+  ChangeMemoryPermissionsSvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;\r
+  ChangeMemoryPermissionsSvcArgs.Arg1 = BaseAddress;\r
+  ChangeMemoryPermissionsSvcArgs.Arg2 = EFI_SIZE_TO_PAGES(Length);\r
+  ChangeMemoryPermissionsSvcArgs.Arg3 = Permissions;\r
+\r
+  ArmCallSvc (&ChangeMemoryPermissionsSvcArgs);\r
+\r
+  Status = ChangeMemoryPermissionsSvcArgs.Arg0;\r
+\r
+  switch (Status) {\r
+  case ARM_SVC_SPM_RET_SUCCESS:\r
+    Status = EFI_SUCCESS;\r
+    break;\r
+\r
+  case ARM_SVC_SPM_RET_NOT_SUPPORTED:\r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
+\r
+  case ARM_SVC_SPM_RET_INVALID_PARAMS:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+\r
+  case ARM_SVC_SPM_RET_DENIED:\r
+    Status = EFI_ACCESS_DENIED;\r
+    break;\r
+\r
+  case ARM_SVC_SPM_RET_NO_MEMORY:\r
+    Status = EFI_BAD_BUFFER_SIZE;\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_ACCESS_DENIED;\r
+    ASSERT (0);\r
+  }\r
+\r
+  return Status;\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 (Status != EFI_INVALID_PARAMETER) {\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 EFI_INVALID_PARAMETER;\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 (Status != EFI_INVALID_PARAMETER) {\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 EFI_INVALID_PARAMETER;\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 (Status != EFI_INVALID_PARAMETER) {\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 EFI_INVALID_PARAMETER;\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 (Status != EFI_INVALID_PARAMETER) {\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 EFI_INVALID_PARAMETER;\r
+}\r
diff --git a/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf b/ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
new file mode 100644 (file)
index 0000000..d589b23
--- /dev/null
@@ -0,0 +1,36 @@
+#/** @file\r
+#\r
+#  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x0001001A\r
+  BASE_NAME                      = ArmMmuStandaloneMmCoreLib\r
+  FILE_GUID                      = da8f0232-fb14-42f0-922c-63104d2c70bd\r
+  MODULE_TYPE                    = MM_CORE_STANDALONE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = StandaloneMmMmuLib\r
+  PI_SPECIFICATION_VERSION       = 0x00010032\r
+\r
+[Sources.AARCH64]\r
+  Aarch64/ArmMmuStandaloneMmLib.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  ArmLib\r
+  CacheMaintenanceLib\r
+  MemoryAllocationLib\r
+\r
+\r