/** @file
  This library is TPM2 device router. Platform can register multi TPM2 instance to it
  via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
  At most one TPM2 instance can be finally registered, and other will return unsupported.

Copyright (c) 2013 - 2017, Intel Corporation. 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.

**/

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/Tpm2DeviceLib.h>

EFI_GUID mInternalTpm2DeviceInterfaceGuid = {
  0x349cf818, 0xc0ba, 0x4c43, { 0x92, 0x9a, 0xc8, 0xa1, 0xb1, 0xb3, 0xd2, 0x55 }
};

/**
  This function get TPM2.0 interface.

  @retval TPM2.0 interface.
**/
TPM2_DEVICE_INTERFACE *
InternalGetTpm2DeviceInterface (
  VOID
  )
{
  EFI_HOB_GUID_TYPE *Hob;

  Hob = GetFirstGuidHob (&mInternalTpm2DeviceInterfaceGuid);
  if (Hob == NULL) {
    return NULL;
  }
  return (TPM2_DEVICE_INTERFACE *)(Hob + 1);
}

/**
  This service enables the sending of commands to the TPM2.

  @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter block.
  @param[in]      InputParameterBlock      Pointer to the TPM2 input parameter block.
  @param[in,out]  OutputParameterBlockSize Size of the TPM2 output parameter block.
  @param[in]      OutputParameterBlock     Pointer to the TPM2 output parameter block.

  @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
EFIAPI
Tpm2SubmitCommand (
  IN UINT32            InputParameterBlockSize,
  IN UINT8             *InputParameterBlock,
  IN OUT UINT32        *OutputParameterBlockSize,
  IN UINT8             *OutputParameterBlock
  )
{
  TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;

  Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
  if (Tpm2DeviceInterface == NULL) {
    return EFI_UNSUPPORTED;
  }

  return Tpm2DeviceInterface->Tpm2SubmitCommand (
                                InputParameterBlockSize,
                                InputParameterBlock,
                                OutputParameterBlockSize,
                                OutputParameterBlock
                                );
}

/**
  This service requests use TPM2.

  @retval EFI_SUCCESS      Get the control of TPM2 chip.
  @retval EFI_NOT_FOUND    TPM2 not found.
  @retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
EFIAPI
Tpm2RequestUseTpm (
  VOID
  )
{
  TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;

  Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
  if (Tpm2DeviceInterface == NULL) {
    return EFI_UNSUPPORTED;
  }
  return Tpm2DeviceInterface->Tpm2RequestUseTpm ();
}

/**
  This service register TPM2 device.

  @param Tpm2Device  TPM2 device

  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
**/
EFI_STATUS
EFIAPI
Tpm2RegisterTpm2DeviceLib (
  IN TPM2_DEVICE_INTERFACE   *Tpm2Device
  )
{
  TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
    DEBUG ((DEBUG_WARN, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
    return EFI_UNSUPPORTED;
  }

  Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
  if (Tpm2DeviceInterface != NULL) {
    //
    // In PEI phase, there will be shadow driver dispatched again.
    //
    DEBUG ((EFI_D_INFO, "Tpm2RegisterTpm2DeviceLib - Override\n"));
    CopyMem (Tpm2DeviceInterface, Tpm2Device, sizeof(*Tpm2Device));
    return EFI_SUCCESS;
  } else {
    Tpm2Device = BuildGuidDataHob (&mInternalTpm2DeviceInterfaceGuid, Tpm2Device, sizeof(*Tpm2Device));
    if (Tpm2Device != NULL) {
      return EFI_SUCCESS;
    } else {
      return EFI_OUT_OF_RESOURCES;
    }
  }
}
