On Tue, Jul 03, 2018 at 03:25:13PM +0530, Supreeth Venkatesh wrote:
> 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: Achin Gupta <[email protected]>
> Signed-off-by: Supreeth Venkatesh <[email protected]>
> Cc: Leif Lindholm <[email protected]>
> Cc: Ard Biesheuvel <[email protected]>
> ---
>  .../ArmMmuLib/AArch64/ArmMmuStandaloneMmCoreLib.c  | 195 
> +++++++++++++++++++++
>  1 file changed, 195 insertions(+)
>  create mode 100644 
> ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuStandaloneMmCoreLib.c
> 
> diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuStandaloneMmCoreLib.c 
> b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuStandaloneMmCoreLib.c
> new file mode 100644
> index 0000000..0f5e68d
> --- /dev/null
> +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuStandaloneMmCoreLib.c
> @@ -0,0 +1,195 @@
> +/** @file
> +*  File managing the MMU for ARMv8 architecture in S-EL0
> +*
> +*  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of the BSD 
> License
> +*  which accompanies this distribution.  The full text of the license may be 
> found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
> IMPLIED.
> +*
> +**/
> +
> +#include <Uefi.h>
> +#include <Chipset/AArch64.h>
> +#include <IndustryStandard/ArmMmSvc.h>
> +
> +#include <Library/ArmLib.h>
> +#include <Library/ArmMmuLib.h>
> +#include <Library/ArmSvcLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +EFI_STATUS
> +GetMemoryPermissions (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  OUT UINT32                    *MemoryAttributes
> +  )
> +{
> +  ARM_SVC_ARGS  GetMemoryPermissionsSvcArgs = {0};
> +
> +  GetMemoryPermissionsSvcArgs.Arg0 = 
> ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
> +  GetMemoryPermissionsSvcArgs.Arg1 = BaseAddress;
> +  GetMemoryPermissionsSvcArgs.Arg2 = 0;
> +  GetMemoryPermissionsSvcArgs.Arg3 = 0;
> +
> +  ArmCallSvc (&GetMemoryPermissionsSvcArgs);
> +  if (GetMemoryPermissionsSvcArgs.Arg0 == ARM_SVC_SPM_RET_INVALID_PARAMS) {
> +    *MemoryAttributes = 0;
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *MemoryAttributes = GetMemoryPermissionsSvcArgs.Arg0;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +RequestMemoryPermissionChange (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length,
> +  IN  UINTN                     Permissions
> +  )
> +{
> +  EFI_STATUS    Status;
> +  ARM_SVC_ARGS  ChangeMemoryPermissionsSvcArgs = {0};
> +
> +  ChangeMemoryPermissionsSvcArgs.Arg0 = 
> ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
> +  ChangeMemoryPermissionsSvcArgs.Arg1 = BaseAddress;
> +  ChangeMemoryPermissionsSvcArgs.Arg2 = (Length >= EFI_PAGE_SIZE) ? \
> +                                         Length >> EFI_PAGE_SHIFT : 1;

Use EFI_SIZE_TO_PAGES?

> +  ChangeMemoryPermissionsSvcArgs.Arg3 = Permissions;
> +
> +  ArmCallSvc (&ChangeMemoryPermissionsSvcArgs);
> +
> +  Status = ChangeMemoryPermissionsSvcArgs.Arg0;
> +
> +  switch (Status) {
> +  case ARM_SVC_SPM_RET_SUCCESS:
> +    Status = EFI_SUCCESS;
> +    break;
> +
> +  case ARM_SVC_SPM_RET_NOT_SUPPORTED:
> +    Status = EFI_UNSUPPORTED;
> +    break;
> +
> +  case ARM_SVC_SPM_RET_INVALID_PARAMS:
> +    Status = EFI_INVALID_PARAMETER;
> +    break;
> +
> +  case ARM_SVC_SPM_RET_DENIED:
> +    Status = EFI_ACCESS_DENIED;
> +    break;
> +
> +  case ARM_SVC_SPM_RET_NO_MEMORY:
> +    Status = EFI_BAD_BUFFER_SIZE;
> +    break;
> +
> +  default:
> +    Status = EFI_ACCESS_DENIED;
> +    ASSERT (0);
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +ArmSetMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINT32 MemoryAttributes;
> +
> +  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
> +  if (Status != EFI_INVALID_PARAMETER) {
> +    return RequestMemoryPermissionChange (BaseAddress,
> +                                          Length,
> +                                          MemoryAttributes |
> +                                          (SET_MEM_ATTR_CODE_PERM_XN << 
> SET_MEM_ATTR_CODE_PERM_SHIFT));

Very long line - please use a temporary variable to shorten.
(Throughout.)

> +  }
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +EFI_STATUS
> +ArmClearMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINT32 MemoryAttributes;
> +
> +  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
> +  if (Status != EFI_INVALID_PARAMETER) {
> +    return RequestMemoryPermissionChange (BaseAddress,
> +                                          Length,
> +                                          MemoryAttributes &
> +                                          ~(SET_MEM_ATTR_CODE_PERM_XN << 
> SET_MEM_ATTR_CODE_PERM_SHIFT));
> +  }
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +EFI_STATUS
> +ArmSetMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINT32 MemoryAttributes;
> +
> +  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
> +  if (Status != EFI_INVALID_PARAMETER) {
> +    return RequestMemoryPermissionChange (BaseAddress,
> +                                          Length,
> +                                          MemoryAttributes |
> +                                          (SET_MEM_ATTR_DATA_PERM_RO << 
> SET_MEM_ATTR_DATA_PERM_SHIFT));
> +  }
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +EFI_STATUS
> +ArmClearMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINT32 MemoryAttributes;
> +
> +  Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
> +  if (Status != EFI_INVALID_PARAMETER) {
> +    return RequestMemoryPermissionChange (BaseAddress,
> +                                          Length,
> +                                          SET_MEM_ATTR_MAKE_PERM_REQUEST
> +                                            ( \
> +                                             SET_MEM_ATTR_DATA_PERM_RW, \
> +                                             MemoryAttributes));

Use temporary variable.

/
    Leif

> +  }
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +ArmConfigureMmu (
> +  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,
> +  OUT VOID                          **TranslationTableBase OPTIONAL,
> +  OUT UINTN                         *TranslationTableSize OPTIONAL
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +ArmMmuStandaloneMmCoreLibConstructor (
> +  IN EFI_HANDLE            ImageHandle,
> +  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.7.4
> 
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to