diff mbox series

[1/1] ArmPkg/OpteeLib: Add APIs to communicate with OP-TEE

Message ID 1534772119-27166-1-git-send-email-sumit.garg@linaro.org
State New
Headers show
Series [1/1] ArmPkg/OpteeLib: Add APIs to communicate with OP-TEE | expand

Commit Message

Sumit Garg Aug. 20, 2018, 1:35 p.m. UTC
Add following APIs to communicate with OP-TEE static TA:
1. OpteeInit
2. OpteeOpenSession
3. OpteeCloseSession
4. OpteeInvokeFunc

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

---
 ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++
 ArmPkg/Library/OpteeLib/Optee.c      | 344 +++++++++++++++++++++++++++++++++++
 ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +
 ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++
 4 files changed, 499 insertions(+)
 create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h

-- 
2.7.4

Comments

Sumit Garg Aug. 20, 2018, 1:42 p.m. UTC | #1
Hi All,

I have tried to prepare a generic OP-TEE driver for edk2/UEFI. Use-case for
edk2/UEFI OP-TEE driver is to provide boot-time services using Static TA.
One of examples is RNG service for Developerbox useful for features like
KASLR.

Please help me with internal review.

Regards,
Sumit


On Mon, 20 Aug 2018 at 19:05, Sumit Garg <sumit.garg@linaro.org> wrote:

> Add following APIs to communicate with OP-TEE static TA:

> 1. OpteeInit

> 2. OpteeOpenSession

> 3. OpteeCloseSession

> 4. OpteeInvokeFunc

>

> Contributed-under: TianoCore Contribution Agreement 1.1

> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

> ---

>  ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++

>  ArmPkg/Library/OpteeLib/Optee.c      | 344

> +++++++++++++++++++++++++++++++++++

>  ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +

>  ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++

>  4 files changed, 499 insertions(+)

>  create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h

>

> diff --git a/ArmPkg/Include/Library/OpteeLib.h

> b/ArmPkg/Include/Library/OpteeLib.h

> index f65d8674d9b8..59ae63526f58 100644

> --- a/ArmPkg/Include/Library/OpteeLib.h

> +++ b/ArmPkg/Include/Library/OpteeLib.h

> @@ -25,10 +25,112 @@

>  #define OPTEE_OS_UID2          0xaf630002

>  #define OPTEE_OS_UID3          0xa5d5c51b

>

> +#define OPTEE_MSG_ATTR_TYPE_NONE                0x0

> +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1

> +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2

> +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3

> +#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9

> +#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa

> +#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb

> +

> +#define OPTEE_MSG_ATTR_TYPE_MASK                0xff

> +

> +typedef struct {

> +  UINT64    BufPtr;

> +  UINT64    Size;

> +  UINT64    ShmRef;

> +} OPTEE_MSG_PARAM_MEM;

> +

> +typedef struct {

> +  UINT64    A;

> +  UINT64    B;

> +  UINT64    C;

> +} OPTEE_MSG_PARAM_VALUE;

> +

> +typedef struct {

> +  UINT64 Attr;

> +  union {

> +    OPTEE_MSG_PARAM_MEM      Mem;

> +    OPTEE_MSG_PARAM_VALUE    Value;

> +  } U;

> +} OPTEE_MSG_PARAM;

> +

> +#define MAX_PARAMS           4

> +

> +typedef struct {

> +        UINT32             Cmd;

> +        UINT32             Func;

> +        UINT32             Session;

> +        UINT32             CancelId;

> +        UINT32             Pad;

> +        UINT32             Ret;

> +        UINT32             RetOrigin;

> +        UINT32             NumParams;

> +

> +        /* NumParams tells the actual number of element in Params */

> +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> +} OPTEE_MSG_ARG;

> +

> +#define OPTEE_UUID_LEN       16

> +

> +/**

> + * struct OPTEE_OPEN_SESSION_ARG - Open session argument

> + * @Uuid:       [in] UUID of the Trusted Application

> + * @Session:    [out] Session id

> + * @Ret:        [out] Return value

> + * @RetOrigin   [out] Origin of the return value

> + */

> +typedef struct {

> +        UINT8     Uuid[OPTEE_UUID_LEN];

> +        UINT32    Session;

> +        UINT32    Ret;

> +        UINT32    RetOrigin;

> +} OPTEE_OPEN_SESSION_ARG;

> +

> +/**

> + * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument

> + * @Func:       [in] Trusted Application function, specific to the TA

> + * @Session:    [in] Session id

> + * @Ret:        [out] Return value

> + * @RetOrigin   [out] Origin of the return value

> + * @Params      [inout] Parameters for function to be invoked

> + */

> +typedef struct {

> +        UINT32             Func;

> +        UINT32             Session;

> +        UINT32             Ret;

> +        UINT32             RetOrigin;

> +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> +} OPTEE_INVOKE_FUNC_ARG;

> +

>  BOOLEAN

>  EFIAPI

>  IsOpteePresent (

>    VOID

>    );

>

> +EFI_STATUS

> +EFIAPI

> +OpteeInit (

> +  VOID

> +  );

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeOpenSession (

> +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> +  );

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeCloseSession (

> +  IN UINT32                      Session

> +  );

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeInvokeFunc (

> +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> +  );

> +

>  #endif

> diff --git a/ArmPkg/Library/OpteeLib/Optee.c

> b/ArmPkg/Library/OpteeLib/Optee.c

> index 574527f8b5ea..498bf0165f24 100644

> --- a/ArmPkg/Library/OpteeLib/Optee.c

> +++ b/ArmPkg/Library/OpteeLib/Optee.c

> @@ -14,11 +14,19 @@

>

>  **/

>

> +#include <Library/ArmMmuLib.h>

>  #include <Library/ArmSmcLib.h>

>  #include <Library/BaseLib.h>

> +#include <Library/DebugLib.h>

>  #include <Library/OpteeLib.h>

>

>  #include <IndustryStandard/ArmStdSmc.h>

> +#include <OpteeSmc.h>

> +#include <string.h>

> +#include <sys/param.h>

> +#include <Uefi.h>

> +

> +STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };

>

>  /**

>    Check for OP-TEE presence.

> @@ -31,6 +39,7 @@ IsOpteePresent (

>  {

>    ARM_SMC_ARGS ArmSmcArgs;

>

> +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

>    // Send a Trusted OS Calls UID command

>    ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;

>    ArmCallSmc (&ArmSmcArgs);

> @@ -44,3 +53,338 @@ IsOpteePresent (

>      return FALSE;

>    }

>  }

> +

> +STATIC

> +EFI_STATUS

> +OpteeShmMemRemap (

> +  VOID

> +  )

> +{

> +  ARM_SMC_ARGS                 ArmSmcArgs;

> +  EFI_PHYSICAL_ADDRESS         Paddr;

> +  EFI_PHYSICAL_ADDRESS         Start;

> +  EFI_PHYSICAL_ADDRESS         End;

> +  EFI_STATUS                   Status;

> +  UINTN                        Size;

> +

> +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> +  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_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_SHM_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);

> +  Paddr = 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 (Paddr, Size, EFI_MEMORY_WB);

> +  if (EFI_ERROR (Status)) {

> +    return Status;

> +  }

> +

> +  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;

> +  OpteeShmInfo.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 = OpteeShmMemRemap ();

> +  if (EFI_ERROR (Status)) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));

> +    return Status;

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +/**

> + * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world

> + * @Parg:  physical address of message to pass to secure world

> + *

> + * Does Standard SMC to OP-TEE in secure world.

> + *

> + * Returns return code from secure world, 0 is OK

> + */

> +STATIC

> +UINT32

> +OpteeCallWithArg (

> +  IN EFI_PHYSICAL_ADDRESS Parg

> +  )

> +{

> +  ARM_SMC_ARGS ArmSmcArgs;

> +

> +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> +  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;

> +  ArmSmcArgs.Arg1 = (UINT32) (Parg >> 32);

> +  ArmSmcArgs.Arg2 = (UINT32) Parg;

> +

> +  while (TRUE) {

> +    ArmCallSmc (&ArmSmcArgs);

> +

> +    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {

> +      /*

> +       * 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.

> +       */

> +      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;

> +    } else {

> +      break;

> +    }

> +  }

> +

> +  return ArmSmcArgs.Arg0;

> +}

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeOpenSession (

> +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> +  )

> +{

> +  OPTEE_MSG_ARG *MsgArg = NULL;

> +

> +  if (OpteeShmInfo.Base == 0) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> +    return EFI_NOT_STARTED;

> +  }

> +

> +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

> +

> +  MsgArg->Cmd = OPTEE_MSG_CMD_OPEN_SESSION;

> +

> +  /*

> +   * Initialize and add the meta parameters needed when opening a

> +   * session.

> +   */

> +  MsgArg->Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> +                           OPTEE_MSG_ATTR_META;

> +  MsgArg->Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> +                           OPTEE_MSG_ATTR_META;

> +  memcpy(&MsgArg->Params[0].U.Value, OpenSessionArg->Uuid,

> OPTEE_UUID_LEN);

> +  memset(&MsgArg->Params[1].U.Value, 0, OPTEE_UUID_LEN);

> +  MsgArg->Params[1].U.Value.C = TEE_LOGIN_PUBLIC;

> +

> +  MsgArg->NumParams = 2;

> +

> +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

> +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> +  }

> +

> +  OpenSessionArg->Session = MsgArg->Session;

> +  OpenSessionArg->Ret = MsgArg->Ret;

> +  OpenSessionArg->RetOrigin = MsgArg->RetOrigin;

> +

> +  return EFI_SUCCESS;

> +}

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeCloseSession (

> +  IN UINT32                      Session

> +  )

> +{

> +  OPTEE_MSG_ARG *MsgArg = NULL;

> +

> +  if (OpteeShmInfo.Base == 0) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> +    return EFI_NOT_STARTED;

> +  }

> +

> +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> +  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));

> +

> +  MsgArg->Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;

> +  MsgArg->Session = Session;

> +

> +  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);

> +

> +  return EFI_SUCCESS;

> +}

> +

> +STATIC

> +EFI_STATUS

> +OpteeToMsgParam (

> +  OUT OPTEE_MSG_PARAM    *MsgParams,

> +  IN UINT32              NumParams,

> +  IN OPTEE_MSG_PARAM     *InParams

> +  )

> +{

> +  UINT32                  n;

> +  EFI_VIRTUAL_ADDRESS     ParamShmAddr;

> +  UINTN                   ShmSize;

> +  UINTN                   Size;

> +

> +  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));

> +  ParamShmAddr = OpteeShmInfo.Base + Size;

> +  ShmSize = OpteeShmInfo.Size - Size;

> +

> +  for (n = 0; n < NumParams; n++) {

> +    CONST OPTEE_MSG_PARAM *Ip = InParams + n;

> +    OPTEE_MSG_PARAM *Mp = MsgParams + n;

> +    UINT32 Attr = Ip->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> +

> +    switch (Attr) {

> +    case OPTEE_MSG_ATTR_TYPE_NONE:

> +      Mp->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> +      memset(&Mp->U, 0, sizeof (Mp->U));

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> +      Mp->Attr = Attr;

> +      Mp->U.Value.A = Ip->U.Value.A;

> +      Mp->U.Value.B = Ip->U.Value.B;

> +      Mp->U.Value.C = Ip->U.Value.C;

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> +      Mp->Attr = Attr;

> +

> +      if (Ip->U.Mem.Size > ShmSize) {

> +        return EFI_OUT_OF_RESOURCES;

> +      }

> +

> +      memcpy((VOID *) ParamShmAddr, (VOID *) Ip->U.Mem.BufPtr,

> Ip->U.Mem.Size);

> +      Mp->U.Mem.BufPtr = (UINT64) ParamShmAddr;

> +      Mp->U.Mem.Size = Ip->U.Mem.Size;

> +

> +      Size = roundup (Ip->U.Mem.Size, sizeof (UINT64));

> +      ParamShmAddr += Size;

> +      ShmSize -= Size;

> +      break;

> +

> +    default:

> +      return EFI_INVALID_PARAMETER;

> +    }

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +STATIC

> +EFI_STATUS

> +OpteeFromMsgParam (

> +  OUT OPTEE_MSG_PARAM    *OutParams,

> +  IN UINT32              NumParams,

> +  IN OPTEE_MSG_PARAM     *MsgParams

> +  )

> +{

> +  UINT32                  n;

> +

> +  for (n = 0; n < NumParams; n++) {

> +    OPTEE_MSG_PARAM *Op = OutParams + n;

> +    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;

> +    UINT32 Attr = Mp->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> +

> +    switch (Attr) {

> +    case OPTEE_MSG_ATTR_TYPE_NONE:

> +      Op->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> +      memset(&Op->U, 0, sizeof (Op->U));

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> +      Op->Attr = Attr;

> +      Op->U.Value.A = Mp->U.Value.A;

> +      Op->U.Value.B = Mp->U.Value.B;

> +      Op->U.Value.C = Mp->U.Value.C;

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> +      Op->Attr = Attr;

> +

> +      if (Mp->U.Mem.Size > Op->U.Mem.Size) {

> +        return EFI_BAD_BUFFER_SIZE;

> +      }

> +

> +      memcpy((VOID *) Op->U.Mem.BufPtr, (VOID *) Mp->U.Mem.BufPtr,

> Mp->U.Mem.Size);

> +      Op->U.Mem.Size = Mp->U.Mem.Size;

> +      break;

> +

> +    default:

> +      return EFI_INVALID_PARAMETER;

> +    }

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeInvokeFunc (

> +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> +  )

> +{

> +  EFI_STATUS    Status;

> +  OPTEE_MSG_ARG *MsgArg = NULL;

> +

> +  if (OpteeShmInfo.Base == 0) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> +    return EFI_NOT_STARTED;

> +  }

> +

> +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

> +

> +  MsgArg->Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;

> +  MsgArg->Func = InvokeFuncArg->Func;

> +  MsgArg->Session = InvokeFuncArg->Session;

> +

> +  Status = OpteeToMsgParam(MsgArg->Params, MAX_PARAMS,

> InvokeFuncArg->Params);

> +  if (Status)

> +    return Status;

> +

> +  MsgArg->NumParams = MAX_PARAMS;

> +

> +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

> +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> +  }

> +

> +  if (OpteeFromMsgParam(InvokeFuncArg->Params, MAX_PARAMS,

> MsgArg->Params)) {

> +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> +  }

> +

> +  InvokeFuncArg->Ret = MsgArg->Ret;

> +  InvokeFuncArg->RetOrigin = MsgArg->RetOrigin;

> +

> +  return EFI_SUCCESS;

> +}

> diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf

> b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> index 5abd427379cc..e03054a7167d 100644

> --- a/ArmPkg/Library/OpteeLib/OpteeLib.inf

> +++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> @@ -23,11 +23,13 @@ [Defines]

>

>  [Sources]

>    Optee.c

> +  OpteeSmc.h

>

>  [Packages]

>    ArmPkg/ArmPkg.dec

>    MdePkg/MdePkg.dec

>

>  [LibraryClasses]

> +  ArmMmuLib

>    ArmSmcLib

>    BaseLib

> diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h

> b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> new file mode 100644

> index 000000000000..f98a9c5b85cc

> --- /dev/null

> +++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> @@ -0,0 +1,51 @@

> +/** @file

> +  OP-TEE SMC header file.

> +

> +  Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>

> +

> +  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.

> +

> +**/

> +

> +#ifndef _OPTEE_SMC_H_

> +#define _OPTEE_SMC_H_

> +

> +/* Returned in Arg0 only from Trusted OS functions */

> +#define OPTEE_SMC_RETURN_OK                     0x0

> +

> +#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003

> +#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004

> +#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007

> +

> +#define OPTEE_SMC_SHM_CACHED                    1

> +

> +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004

> +

> +#define OPTEE_MSG_CMD_OPEN_SESSION              0

> +#define OPTEE_MSG_CMD_INVOKE_COMMAND            1

> +#define OPTEE_MSG_CMD_CLOSE_SESSION             2

> +

> +#define OPTEE_MSG_ATTR_META                     0x100

> +

> +#define TEE_LOGIN_PUBLIC                        0x0

> +

> +/* Some Global Platform error codes used in this driver */

> +#define TEEC_SUCCESS                            0x00000000

> +#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006

> +#define TEEC_ERROR_COMMUNICATION                0xFFFF000E

> +#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C

> +

> +#define TEEC_ORIGIN_COMMS                       0x00000002

> +

> +typedef struct {

> +  EFI_VIRTUAL_ADDRESS    Base;

> +  UINTN                  Size;

> +} OPTEE_SHARED_MEMORY_INFO;

> +

> +#endif

> --

> 2.7.4

>

>
<div dir="ltr">Hi All,<div><br></div><div>I have tried to prepare a generic OP-TEE driver for edk2/UEFI. Use-case for edk2/UEFI OP-TEE driver is to provide boot-time services using Static TA. One of examples is RNG service for Developerbox useful for features like KASLR.</div><div><br></div><div><div>Please help me with internal review.</div></div><div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">Regards,<div>Sumit</div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 20 Aug 2018 at 19:05, Sumit Garg &lt;<a href="mailto:sumit.garg@linaro.org">sumit.garg@linaro.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Add following APIs to communicate with OP-TEE static TA:<br>
1. OpteeInit<br>
2. OpteeOpenSession<br>
3. OpteeCloseSession<br>
4. OpteeInvokeFunc<br>
<br>
Contributed-under: TianoCore Contribution Agreement 1.1<br>
Signed-off-by: Sumit Garg &lt;<a href="mailto:sumit.garg@linaro.org" target="_blank">sumit.garg@linaro.org</a>&gt;<br>

---<br>
 ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++<br>
 ArmPkg/Library/OpteeLib/Optee.c      | 344 +++++++++++++++++++++++++++++++++++<br>
 ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +<br>
 ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++<br>
 4 files changed, 499 insertions(+)<br>
 create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h<br>
<br>
diff --git a/ArmPkg/Include/Library/OpteeLib.h b/ArmPkg/Include/Library/OpteeLib.h<br>
index f65d8674d9b8..59ae63526f58 100644<br>
--- a/ArmPkg/Include/Library/OpteeLib.h<br>
+++ b/ArmPkg/Include/Library/OpteeLib.h<br>
@@ -25,10 +25,112 @@<br>
 #define OPTEE_OS_UID2          0xaf630002<br>
 #define OPTEE_OS_UID3          0xa5d5c51b<br>
<br>
+#define OPTEE_MSG_ATTR_TYPE_NONE                0x0<br>
+#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1<br>
+#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2<br>
+#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3<br>
+#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9<br>
+#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa<br>
+#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb<br>
+<br>
+#define OPTEE_MSG_ATTR_TYPE_MASK                0xff<br>
+<br>
+typedef struct {<br>
+  UINT64    BufPtr;<br>
+  UINT64    Size;<br>
+  UINT64    ShmRef;<br>
+} OPTEE_MSG_PARAM_MEM;<br>
+<br>
+typedef struct {<br>
+  UINT64    A;<br>
+  UINT64    B;<br>
+  UINT64    C;<br>
+} OPTEE_MSG_PARAM_VALUE;<br>
+<br>
+typedef struct {<br>
+  UINT64 Attr;<br>
+  union {<br>
+    OPTEE_MSG_PARAM_MEM      Mem;<br>
+    OPTEE_MSG_PARAM_VALUE    Value;<br>
+  } U;<br>
+} OPTEE_MSG_PARAM;<br>
+<br>
+#define MAX_PARAMS           4<br>
+<br>
+typedef struct {<br>
+        UINT32             Cmd;<br>
+        UINT32             Func;<br>
+        UINT32             Session;<br>
+        UINT32             CancelId;<br>
+        UINT32             Pad;<br>
+        UINT32             Ret;<br>
+        UINT32             RetOrigin;<br>
+        UINT32             NumParams;<br>
+<br>
+        /* NumParams tells the actual number of element in Params */<br>
+        OPTEE_MSG_PARAM    Params[MAX_PARAMS];<br>
+} OPTEE_MSG_ARG;<br>
+<br>
+#define OPTEE_UUID_LEN       16<br>
+<br>
+/**<br>
+ * struct OPTEE_OPEN_SESSION_ARG - Open session argument<br>
+ * @Uuid:       [in] UUID of the Trusted Application<br>
+ * @Session:    [out] Session id<br>
+ * @Ret:        [out] Return value<br>
+ * @RetOrigin   [out] Origin of the return value<br>
+ */<br>
+typedef struct {<br>
+        UINT8     Uuid[OPTEE_UUID_LEN];<br>
+        UINT32    Session;<br>
+        UINT32    Ret;<br>
+        UINT32    RetOrigin;<br>
+} OPTEE_OPEN_SESSION_ARG;<br>
+<br>
+/**<br>
+ * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument<br>
+ * @Func:       [in] Trusted Application function, specific to the TA<br>
+ * @Session:    [in] Session id<br>
+ * @Ret:        [out] Return value<br>
+ * @RetOrigin   [out] Origin of the return value<br>
+ * @Params      [inout] Parameters for function to be invoked<br>
+ */<br>
+typedef struct {<br>
+        UINT32             Func;<br>
+        UINT32             Session;<br>
+        UINT32             Ret;<br>
+        UINT32             RetOrigin;<br>
+        OPTEE_MSG_PARAM    Params[MAX_PARAMS];<br>
+} OPTEE_INVOKE_FUNC_ARG;<br>
+<br>
 BOOLEAN<br>
 EFIAPI<br>
 IsOpteePresent (<br>
   VOID<br>
   );<br>
<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeInit (<br>
+  VOID<br>
+  );<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeOpenSession (<br>
+  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg<br>
+  );<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeCloseSession (<br>
+  IN UINT32                      Session<br>
+  );<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeInvokeFunc (<br>
+  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg<br>
+  );<br>
+<br>
 #endif<br>
diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c<br>
index 574527f8b5ea..498bf0165f24 100644<br>
--- a/ArmPkg/Library/OpteeLib/Optee.c<br>
+++ b/ArmPkg/Library/OpteeLib/Optee.c<br>
@@ -14,11 +14,19 @@<br>
<br>
 **/<br>
<br>
+#include &lt;Library/ArmMmuLib.h&gt;<br>
 #include &lt;Library/ArmSmcLib.h&gt;<br>
 #include &lt;Library/BaseLib.h&gt;<br>
+#include &lt;Library/DebugLib.h&gt;<br>
 #include &lt;Library/OpteeLib.h&gt;<br>
<br>
 #include &lt;IndustryStandard/ArmStdSmc.h&gt;<br>
+#include &lt;OpteeSmc.h&gt;<br>
+#include &lt;string.h&gt;<br>
+#include &lt;sys/param.h&gt;<br>
+#include &lt;Uefi.h&gt;<br>
+<br>
+STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };<br>
<br>
 /**<br>
   Check for OP-TEE presence.<br>
@@ -31,6 +39,7 @@ IsOpteePresent (<br>
 {<br>
   ARM_SMC_ARGS ArmSmcArgs;<br>
<br>
+  memset (&amp;ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));<br>
   // Send a Trusted OS Calls UID command<br>
   ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;<br>
   ArmCallSmc (&amp;ArmSmcArgs);<br>
@@ -44,3 +53,338 @@ IsOpteePresent (<br>
     return FALSE;<br>
   }<br>
 }<br>
+<br>
+STATIC<br>
+EFI_STATUS<br>
+OpteeShmMemRemap (<br>
+  VOID<br>
+  )<br>
+{<br>
+  ARM_SMC_ARGS                 ArmSmcArgs;<br>
+  EFI_PHYSICAL_ADDRESS         Paddr;<br>
+  EFI_PHYSICAL_ADDRESS         Start;<br>
+  EFI_PHYSICAL_ADDRESS         End;<br>
+  EFI_STATUS                   Status;<br>
+  UINTN                        Size;<br>
+<br>
+  memset (&amp;ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));<br>
+  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_CONFIG;<br>
+<br>
+  ArmCallSmc (&amp;ArmSmcArgs);<br>
+  if (ArmSmcArgs.Arg0 != OPTEE_SMC_RETURN_OK) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE shared memory not supported\n&quot;));<br>
+    return EFI_UNSUPPORTED;<br>
+  }<br>
+<br>
+  if (ArmSmcArgs.Arg3 != OPTEE_SMC_SHM_CACHED) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE: Only normal cached shared memory supported\n&quot;));<br>
+    return EFI_UNSUPPORTED;<br>
+  }<br>
+<br>
+  Start = (ArmSmcArgs.Arg1 + SIZE_4KB - 1) &amp; ~(SIZE_4KB - 1);<br>
+  End = (ArmSmcArgs.Arg1 + ArmSmcArgs.Arg2) &amp; ~(SIZE_4KB - 1);<br>
+  Paddr = Start;<br>
+  Size = End - Start;<br>
+<br>
+  if (Size &lt; SIZE_4KB) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE shared memory too small\n&quot;));<br>
+    return EFI_BUFFER_TOO_SMALL;<br>
+  }<br>
+<br>
+  Status = ArmSetMemoryAttributes (Paddr, Size, EFI_MEMORY_WB);<br>
+  if (EFI_ERROR (Status)) {<br>
+    return Status;<br>
+  }<br>
+<br>
+  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;<br>
+  OpteeShmInfo.Size = Size;<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeInit (<br>
+  VOID<br>
+  )<br>
+{<br>
+  EFI_STATUS      Status;<br>
+<br>
+  if (!IsOpteePresent()) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE not present\n&quot;));<br>
+    return EFI_UNSUPPORTED;<br>
+  }<br>
+<br>
+  Status = OpteeShmMemRemap ();<br>
+  if (EFI_ERROR (Status)) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE shared memory remap failed\n&quot;));<br>
+    return Status;<br>
+  }<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
+<br>
+/**<br>
+ * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world<br>
+ * @Parg:  physical address of message to pass to secure world<br>
+ *<br>
+ * Does Standard SMC to OP-TEE in secure world.<br>
+ *<br>
+ * Returns return code from secure world, 0 is OK<br>
+ */<br>
+STATIC<br>
+UINT32<br>
+OpteeCallWithArg (<br>
+  IN EFI_PHYSICAL_ADDRESS Parg<br>
+  )<br>
+{<br>
+  ARM_SMC_ARGS ArmSmcArgs;<br>
+<br>
+  memset (&amp;ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));<br>
+  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;<br>
+  ArmSmcArgs.Arg1 = (UINT32) (Parg &gt;&gt; 32);<br>
+  ArmSmcArgs.Arg2 = (UINT32) Parg;<br>
+<br>
+  while (TRUE) {<br>
+    ArmCallSmc (&amp;ArmSmcArgs);<br>
+<br>
+    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {<br>
+      /*<br>
+       * A foreign interrupt was raised while secure world was<br>
+       * executing, since they are handled in UEFI a dummy RPC is<br>
+       * performed to let UEFI take the interrupt through the normal<br>
+       * vector.<br>
+       */<br>
+      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;<br>
+    } else {<br>
+      break;<br>
+    }<br>
+  }<br>
+<br>
+  return ArmSmcArgs.Arg0;<br>
+}<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeOpenSession (<br>
+  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg<br>
+  )<br>
+{<br>
+  OPTEE_MSG_ARG *MsgArg = NULL;<br>
+<br>
+  if (OpteeShmInfo.Base == 0) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE not initialized\n&quot;));<br>
+    return EFI_NOT_STARTED;<br>
+  }<br>
+<br>
+  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;<br>
+  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));<br>
+<br>
+  MsgArg-&gt;Cmd = OPTEE_MSG_CMD_OPEN_SESSION;<br>
+<br>
+  /*<br>
+   * Initialize and add the meta parameters needed when opening a<br>
+   * session.<br>
+   */<br>
+  MsgArg-&gt;Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |<br>
+                           OPTEE_MSG_ATTR_META;<br>
+  MsgArg-&gt;Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |<br>
+                           OPTEE_MSG_ATTR_META;<br>
+  memcpy(&amp;MsgArg-&gt;Params[0].U.Value, OpenSessionArg-&gt;Uuid, OPTEE_UUID_LEN);<br>
+  memset(&amp;MsgArg-&gt;Params[1].U.Value, 0, OPTEE_UUID_LEN);<br>
+  MsgArg-&gt;Params[1].U.Value.C = TEE_LOGIN_PUBLIC;<br>
+<br>
+  MsgArg-&gt;NumParams = 2;<br>
+<br>
+  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {<br>
+    MsgArg-&gt;Ret = TEEC_ERROR_COMMUNICATION;<br>
+    MsgArg-&gt;RetOrigin = TEEC_ORIGIN_COMMS;<br>
+  }<br>
+<br>
+  OpenSessionArg-&gt;Session = MsgArg-&gt;Session;<br>
+  OpenSessionArg-&gt;Ret = MsgArg-&gt;Ret;<br>
+  OpenSessionArg-&gt;RetOrigin = MsgArg-&gt;RetOrigin;<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeCloseSession (<br>
+  IN UINT32                      Session<br>
+  )<br>
+{<br>
+  OPTEE_MSG_ARG *MsgArg = NULL;<br>
+<br>
+  if (OpteeShmInfo.Base == 0) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE not initialized\n&quot;));<br>
+    return EFI_NOT_STARTED;<br>
+  }<br>
+<br>
+  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;<br>
+  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));<br>
+<br>
+  MsgArg-&gt;Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;<br>
+  MsgArg-&gt;Session = Session;<br>
+<br>
+  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
+<br>
+STATIC<br>
+EFI_STATUS<br>
+OpteeToMsgParam (<br>
+  OUT OPTEE_MSG_PARAM    *MsgParams,<br>
+  IN UINT32              NumParams,<br>
+  IN OPTEE_MSG_PARAM     *InParams<br>
+  )<br>
+{<br>
+  UINT32                  n;<br>
+  EFI_VIRTUAL_ADDRESS     ParamShmAddr;<br>
+  UINTN                   ShmSize;<br>
+  UINTN                   Size;<br>
+<br>
+  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));<br>
+  ParamShmAddr = OpteeShmInfo.Base + Size;<br>
+  ShmSize = OpteeShmInfo.Size - Size;<br>
+<br>
+  for (n = 0; n &lt; NumParams; n++) {<br>
+    CONST OPTEE_MSG_PARAM *Ip = InParams + n;<br>
+    OPTEE_MSG_PARAM *Mp = MsgParams + n;<br>
+    UINT32 Attr = Ip-&gt;Attr &amp; OPTEE_MSG_ATTR_TYPE_MASK;<br>
+<br>
+    switch (Attr) {<br>
+    case OPTEE_MSG_ATTR_TYPE_NONE:<br>
+      Mp-&gt;Attr = OPTEE_MSG_ATTR_TYPE_NONE;<br>
+      memset(&amp;Mp-&gt;U, 0, sizeof (Mp-&gt;U));<br>
+      break;<br>
+<br>
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:<br>
+      Mp-&gt;Attr = Attr;<br>
+      Mp-&gt;U.Value.A = Ip-&gt;U.Value.A;<br>
+      Mp-&gt;U.Value.B = Ip-&gt;U.Value.B;<br>
+      Mp-&gt;U.Value.C = Ip-&gt;U.Value.C;<br>
+      break;<br>
+<br>
+    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:<br>
+      Mp-&gt;Attr = Attr;<br>
+<br>
+      if (Ip-&gt;U.Mem.Size &gt; ShmSize) {<br>
+        return EFI_OUT_OF_RESOURCES;<br>
+      }<br>
+<br>
+      memcpy((VOID *) ParamShmAddr, (VOID *) Ip-&gt;U.Mem.BufPtr, Ip-&gt;U.Mem.Size);<br>
+      Mp-&gt;U.Mem.BufPtr = (UINT64) ParamShmAddr;<br>
+      Mp-&gt;U.Mem.Size = Ip-&gt;U.Mem.Size;<br>
+<br>
+      Size = roundup (Ip-&gt;U.Mem.Size, sizeof (UINT64));<br>
+      ParamShmAddr += Size;<br>
+      ShmSize -= Size;<br>
+      break;<br>
+<br>
+    default:<br>
+      return EFI_INVALID_PARAMETER;<br>
+    }<br>
+  }<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
+<br>
+STATIC<br>
+EFI_STATUS<br>
+OpteeFromMsgParam (<br>
+  OUT OPTEE_MSG_PARAM    *OutParams,<br>
+  IN UINT32              NumParams,<br>
+  IN OPTEE_MSG_PARAM     *MsgParams<br>
+  )<br>
+{<br>
+  UINT32                  n;<br>
+<br>
+  for (n = 0; n &lt; NumParams; n++) {<br>
+    OPTEE_MSG_PARAM *Op = OutParams + n;<br>
+    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;<br>
+    UINT32 Attr = Mp-&gt;Attr &amp; OPTEE_MSG_ATTR_TYPE_MASK;<br>
+<br>
+    switch (Attr) {<br>
+    case OPTEE_MSG_ATTR_TYPE_NONE:<br>
+      Op-&gt;Attr = OPTEE_MSG_ATTR_TYPE_NONE;<br>
+      memset(&amp;Op-&gt;U, 0, sizeof (Op-&gt;U));<br>
+      break;<br>
+<br>
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:<br>
+      Op-&gt;Attr = Attr;<br>
+      Op-&gt;U.Value.A = Mp-&gt;U.Value.A;<br>
+      Op-&gt;U.Value.B = Mp-&gt;U.Value.B;<br>
+      Op-&gt;U.Value.C = Mp-&gt;U.Value.C;<br>
+      break;<br>
+<br>
+    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:<br>
+    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:<br>
+      Op-&gt;Attr = Attr;<br>
+<br>
+      if (Mp-&gt;U.Mem.Size &gt; Op-&gt;U.Mem.Size) {<br>
+        return EFI_BAD_BUFFER_SIZE;<br>
+      }<br>
+<br>
+      memcpy((VOID *) Op-&gt;U.Mem.BufPtr, (VOID *) Mp-&gt;U.Mem.BufPtr, Mp-&gt;U.Mem.Size);<br>
+      Op-&gt;U.Mem.Size = Mp-&gt;U.Mem.Size;<br>
+      break;<br>
+<br>
+    default:<br>
+      return EFI_INVALID_PARAMETER;<br>
+    }<br>
+  }<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
+<br>
+EFI_STATUS<br>
+EFIAPI<br>
+OpteeInvokeFunc (<br>
+  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg<br>
+  )<br>
+{<br>
+  EFI_STATUS    Status;<br>
+  OPTEE_MSG_ARG *MsgArg = NULL;<br>
+<br>
+  if (OpteeShmInfo.Base == 0) {<br>
+    DEBUG ((DEBUG_WARN, &quot;OP-TEE not initialized\n&quot;));<br>
+    return EFI_NOT_STARTED;<br>
+  }<br>
+<br>
+  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;<br>
+  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));<br>
+<br>
+  MsgArg-&gt;Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;<br>
+  MsgArg-&gt;Func = InvokeFuncArg-&gt;Func;<br>
+  MsgArg-&gt;Session = InvokeFuncArg-&gt;Session;<br>
+<br>
+  Status = OpteeToMsgParam(MsgArg-&gt;Params, MAX_PARAMS, InvokeFuncArg-&gt;Params);<br>
+  if (Status)<br>
+    return Status;<br>
+<br>
+  MsgArg-&gt;NumParams = MAX_PARAMS;<br>
+<br>
+  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {<br>
+    MsgArg-&gt;Ret = TEEC_ERROR_COMMUNICATION;<br>
+    MsgArg-&gt;RetOrigin = TEEC_ORIGIN_COMMS;<br>
+  }<br>
+<br>
+  if (OpteeFromMsgParam(InvokeFuncArg-&gt;Params, MAX_PARAMS, MsgArg-&gt;Params)) {<br>
+    MsgArg-&gt;Ret = TEEC_ERROR_COMMUNICATION;<br>
+    MsgArg-&gt;RetOrigin = TEEC_ORIGIN_COMMS;<br>
+  }<br>
+<br>
+  InvokeFuncArg-&gt;Ret = MsgArg-&gt;Ret;<br>
+  InvokeFuncArg-&gt;RetOrigin = MsgArg-&gt;RetOrigin;<br>
+<br>
+  return EFI_SUCCESS;<br>
+}<br>
diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf b/ArmPkg/Library/OpteeLib/OpteeLib.inf<br>
index 5abd427379cc..e03054a7167d 100644<br>
--- a/ArmPkg/Library/OpteeLib/OpteeLib.inf<br>
+++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf<br>
@@ -23,11 +23,13 @@ [Defines]<br>
<br>
 [Sources]<br>
   Optee.c<br>
+  OpteeSmc.h<br>
<br>
 [Packages]<br>
   ArmPkg/ArmPkg.dec<br>
   MdePkg/MdePkg.dec<br>
<br>
 [LibraryClasses]<br>
+  ArmMmuLib<br>
   ArmSmcLib<br>
   BaseLib<br>
diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h b/ArmPkg/Library/OpteeLib/OpteeSmc.h<br>
new file mode 100644<br>
index 000000000000..f98a9c5b85cc<br>
--- /dev/null<br>
+++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h<br>
@@ -0,0 +1,51 @@<br>
+/** @file<br>
+  OP-TEE SMC header file.<br>
+<br>
+  Copyright (c) 2018, Linaro Ltd. All rights reserved.&lt;BR&gt;<br>
+<br>
+  This program and the accompanying materials<br>
+  are licensed and made available under the terms and conditions of the BSD License<br>
+  which accompanies this distribution.  The full text of the license may be found at<br>
+  <a href="http://opensource.org/licenses/bsd-license.php" rel="noreferrer" target="_blank">http://opensource.org/licenses/bsd-license.php</a><br>
+<br>
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN &quot;AS IS&quot; BASIS,<br>
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.<br>
+<br>
+**/<br>
+<br>
+#ifndef _OPTEE_SMC_H_<br>
+#define _OPTEE_SMC_H_<br>
+<br>
+/* Returned in Arg0 only from Trusted OS functions */<br>
+#define OPTEE_SMC_RETURN_OK                     0x0<br>
+<br>
+#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003<br>
+#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004<br>
+#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007<br>
+<br>
+#define OPTEE_SMC_SHM_CACHED                    1<br>
+<br>
+#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004<br>
+<br>
+#define OPTEE_MSG_CMD_OPEN_SESSION              0<br>
+#define OPTEE_MSG_CMD_INVOKE_COMMAND            1<br>
+#define OPTEE_MSG_CMD_CLOSE_SESSION             2<br>
+<br>
+#define OPTEE_MSG_ATTR_META                     0x100<br>
+<br>
+#define TEE_LOGIN_PUBLIC                        0x0<br>
+<br>
+/* Some Global Platform error codes used in this driver */<br>
+#define TEEC_SUCCESS                            0x00000000<br>
+#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006<br>
+#define TEEC_ERROR_COMMUNICATION                0xFFFF000E<br>
+#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C<br>
+<br>
+#define TEEC_ORIGIN_COMMS                       0x00000002<br>
+<br>
+typedef struct {<br>
+  EFI_VIRTUAL_ADDRESS    Base;<br>
+  UINTN                  Size;<br>
+} OPTEE_SHARED_MEMORY_INFO;<br>
+<br>
+#endif<br>
-- <br>
2.7.4<br>
<br>
</blockquote></div>
Ard Biesheuvel Aug. 21, 2018, 1:09 p.m. UTC | #2
On 20 August 2018 at 15:35, Sumit Garg <sumit.garg@linaro.org> wrote:
> Add following APIs to communicate with OP-TEE static TA:

> 1. OpteeInit

> 2. OpteeOpenSession

> 3. OpteeCloseSession

> 4. OpteeInvokeFunc

>

> Contributed-under: TianoCore Contribution Agreement 1.1

> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

> ---

>  ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++

>  ArmPkg/Library/OpteeLib/Optee.c      | 344 +++++++++++++++++++++++++++++++++++

>  ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +

>  ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++

>  4 files changed, 499 insertions(+)

>  create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h

>

> diff --git a/ArmPkg/Include/Library/OpteeLib.h b/ArmPkg/Include/Library/OpteeLib.h

> index f65d8674d9b8..59ae63526f58 100644

> --- a/ArmPkg/Include/Library/OpteeLib.h

> +++ b/ArmPkg/Include/Library/OpteeLib.h

> @@ -25,10 +25,112 @@

>  #define OPTEE_OS_UID2          0xaf630002

>  #define OPTEE_OS_UID3          0xa5d5c51b

>

> +#define OPTEE_MSG_ATTR_TYPE_NONE                0x0

> +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1

> +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2

> +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3

> +#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9

> +#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa

> +#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb

> +

> +#define OPTEE_MSG_ATTR_TYPE_MASK                0xff

> +

> +typedef struct {

> +  UINT64    BufPtr;

> +  UINT64    Size;

> +  UINT64    ShmRef;

> +} OPTEE_MSG_PARAM_MEM;

> +

> +typedef struct {

> +  UINT64    A;

> +  UINT64    B;

> +  UINT64    C;

> +} OPTEE_MSG_PARAM_VALUE;

> +

> +typedef struct {

> +  UINT64 Attr;

> +  union {

> +    OPTEE_MSG_PARAM_MEM      Mem;

> +    OPTEE_MSG_PARAM_VALUE    Value;

> +  } U;

> +} OPTEE_MSG_PARAM;

> +

> +#define MAX_PARAMS           4

> +

> +typedef struct {

> +        UINT32             Cmd;

> +        UINT32             Func;

> +        UINT32             Session;

> +        UINT32             CancelId;

> +        UINT32             Pad;

> +        UINT32             Ret;

> +        UINT32             RetOrigin;

> +        UINT32             NumParams;

> +

> +        /* NumParams tells the actual number of element in Params */

> +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> +} OPTEE_MSG_ARG;

> +

> +#define OPTEE_UUID_LEN       16

> +

> +/**

> + * struct OPTEE_OPEN_SESSION_ARG - Open session argument

> + * @Uuid:       [in] UUID of the Trusted Application

> + * @Session:    [out] Session id

> + * @Ret:        [out] Return value

> + * @RetOrigin   [out] Origin of the return value


Please use trailing // comments to describe the struct members. Using
a header like this is not idiomatic for Tianocore.

Alternatively, if the license allows it, you can simply introduce the
OP-TEE client header file in Include/IndustryStandard/ and refer to
the types by their original names.

> + */

> +typedef struct {

> +        UINT8     Uuid[OPTEE_UUID_LEN];

> +        UINT32    Session;

> +        UINT32    Ret;

> +        UINT32    RetOrigin;

> +} OPTEE_OPEN_SESSION_ARG;

> +

> +/**

> + * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument

> + * @Func:       [in] Trusted Application function, specific to the TA

> + * @Session:    [in] Session id

> + * @Ret:        [out] Return value

> + * @RetOrigin   [out] Origin of the return value

> + * @Params      [inout] Parameters for function to be invoked

> + */

> +typedef struct {

> +        UINT32             Func;

> +        UINT32             Session;

> +        UINT32             Ret;

> +        UINT32             RetOrigin;

> +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> +} OPTEE_INVOKE_FUNC_ARG;

> +

>  BOOLEAN

>  EFIAPI

>  IsOpteePresent (

>    VOID

>    );

>

> +EFI_STATUS

> +EFIAPI

> +OpteeInit (

> +  VOID

> +  );

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeOpenSession (

> +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> +  );

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeCloseSession (

> +  IN UINT32                      Session

> +  );

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeInvokeFunc (

> +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> +  );

> +

>  #endif

> diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c

> index 574527f8b5ea..498bf0165f24 100644

> --- a/ArmPkg/Library/OpteeLib/Optee.c

> +++ b/ArmPkg/Library/OpteeLib/Optee.c

> @@ -14,11 +14,19 @@

>

>  **/

>

> +#include <Library/ArmMmuLib.h>

>  #include <Library/ArmSmcLib.h>

>  #include <Library/BaseLib.h>

> +#include <Library/DebugLib.h>

>  #include <Library/OpteeLib.h>

>

>  #include <IndustryStandard/ArmStdSmc.h>

> +#include <OpteeSmc.h>


> +#include <string.h>

> +#include <sys/param.h>


Please drop these includes.

> +#include <Uefi.h>

> +

> +STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };

>

>  /**

>    Check for OP-TEE presence.

> @@ -31,6 +39,7 @@ IsOpteePresent (

>  {

>    ARM_SMC_ARGS ArmSmcArgs;

>

> +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));


Please use ZeroMem() here

>    // Send a Trusted OS Calls UID command

>    ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;

>    ArmCallSmc (&ArmSmcArgs);

> @@ -44,3 +53,338 @@ IsOpteePresent (

>      return FALSE;

>    }

>  }

> +

> +STATIC

> +EFI_STATUS

> +OpteeShmMemRemap (

> +  VOID

> +  )

> +{

> +  ARM_SMC_ARGS                 ArmSmcArgs;

> +  EFI_PHYSICAL_ADDRESS         Paddr;

> +  EFI_PHYSICAL_ADDRESS         Start;

> +  EFI_PHYSICAL_ADDRESS         End;

> +  EFI_STATUS                   Status;

> +  UINTN                        Size;

> +

> +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> +  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_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_SHM_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);

> +  Paddr = 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 (Paddr, Size, EFI_MEMORY_WB);

> +  if (EFI_ERROR (Status)) {

> +    return Status;

> +  }

> +

> +  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;


Please use UINTN for virtual addresses: if we ever want to run this
code on 32-bit ARM, having 64-bit virtual addresses is probably not
going to work, right?

> +  OpteeShmInfo.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 = OpteeShmMemRemap ();

> +  if (EFI_ERROR (Status)) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));

> +    return Status;

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +/**

> + * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world

> + * @Parg:  physical address of message to pass to secure world


Please use the common Tianocore notation here:

@param[in]  Parg   Physical address of message to pass to secure world

@return            0 on success, secure world return code otherwise

> + *

> + * Does Standard SMC to OP-TEE in secure world.

> + *

> + * Returns return code from secure world, 0 is OK

> + */

> +STATIC

> +UINT32

> +OpteeCallWithArg (

> +  IN EFI_PHYSICAL_ADDRESS Parg

> +  )

> +{

> +  ARM_SMC_ARGS ArmSmcArgs;

> +

> +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));


Use ZeroMem()

> +  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;

> +  ArmSmcArgs.Arg1 = (UINT32) (Parg >> 32);

> +  ArmSmcArgs.Arg2 = (UINT32) Parg;

> +

> +  while (TRUE) {

> +    ArmCallSmc (&ArmSmcArgs);

> +

> +    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {

> +      /*

> +       * 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.

> +       */


I don't care deeply personally, but using // for multiline comments is
more idiomatic for Tianocore

> +      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;

> +    } else {

> +      break;

> +    }

> +  }

> +

> +  return ArmSmcArgs.Arg0;

> +}

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeOpenSession (

> +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> +  )

> +{

> +  OPTEE_MSG_ARG *MsgArg = NULL;

> +


Please avoid initializers for automatic variables: use assignments instead.

> +  if (OpteeShmInfo.Base == 0) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> +    return EFI_NOT_STARTED;

> +  }

> +

> +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;


No space after () cast operator

> +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

> +


ZeroMem()

> +  MsgArg->Cmd = OPTEE_MSG_CMD_OPEN_SESSION;

> +

> +  /*

> +   * Initialize and add the meta parameters needed when opening a

> +   * session.

> +   */

> +  MsgArg->Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> +                           OPTEE_MSG_ATTR_META;

> +  MsgArg->Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> +                           OPTEE_MSG_ATTR_META;

> +  memcpy(&MsgArg->Params[0].U.Value, OpenSessionArg->Uuid, OPTEE_UUID_LEN);


CopyMem()

> +  memset(&MsgArg->Params[1].U.Value, 0, OPTEE_UUID_LEN);


ZeroMem()

> +  MsgArg->Params[1].U.Value.C = TEE_LOGIN_PUBLIC;

> +

> +  MsgArg->NumParams = 2;

> +

> +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {


No space after () cast operator

> +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> +  }

> +

> +  OpenSessionArg->Session = MsgArg->Session;

> +  OpenSessionArg->Ret = MsgArg->Ret;

> +  OpenSessionArg->RetOrigin = MsgArg->RetOrigin;

> +

> +  return EFI_SUCCESS;

> +}

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeCloseSession (

> +  IN UINT32                      Session

> +  )

> +{

> +  OPTEE_MSG_ARG *MsgArg = NULL;

> +


No initializers

> +  if (OpteeShmInfo.Base == 0) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> +    return EFI_NOT_STARTED;

> +  }

> +

> +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> +  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));

> +


ZeroMem()

> +  MsgArg->Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;

> +  MsgArg->Session = Session;

> +

> +  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);


Space before function call ().

> +

> +  return EFI_SUCCESS;

> +}

> +

> +STATIC

> +EFI_STATUS

> +OpteeToMsgParam (

> +  OUT OPTEE_MSG_PARAM    *MsgParams,

> +  IN UINT32              NumParams,

> +  IN OPTEE_MSG_PARAM     *InParams

> +  )

> +{

> +  UINT32                  n;


Use Idx or similar for loop iterators.

> +  EFI_VIRTUAL_ADDRESS     ParamShmAddr;

> +  UINTN                   ShmSize;

> +  UINTN                   Size;

> +

> +  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));

> +  ParamShmAddr = OpteeShmInfo.Base + Size;

> +  ShmSize = OpteeShmInfo.Size - Size;

> +

> +  for (n = 0; n < NumParams; n++) {

> +    CONST OPTEE_MSG_PARAM *Ip = InParams + n;

> +    OPTEE_MSG_PARAM *Mp = MsgParams + n;

> +    UINT32 Attr = Ip->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> +


No initializers.

> +    switch (Attr) {

> +    case OPTEE_MSG_ATTR_TYPE_NONE:

> +      Mp->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> +      memset(&Mp->U, 0, sizeof (Mp->U));


ZeroMem()

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> +      Mp->Attr = Attr;

> +      Mp->U.Value.A = Ip->U.Value.A;

> +      Mp->U.Value.B = Ip->U.Value.B;

> +      Mp->U.Value.C = Ip->U.Value.C;

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> +      Mp->Attr = Attr;

> +

> +      if (Ip->U.Mem.Size > ShmSize) {

> +        return EFI_OUT_OF_RESOURCES;

> +      }

> +

> +      memcpy((VOID *) ParamShmAddr, (VOID *) Ip->U.Mem.BufPtr, Ip->U.Mem.Size);


CopyMem ()

> +      Mp->U.Mem.BufPtr = (UINT64) ParamShmAddr;

> +      Mp->U.Mem.Size = Ip->U.Mem.Size;

> +

> +      Size = roundup (Ip->U.Mem.Size, sizeof (UINT64));

> +      ParamShmAddr += Size;

> +      ShmSize -= Size;

> +      break;

> +

> +    default:

> +      return EFI_INVALID_PARAMETER;

> +    }

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +STATIC

> +EFI_STATUS

> +OpteeFromMsgParam (

> +  OUT OPTEE_MSG_PARAM    *OutParams,

> +  IN UINT32              NumParams,

> +  IN OPTEE_MSG_PARAM     *MsgParams

> +  )

> +{

> +  UINT32                  n;

> +


Idx

> +  for (n = 0; n < NumParams; n++) {

> +    OPTEE_MSG_PARAM *Op = OutParams + n;

> +    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;

> +    UINT32 Attr = Mp->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> +


Initializers

> +    switch (Attr) {

> +    case OPTEE_MSG_ATTR_TYPE_NONE:

> +      Op->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> +      memset(&Op->U, 0, sizeof (Op->U));


ZeroMem()

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> +      Op->Attr = Attr;

> +      Op->U.Value.A = Mp->U.Value.A;

> +      Op->U.Value.B = Mp->U.Value.B;

> +      Op->U.Value.C = Mp->U.Value.C;

> +      break;

> +

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> +      Op->Attr = Attr;

> +

> +      if (Mp->U.Mem.Size > Op->U.Mem.Size) {

> +        return EFI_BAD_BUFFER_SIZE;

> +      }

> +

> +      memcpy((VOID *) Op->U.Mem.BufPtr, (VOID *) Mp->U.Mem.BufPtr, Mp->U.Mem.Size);


CopyMem()

> +      Op->U.Mem.Size = Mp->U.Mem.Size;

> +      break;

> +

> +    default:

> +      return EFI_INVALID_PARAMETER;

> +    }

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +EFI_STATUS

> +EFIAPI

> +OpteeInvokeFunc (

> +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> +  )

> +{

> +  EFI_STATUS    Status;

> +  OPTEE_MSG_ARG *MsgArg = NULL;

> +


Initializers

> +  if (OpteeShmInfo.Base == 0) {

> +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> +    return EFI_NOT_STARTED;

> +  }

> +

> +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;


No space after () cast operator

> +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));


ZeroMem()

> +

> +  MsgArg->Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;

> +  MsgArg->Func = InvokeFuncArg->Func;

> +  MsgArg->Session = InvokeFuncArg->Session;

> +

> +  Status = OpteeToMsgParam(MsgArg->Params, MAX_PARAMS, InvokeFuncArg->Params);


Space before (

> +  if (Status)

> +    return Status;

> +

> +  MsgArg->NumParams = MAX_PARAMS;

> +

> +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {


Space before (

> +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> +  }

> +

> +  if (OpteeFromMsgParam(InvokeFuncArg->Params, MAX_PARAMS, MsgArg->Params)) {


idem

> +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> +  }

> +

> +  InvokeFuncArg->Ret = MsgArg->Ret;

> +  InvokeFuncArg->RetOrigin = MsgArg->RetOrigin;

> +

> +  return EFI_SUCCESS;

> +}

> diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> index 5abd427379cc..e03054a7167d 100644

> --- a/ArmPkg/Library/OpteeLib/OpteeLib.inf

> +++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> @@ -23,11 +23,13 @@ [Defines]

>

>  [Sources]

>    Optee.c

> +  OpteeSmc.h

>

>  [Packages]

>    ArmPkg/ArmPkg.dec

>    MdePkg/MdePkg.dec

>

>  [LibraryClasses]

> +  ArmMmuLib

>    ArmSmcLib

>    BaseLib

> diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> new file mode 100644

> index 000000000000..f98a9c5b85cc

> --- /dev/null

> +++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> @@ -0,0 +1,51 @@

> +/** @file

> +  OP-TEE SMC header file.

> +

> +  Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>

> +

> +  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.

> +

> +**/

> +

> +#ifndef _OPTEE_SMC_H_

> +#define _OPTEE_SMC_H_

> +

> +/* Returned in Arg0 only from Trusted OS functions */

> +#define OPTEE_SMC_RETURN_OK                     0x0

> +

> +#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003

> +#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004

> +#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007

> +

> +#define OPTEE_SMC_SHM_CACHED                    1

> +

> +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004

> +

> +#define OPTEE_MSG_CMD_OPEN_SESSION              0

> +#define OPTEE_MSG_CMD_INVOKE_COMMAND            1

> +#define OPTEE_MSG_CMD_CLOSE_SESSION             2

> +

> +#define OPTEE_MSG_ATTR_META                     0x100

> +

> +#define TEE_LOGIN_PUBLIC                        0x0

> +

> +/* Some Global Platform error codes used in this driver */


Standardized GlobalPlatform error codes should definitely go into a
separate header file, and probably even in MdePkg, i.e.,
MdePkg/Include/IndustryStandard/GlobalPlatform.h

Leif?

> +#define TEEC_SUCCESS                            0x00000000

> +#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006

> +#define TEEC_ERROR_COMMUNICATION                0xFFFF000E

> +#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C

> +

> +#define TEEC_ORIGIN_COMMS                       0x00000002

> +

> +typedef struct {

> +  EFI_VIRTUAL_ADDRESS    Base;

> +  UINTN                  Size;

> +} OPTEE_SHARED_MEMORY_INFO;

> +

> +#endif

> --

> 2.7.4

>
Sumit Garg Aug. 22, 2018, 5:35 a.m. UTC | #3
Thanks Ard for the detailed review. Is there any script like
checkpatch.pl for UEFI coding style? So that I could take care of
coding style errors while creating patch.

Actually I did used following script as per Laszlo's git guide for edk2 [1].

python BaseTools/Scripts/PatchCheck.py -1

[1] https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers

On Tue, 21 Aug 2018 at 18:39, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>

> On 20 August 2018 at 15:35, Sumit Garg <sumit.garg@linaro.org> wrote:

> > Add following APIs to communicate with OP-TEE static TA:

> > 1. OpteeInit

> > 2. OpteeOpenSession

> > 3. OpteeCloseSession

> > 4. OpteeInvokeFunc

> >

> > Contributed-under: TianoCore Contribution Agreement 1.1

> > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

> > ---

> >  ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++

> >  ArmPkg/Library/OpteeLib/Optee.c      | 344 +++++++++++++++++++++++++++++++++++

> >  ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +

> >  ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++

> >  4 files changed, 499 insertions(+)

> >  create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h

> >

> > diff --git a/ArmPkg/Include/Library/OpteeLib.h b/ArmPkg/Include/Library/OpteeLib.h

> > index f65d8674d9b8..59ae63526f58 100644

> > --- a/ArmPkg/Include/Library/OpteeLib.h

> > +++ b/ArmPkg/Include/Library/OpteeLib.h

> > @@ -25,10 +25,112 @@

> >  #define OPTEE_OS_UID2          0xaf630002

> >  #define OPTEE_OS_UID3          0xa5d5c51b

> >

> > +#define OPTEE_MSG_ATTR_TYPE_NONE                0x0

> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1

> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2

> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3

> > +#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9

> > +#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa

> > +#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb

> > +

> > +#define OPTEE_MSG_ATTR_TYPE_MASK                0xff

> > +

> > +typedef struct {

> > +  UINT64    BufPtr;

> > +  UINT64    Size;

> > +  UINT64    ShmRef;

> > +} OPTEE_MSG_PARAM_MEM;

> > +

> > +typedef struct {

> > +  UINT64    A;

> > +  UINT64    B;

> > +  UINT64    C;

> > +} OPTEE_MSG_PARAM_VALUE;

> > +

> > +typedef struct {

> > +  UINT64 Attr;

> > +  union {

> > +    OPTEE_MSG_PARAM_MEM      Mem;

> > +    OPTEE_MSG_PARAM_VALUE    Value;

> > +  } U;

> > +} OPTEE_MSG_PARAM;

> > +

> > +#define MAX_PARAMS           4

> > +

> > +typedef struct {

> > +        UINT32             Cmd;

> > +        UINT32             Func;

> > +        UINT32             Session;

> > +        UINT32             CancelId;

> > +        UINT32             Pad;

> > +        UINT32             Ret;

> > +        UINT32             RetOrigin;

> > +        UINT32             NumParams;

> > +

> > +        /* NumParams tells the actual number of element in Params */

> > +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> > +} OPTEE_MSG_ARG;

> > +

> > +#define OPTEE_UUID_LEN       16

> > +

> > +/**

> > + * struct OPTEE_OPEN_SESSION_ARG - Open session argument

> > + * @Uuid:       [in] UUID of the Trusted Application

> > + * @Session:    [out] Session id

> > + * @Ret:        [out] Return value

> > + * @RetOrigin   [out] Origin of the return value

>

> Please use trailing // comments to describe the struct members. Using

> a header like this is not idiomatic for Tianocore.

>


Ok I would use // comments to describe the struct members.

> Alternatively, if the license allows it, you can simply introduce the

> OP-TEE client header file in Include/IndustryStandard/ and refer to

> the types by their original names.

>

> > + */

> > +typedef struct {

> > +        UINT8     Uuid[OPTEE_UUID_LEN];

> > +        UINT32    Session;

> > +        UINT32    Ret;

> > +        UINT32    RetOrigin;

> > +} OPTEE_OPEN_SESSION_ARG;

> > +

> > +/**

> > + * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument

> > + * @Func:       [in] Trusted Application function, specific to the TA

> > + * @Session:    [in] Session id

> > + * @Ret:        [out] Return value

> > + * @RetOrigin   [out] Origin of the return value

> > + * @Params      [inout] Parameters for function to be invoked

> > + */

> > +typedef struct {

> > +        UINT32             Func;

> > +        UINT32             Session;

> > +        UINT32             Ret;

> > +        UINT32             RetOrigin;

> > +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> > +} OPTEE_INVOKE_FUNC_ARG;

> > +

> >  BOOLEAN

> >  EFIAPI

> >  IsOpteePresent (

> >    VOID

> >    );

> >

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeInit (

> > +  VOID

> > +  );

> > +

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeOpenSession (

> > +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> > +  );

> > +

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeCloseSession (

> > +  IN UINT32                      Session

> > +  );

> > +

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeInvokeFunc (

> > +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> > +  );

> > +

> >  #endif

> > diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c

> > index 574527f8b5ea..498bf0165f24 100644

> > --- a/ArmPkg/Library/OpteeLib/Optee.c

> > +++ b/ArmPkg/Library/OpteeLib/Optee.c

> > @@ -14,11 +14,19 @@

> >

> >  **/

> >

> > +#include <Library/ArmMmuLib.h>

> >  #include <Library/ArmSmcLib.h>

> >  #include <Library/BaseLib.h>

> > +#include <Library/DebugLib.h>

> >  #include <Library/OpteeLib.h>

> >

> >  #include <IndustryStandard/ArmStdSmc.h>

> > +#include <OpteeSmc.h>

>

> > +#include <string.h>

> > +#include <sys/param.h>

>

> Please drop these includes.

>


Ok will drop them.

> > +#include <Uefi.h>

> > +

> > +STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };

> >

> >  /**

> >    Check for OP-TEE presence.

> > @@ -31,6 +39,7 @@ IsOpteePresent (

> >  {

> >    ARM_SMC_ARGS ArmSmcArgs;

> >

> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

>

> Please use ZeroMem() here

>


Ok.

> >    // Send a Trusted OS Calls UID command

> >    ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;

> >    ArmCallSmc (&ArmSmcArgs);

> > @@ -44,3 +53,338 @@ IsOpteePresent (

> >      return FALSE;

> >    }

> >  }

> > +

> > +STATIC

> > +EFI_STATUS

> > +OpteeShmMemRemap (

> > +  VOID

> > +  )

> > +{

> > +  ARM_SMC_ARGS                 ArmSmcArgs;

> > +  EFI_PHYSICAL_ADDRESS         Paddr;

> > +  EFI_PHYSICAL_ADDRESS         Start;

> > +  EFI_PHYSICAL_ADDRESS         End;

> > +  EFI_STATUS                   Status;

> > +  UINTN                        Size;

> > +

> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> > +  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_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_SHM_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);

> > +  Paddr = 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 (Paddr, Size, EFI_MEMORY_WB);

> > +  if (EFI_ERROR (Status)) {

> > +    return Status;

> > +  }

> > +

> > +  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;

>

> Please use UINTN for virtual addresses: if we ever want to run this

> code on 32-bit ARM, having 64-bit virtual addresses is probably not

> going to work, right?

>


Right, will use UINTN instead of EFI_VIRTUAL_ADDRESS and EFI_PHYSICAL_ADDRESS.

> > +  OpteeShmInfo.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 = OpteeShmMemRemap ();

> > +  if (EFI_ERROR (Status)) {

> > +    DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));

> > +    return Status;

> > +  }

> > +

> > +  return EFI_SUCCESS;

> > +}

> > +

> > +/**

> > + * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world

> > + * @Parg:  physical address of message to pass to secure world

>

> Please use the common Tianocore notation here:

>

> @param[in]  Parg   Physical address of message to pass to secure world

>

> @return            0 on success, secure world return code otherwise

>


Ok will use this notation.

> > + *

> > + * Does Standard SMC to OP-TEE in secure world.

> > + *

> > + * Returns return code from secure world, 0 is OK

> > + */

> > +STATIC

> > +UINT32

> > +OpteeCallWithArg (

> > +  IN EFI_PHYSICAL_ADDRESS Parg

> > +  )

> > +{

> > +  ARM_SMC_ARGS ArmSmcArgs;

> > +

> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

>

> Use ZeroMem()

>


Ok.

> > +  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;

> > +  ArmSmcArgs.Arg1 = (UINT32) (Parg >> 32);

> > +  ArmSmcArgs.Arg2 = (UINT32) Parg;

> > +

> > +  while (TRUE) {

> > +    ArmCallSmc (&ArmSmcArgs);

> > +

> > +    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {

> > +      /*

> > +       * 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.

> > +       */

>

> I don't care deeply personally, but using // for multiline comments is

> more idiomatic for Tianocore

>


Will use // for multi-line comments.

> > +      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;

> > +    } else {

> > +      break;

> > +    }

> > +  }

> > +

> > +  return ArmSmcArgs.Arg0;

> > +}

> > +

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeOpenSession (

> > +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> > +  )

> > +{

> > +  OPTEE_MSG_ARG *MsgArg = NULL;

> > +

>

> Please avoid initializers for automatic variables: use assignments instead.

>


Ok.

> > +  if (OpteeShmInfo.Base == 0) {

> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> > +    return EFI_NOT_STARTED;

> > +  }

> > +

> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

>

> No space after () cast operator

>


Ok.

> > +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

> > +

>

> ZeroMem()

>


Ok.

> > +  MsgArg->Cmd = OPTEE_MSG_CMD_OPEN_SESSION;

> > +

> > +  /*

> > +   * Initialize and add the meta parameters needed when opening a

> > +   * session.

> > +   */

> > +  MsgArg->Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> > +                           OPTEE_MSG_ATTR_META;

> > +  MsgArg->Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> > +                           OPTEE_MSG_ATTR_META;

> > +  memcpy(&MsgArg->Params[0].U.Value, OpenSessionArg->Uuid, OPTEE_UUID_LEN);

>

> CopyMem()

>


Ok.

> > +  memset(&MsgArg->Params[1].U.Value, 0, OPTEE_UUID_LEN);

>

> ZeroMem()

>


Ok.

> > +  MsgArg->Params[1].U.Value.C = TEE_LOGIN_PUBLIC;

> > +

> > +  MsgArg->NumParams = 2;

> > +

> > +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

>

> No space after () cast operator

>


Ok.

> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> > +  }

> > +

> > +  OpenSessionArg->Session = MsgArg->Session;

> > +  OpenSessionArg->Ret = MsgArg->Ret;

> > +  OpenSessionArg->RetOrigin = MsgArg->RetOrigin;

> > +

> > +  return EFI_SUCCESS;

> > +}

> > +

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeCloseSession (

> > +  IN UINT32                      Session

> > +  )

> > +{

> > +  OPTEE_MSG_ARG *MsgArg = NULL;

> > +

>

> No initializers

>


Ok.

> > +  if (OpteeShmInfo.Base == 0) {

> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> > +    return EFI_NOT_STARTED;

> > +  }

> > +

> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> > +  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));

> > +

>

> ZeroMem()

>


Ok.

> > +  MsgArg->Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;

> > +  MsgArg->Session = Session;

> > +

> > +  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);

>

> Space before function call ().

>


Ok.

> > +

> > +  return EFI_SUCCESS;

> > +}

> > +

> > +STATIC

> > +EFI_STATUS

> > +OpteeToMsgParam (

> > +  OUT OPTEE_MSG_PARAM    *MsgParams,

> > +  IN UINT32              NumParams,

> > +  IN OPTEE_MSG_PARAM     *InParams

> > +  )

> > +{

> > +  UINT32                  n;

>

> Use Idx or similar for loop iterators.

>


Ok.

> > +  EFI_VIRTUAL_ADDRESS     ParamShmAddr;

> > +  UINTN                   ShmSize;

> > +  UINTN                   Size;

> > +

> > +  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));

> > +  ParamShmAddr = OpteeShmInfo.Base + Size;

> > +  ShmSize = OpteeShmInfo.Size - Size;

> > +

> > +  for (n = 0; n < NumParams; n++) {

> > +    CONST OPTEE_MSG_PARAM *Ip = InParams + n;

> > +    OPTEE_MSG_PARAM *Mp = MsgParams + n;

> > +    UINT32 Attr = Ip->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> > +

>

> No initializers.

>


Ok.

> > +    switch (Attr) {

> > +    case OPTEE_MSG_ATTR_TYPE_NONE:

> > +      Mp->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> > +      memset(&Mp->U, 0, sizeof (Mp->U));

>

> ZeroMem()

>


Ok.

> > +      break;

> > +

> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> > +      Mp->Attr = Attr;

> > +      Mp->U.Value.A = Ip->U.Value.A;

> > +      Mp->U.Value.B = Ip->U.Value.B;

> > +      Mp->U.Value.C = Ip->U.Value.C;

> > +      break;

> > +

> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> > +      Mp->Attr = Attr;

> > +

> > +      if (Ip->U.Mem.Size > ShmSize) {

> > +        return EFI_OUT_OF_RESOURCES;

> > +      }

> > +

> > +      memcpy((VOID *) ParamShmAddr, (VOID *) Ip->U.Mem.BufPtr, Ip->U.Mem.Size);

>

> CopyMem ()

>


Ok.

> > +      Mp->U.Mem.BufPtr = (UINT64) ParamShmAddr;

> > +      Mp->U.Mem.Size = Ip->U.Mem.Size;

> > +

> > +      Size = roundup (Ip->U.Mem.Size, sizeof (UINT64));

> > +      ParamShmAddr += Size;

> > +      ShmSize -= Size;

> > +      break;

> > +

> > +    default:

> > +      return EFI_INVALID_PARAMETER;

> > +    }

> > +  }

> > +

> > +  return EFI_SUCCESS;

> > +}

> > +

> > +STATIC

> > +EFI_STATUS

> > +OpteeFromMsgParam (

> > +  OUT OPTEE_MSG_PARAM    *OutParams,

> > +  IN UINT32              NumParams,

> > +  IN OPTEE_MSG_PARAM     *MsgParams

> > +  )

> > +{

> > +  UINT32                  n;

> > +

>

> Idx

>


Ok.

> > +  for (n = 0; n < NumParams; n++) {

> > +    OPTEE_MSG_PARAM *Op = OutParams + n;

> > +    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;

> > +    UINT32 Attr = Mp->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> > +

>

> Initializers

>


Ok.

> > +    switch (Attr) {

> > +    case OPTEE_MSG_ATTR_TYPE_NONE:

> > +      Op->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> > +      memset(&Op->U, 0, sizeof (Op->U));

>

> ZeroMem()

>


Ok.

> > +      break;

> > +

> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> > +      Op->Attr = Attr;

> > +      Op->U.Value.A = Mp->U.Value.A;

> > +      Op->U.Value.B = Mp->U.Value.B;

> > +      Op->U.Value.C = Mp->U.Value.C;

> > +      break;

> > +

> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> > +      Op->Attr = Attr;

> > +

> > +      if (Mp->U.Mem.Size > Op->U.Mem.Size) {

> > +        return EFI_BAD_BUFFER_SIZE;

> > +      }

> > +

> > +      memcpy((VOID *) Op->U.Mem.BufPtr, (VOID *) Mp->U.Mem.BufPtr, Mp->U.Mem.Size);

>

> CopyMem()

>


Ok.

> > +      Op->U.Mem.Size = Mp->U.Mem.Size;

> > +      break;

> > +

> > +    default:

> > +      return EFI_INVALID_PARAMETER;

> > +    }

> > +  }

> > +

> > +  return EFI_SUCCESS;

> > +}

> > +

> > +EFI_STATUS

> > +EFIAPI

> > +OpteeInvokeFunc (

> > +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> > +  )

> > +{

> > +  EFI_STATUS    Status;

> > +  OPTEE_MSG_ARG *MsgArg = NULL;

> > +

>

> Initializers

>


Ok.

> > +  if (OpteeShmInfo.Base == 0) {

> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> > +    return EFI_NOT_STARTED;

> > +  }

> > +

> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

>

> No space after () cast operator


Ok.

>

> > +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

>

> ZeroMem()

>


Ok.

> > +

> > +  MsgArg->Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;

> > +  MsgArg->Func = InvokeFuncArg->Func;

> > +  MsgArg->Session = InvokeFuncArg->Session;

> > +

> > +  Status = OpteeToMsgParam(MsgArg->Params, MAX_PARAMS, InvokeFuncArg->Params);

>

> Space before (

>


Ok.

> > +  if (Status)

> > +    return Status;

> > +

> > +  MsgArg->NumParams = MAX_PARAMS;

> > +

> > +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

>

> Space before (

>


Ok.

> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> > +  }

> > +

> > +  if (OpteeFromMsgParam(InvokeFuncArg->Params, MAX_PARAMS, MsgArg->Params)) {

>

> idem

>


Ok.

> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> > +  }

> > +

> > +  InvokeFuncArg->Ret = MsgArg->Ret;

> > +  InvokeFuncArg->RetOrigin = MsgArg->RetOrigin;

> > +

> > +  return EFI_SUCCESS;

> > +}

> > diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> > index 5abd427379cc..e03054a7167d 100644

> > --- a/ArmPkg/Library/OpteeLib/OpteeLib.inf

> > +++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> > @@ -23,11 +23,13 @@ [Defines]

> >

> >  [Sources]

> >    Optee.c

> > +  OpteeSmc.h

> >

> >  [Packages]

> >    ArmPkg/ArmPkg.dec

> >    MdePkg/MdePkg.dec

> >

> >  [LibraryClasses]

> > +  ArmMmuLib

> >    ArmSmcLib

> >    BaseLib

> > diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> > new file mode 100644

> > index 000000000000..f98a9c5b85cc

> > --- /dev/null

> > +++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> > @@ -0,0 +1,51 @@

> > +/** @file

> > +  OP-TEE SMC header file.

> > +

> > +  Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>

> > +

> > +  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.

> > +

> > +**/

> > +

> > +#ifndef _OPTEE_SMC_H_

> > +#define _OPTEE_SMC_H_

> > +

> > +/* Returned in Arg0 only from Trusted OS functions */

> > +#define OPTEE_SMC_RETURN_OK                     0x0

> > +

> > +#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003

> > +#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004

> > +#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007

> > +

> > +#define OPTEE_SMC_SHM_CACHED                    1

> > +

> > +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004

> > +

> > +#define OPTEE_MSG_CMD_OPEN_SESSION              0

> > +#define OPTEE_MSG_CMD_INVOKE_COMMAND            1

> > +#define OPTEE_MSG_CMD_CLOSE_SESSION             2

> > +

> > +#define OPTEE_MSG_ATTR_META                     0x100

> > +

> > +#define TEE_LOGIN_PUBLIC                        0x0

> > +

> > +/* Some Global Platform error codes used in this driver */

>

> Standardized GlobalPlatform error codes should definitely go into a

> separate header file, and probably even in MdePkg, i.e.,

> MdePkg/Include/IndustryStandard/GlobalPlatform.h

>

> Leif?

>

> > +#define TEEC_SUCCESS                            0x00000000

> > +#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006

> > +#define TEEC_ERROR_COMMUNICATION                0xFFFF000E

> > +#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C

> > +

> > +#define TEEC_ORIGIN_COMMS                       0x00000002

> > +

> > +typedef struct {

> > +  EFI_VIRTUAL_ADDRESS    Base;

> > +  UINTN                  Size;

> > +} OPTEE_SHARED_MEMORY_INFO;

> > +

> > +#endif

> > --

> > 2.7.4

> >
Ard Biesheuvel Aug. 22, 2018, 7:24 a.m. UTC | #4
On 22 August 2018 at 07:35, Sumit Garg <sumit.garg@linaro.org> wrote:
> Thanks Ard for the detailed review. Is there any script like

> checkpatch.pl for UEFI coding style? So that I could take care of

> coding style errors while creating patch.

>

> Actually I did used following script as per Laszlo's git guide for edk2 [1].

>

> python BaseTools/Scripts/PatchCheck.py -1

>

> [1] https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers

>


There is an elaborate EccCheck script somewhere but I never used it,

> On Tue, 21 Aug 2018 at 18:39, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

>>

>> On 20 August 2018 at 15:35, Sumit Garg <sumit.garg@linaro.org> wrote:

>> > Add following APIs to communicate with OP-TEE static TA:

>> > 1. OpteeInit

>> > 2. OpteeOpenSession

>> > 3. OpteeCloseSession

>> > 4. OpteeInvokeFunc

>> >

>> > Contributed-under: TianoCore Contribution Agreement 1.1

>> > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

>> > ---

>> >  ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++

>> >  ArmPkg/Library/OpteeLib/Optee.c      | 344 +++++++++++++++++++++++++++++++++++

>> >  ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +

>> >  ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++

>> >  4 files changed, 499 insertions(+)

>> >  create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h

>> >

>> > diff --git a/ArmPkg/Include/Library/OpteeLib.h b/ArmPkg/Include/Library/OpteeLib.h

>> > index f65d8674d9b8..59ae63526f58 100644

>> > --- a/ArmPkg/Include/Library/OpteeLib.h

>> > +++ b/ArmPkg/Include/Library/OpteeLib.h

>> > @@ -25,10 +25,112 @@

>> >  #define OPTEE_OS_UID2          0xaf630002

>> >  #define OPTEE_OS_UID3          0xa5d5c51b

>> >

>> > +#define OPTEE_MSG_ATTR_TYPE_NONE                0x0

>> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1

>> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2

>> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3

>> > +#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9

>> > +#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa

>> > +#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb

>> > +

>> > +#define OPTEE_MSG_ATTR_TYPE_MASK                0xff

>> > +

>> > +typedef struct {

>> > +  UINT64    BufPtr;

>> > +  UINT64    Size;

>> > +  UINT64    ShmRef;

>> > +} OPTEE_MSG_PARAM_MEM;

>> > +

>> > +typedef struct {

>> > +  UINT64    A;

>> > +  UINT64    B;

>> > +  UINT64    C;

>> > +} OPTEE_MSG_PARAM_VALUE;

>> > +

>> > +typedef struct {

>> > +  UINT64 Attr;

>> > +  union {

>> > +    OPTEE_MSG_PARAM_MEM      Mem;

>> > +    OPTEE_MSG_PARAM_VALUE    Value;

>> > +  } U;

>> > +} OPTEE_MSG_PARAM;

>> > +

>> > +#define MAX_PARAMS           4

>> > +

>> > +typedef struct {

>> > +        UINT32             Cmd;

>> > +        UINT32             Func;

>> > +        UINT32             Session;

>> > +        UINT32             CancelId;

>> > +        UINT32             Pad;

>> > +        UINT32             Ret;

>> > +        UINT32             RetOrigin;

>> > +        UINT32             NumParams;

>> > +

>> > +        /* NumParams tells the actual number of element in Params */

>> > +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

>> > +} OPTEE_MSG_ARG;

>> > +

>> > +#define OPTEE_UUID_LEN       16

>> > +

>> > +/**

>> > + * struct OPTEE_OPEN_SESSION_ARG - Open session argument

>> > + * @Uuid:       [in] UUID of the Trusted Application

>> > + * @Session:    [out] Session id

>> > + * @Ret:        [out] Return value

>> > + * @RetOrigin   [out] Origin of the return value

>>

>> Please use trailing // comments to describe the struct members. Using

>> a header like this is not idiomatic for Tianocore.

>>

>

> Ok I would use // comments to describe the struct members.

>

>> Alternatively, if the license allows it, you can simply introduce the

>> OP-TEE client header file in Include/IndustryStandard/ and refer to

>> the types by their original names.

>>

>> > + */

>> > +typedef struct {

>> > +        UINT8     Uuid[OPTEE_UUID_LEN];

>> > +        UINT32    Session;

>> > +        UINT32    Ret;

>> > +        UINT32    RetOrigin;

>> > +} OPTEE_OPEN_SESSION_ARG;

>> > +

>> > +/**

>> > + * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument

>> > + * @Func:       [in] Trusted Application function, specific to the TA

>> > + * @Session:    [in] Session id

>> > + * @Ret:        [out] Return value

>> > + * @RetOrigin   [out] Origin of the return value

>> > + * @Params      [inout] Parameters for function to be invoked

>> > + */

>> > +typedef struct {

>> > +        UINT32             Func;

>> > +        UINT32             Session;

>> > +        UINT32             Ret;

>> > +        UINT32             RetOrigin;

>> > +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

>> > +} OPTEE_INVOKE_FUNC_ARG;

>> > +

>> >  BOOLEAN

>> >  EFIAPI

>> >  IsOpteePresent (

>> >    VOID

>> >    );

>> >

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeInit (

>> > +  VOID

>> > +  );

>> > +

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeOpenSession (

>> > +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

>> > +  );

>> > +

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeCloseSession (

>> > +  IN UINT32                      Session

>> > +  );

>> > +

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeInvokeFunc (

>> > +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

>> > +  );

>> > +

>> >  #endif

>> > diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c

>> > index 574527f8b5ea..498bf0165f24 100644

>> > --- a/ArmPkg/Library/OpteeLib/Optee.c

>> > +++ b/ArmPkg/Library/OpteeLib/Optee.c

>> > @@ -14,11 +14,19 @@

>> >

>> >  **/

>> >

>> > +#include <Library/ArmMmuLib.h>

>> >  #include <Library/ArmSmcLib.h>

>> >  #include <Library/BaseLib.h>

>> > +#include <Library/DebugLib.h>

>> >  #include <Library/OpteeLib.h>

>> >

>> >  #include <IndustryStandard/ArmStdSmc.h>

>> > +#include <OpteeSmc.h>

>>

>> > +#include <string.h>

>> > +#include <sys/param.h>

>>

>> Please drop these includes.

>>

>

> Ok will drop them.

>

>> > +#include <Uefi.h>

>> > +

>> > +STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };

>> >

>> >  /**

>> >    Check for OP-TEE presence.

>> > @@ -31,6 +39,7 @@ IsOpteePresent (

>> >  {

>> >    ARM_SMC_ARGS ArmSmcArgs;

>> >

>> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

>>

>> Please use ZeroMem() here

>>

>

> Ok.

>

>> >    // Send a Trusted OS Calls UID command

>> >    ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;

>> >    ArmCallSmc (&ArmSmcArgs);

>> > @@ -44,3 +53,338 @@ IsOpteePresent (

>> >      return FALSE;

>> >    }

>> >  }

>> > +

>> > +STATIC

>> > +EFI_STATUS

>> > +OpteeShmMemRemap (

>> > +  VOID

>> > +  )

>> > +{

>> > +  ARM_SMC_ARGS                 ArmSmcArgs;

>> > +  EFI_PHYSICAL_ADDRESS         Paddr;

>> > +  EFI_PHYSICAL_ADDRESS         Start;

>> > +  EFI_PHYSICAL_ADDRESS         End;

>> > +  EFI_STATUS                   Status;

>> > +  UINTN                        Size;

>> > +

>> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

>> > +  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_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_SHM_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);

>> > +  Paddr = 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 (Paddr, Size, EFI_MEMORY_WB);

>> > +  if (EFI_ERROR (Status)) {

>> > +    return Status;

>> > +  }

>> > +

>> > +  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;

>>

>> Please use UINTN for virtual addresses: if we ever want to run this

>> code on 32-bit ARM, having 64-bit virtual addresses is probably not

>> going to work, right?

>>

>

> Right, will use UINTN instead of EFI_VIRTUAL_ADDRESS and EFI_PHYSICAL_ADDRESS.

>


No, only for virtual addresses, please. Physical addresses are 64-bit
in UEFI, virtual addresses are the same size as the native word size.

>> > +  OpteeShmInfo.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 = OpteeShmMemRemap ();

>> > +  if (EFI_ERROR (Status)) {

>> > +    DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));

>> > +    return Status;

>> > +  }

>> > +

>> > +  return EFI_SUCCESS;

>> > +}

>> > +

>> > +/**

>> > + * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world

>> > + * @Parg:  physical address of message to pass to secure world

>>

>> Please use the common Tianocore notation here:

>>

>> @param[in]  Parg   Physical address of message to pass to secure world

>>

>> @return            0 on success, secure world return code otherwise

>>

>

> Ok will use this notation.

>

>> > + *

>> > + * Does Standard SMC to OP-TEE in secure world.

>> > + *

>> > + * Returns return code from secure world, 0 is OK

>> > + */

>> > +STATIC

>> > +UINT32

>> > +OpteeCallWithArg (

>> > +  IN EFI_PHYSICAL_ADDRESS Parg

>> > +  )

>> > +{

>> > +  ARM_SMC_ARGS ArmSmcArgs;

>> > +

>> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

>>

>> Use ZeroMem()

>>

>

> Ok.

>

>> > +  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;

>> > +  ArmSmcArgs.Arg1 = (UINT32) (Parg >> 32);

>> > +  ArmSmcArgs.Arg2 = (UINT32) Parg;

>> > +

>> > +  while (TRUE) {

>> > +    ArmCallSmc (&ArmSmcArgs);

>> > +

>> > +    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {

>> > +      /*

>> > +       * 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.

>> > +       */

>>

>> I don't care deeply personally, but using // for multiline comments is

>> more idiomatic for Tianocore

>>

>

> Will use // for multi-line comments.

>

>> > +      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;

>> > +    } else {

>> > +      break;

>> > +    }

>> > +  }

>> > +

>> > +  return ArmSmcArgs.Arg0;

>> > +}

>> > +

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeOpenSession (

>> > +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

>> > +  )

>> > +{

>> > +  OPTEE_MSG_ARG *MsgArg = NULL;

>> > +

>>

>> Please avoid initializers for automatic variables: use assignments instead.

>>

>

> Ok.

>

>> > +  if (OpteeShmInfo.Base == 0) {

>> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

>> > +    return EFI_NOT_STARTED;

>> > +  }

>> > +

>> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

>>

>> No space after () cast operator

>>

>

> Ok.

>

>> > +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

>> > +

>>

>> ZeroMem()

>>

>

> Ok.

>

>> > +  MsgArg->Cmd = OPTEE_MSG_CMD_OPEN_SESSION;

>> > +

>> > +  /*

>> > +   * Initialize and add the meta parameters needed when opening a

>> > +   * session.

>> > +   */

>> > +  MsgArg->Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

>> > +                           OPTEE_MSG_ATTR_META;

>> > +  MsgArg->Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

>> > +                           OPTEE_MSG_ATTR_META;

>> > +  memcpy(&MsgArg->Params[0].U.Value, OpenSessionArg->Uuid, OPTEE_UUID_LEN);

>>

>> CopyMem()

>>

>

> Ok.

>

>> > +  memset(&MsgArg->Params[1].U.Value, 0, OPTEE_UUID_LEN);

>>

>> ZeroMem()

>>

>

> Ok.

>

>> > +  MsgArg->Params[1].U.Value.C = TEE_LOGIN_PUBLIC;

>> > +

>> > +  MsgArg->NumParams = 2;

>> > +

>> > +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

>>

>> No space after () cast operator

>>

>

> Ok.

>

>> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

>> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

>> > +  }

>> > +

>> > +  OpenSessionArg->Session = MsgArg->Session;

>> > +  OpenSessionArg->Ret = MsgArg->Ret;

>> > +  OpenSessionArg->RetOrigin = MsgArg->RetOrigin;

>> > +

>> > +  return EFI_SUCCESS;

>> > +}

>> > +

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeCloseSession (

>> > +  IN UINT32                      Session

>> > +  )

>> > +{

>> > +  OPTEE_MSG_ARG *MsgArg = NULL;

>> > +

>>

>> No initializers

>>

>

> Ok.

>

>> > +  if (OpteeShmInfo.Base == 0) {

>> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

>> > +    return EFI_NOT_STARTED;

>> > +  }

>> > +

>> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

>> > +  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));

>> > +

>>

>> ZeroMem()

>>

>

> Ok.

>

>> > +  MsgArg->Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;

>> > +  MsgArg->Session = Session;

>> > +

>> > +  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);

>>

>> Space before function call ().

>>

>

> Ok.

>

>> > +

>> > +  return EFI_SUCCESS;

>> > +}

>> > +

>> > +STATIC

>> > +EFI_STATUS

>> > +OpteeToMsgParam (

>> > +  OUT OPTEE_MSG_PARAM    *MsgParams,

>> > +  IN UINT32              NumParams,

>> > +  IN OPTEE_MSG_PARAM     *InParams

>> > +  )

>> > +{

>> > +  UINT32                  n;

>>

>> Use Idx or similar for loop iterators.

>>

>

> Ok.

>

>> > +  EFI_VIRTUAL_ADDRESS     ParamShmAddr;

>> > +  UINTN                   ShmSize;

>> > +  UINTN                   Size;

>> > +

>> > +  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));

>> > +  ParamShmAddr = OpteeShmInfo.Base + Size;

>> > +  ShmSize = OpteeShmInfo.Size - Size;

>> > +

>> > +  for (n = 0; n < NumParams; n++) {

>> > +    CONST OPTEE_MSG_PARAM *Ip = InParams + n;

>> > +    OPTEE_MSG_PARAM *Mp = MsgParams + n;

>> > +    UINT32 Attr = Ip->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

>> > +

>>

>> No initializers.

>>

>

> Ok.

>

>> > +    switch (Attr) {

>> > +    case OPTEE_MSG_ATTR_TYPE_NONE:

>> > +      Mp->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

>> > +      memset(&Mp->U, 0, sizeof (Mp->U));

>>

>> ZeroMem()

>>

>

> Ok.

>

>> > +      break;

>> > +

>> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

>> > +      Mp->Attr = Attr;

>> > +      Mp->U.Value.A = Ip->U.Value.A;

>> > +      Mp->U.Value.B = Ip->U.Value.B;

>> > +      Mp->U.Value.C = Ip->U.Value.C;

>> > +      break;

>> > +

>> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

>> > +      Mp->Attr = Attr;

>> > +

>> > +      if (Ip->U.Mem.Size > ShmSize) {

>> > +        return EFI_OUT_OF_RESOURCES;

>> > +      }

>> > +

>> > +      memcpy((VOID *) ParamShmAddr, (VOID *) Ip->U.Mem.BufPtr, Ip->U.Mem.Size);

>>

>> CopyMem ()

>>

>

> Ok.

>

>> > +      Mp->U.Mem.BufPtr = (UINT64) ParamShmAddr;

>> > +      Mp->U.Mem.Size = Ip->U.Mem.Size;

>> > +

>> > +      Size = roundup (Ip->U.Mem.Size, sizeof (UINT64));

>> > +      ParamShmAddr += Size;

>> > +      ShmSize -= Size;

>> > +      break;

>> > +

>> > +    default:

>> > +      return EFI_INVALID_PARAMETER;

>> > +    }

>> > +  }

>> > +

>> > +  return EFI_SUCCESS;

>> > +}

>> > +

>> > +STATIC

>> > +EFI_STATUS

>> > +OpteeFromMsgParam (

>> > +  OUT OPTEE_MSG_PARAM    *OutParams,

>> > +  IN UINT32              NumParams,

>> > +  IN OPTEE_MSG_PARAM     *MsgParams

>> > +  )

>> > +{

>> > +  UINT32                  n;

>> > +

>>

>> Idx

>>

>

> Ok.

>

>> > +  for (n = 0; n < NumParams; n++) {

>> > +    OPTEE_MSG_PARAM *Op = OutParams + n;

>> > +    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;

>> > +    UINT32 Attr = Mp->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

>> > +

>>

>> Initializers

>>

>

> Ok.

>

>> > +    switch (Attr) {

>> > +    case OPTEE_MSG_ATTR_TYPE_NONE:

>> > +      Op->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

>> > +      memset(&Op->U, 0, sizeof (Op->U));

>>

>> ZeroMem()

>>

>

> Ok.

>

>> > +      break;

>> > +

>> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

>> > +      Op->Attr = Attr;

>> > +      Op->U.Value.A = Mp->U.Value.A;

>> > +      Op->U.Value.B = Mp->U.Value.B;

>> > +      Op->U.Value.C = Mp->U.Value.C;

>> > +      break;

>> > +

>> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

>> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

>> > +      Op->Attr = Attr;

>> > +

>> > +      if (Mp->U.Mem.Size > Op->U.Mem.Size) {

>> > +        return EFI_BAD_BUFFER_SIZE;

>> > +      }

>> > +

>> > +      memcpy((VOID *) Op->U.Mem.BufPtr, (VOID *) Mp->U.Mem.BufPtr, Mp->U.Mem.Size);

>>

>> CopyMem()

>>

>

> Ok.

>

>> > +      Op->U.Mem.Size = Mp->U.Mem.Size;

>> > +      break;

>> > +

>> > +    default:

>> > +      return EFI_INVALID_PARAMETER;

>> > +    }

>> > +  }

>> > +

>> > +  return EFI_SUCCESS;

>> > +}

>> > +

>> > +EFI_STATUS

>> > +EFIAPI

>> > +OpteeInvokeFunc (

>> > +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

>> > +  )

>> > +{

>> > +  EFI_STATUS    Status;

>> > +  OPTEE_MSG_ARG *MsgArg = NULL;

>> > +

>>

>> Initializers

>>

>

> Ok.

>

>> > +  if (OpteeShmInfo.Base == 0) {

>> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

>> > +    return EFI_NOT_STARTED;

>> > +  }

>> > +

>> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

>>

>> No space after () cast operator

>

> Ok.

>

>>

>> > +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

>>

>> ZeroMem()

>>

>

> Ok.

>

>> > +

>> > +  MsgArg->Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;

>> > +  MsgArg->Func = InvokeFuncArg->Func;

>> > +  MsgArg->Session = InvokeFuncArg->Session;

>> > +

>> > +  Status = OpteeToMsgParam(MsgArg->Params, MAX_PARAMS, InvokeFuncArg->Params);

>>

>> Space before (

>>

>

> Ok.

>

>> > +  if (Status)

>> > +    return Status;

>> > +

>> > +  MsgArg->NumParams = MAX_PARAMS;

>> > +

>> > +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

>>

>> Space before (

>>

>

> Ok.

>

>> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

>> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

>> > +  }

>> > +

>> > +  if (OpteeFromMsgParam(InvokeFuncArg->Params, MAX_PARAMS, MsgArg->Params)) {

>>

>> idem

>>

>

> Ok.

>

>> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

>> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

>> > +  }

>> > +

>> > +  InvokeFuncArg->Ret = MsgArg->Ret;

>> > +  InvokeFuncArg->RetOrigin = MsgArg->RetOrigin;

>> > +

>> > +  return EFI_SUCCESS;

>> > +}

>> > diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf b/ArmPkg/Library/OpteeLib/OpteeLib.inf

>> > index 5abd427379cc..e03054a7167d 100644

>> > --- a/ArmPkg/Library/OpteeLib/OpteeLib.inf

>> > +++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf

>> > @@ -23,11 +23,13 @@ [Defines]

>> >

>> >  [Sources]

>> >    Optee.c

>> > +  OpteeSmc.h

>> >

>> >  [Packages]

>> >    ArmPkg/ArmPkg.dec

>> >    MdePkg/MdePkg.dec

>> >

>> >  [LibraryClasses]

>> > +  ArmMmuLib

>> >    ArmSmcLib

>> >    BaseLib

>> > diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h b/ArmPkg/Library/OpteeLib/OpteeSmc.h

>> > new file mode 100644

>> > index 000000000000..f98a9c5b85cc

>> > --- /dev/null

>> > +++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h

>> > @@ -0,0 +1,51 @@

>> > +/** @file

>> > +  OP-TEE SMC header file.

>> > +

>> > +  Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>

>> > +

>> > +  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.

>> > +

>> > +**/

>> > +

>> > +#ifndef _OPTEE_SMC_H_

>> > +#define _OPTEE_SMC_H_

>> > +

>> > +/* Returned in Arg0 only from Trusted OS functions */

>> > +#define OPTEE_SMC_RETURN_OK                     0x0

>> > +

>> > +#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003

>> > +#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004

>> > +#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007

>> > +

>> > +#define OPTEE_SMC_SHM_CACHED                    1

>> > +

>> > +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004

>> > +

>> > +#define OPTEE_MSG_CMD_OPEN_SESSION              0

>> > +#define OPTEE_MSG_CMD_INVOKE_COMMAND            1

>> > +#define OPTEE_MSG_CMD_CLOSE_SESSION             2

>> > +

>> > +#define OPTEE_MSG_ATTR_META                     0x100

>> > +

>> > +#define TEE_LOGIN_PUBLIC                        0x0

>> > +

>> > +/* Some Global Platform error codes used in this driver */

>>

>> Standardized GlobalPlatform error codes should definitely go into a

>> separate header file, and probably even in MdePkg, i.e.,

>> MdePkg/Include/IndustryStandard/GlobalPlatform.h

>>

>> Leif?

>>

>> > +#define TEEC_SUCCESS                            0x00000000

>> > +#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006

>> > +#define TEEC_ERROR_COMMUNICATION                0xFFFF000E

>> > +#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C

>> > +

>> > +#define TEEC_ORIGIN_COMMS                       0x00000002

>> > +

>> > +typedef struct {

>> > +  EFI_VIRTUAL_ADDRESS    Base;

>> > +  UINTN                  Size;

>> > +} OPTEE_SHARED_MEMORY_INFO;

>> > +

>> > +#endif

>> > --

>> > 2.7.4

>> >
Sumit Garg Aug. 22, 2018, 7:25 a.m. UTC | #5
On Wed, 22 Aug 2018 at 12:54, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>

> On 22 August 2018 at 07:35, Sumit Garg <sumit.garg@linaro.org> wrote:

> > Thanks Ard for the detailed review. Is there any script like

> > checkpatch.pl for UEFI coding style? So that I could take care of

> > coding style errors while creating patch.

> >

> > Actually I did used following script as per Laszlo's git guide for edk2 [1].

> >

> > python BaseTools/Scripts/PatchCheck.py -1

> >

> > [1] https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers

> >

>

> There is an elaborate EccCheck script somewhere but I never used it,

>

> > On Tue, 21 Aug 2018 at 18:39, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >>

> >> On 20 August 2018 at 15:35, Sumit Garg <sumit.garg@linaro.org> wrote:

> >> > Add following APIs to communicate with OP-TEE static TA:

> >> > 1. OpteeInit

> >> > 2. OpteeOpenSession

> >> > 3. OpteeCloseSession

> >> > 4. OpteeInvokeFunc

> >> >

> >> > Contributed-under: TianoCore Contribution Agreement 1.1

> >> > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

> >> > ---

> >> >  ArmPkg/Include/Library/OpteeLib.h    | 102 +++++++++++

> >> >  ArmPkg/Library/OpteeLib/Optee.c      | 344 +++++++++++++++++++++++++++++++++++

> >> >  ArmPkg/Library/OpteeLib/OpteeLib.inf |   2 +

> >> >  ArmPkg/Library/OpteeLib/OpteeSmc.h   |  51 ++++++

> >> >  4 files changed, 499 insertions(+)

> >> >  create mode 100644 ArmPkg/Library/OpteeLib/OpteeSmc.h

> >> >

> >> > diff --git a/ArmPkg/Include/Library/OpteeLib.h b/ArmPkg/Include/Library/OpteeLib.h

> >> > index f65d8674d9b8..59ae63526f58 100644

> >> > --- a/ArmPkg/Include/Library/OpteeLib.h

> >> > +++ b/ArmPkg/Include/Library/OpteeLib.h

> >> > @@ -25,10 +25,112 @@

> >> >  #define OPTEE_OS_UID2          0xaf630002

> >> >  #define OPTEE_OS_UID3          0xa5d5c51b

> >> >

> >> > +#define OPTEE_MSG_ATTR_TYPE_NONE                0x0

> >> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1

> >> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2

> >> > +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3

> >> > +#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9

> >> > +#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa

> >> > +#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb

> >> > +

> >> > +#define OPTEE_MSG_ATTR_TYPE_MASK                0xff

> >> > +

> >> > +typedef struct {

> >> > +  UINT64    BufPtr;

> >> > +  UINT64    Size;

> >> > +  UINT64    ShmRef;

> >> > +} OPTEE_MSG_PARAM_MEM;

> >> > +

> >> > +typedef struct {

> >> > +  UINT64    A;

> >> > +  UINT64    B;

> >> > +  UINT64    C;

> >> > +} OPTEE_MSG_PARAM_VALUE;

> >> > +

> >> > +typedef struct {

> >> > +  UINT64 Attr;

> >> > +  union {

> >> > +    OPTEE_MSG_PARAM_MEM      Mem;

> >> > +    OPTEE_MSG_PARAM_VALUE    Value;

> >> > +  } U;

> >> > +} OPTEE_MSG_PARAM;

> >> > +

> >> > +#define MAX_PARAMS           4

> >> > +

> >> > +typedef struct {

> >> > +        UINT32             Cmd;

> >> > +        UINT32             Func;

> >> > +        UINT32             Session;

> >> > +        UINT32             CancelId;

> >> > +        UINT32             Pad;

> >> > +        UINT32             Ret;

> >> > +        UINT32             RetOrigin;

> >> > +        UINT32             NumParams;

> >> > +

> >> > +        /* NumParams tells the actual number of element in Params */

> >> > +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> >> > +} OPTEE_MSG_ARG;

> >> > +

> >> > +#define OPTEE_UUID_LEN       16

> >> > +

> >> > +/**

> >> > + * struct OPTEE_OPEN_SESSION_ARG - Open session argument

> >> > + * @Uuid:       [in] UUID of the Trusted Application

> >> > + * @Session:    [out] Session id

> >> > + * @Ret:        [out] Return value

> >> > + * @RetOrigin   [out] Origin of the return value

> >>

> >> Please use trailing // comments to describe the struct members. Using

> >> a header like this is not idiomatic for Tianocore.

> >>

> >

> > Ok I would use // comments to describe the struct members.

> >

> >> Alternatively, if the license allows it, you can simply introduce the

> >> OP-TEE client header file in Include/IndustryStandard/ and refer to

> >> the types by their original names.

> >>

> >> > + */

> >> > +typedef struct {

> >> > +        UINT8     Uuid[OPTEE_UUID_LEN];

> >> > +        UINT32    Session;

> >> > +        UINT32    Ret;

> >> > +        UINT32    RetOrigin;

> >> > +} OPTEE_OPEN_SESSION_ARG;

> >> > +

> >> > +/**

> >> > + * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument

> >> > + * @Func:       [in] Trusted Application function, specific to the TA

> >> > + * @Session:    [in] Session id

> >> > + * @Ret:        [out] Return value

> >> > + * @RetOrigin   [out] Origin of the return value

> >> > + * @Params      [inout] Parameters for function to be invoked

> >> > + */

> >> > +typedef struct {

> >> > +        UINT32             Func;

> >> > +        UINT32             Session;

> >> > +        UINT32             Ret;

> >> > +        UINT32             RetOrigin;

> >> > +        OPTEE_MSG_PARAM    Params[MAX_PARAMS];

> >> > +} OPTEE_INVOKE_FUNC_ARG;

> >> > +

> >> >  BOOLEAN

> >> >  EFIAPI

> >> >  IsOpteePresent (

> >> >    VOID

> >> >    );

> >> >

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeInit (

> >> > +  VOID

> >> > +  );

> >> > +

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeOpenSession (

> >> > +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> >> > +  );

> >> > +

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeCloseSession (

> >> > +  IN UINT32                      Session

> >> > +  );

> >> > +

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeInvokeFunc (

> >> > +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> >> > +  );

> >> > +

> >> >  #endif

> >> > diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c

> >> > index 574527f8b5ea..498bf0165f24 100644

> >> > --- a/ArmPkg/Library/OpteeLib/Optee.c

> >> > +++ b/ArmPkg/Library/OpteeLib/Optee.c

> >> > @@ -14,11 +14,19 @@

> >> >

> >> >  **/

> >> >

> >> > +#include <Library/ArmMmuLib.h>

> >> >  #include <Library/ArmSmcLib.h>

> >> >  #include <Library/BaseLib.h>

> >> > +#include <Library/DebugLib.h>

> >> >  #include <Library/OpteeLib.h>

> >> >

> >> >  #include <IndustryStandard/ArmStdSmc.h>

> >> > +#include <OpteeSmc.h>

> >>

> >> > +#include <string.h>

> >> > +#include <sys/param.h>

> >>

> >> Please drop these includes.

> >>

> >

> > Ok will drop them.

> >

> >> > +#include <Uefi.h>

> >> > +

> >> > +STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };

> >> >

> >> >  /**

> >> >    Check for OP-TEE presence.

> >> > @@ -31,6 +39,7 @@ IsOpteePresent (

> >> >  {

> >> >    ARM_SMC_ARGS ArmSmcArgs;

> >> >

> >> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> >>

> >> Please use ZeroMem() here

> >>

> >

> > Ok.

> >

> >> >    // Send a Trusted OS Calls UID command

> >> >    ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;

> >> >    ArmCallSmc (&ArmSmcArgs);

> >> > @@ -44,3 +53,338 @@ IsOpteePresent (

> >> >      return FALSE;

> >> >    }

> >> >  }

> >> > +

> >> > +STATIC

> >> > +EFI_STATUS

> >> > +OpteeShmMemRemap (

> >> > +  VOID

> >> > +  )

> >> > +{

> >> > +  ARM_SMC_ARGS                 ArmSmcArgs;

> >> > +  EFI_PHYSICAL_ADDRESS         Paddr;

> >> > +  EFI_PHYSICAL_ADDRESS         Start;

> >> > +  EFI_PHYSICAL_ADDRESS         End;

> >> > +  EFI_STATUS                   Status;

> >> > +  UINTN                        Size;

> >> > +

> >> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> >> > +  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_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_SHM_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);

> >> > +  Paddr = 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 (Paddr, Size, EFI_MEMORY_WB);

> >> > +  if (EFI_ERROR (Status)) {

> >> > +    return Status;

> >> > +  }

> >> > +

> >> > +  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;

> >>

> >> Please use UINTN for virtual addresses: if we ever want to run this

> >> code on 32-bit ARM, having 64-bit virtual addresses is probably not

> >> going to work, right?

> >>

> >

> > Right, will use UINTN instead of EFI_VIRTUAL_ADDRESS and EFI_PHYSICAL_ADDRESS.

> >

>

> No, only for virtual addresses, please. Physical addresses are 64-bit

> in UEFI, virtual addresses are the same size as the native word size.

>


Ok.

> >> > +  OpteeShmInfo.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 = OpteeShmMemRemap ();

> >> > +  if (EFI_ERROR (Status)) {

> >> > +    DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));

> >> > +    return Status;

> >> > +  }

> >> > +

> >> > +  return EFI_SUCCESS;

> >> > +}

> >> > +

> >> > +/**

> >> > + * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world

> >> > + * @Parg:  physical address of message to pass to secure world

> >>

> >> Please use the common Tianocore notation here:

> >>

> >> @param[in]  Parg   Physical address of message to pass to secure world

> >>

> >> @return            0 on success, secure world return code otherwise

> >>

> >

> > Ok will use this notation.

> >

> >> > + *

> >> > + * Does Standard SMC to OP-TEE in secure world.

> >> > + *

> >> > + * Returns return code from secure world, 0 is OK

> >> > + */

> >> > +STATIC

> >> > +UINT32

> >> > +OpteeCallWithArg (

> >> > +  IN EFI_PHYSICAL_ADDRESS Parg

> >> > +  )

> >> > +{

> >> > +  ARM_SMC_ARGS ArmSmcArgs;

> >> > +

> >> > +  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));

> >>

> >> Use ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;

> >> > +  ArmSmcArgs.Arg1 = (UINT32) (Parg >> 32);

> >> > +  ArmSmcArgs.Arg2 = (UINT32) Parg;

> >> > +

> >> > +  while (TRUE) {

> >> > +    ArmCallSmc (&ArmSmcArgs);

> >> > +

> >> > +    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {

> >> > +      /*

> >> > +       * 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.

> >> > +       */

> >>

> >> I don't care deeply personally, but using // for multiline comments is

> >> more idiomatic for Tianocore

> >>

> >

> > Will use // for multi-line comments.

> >

> >> > +      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;

> >> > +    } else {

> >> > +      break;

> >> > +    }

> >> > +  }

> >> > +

> >> > +  return ArmSmcArgs.Arg0;

> >> > +}

> >> > +

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeOpenSession (

> >> > +  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg

> >> > +  )

> >> > +{

> >> > +  OPTEE_MSG_ARG *MsgArg = NULL;

> >> > +

> >>

> >> Please avoid initializers for automatic variables: use assignments instead.

> >>

> >

> > Ok.

> >

> >> > +  if (OpteeShmInfo.Base == 0) {

> >> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> >> > +    return EFI_NOT_STARTED;

> >> > +  }

> >> > +

> >> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> >>

> >> No space after () cast operator

> >>

> >

> > Ok.

> >

> >> > +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

> >> > +

> >>

> >> ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +  MsgArg->Cmd = OPTEE_MSG_CMD_OPEN_SESSION;

> >> > +

> >> > +  /*

> >> > +   * Initialize and add the meta parameters needed when opening a

> >> > +   * session.

> >> > +   */

> >> > +  MsgArg->Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> >> > +                           OPTEE_MSG_ATTR_META;

> >> > +  MsgArg->Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |

> >> > +                           OPTEE_MSG_ATTR_META;

> >> > +  memcpy(&MsgArg->Params[0].U.Value, OpenSessionArg->Uuid, OPTEE_UUID_LEN);

> >>

> >> CopyMem()

> >>

> >

> > Ok.

> >

> >> > +  memset(&MsgArg->Params[1].U.Value, 0, OPTEE_UUID_LEN);

> >>

> >> ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +  MsgArg->Params[1].U.Value.C = TEE_LOGIN_PUBLIC;

> >> > +

> >> > +  MsgArg->NumParams = 2;

> >> > +

> >> > +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

> >>

> >> No space after () cast operator

> >>

> >

> > Ok.

> >

> >> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> >> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> >> > +  }

> >> > +

> >> > +  OpenSessionArg->Session = MsgArg->Session;

> >> > +  OpenSessionArg->Ret = MsgArg->Ret;

> >> > +  OpenSessionArg->RetOrigin = MsgArg->RetOrigin;

> >> > +

> >> > +  return EFI_SUCCESS;

> >> > +}

> >> > +

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeCloseSession (

> >> > +  IN UINT32                      Session

> >> > +  )

> >> > +{

> >> > +  OPTEE_MSG_ARG *MsgArg = NULL;

> >> > +

> >>

> >> No initializers

> >>

> >

> > Ok.

> >

> >> > +  if (OpteeShmInfo.Base == 0) {

> >> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> >> > +    return EFI_NOT_STARTED;

> >> > +  }

> >> > +

> >> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> >> > +  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));

> >> > +

> >>

> >> ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +  MsgArg->Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;

> >> > +  MsgArg->Session = Session;

> >> > +

> >> > +  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);

> >>

> >> Space before function call ().

> >>

> >

> > Ok.

> >

> >> > +

> >> > +  return EFI_SUCCESS;

> >> > +}

> >> > +

> >> > +STATIC

> >> > +EFI_STATUS

> >> > +OpteeToMsgParam (

> >> > +  OUT OPTEE_MSG_PARAM    *MsgParams,

> >> > +  IN UINT32              NumParams,

> >> > +  IN OPTEE_MSG_PARAM     *InParams

> >> > +  )

> >> > +{

> >> > +  UINT32                  n;

> >>

> >> Use Idx or similar for loop iterators.

> >>

> >

> > Ok.

> >

> >> > +  EFI_VIRTUAL_ADDRESS     ParamShmAddr;

> >> > +  UINTN                   ShmSize;

> >> > +  UINTN                   Size;

> >> > +

> >> > +  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));

> >> > +  ParamShmAddr = OpteeShmInfo.Base + Size;

> >> > +  ShmSize = OpteeShmInfo.Size - Size;

> >> > +

> >> > +  for (n = 0; n < NumParams; n++) {

> >> > +    CONST OPTEE_MSG_PARAM *Ip = InParams + n;

> >> > +    OPTEE_MSG_PARAM *Mp = MsgParams + n;

> >> > +    UINT32 Attr = Ip->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> >> > +

> >>

> >> No initializers.

> >>

> >

> > Ok.

> >

> >> > +    switch (Attr) {

> >> > +    case OPTEE_MSG_ATTR_TYPE_NONE:

> >> > +      Mp->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> >> > +      memset(&Mp->U, 0, sizeof (Mp->U));

> >>

> >> ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +      break;

> >> > +

> >> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> >> > +      Mp->Attr = Attr;

> >> > +      Mp->U.Value.A = Ip->U.Value.A;

> >> > +      Mp->U.Value.B = Ip->U.Value.B;

> >> > +      Mp->U.Value.C = Ip->U.Value.C;

> >> > +      break;

> >> > +

> >> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> >> > +      Mp->Attr = Attr;

> >> > +

> >> > +      if (Ip->U.Mem.Size > ShmSize) {

> >> > +        return EFI_OUT_OF_RESOURCES;

> >> > +      }

> >> > +

> >> > +      memcpy((VOID *) ParamShmAddr, (VOID *) Ip->U.Mem.BufPtr, Ip->U.Mem.Size);

> >>

> >> CopyMem ()

> >>

> >

> > Ok.

> >

> >> > +      Mp->U.Mem.BufPtr = (UINT64) ParamShmAddr;

> >> > +      Mp->U.Mem.Size = Ip->U.Mem.Size;

> >> > +

> >> > +      Size = roundup (Ip->U.Mem.Size, sizeof (UINT64));

> >> > +      ParamShmAddr += Size;

> >> > +      ShmSize -= Size;

> >> > +      break;

> >> > +

> >> > +    default:

> >> > +      return EFI_INVALID_PARAMETER;

> >> > +    }

> >> > +  }

> >> > +

> >> > +  return EFI_SUCCESS;

> >> > +}

> >> > +

> >> > +STATIC

> >> > +EFI_STATUS

> >> > +OpteeFromMsgParam (

> >> > +  OUT OPTEE_MSG_PARAM    *OutParams,

> >> > +  IN UINT32              NumParams,

> >> > +  IN OPTEE_MSG_PARAM     *MsgParams

> >> > +  )

> >> > +{

> >> > +  UINT32                  n;

> >> > +

> >>

> >> Idx

> >>

> >

> > Ok.

> >

> >> > +  for (n = 0; n < NumParams; n++) {

> >> > +    OPTEE_MSG_PARAM *Op = OutParams + n;

> >> > +    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;

> >> > +    UINT32 Attr = Mp->Attr & OPTEE_MSG_ATTR_TYPE_MASK;

> >> > +

> >>

> >> Initializers

> >>

> >

> > Ok.

> >

> >> > +    switch (Attr) {

> >> > +    case OPTEE_MSG_ATTR_TYPE_NONE:

> >> > +      Op->Attr = OPTEE_MSG_ATTR_TYPE_NONE;

> >> > +      memset(&Op->U, 0, sizeof (Op->U));

> >>

> >> ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +      break;

> >> > +

> >> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:

> >> > +      Op->Attr = Attr;

> >> > +      Op->U.Value.A = Mp->U.Value.A;

> >> > +      Op->U.Value.B = Mp->U.Value.B;

> >> > +      Op->U.Value.C = Mp->U.Value.C;

> >> > +      break;

> >> > +

> >> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:

> >> > +    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:

> >> > +      Op->Attr = Attr;

> >> > +

> >> > +      if (Mp->U.Mem.Size > Op->U.Mem.Size) {

> >> > +        return EFI_BAD_BUFFER_SIZE;

> >> > +      }

> >> > +

> >> > +      memcpy((VOID *) Op->U.Mem.BufPtr, (VOID *) Mp->U.Mem.BufPtr, Mp->U.Mem.Size);

> >>

> >> CopyMem()

> >>

> >

> > Ok.

> >

> >> > +      Op->U.Mem.Size = Mp->U.Mem.Size;

> >> > +      break;

> >> > +

> >> > +    default:

> >> > +      return EFI_INVALID_PARAMETER;

> >> > +    }

> >> > +  }

> >> > +

> >> > +  return EFI_SUCCESS;

> >> > +}

> >> > +

> >> > +EFI_STATUS

> >> > +EFIAPI

> >> > +OpteeInvokeFunc (

> >> > +  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg

> >> > +  )

> >> > +{

> >> > +  EFI_STATUS    Status;

> >> > +  OPTEE_MSG_ARG *MsgArg = NULL;

> >> > +

> >>

> >> Initializers

> >>

> >

> > Ok.

> >

> >> > +  if (OpteeShmInfo.Base == 0) {

> >> > +    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));

> >> > +    return EFI_NOT_STARTED;

> >> > +  }

> >> > +

> >> > +  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;

> >>

> >> No space after () cast operator

> >

> > Ok.

> >

> >>

> >> > +  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));

> >>

> >> ZeroMem()

> >>

> >

> > Ok.

> >

> >> > +

> >> > +  MsgArg->Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;

> >> > +  MsgArg->Func = InvokeFuncArg->Func;

> >> > +  MsgArg->Session = InvokeFuncArg->Session;

> >> > +

> >> > +  Status = OpteeToMsgParam(MsgArg->Params, MAX_PARAMS, InvokeFuncArg->Params);

> >>

> >> Space before (

> >>

> >

> > Ok.

> >

> >> > +  if (Status)

> >> > +    return Status;

> >> > +

> >> > +  MsgArg->NumParams = MAX_PARAMS;

> >> > +

> >> > +  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {

> >>

> >> Space before (

> >>

> >

> > Ok.

> >

> >> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> >> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> >> > +  }

> >> > +

> >> > +  if (OpteeFromMsgParam(InvokeFuncArg->Params, MAX_PARAMS, MsgArg->Params)) {

> >>

> >> idem

> >>

> >

> > Ok.

> >

> >> > +    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;

> >> > +    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;

> >> > +  }

> >> > +

> >> > +  InvokeFuncArg->Ret = MsgArg->Ret;

> >> > +  InvokeFuncArg->RetOrigin = MsgArg->RetOrigin;

> >> > +

> >> > +  return EFI_SUCCESS;

> >> > +}

> >> > diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> >> > index 5abd427379cc..e03054a7167d 100644

> >> > --- a/ArmPkg/Library/OpteeLib/OpteeLib.inf

> >> > +++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf

> >> > @@ -23,11 +23,13 @@ [Defines]

> >> >

> >> >  [Sources]

> >> >    Optee.c

> >> > +  OpteeSmc.h

> >> >

> >> >  [Packages]

> >> >    ArmPkg/ArmPkg.dec

> >> >    MdePkg/MdePkg.dec

> >> >

> >> >  [LibraryClasses]

> >> > +  ArmMmuLib

> >> >    ArmSmcLib

> >> >    BaseLib

> >> > diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> >> > new file mode 100644

> >> > index 000000000000..f98a9c5b85cc

> >> > --- /dev/null

> >> > +++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h

> >> > @@ -0,0 +1,51 @@

> >> > +/** @file

> >> > +  OP-TEE SMC header file.

> >> > +

> >> > +  Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>

> >> > +

> >> > +  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.

> >> > +

> >> > +**/

> >> > +

> >> > +#ifndef _OPTEE_SMC_H_

> >> > +#define _OPTEE_SMC_H_

> >> > +

> >> > +/* Returned in Arg0 only from Trusted OS functions */

> >> > +#define OPTEE_SMC_RETURN_OK                     0x0

> >> > +

> >> > +#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003

> >> > +#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004

> >> > +#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007

> >> > +

> >> > +#define OPTEE_SMC_SHM_CACHED                    1

> >> > +

> >> > +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004

> >> > +

> >> > +#define OPTEE_MSG_CMD_OPEN_SESSION              0

> >> > +#define OPTEE_MSG_CMD_INVOKE_COMMAND            1

> >> > +#define OPTEE_MSG_CMD_CLOSE_SESSION             2

> >> > +

> >> > +#define OPTEE_MSG_ATTR_META                     0x100

> >> > +

> >> > +#define TEE_LOGIN_PUBLIC                        0x0

> >> > +

> >> > +/* Some Global Platform error codes used in this driver */

> >>

> >> Standardized GlobalPlatform error codes should definitely go into a

> >> separate header file, and probably even in MdePkg, i.e.,

> >> MdePkg/Include/IndustryStandard/GlobalPlatform.h

> >>

> >> Leif?

> >>

> >> > +#define TEEC_SUCCESS                            0x00000000

> >> > +#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006

> >> > +#define TEEC_ERROR_COMMUNICATION                0xFFFF000E

> >> > +#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C

> >> > +

> >> > +#define TEEC_ORIGIN_COMMS                       0x00000002

> >> > +

> >> > +typedef struct {

> >> > +  EFI_VIRTUAL_ADDRESS    Base;

> >> > +  UINTN                  Size;

> >> > +} OPTEE_SHARED_MEMORY_INFO;

> >> > +

> >> > +#endif

> >> > --

> >> > 2.7.4

> >> >
diff mbox series

Patch

diff --git a/ArmPkg/Include/Library/OpteeLib.h b/ArmPkg/Include/Library/OpteeLib.h
index f65d8674d9b8..59ae63526f58 100644
--- a/ArmPkg/Include/Library/OpteeLib.h
+++ b/ArmPkg/Include/Library/OpteeLib.h
@@ -25,10 +25,112 @@ 
 #define OPTEE_OS_UID2          0xaf630002
 #define OPTEE_OS_UID3          0xa5d5c51b
 
+#define OPTEE_MSG_ATTR_TYPE_NONE                0x0
+#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT         0x1
+#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT        0x2
+#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT         0x3
+#define OPTEE_MSG_ATTR_TYPE_MEM_INPUT           0x9
+#define OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT          0xa
+#define OPTEE_MSG_ATTR_TYPE_MEM_INOUT           0xb
+
+#define OPTEE_MSG_ATTR_TYPE_MASK                0xff
+
+typedef struct {
+  UINT64    BufPtr;
+  UINT64    Size;
+  UINT64    ShmRef;
+} OPTEE_MSG_PARAM_MEM;
+
+typedef struct {
+  UINT64    A;
+  UINT64    B;
+  UINT64    C;
+} OPTEE_MSG_PARAM_VALUE;
+
+typedef struct {
+  UINT64 Attr;
+  union {
+    OPTEE_MSG_PARAM_MEM      Mem;
+    OPTEE_MSG_PARAM_VALUE    Value;
+  } U;
+} OPTEE_MSG_PARAM;
+
+#define MAX_PARAMS           4
+
+typedef struct {
+        UINT32             Cmd;
+        UINT32             Func;
+        UINT32             Session;
+        UINT32             CancelId;
+        UINT32             Pad;
+        UINT32             Ret;
+        UINT32             RetOrigin;
+        UINT32             NumParams;
+
+        /* NumParams tells the actual number of element in Params */
+        OPTEE_MSG_PARAM    Params[MAX_PARAMS];
+} OPTEE_MSG_ARG;
+
+#define OPTEE_UUID_LEN       16
+
+/**
+ * struct OPTEE_OPEN_SESSION_ARG - Open session argument
+ * @Uuid:       [in] UUID of the Trusted Application
+ * @Session:    [out] Session id
+ * @Ret:        [out] Return value
+ * @RetOrigin   [out] Origin of the return value
+ */
+typedef struct {
+        UINT8     Uuid[OPTEE_UUID_LEN];
+        UINT32    Session;
+        UINT32    Ret;
+        UINT32    RetOrigin;
+} OPTEE_OPEN_SESSION_ARG;
+
+/**
+ * struct OPTEE_INVOKE_FUNC_ARG - Invoke Function argument
+ * @Func:       [in] Trusted Application function, specific to the TA
+ * @Session:    [in] Session id
+ * @Ret:        [out] Return value
+ * @RetOrigin   [out] Origin of the return value
+ * @Params      [inout] Parameters for function to be invoked
+ */
+typedef struct {
+        UINT32             Func;
+        UINT32             Session;
+        UINT32             Ret;
+        UINT32             RetOrigin;
+        OPTEE_MSG_PARAM    Params[MAX_PARAMS];
+} OPTEE_INVOKE_FUNC_ARG;
+
 BOOLEAN
 EFIAPI
 IsOpteePresent (
   VOID
   );
 
+EFI_STATUS
+EFIAPI
+OpteeInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+OpteeOpenSession (
+  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg
+  );
+
+EFI_STATUS
+EFIAPI
+OpteeCloseSession (
+  IN UINT32                      Session
+  );
+
+EFI_STATUS
+EFIAPI
+OpteeInvokeFunc (
+  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg
+  );
+
 #endif
diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c
index 574527f8b5ea..498bf0165f24 100644
--- a/ArmPkg/Library/OpteeLib/Optee.c
+++ b/ArmPkg/Library/OpteeLib/Optee.c
@@ -14,11 +14,19 @@ 
 
 **/
 
+#include <Library/ArmMmuLib.h>
 #include <Library/ArmSmcLib.h>
 #include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
 #include <Library/OpteeLib.h>
 
 #include <IndustryStandard/ArmStdSmc.h>
+#include <OpteeSmc.h>
+#include <string.h>
+#include <sys/param.h>
+#include <Uefi.h>
+
+STATIC OPTEE_SHARED_MEMORY_INFO OpteeShmInfo = { 0 };
 
 /**
   Check for OP-TEE presence.
@@ -31,6 +39,7 @@  IsOpteePresent (
 {
   ARM_SMC_ARGS ArmSmcArgs;
 
+  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));
   // Send a Trusted OS Calls UID command
   ArmSmcArgs.Arg0 = ARM_SMC_ID_TOS_UID;
   ArmCallSmc (&ArmSmcArgs);
@@ -44,3 +53,338 @@  IsOpteePresent (
     return FALSE;
   }
 }
+
+STATIC
+EFI_STATUS
+OpteeShmMemRemap (
+  VOID
+  )
+{
+  ARM_SMC_ARGS                 ArmSmcArgs;
+  EFI_PHYSICAL_ADDRESS         Paddr;
+  EFI_PHYSICAL_ADDRESS         Start;
+  EFI_PHYSICAL_ADDRESS         End;
+  EFI_STATUS                   Status;
+  UINTN                        Size;
+
+  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));
+  ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_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_SHM_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);
+  Paddr = 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 (Paddr, Size, EFI_MEMORY_WB);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  OpteeShmInfo.Base = (EFI_VIRTUAL_ADDRESS)Paddr;
+  OpteeShmInfo.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 = OpteeShmMemRemap ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "OP-TEE shared memory remap failed\n"));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * OpteeCallWithArg() - Do an SMC to OP-TEE in secure world
+ * @Parg:  physical address of message to pass to secure world
+ *
+ * Does Standard SMC to OP-TEE in secure world.
+ *
+ * Returns return code from secure world, 0 is OK
+ */
+STATIC
+UINT32
+OpteeCallWithArg (
+  IN EFI_PHYSICAL_ADDRESS Parg
+  )
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  memset (&ArmSmcArgs, 0, sizeof (ARM_SMC_ARGS));
+  ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG;
+  ArmSmcArgs.Arg1 = (UINT32) (Parg >> 32);
+  ArmSmcArgs.Arg2 = (UINT32) Parg;
+
+  while (TRUE) {
+    ArmCallSmc (&ArmSmcArgs);
+
+    if (ArmSmcArgs.Arg0 == OPTEE_SMC_RETURN_RPC_FOREIGN_INTR) {
+      /*
+       * 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.
+       */
+      ArmSmcArgs.Arg0 = OPTEE_SMC_RETURN_FROM_RPC;
+    } else {
+      break;
+    }
+  }
+
+  return ArmSmcArgs.Arg0;
+}
+
+EFI_STATUS
+EFIAPI
+OpteeOpenSession (
+  IN OUT OPTEE_OPEN_SESSION_ARG      *OpenSessionArg
+  )
+{
+  OPTEE_MSG_ARG *MsgArg = NULL;
+
+  if (OpteeShmInfo.Base == 0) {
+    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));
+    return EFI_NOT_STARTED;
+  }
+
+  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;
+  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));
+
+  MsgArg->Cmd = OPTEE_MSG_CMD_OPEN_SESSION;
+
+  /*
+   * Initialize and add the meta parameters needed when opening a
+   * session.
+   */
+  MsgArg->Params[0].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
+                           OPTEE_MSG_ATTR_META;
+  MsgArg->Params[1].Attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
+                           OPTEE_MSG_ATTR_META;
+  memcpy(&MsgArg->Params[0].U.Value, OpenSessionArg->Uuid, OPTEE_UUID_LEN);
+  memset(&MsgArg->Params[1].U.Value, 0, OPTEE_UUID_LEN);
+  MsgArg->Params[1].U.Value.C = TEE_LOGIN_PUBLIC;
+
+  MsgArg->NumParams = 2;
+
+  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {
+    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;
+    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;
+  }
+
+  OpenSessionArg->Session = MsgArg->Session;
+  OpenSessionArg->Ret = MsgArg->Ret;
+  OpenSessionArg->RetOrigin = MsgArg->RetOrigin;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+OpteeCloseSession (
+  IN UINT32                      Session
+  )
+{
+  OPTEE_MSG_ARG *MsgArg = NULL;
+
+  if (OpteeShmInfo.Base == 0) {
+    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));
+    return EFI_NOT_STARTED;
+  }
+
+  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;
+  memset(MsgArg, 0, sizeof (OPTEE_MSG_ARG));
+
+  MsgArg->Cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
+  MsgArg->Session = Session;
+
+  OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+OpteeToMsgParam (
+  OUT OPTEE_MSG_PARAM    *MsgParams,
+  IN UINT32              NumParams,
+  IN OPTEE_MSG_PARAM     *InParams
+  )
+{
+  UINT32                  n;
+  EFI_VIRTUAL_ADDRESS     ParamShmAddr;
+  UINTN                   ShmSize;
+  UINTN                   Size;
+
+  Size = roundup (sizeof (OPTEE_MSG_ARG), sizeof (UINT64));
+  ParamShmAddr = OpteeShmInfo.Base + Size;
+  ShmSize = OpteeShmInfo.Size - Size;
+
+  for (n = 0; n < NumParams; n++) {
+    CONST OPTEE_MSG_PARAM *Ip = InParams + n;
+    OPTEE_MSG_PARAM *Mp = MsgParams + n;
+    UINT32 Attr = Ip->Attr & OPTEE_MSG_ATTR_TYPE_MASK;
+
+    switch (Attr) {
+    case OPTEE_MSG_ATTR_TYPE_NONE:
+      Mp->Attr = OPTEE_MSG_ATTR_TYPE_NONE;
+      memset(&Mp->U, 0, sizeof (Mp->U));
+      break;
+
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+      Mp->Attr = Attr;
+      Mp->U.Value.A = Ip->U.Value.A;
+      Mp->U.Value.B = Ip->U.Value.B;
+      Mp->U.Value.C = Ip->U.Value.C;
+      break;
+
+    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:
+    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:
+    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:
+      Mp->Attr = Attr;
+
+      if (Ip->U.Mem.Size > ShmSize) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      memcpy((VOID *) ParamShmAddr, (VOID *) Ip->U.Mem.BufPtr, Ip->U.Mem.Size);
+      Mp->U.Mem.BufPtr = (UINT64) ParamShmAddr;
+      Mp->U.Mem.Size = Ip->U.Mem.Size;
+
+      Size = roundup (Ip->U.Mem.Size, sizeof (UINT64));
+      ParamShmAddr += Size;
+      ShmSize -= Size;
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+OpteeFromMsgParam (
+  OUT OPTEE_MSG_PARAM    *OutParams,
+  IN UINT32              NumParams,
+  IN OPTEE_MSG_PARAM     *MsgParams
+  )
+{
+  UINT32                  n;
+
+  for (n = 0; n < NumParams; n++) {
+    OPTEE_MSG_PARAM *Op = OutParams + n;
+    CONST OPTEE_MSG_PARAM *Mp = MsgParams + n;
+    UINT32 Attr = Mp->Attr & OPTEE_MSG_ATTR_TYPE_MASK;
+
+    switch (Attr) {
+    case OPTEE_MSG_ATTR_TYPE_NONE:
+      Op->Attr = OPTEE_MSG_ATTR_TYPE_NONE;
+      memset(&Op->U, 0, sizeof (Op->U));
+      break;
+
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+    case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+    case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+      Op->Attr = Attr;
+      Op->U.Value.A = Mp->U.Value.A;
+      Op->U.Value.B = Mp->U.Value.B;
+      Op->U.Value.C = Mp->U.Value.C;
+      break;
+
+    case OPTEE_MSG_ATTR_TYPE_MEM_INPUT:
+    case OPTEE_MSG_ATTR_TYPE_MEM_OUTPUT:
+    case OPTEE_MSG_ATTR_TYPE_MEM_INOUT:
+      Op->Attr = Attr;
+
+      if (Mp->U.Mem.Size > Op->U.Mem.Size) {
+        return EFI_BAD_BUFFER_SIZE;
+      }
+
+      memcpy((VOID *) Op->U.Mem.BufPtr, (VOID *) Mp->U.Mem.BufPtr, Mp->U.Mem.Size);
+      Op->U.Mem.Size = Mp->U.Mem.Size;
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+OpteeInvokeFunc (
+  IN OUT OPTEE_INVOKE_FUNC_ARG       *InvokeFuncArg
+  )
+{
+  EFI_STATUS    Status;
+  OPTEE_MSG_ARG *MsgArg = NULL;
+
+  if (OpteeShmInfo.Base == 0) {
+    DEBUG ((DEBUG_WARN, "OP-TEE not initialized\n"));
+    return EFI_NOT_STARTED;
+  }
+
+  MsgArg = (OPTEE_MSG_ARG *) OpteeShmInfo.Base;
+  memset(MsgArg, 0, sizeof(OPTEE_MSG_ARG));
+
+  MsgArg->Cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
+  MsgArg->Func = InvokeFuncArg->Func;
+  MsgArg->Session = InvokeFuncArg->Session;
+
+  Status = OpteeToMsgParam(MsgArg->Params, MAX_PARAMS, InvokeFuncArg->Params);
+  if (Status)
+    return Status;
+
+  MsgArg->NumParams = MAX_PARAMS;
+
+  if (OpteeCallWithArg((EFI_PHYSICAL_ADDRESS) MsgArg)) {
+    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;
+    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;
+  }
+
+  if (OpteeFromMsgParam(InvokeFuncArg->Params, MAX_PARAMS, MsgArg->Params)) {
+    MsgArg->Ret = TEEC_ERROR_COMMUNICATION;
+    MsgArg->RetOrigin = TEEC_ORIGIN_COMMS;
+  }
+
+  InvokeFuncArg->Ret = MsgArg->Ret;
+  InvokeFuncArg->RetOrigin = MsgArg->RetOrigin;
+
+  return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Library/OpteeLib/OpteeLib.inf b/ArmPkg/Library/OpteeLib/OpteeLib.inf
index 5abd427379cc..e03054a7167d 100644
--- a/ArmPkg/Library/OpteeLib/OpteeLib.inf
+++ b/ArmPkg/Library/OpteeLib/OpteeLib.inf
@@ -23,11 +23,13 @@  [Defines]
 
 [Sources]
   Optee.c
+  OpteeSmc.h
 
 [Packages]
   ArmPkg/ArmPkg.dec
   MdePkg/MdePkg.dec
 
 [LibraryClasses]
+  ArmMmuLib
   ArmSmcLib
   BaseLib
diff --git a/ArmPkg/Library/OpteeLib/OpteeSmc.h b/ArmPkg/Library/OpteeLib/OpteeSmc.h
new file mode 100644
index 000000000000..f98a9c5b85cc
--- /dev/null
+++ b/ArmPkg/Library/OpteeLib/OpteeSmc.h
@@ -0,0 +1,51 @@ 
+/** @file
+  OP-TEE SMC header file.
+
+  Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _OPTEE_SMC_H_
+#define _OPTEE_SMC_H_
+
+/* Returned in Arg0 only from Trusted OS functions */
+#define OPTEE_SMC_RETURN_OK                     0x0
+
+#define OPTEE_SMC_RETURN_FROM_RPC               0x32000003
+#define OPTEE_SMC_CALL_WITH_ARG                 0x32000004
+#define OPTEE_SMC_GET_SHM_CONFIG                0xb2000007
+
+#define OPTEE_SMC_SHM_CACHED                    1
+
+#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR       0xffff0004
+
+#define OPTEE_MSG_CMD_OPEN_SESSION              0
+#define OPTEE_MSG_CMD_INVOKE_COMMAND            1
+#define OPTEE_MSG_CMD_CLOSE_SESSION             2
+
+#define OPTEE_MSG_ATTR_META                     0x100
+
+#define TEE_LOGIN_PUBLIC                        0x0
+
+/* Some Global Platform error codes used in this driver */
+#define TEEC_SUCCESS                            0x00000000
+#define TEEC_ERROR_BAD_PARAMETERS               0xFFFF0006
+#define TEEC_ERROR_COMMUNICATION                0xFFFF000E
+#define TEEC_ERROR_OUT_OF_MEMORY                0xFFFF000C
+
+#define TEEC_ORIGIN_COMMS                       0x00000002
+
+typedef struct {
+  EFI_VIRTUAL_ADDRESS    Base;
+  UINTN                  Size;
+} OPTEE_SHARED_MEMORY_INFO;
+
+#endif