/** @file
  This library provides an implementation of Tpm2DeviceLib
  using ARM64 SMC calls to request TPM service.

  The implementation is only supporting the Command Response Buffer (CRB)
  for sharing data with the TPM.

  Copyright (c), Microsoft Corporation.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Pi/PiMultiPhase.h>
#include <IndustryStandard/ArmFfaSvc.h>
#include <IndustryStandard/ArmFfaBootInfo.h>
#include <IndustryStandard/ArmFfaPartInfo.h>
#include <Guid/Tpm2ServiceFfa.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/Tpm2DeviceLib.h>
#include <Library/ArmFfaLib.h>

#include "Tpm2DeviceLibFfa.h"

UINT16  mFfaTpm2PartitionId = TPM2_FFA_PARTITION_ID_INVALID;

/**
  Check the return status from the FF-A call and returns EFI_STATUS

  @param EFI_LOAD_ERROR  FF-A status code returned in x0

  @retval EFI_SUCCESS    The entry point is executed successfully.
**/
EFI_STATUS
TranslateTpmReturnStatus (
  UINTN  TpmReturnStatus
  )
{
  EFI_STATUS  Status;

  switch (TpmReturnStatus) {
    case TPM2_FFA_SUCCESS_OK:
    case TPM2_FFA_SUCCESS_OK_RESULTS_RETURNED:
      Status = EFI_SUCCESS;
      break;

    case TPM2_FFA_ERROR_NOFUNC:
      Status = EFI_NOT_FOUND;
      break;

    case TPM2_FFA_ERROR_NOTSUP:
      Status = EFI_UNSUPPORTED;
      break;

    case TPM2_FFA_ERROR_INVARG:
      Status = EFI_INVALID_PARAMETER;
      break;

    case TPM2_FFA_ERROR_INV_CRB_CTRL_DATA:
      Status = EFI_COMPROMISED_DATA;
      break;

    case TPM2_FFA_ERROR_ALREADY:
      Status = EFI_ALREADY_STARTED;
      break;

    case TPM2_FFA_ERROR_DENIED:
      Status = EFI_ACCESS_DENIED;
      break;

    case TPM2_FFA_ERROR_NOMEM:
      Status = EFI_OUT_OF_RESOURCES;
      break;

    default:
      Status = EFI_DEVICE_ERROR;
  }

  return Status;
}

/**
  This function is used to get the TPM service partition id via FF-A.

  @param[out] PartitionId - Supplies the pointer to the TPM service partition id.

  @retval EFI_SUCCESS           The TPM command was successfully sent to the TPM
                                and the response was copied to the Output buffer.
  @retval EFI_INVALID_PARAMETER The TPM command buffer is NULL or the TPM command
                                buffer size is 0.
  @retval EFI_DEVICE_ERROR      The TPM partition information is wrong.
  @retval EFI_DEVICE_ERROR      An error occurred in communication with the TPM.
**/
EFI_STATUS
FfaTpm2GetServicePartitionId (
  OUT UINT16  *PartitionId
  )
{
  EFI_STATUS              Status;
  UINT32                  Count;
  UINT32                  Size;
  EFI_FFA_PART_INFO_DESC  *TpmPartInfo;
  VOID                    *TxBuffer;
  UINT64                  TxBufferSize;
  VOID                    *RxBuffer;
  UINT64                  RxBufferSize;
  UINT16                  PartId;

  if (PartitionId == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  Status = ArmFfaLibPartitionIdGet (&PartId);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "Failed to get partition id. Status: %r\n",
      Status
      ));
    goto Exit;
  }

  Status = ArmFfaLibGetRxTxBuffers (
             &TxBuffer,
             &TxBufferSize,
             &RxBuffer,
             &RxBufferSize
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to get Rx/Tx Buffer. Status: %r\n", Status));
    goto Exit;
  }

  Status = ArmFfaLibPartitionInfoGet (
             &gTpm2ServiceFfaGuid,
             FFA_PART_INFO_FLAG_TYPE_DESC,
             &Count,
             &Size
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to get Tpm2 partition info. Status: %r\n", Status));
    goto RxRelease;
  }

  if ((Count != 1) || (Size < sizeof (EFI_FFA_PART_INFO_DESC))) {
    Status = EFI_INVALID_PARAMETER;
    DEBUG ((DEBUG_ERROR, "Invalid partition Info(%g). Count: %d, Size: %d\n", &gTpm2ServiceFfaGuid, Count, Size));
  } else {
    TpmPartInfo  = (EFI_FFA_PART_INFO_DESC *)RxBuffer;
    *PartitionId = TpmPartInfo->PartitionId;
    if (TpmPartInfo->PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
      /*
       * Tpm partition id never be TPM2_FFA_PARTITION_ID_INVALID.
       */
      Status = EFI_DEVICE_ERROR;
    }
  }

RxRelease:
  ArmFfaLibRxRelease (PartId);

Exit:
  return Status;
}

/**
  This function is used to get the TPM interface version.

  @param[out] Version - Supplies the pointer to the TPM interface version.

  @retval EFI_SUCCESS           The TPM command was successfully sent to the TPM
                                and the response was copied to the Output buffer.
  @retval EFI_INVALID_PARAMETER The TPM command buffer is NULL or the TPM command
                                buffer size is 0.
  @retval EFI_DEVICE_ERROR      An error occurred in communication with the TPM.
**/
EFI_STATUS
Tpm2GetInterfaceVersion (
  OUT UINT32  *Version
  )
{
  EFI_STATUS       Status;
  DIRECT_MSG_ARGS  FfaDirectReq2Args;

  if (Version == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  if (mFfaTpm2PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
    GetTpmServicePartitionId (&mFfaTpm2PartitionId);
  }

  ZeroMem (&FfaDirectReq2Args, sizeof (DIRECT_MSG_ARGS));
  FfaDirectReq2Args.Arg0 = TPM2_FFA_GET_INTERFACE_VERSION;

  Status = ArmFfaLibMsgSendDirectReq2 (mFfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args);
  while (Status == EFI_INTERRUPT_PENDING) {
    // We are assuming vCPU0 of the TPM SP since it is UP.
    Status = ArmFfaLibRun (mFfaTpm2PartitionId, 0x00, &FfaDirectReq2Args);
  }

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = TranslateTpmReturnStatus (FfaDirectReq2Args.Arg0);

  if (!EFI_ERROR (Status)) {
    *Version = FfaDirectReq2Args.Arg1;
  }

Exit:
  return Status;
}

/**
  This function is used to get the TPM feature information.

  @param[out] FeatureInfo - Supplies the pointer to the feature information.

  @retval EFI_SUCCESS           The TPM command was successfully sent to the TPM
                                and the response was copied to the Output buffer.
  @retval EFI_INVALID_PARAMETER The TPM command buffer is NULL or the TPM command
                                buffer size is 0.
  @retval EFI_DEVICE_ERROR      An error occurred in communication with the TPM.
**/
EFI_STATUS
Tpm2GetFeatureInfo (
  OUT UINT32  *FeatureInfo
  )
{
  EFI_STATUS       Status;
  DIRECT_MSG_ARGS  FfaDirectReq2Args;

  if (FeatureInfo == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  if (mFfaTpm2PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
    GetTpmServicePartitionId (&mFfaTpm2PartitionId);
  }

  ZeroMem (&FfaDirectReq2Args, sizeof (DIRECT_MSG_ARGS));
  FfaDirectReq2Args.Arg0 = TPM2_FFA_GET_FEATURE_INFO;
  FfaDirectReq2Args.Arg1 = TPM_SERVICE_FEATURE_SUPPORT_NOTIFICATION;

  Status = ArmFfaLibMsgSendDirectReq2 (mFfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args);
  while (Status == EFI_INTERRUPT_PENDING) {
    // We are assuming vCPU0 of the TPM SP since it is UP.
    Status = ArmFfaLibRun (mFfaTpm2PartitionId, 0x00, &FfaDirectReq2Args);
  }

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = TranslateTpmReturnStatus (FfaDirectReq2Args.Arg0);

Exit:
  return Status;
}

/**
  This service enables the sending of commands to the TPM2.

  @param[in]  FuncQualifier          Function qualifier.
  @param[in]  LocalityQualifier      Locality qualifier.

  @retval EFI_SUCCESS           The command byte stream was successfully sent to the device and a response was successfully received.
  @retval EFI_DEVICE_ERROR      The command was not successfully sent to the device or a response was not successfully received from the device.
  @retval EFI_BUFFER_TOO_SMALL  The output parameter block is too small.
**/
EFI_STATUS
Tpm2ServiceStart (
  IN UINT64  FuncQualifier,
  IN UINT64  LocalityQualifier
  )
{
  EFI_STATUS       Status;
  DIRECT_MSG_ARGS  FfaDirectReq2Args;

  if (mFfaTpm2PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
    GetTpmServicePartitionId (&mFfaTpm2PartitionId);
  }

  ZeroMem (&FfaDirectReq2Args, sizeof (DIRECT_MSG_ARGS));
  FfaDirectReq2Args.Arg0 = TPM2_FFA_START;
  FfaDirectReq2Args.Arg1 = (FuncQualifier & 0xFF);
  FfaDirectReq2Args.Arg2 = (LocalityQualifier & 0xFF);

  Status = ArmFfaLibMsgSendDirectReq2 (mFfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args);
  while (Status == EFI_INTERRUPT_PENDING) {
    // We are assuming vCPU0 of the TPM SP since it is UP.
    Status = ArmFfaLibRun (mFfaTpm2PartitionId, 0x00, &FfaDirectReq2Args);
  }

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = TranslateTpmReturnStatus (FfaDirectReq2Args.Arg0);

Exit:
  return Status;
}

/**
  Register TPM2 device notification.

  @param[in] NotificationTypeQualifier  Notification type qualifier.
  @param[in] vCpuId                     vCPU ID.
  @param[in] NotificationId             Bitmap ID for the notification.

  @retval EFI_SUCCESS  The command was successfully sent to the device and a response was successfully received.
  @retval Others       Some error occurred in communication with the device.
**/
EFI_STATUS
Tpm2RegisterNotification (
  IN BOOLEAN  NotificationTypeQualifier,
  IN UINT16   vCpuId,
  IN UINT64   NotificationId
  )
{
  EFI_STATUS       Status;
  DIRECT_MSG_ARGS  FfaDirectReq2Args;

  if (mFfaTpm2PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
    GetTpmServicePartitionId (&mFfaTpm2PartitionId);
  }

  ZeroMem (&FfaDirectReq2Args, sizeof (DIRECT_MSG_ARGS));
  FfaDirectReq2Args.Arg0 = TPM2_FFA_REGISTER_FOR_NOTIFICATION;
  FfaDirectReq2Args.Arg1 = (NotificationTypeQualifier << 16 | vCpuId);
  FfaDirectReq2Args.Arg2 = (NotificationId & 0xFF);

  Status = ArmFfaLibMsgSendDirectReq2 (mFfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args);
  while (Status == EFI_INTERRUPT_PENDING) {
    // We are assuming vCPU0 of the TPM SP since it is UP.
    Status = ArmFfaLibRun (mFfaTpm2PartitionId, 0x00, &FfaDirectReq2Args);
  }

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = TranslateTpmReturnStatus (FfaDirectReq2Args.Arg0);

Exit:
  return Status;
}

/**
  Unregister TPM2 device notification.

  @retval EFI_SUCCESS  The command was successfully sent to the device and a response was successfully received.
  @retval Others       Some error occurred in communication with the device.
**/
EFI_STATUS
Tpm2UnregisterNotification (
  VOID
  )
{
  EFI_STATUS       Status;
  DIRECT_MSG_ARGS  FfaDirectReq2Args;

  if (mFfaTpm2PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
    GetTpmServicePartitionId (&mFfaTpm2PartitionId);
  }

  ZeroMem (&FfaDirectReq2Args, sizeof (DIRECT_MSG_ARGS));
  FfaDirectReq2Args.Arg0 = TPM2_FFA_UNREGISTER_FROM_NOTIFICATION;

  Status = ArmFfaLibMsgSendDirectReq2 (mFfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args);
  while (Status == EFI_INTERRUPT_PENDING) {
    // We are assuming vCPU0 of the TPM SP since it is UP.
    Status = ArmFfaLibRun (mFfaTpm2PartitionId, 0x00, &FfaDirectReq2Args);
  }

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = TranslateTpmReturnStatus (FfaDirectReq2Args.Arg0);

Exit:
  return Status;
}

/**
  Issue a finished notification command to the TPM service over FF-A.

  @retval EFI_SUCCESS  The command was successfully sent to the device and a response was successfully received.
  @retval Others       Some error occurred in communication with the device.
**/
EFI_STATUS
Tpm2FinishNotified (
  VOID
  )
{
  EFI_STATUS       Status;
  DIRECT_MSG_ARGS  FfaDirectReq2Args;

  if (mFfaTpm2PartitionId == TPM2_FFA_PARTITION_ID_INVALID) {
    GetTpmServicePartitionId (&mFfaTpm2PartitionId);
  }

  ZeroMem (&FfaDirectReq2Args, sizeof (DIRECT_MSG_ARGS));
  FfaDirectReq2Args.Arg0 = TPM2_FFA_FINISH_NOTIFIED;

  Status = ArmFfaLibMsgSendDirectReq2 (mFfaTpm2PartitionId, &gTpm2ServiceFfaGuid, &FfaDirectReq2Args);
  while (Status == EFI_INTERRUPT_PENDING) {
    // We are assuming vCPU0 of the TPM SP since it is UP.
    Status = ArmFfaLibRun (mFfaTpm2PartitionId, 0x00, &FfaDirectReq2Args);
  }

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = TranslateTpmReturnStatus (FfaDirectReq2Args.Arg0);

Exit:
  return Status;
}
