REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ArmPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			456 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			456 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Api's to communicate with OP-TEE OS (Trusted OS based on ARM TrustZone) via
 | |
|   secure monitor calls.
 | |
| 
 | |
|   Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
 | |
|   Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Library/ArmMmuLib.h>
 | |
| #include <Library/ArmSmcLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/OpteeLib.h>
 | |
| 
 | |
| #include <IndustryStandard/ArmStdSmc.h>
 | |
| #include <OpteeSmc.h>
 | |
| #include <Uefi.h>
 | |
| 
 | |
| STATIC OPTEE_SHARED_MEMORY_INFORMATION  OpteeSharedMemoryInformation = { 0 };
 | |
| 
 | |
| /**
 | |
|   Check for OP-TEE presence.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| IsOpteePresent (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   ARM_SMC_ARGS  ArmSmcArgs;
 | |
| 
 | |
|   ZeroMem (&ArmSmcArgs, sizeof (ARM_SMC_ARGS));
 | |
|   // Send a Trusted OS Calls UID command
 | |
|   ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;
 | |
|   ArmCallSmc (&ArmSmcArgs);
 | |
| 
 | |
|   if ((ArmSmcArgs.Arg0 == OPTEE_OS_UID0) &&
 | |
|       (ArmSmcArgs.Arg1 == OPTEE_OS_UID1) &&
 | |
|       (ArmSmcArgs.Arg2 == OPTEE_OS_UID2) &&
 | |
|       (ArmSmcArgs.Arg3 == OPTEE_OS_UID3))
 | |
|   {
 | |
|     return TRUE;
 | |
|   } else {
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| OpteeSharedMemoryRemap (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   ARM_SMC_ARGS          ArmSmcArgs;
 | |
|   EFI_PHYSICAL_ADDRESS  PhysicalAddress;
 | |
|   EFI_PHYSICAL_ADDRESS  Start;
 | |
|   EFI_PHYSICAL_ADDRESS  End;
 | |
|   EFI_STATUS            Status;
 | |
|   UINTN                 Size;
 | |
| 
 | |
|   ZeroMem (&ArmSmcArgs, sizeof (ARM_SMC_ARGS));
 | |
|   ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHARED_MEMORY_CONFIG;
 | |
| 
 | |
|   ArmCallSmc (&ArmSmcArgs);
 | |
|   if (ArmSmcArgs.Arg0 != OPTEE_SMC_RETURN_OK) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE shared memory not supported\n"));
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   if (ArmSmcArgs.Arg3 != OPTEE_SMC_SHARED_MEMORY_CACHED) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE: Only normal cached shared memory supported\n"));
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   Start           = (ArmSmcArgs.Arg1 + SIZE_4KB - 1) & ~(SIZE_4KB - 1);
 | |
|   End             = (ArmSmcArgs.Arg1 + ArmSmcArgs.Arg2) & ~(SIZE_4KB - 1);
 | |
|   PhysicalAddress = Start;
 | |
|   Size            = End - Start;
 | |
| 
 | |
|   if (Size < SIZE_4KB) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE shared memory too small\n"));
 | |
|     return EFI_BUFFER_TOO_SMALL;
 | |
|   }
 | |
| 
 | |
|   Status = ArmSetMemoryAttributes (PhysicalAddress, Size, EFI_MEMORY_WB);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   OpteeSharedMemoryInformation.Base = (UINTN)PhysicalAddress;
 | |
|   OpteeSharedMemoryInformation.Size = Size;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| OpteeInit (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   if (!IsOpteePresent ()) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE not present\n"));
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   Status = OpteeSharedMemoryRemap ();
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| BOOLEAN
 | |
| IsOpteeSmcReturnRpc (
 | |
|   UINT32  Return
 | |
|   )
 | |
| {
 | |
|   return (Return != OPTEE_SMC_RETURN_UNKNOWN_FUNCTION) &&
 | |
|          ((Return & OPTEE_SMC_RETURN_RPC_PREFIX_MASK) ==
 | |
|           OPTEE_SMC_RETURN_RPC_PREFIX);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Does Standard SMC to OP-TEE in secure world.
 | |
| 
 | |
|   @param[in]  PhysicalArg   Physical address of message to pass to secure world
 | |
| 
 | |
|   @return                   0 on success, secure world return code otherwise
 | |
| 
 | |
| **/
 | |
| STATIC
 | |
| UINT32
 | |
| OpteeCallWithArg (
 | |
|   IN UINT64  PhysicalArg
 | |
|   )
 | |
| {
 | |
|   ARM_SMC_ARGS  ArmSmcArgs;
 | |
| 
 | |
|   ZeroMem (&ArmSmcArgs, sizeof (ARM_SMC_ARGS));
 | |
|   ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;
 | |
|   ArmSmcArgs.Arg1 = (UINT32)(PhysicalArg >> 32);
 | |
|   ArmSmcArgs.Arg2 = (UINT32)PhysicalArg;
 | |
| 
 | |
|   while (TRUE) {
 | |
|     ArmCallSmc (&ArmSmcArgs);
 | |
| 
 | |
|     if (IsOpteeSmcReturnRpc (ArmSmcArgs.Arg0)) {
 | |
|       switch (ArmSmcArgs.Arg0) {
 | |
|         case OPTEE_SMC_RETURN_RPC_FOREIGN_INTERRUPT:
 | |
|           //
 | |
|           // A foreign interrupt was raised while secure world was
 | |
|           // executing, since they are handled in UEFI a dummy RPC is
 | |
|           // performed to let UEFI take the interrupt through the normal
 | |
|           // vector.
 | |
|           //
 | |
|           break;
 | |
| 
 | |
|         default:
 | |
|           // Do nothing in case RPC is not implemented.
 | |
|           break;
 | |
|       }
 | |
| 
 | |
|       ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;
 | |
|     } else {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return ArmSmcArgs.Arg0;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| VOID
 | |
| EfiGuidToRfc4122Uuid (
 | |
|   OUT RFC4122_UUID  *Rfc4122Uuid,
 | |
|   IN EFI_GUID       *Guid
 | |
|   )
 | |
| {
 | |
|   Rfc4122Uuid->Data1 = SwapBytes32 (Guid->Data1);
 | |
|   Rfc4122Uuid->Data2 = SwapBytes16 (Guid->Data2);
 | |
|   Rfc4122Uuid->Data3 = SwapBytes16 (Guid->Data3);
 | |
|   CopyMem (Rfc4122Uuid->Data4, Guid->Data4, sizeof (Rfc4122Uuid->Data4));
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| OpteeOpenSession (
 | |
|   IN OUT OPTEE_OPEN_SESSION_ARG  *OpenSessionArg
 | |
|   )
 | |
| {
 | |
|   OPTEE_MESSAGE_ARG  *MessageArg;
 | |
| 
 | |
|   MessageArg = NULL;
 | |
| 
 | |
|   if (OpteeSharedMemoryInformation.Base == 0) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));
 | |
|     return EFI_NOT_STARTED;
 | |
|   }
 | |
| 
 | |
|   MessageArg = (OPTEE_MESSAGE_ARG *)OpteeSharedMemoryInformation.Base;
 | |
|   ZeroMem (MessageArg, sizeof (OPTEE_MESSAGE_ARG));
 | |
| 
 | |
|   MessageArg->Command = OPTEE_MESSAGE_COMMAND_OPEN_SESSION;
 | |
| 
 | |
|   //
 | |
|   // Initialize and add the meta parameters needed when opening a
 | |
|   // session.
 | |
|   //
 | |
|   MessageArg->Params[0].Attribute = OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_INPUT |
 | |
|                                     OPTEE_MESSAGE_ATTRIBUTE_META;
 | |
|   MessageArg->Params[1].Attribute = OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_INPUT |
 | |
|                                     OPTEE_MESSAGE_ATTRIBUTE_META;
 | |
|   EfiGuidToRfc4122Uuid (
 | |
|     (RFC4122_UUID *)&MessageArg->Params[0].Union.Value,
 | |
|     &OpenSessionArg->Uuid
 | |
|     );
 | |
|   ZeroMem (&MessageArg->Params[1].Union.Value, sizeof (EFI_GUID));
 | |
|   MessageArg->Params[1].Union.Value.C = OPTEE_LOGIN_PUBLIC;
 | |
| 
 | |
|   MessageArg->NumParams = 2;
 | |
| 
 | |
|   if (OpteeCallWithArg ((UINTN)MessageArg) != 0) {
 | |
|     MessageArg->Return       = OPTEE_ERROR_COMMUNICATION;
 | |
|     MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
 | |
|   }
 | |
| 
 | |
|   OpenSessionArg->Session      = MessageArg->Session;
 | |
|   OpenSessionArg->Return       = MessageArg->Return;
 | |
|   OpenSessionArg->ReturnOrigin = MessageArg->ReturnOrigin;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| OpteeCloseSession (
 | |
|   IN UINT32  Session
 | |
|   )
 | |
| {
 | |
|   OPTEE_MESSAGE_ARG  *MessageArg;
 | |
| 
 | |
|   MessageArg = NULL;
 | |
| 
 | |
|   if (OpteeSharedMemoryInformation.Base == 0) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));
 | |
|     return EFI_NOT_STARTED;
 | |
|   }
 | |
| 
 | |
|   MessageArg = (OPTEE_MESSAGE_ARG *)OpteeSharedMemoryInformation.Base;
 | |
|   ZeroMem (MessageArg, sizeof (OPTEE_MESSAGE_ARG));
 | |
| 
 | |
|   MessageArg->Command = OPTEE_MESSAGE_COMMAND_CLOSE_SESSION;
 | |
|   MessageArg->Session = Session;
 | |
| 
 | |
|   OpteeCallWithArg ((UINTN)MessageArg);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| OpteeToMessageParam (
 | |
|   OUT OPTEE_MESSAGE_PARAM  *MessageParams,
 | |
|   IN UINT32                NumParams,
 | |
|   IN OPTEE_MESSAGE_PARAM   *InParams
 | |
|   )
 | |
| {
 | |
|   UINT32  Idx;
 | |
|   UINTN   ParamSharedMemoryAddress;
 | |
|   UINTN   SharedMemorySize;
 | |
|   UINTN   Size;
 | |
| 
 | |
|   Size = (sizeof (OPTEE_MESSAGE_ARG) + sizeof (UINT64) - 1) &
 | |
|          ~(sizeof (UINT64) - 1);
 | |
|   ParamSharedMemoryAddress = OpteeSharedMemoryInformation.Base + Size;
 | |
|   SharedMemorySize         = OpteeSharedMemoryInformation.Size - Size;
 | |
| 
 | |
|   for (Idx = 0; Idx < NumParams; Idx++) {
 | |
|     CONST OPTEE_MESSAGE_PARAM  *InParam;
 | |
|     OPTEE_MESSAGE_PARAM        *MessageParam;
 | |
|     UINT32                     Attribute;
 | |
| 
 | |
|     InParam      = InParams + Idx;
 | |
|     MessageParam = MessageParams + Idx;
 | |
|     Attribute    = InParam->Attribute & OPTEE_MESSAGE_ATTRIBUTE_TYPE_MASK;
 | |
| 
 | |
|     switch (Attribute) {
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_NONE:
 | |
|         MessageParam->Attribute = OPTEE_MESSAGE_ATTRIBUTE_TYPE_NONE;
 | |
|         ZeroMem (&MessageParam->Union, sizeof (MessageParam->Union));
 | |
|         break;
 | |
| 
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_INPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_OUTPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_INOUT:
 | |
|         MessageParam->Attribute     = Attribute;
 | |
|         MessageParam->Union.Value.A = InParam->Union.Value.A;
 | |
|         MessageParam->Union.Value.B = InParam->Union.Value.B;
 | |
|         MessageParam->Union.Value.C = InParam->Union.Value.C;
 | |
|         break;
 | |
| 
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_INPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_OUTPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_INOUT:
 | |
|         MessageParam->Attribute = Attribute;
 | |
| 
 | |
|         if (InParam->Union.Memory.Size > SharedMemorySize) {
 | |
|           return EFI_OUT_OF_RESOURCES;
 | |
|         }
 | |
| 
 | |
|         CopyMem (
 | |
|           (VOID *)ParamSharedMemoryAddress,
 | |
|           (VOID *)(UINTN)InParam->Union.Memory.BufferAddress,
 | |
|           InParam->Union.Memory.Size
 | |
|           );
 | |
|         MessageParam->Union.Memory.BufferAddress = (UINT64)ParamSharedMemoryAddress;
 | |
|         MessageParam->Union.Memory.Size          = InParam->Union.Memory.Size;
 | |
| 
 | |
|         Size = (InParam->Union.Memory.Size + sizeof (UINT64) - 1) &
 | |
|                ~(sizeof (UINT64) - 1);
 | |
|         ParamSharedMemoryAddress += Size;
 | |
|         SharedMemorySize         -= Size;
 | |
|         break;
 | |
| 
 | |
|       default:
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| OpteeFromMessageParam (
 | |
|   OUT OPTEE_MESSAGE_PARAM  *OutParams,
 | |
|   IN UINT32                NumParams,
 | |
|   IN OPTEE_MESSAGE_PARAM   *MessageParams
 | |
|   )
 | |
| {
 | |
|   UINT32  Idx;
 | |
| 
 | |
|   for (Idx = 0; Idx < NumParams; Idx++) {
 | |
|     OPTEE_MESSAGE_PARAM        *OutParam;
 | |
|     CONST OPTEE_MESSAGE_PARAM  *MessageParam;
 | |
|     UINT32                     Attribute;
 | |
| 
 | |
|     OutParam     = OutParams + Idx;
 | |
|     MessageParam = MessageParams + Idx;
 | |
|     Attribute    = MessageParam->Attribute & OPTEE_MESSAGE_ATTRIBUTE_TYPE_MASK;
 | |
| 
 | |
|     switch (Attribute) {
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_NONE:
 | |
|         OutParam->Attribute = OPTEE_MESSAGE_ATTRIBUTE_TYPE_NONE;
 | |
|         ZeroMem (&OutParam->Union, sizeof (OutParam->Union));
 | |
|         break;
 | |
| 
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_INPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_OUTPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_VALUE_INOUT:
 | |
|         OutParam->Attribute     = Attribute;
 | |
|         OutParam->Union.Value.A = MessageParam->Union.Value.A;
 | |
|         OutParam->Union.Value.B = MessageParam->Union.Value.B;
 | |
|         OutParam->Union.Value.C = MessageParam->Union.Value.C;
 | |
|         break;
 | |
| 
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_INPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_OUTPUT:
 | |
|       case OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_INOUT:
 | |
|         OutParam->Attribute = Attribute;
 | |
| 
 | |
|         if (MessageParam->Union.Memory.Size > OutParam->Union.Memory.Size) {
 | |
|           return EFI_BAD_BUFFER_SIZE;
 | |
|         }
 | |
| 
 | |
|         CopyMem (
 | |
|           (VOID *)(UINTN)OutParam->Union.Memory.BufferAddress,
 | |
|           (VOID *)(UINTN)MessageParam->Union.Memory.BufferAddress,
 | |
|           MessageParam->Union.Memory.Size
 | |
|           );
 | |
|         OutParam->Union.Memory.Size = MessageParam->Union.Memory.Size;
 | |
|         break;
 | |
| 
 | |
|       default:
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| OpteeInvokeFunction (
 | |
|   IN OUT OPTEE_INVOKE_FUNCTION_ARG  *InvokeFunctionArg
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS         Status;
 | |
|   OPTEE_MESSAGE_ARG  *MessageArg;
 | |
| 
 | |
|   MessageArg = NULL;
 | |
| 
 | |
|   if (OpteeSharedMemoryInformation.Base == 0) {
 | |
|     DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));
 | |
|     return EFI_NOT_STARTED;
 | |
|   }
 | |
| 
 | |
|   MessageArg = (OPTEE_MESSAGE_ARG *)OpteeSharedMemoryInformation.Base;
 | |
|   ZeroMem (MessageArg, sizeof (OPTEE_MESSAGE_ARG));
 | |
| 
 | |
|   MessageArg->Command  = OPTEE_MESSAGE_COMMAND_INVOKE_FUNCTION;
 | |
|   MessageArg->Function = InvokeFunctionArg->Function;
 | |
|   MessageArg->Session  = InvokeFunctionArg->Session;
 | |
| 
 | |
|   Status = OpteeToMessageParam (
 | |
|              MessageArg->Params,
 | |
|              OPTEE_MAX_CALL_PARAMS,
 | |
|              InvokeFunctionArg->Params
 | |
|              );
 | |
|   if (Status) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   MessageArg->NumParams = OPTEE_MAX_CALL_PARAMS;
 | |
| 
 | |
|   if (OpteeCallWithArg ((UINTN)MessageArg) != 0) {
 | |
|     MessageArg->Return       = OPTEE_ERROR_COMMUNICATION;
 | |
|     MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
 | |
|   }
 | |
| 
 | |
|   if (OpteeFromMessageParam (
 | |
|         InvokeFunctionArg->Params,
 | |
|         OPTEE_MAX_CALL_PARAMS,
 | |
|         MessageArg->Params
 | |
|         ) != 0)
 | |
|   {
 | |
|     MessageArg->Return       = OPTEE_ERROR_COMMUNICATION;
 | |
|     MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
 | |
|   }
 | |
| 
 | |
|   InvokeFunctionArg->Return       = MessageArg->Return;
 | |
|   InvokeFunctionArg->ReturnOrigin = MessageArg->ReturnOrigin;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |