/** @file
  Implement TPM2 Context related command.
Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved. 
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include 
#include 
#include 
#include 
#include 
#include 
#pragma pack(1)
typedef struct {
  TPM2_COMMAND_HEADER    Header;
  TPMI_DH_CONTEXT        FlushHandle;
} TPM2_FLUSH_CONTEXT_COMMAND;
typedef struct {
  TPM2_RESPONSE_HEADER    Header;
} TPM2_FLUSH_CONTEXT_RESPONSE;
#pragma pack()
/**
  This command causes all context associated with a loaded object or session to be removed from TPM memory.
  @param[in]  FlushHandle        The handle of the item to flush.
  @retval EFI_SUCCESS            Operation completed successfully.
  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
Tpm2FlushContext (
  IN      TPMI_DH_CONTEXT  FlushHandle
  )
{
  EFI_STATUS                   Status;
  TPM2_FLUSH_CONTEXT_COMMAND   SendBuffer;
  TPM2_FLUSH_CONTEXT_RESPONSE  RecvBuffer;
  UINT32                       SendBufferSize;
  UINT32                       RecvBufferSize;
  //
  // Construct command
  //
  SendBuffer.Header.tag         = SwapBytes16 (TPM_ST_NO_SESSIONS);
  SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_FlushContext);
  SendBuffer.FlushHandle = SwapBytes32 (FlushHandle);
  SendBufferSize              = (UINT32)sizeof (SendBuffer);
  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
  //
  // send Tpm command
  //
  RecvBufferSize = sizeof (RecvBuffer);
  Status         = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
    DEBUG ((DEBUG_ERROR, "Tpm2FlushContext - RecvBufferSize Error - %x\n", RecvBufferSize));
    return EFI_DEVICE_ERROR;
  }
  if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
    DEBUG ((DEBUG_ERROR, "Tpm2FlushContext - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));
    return EFI_DEVICE_ERROR;
  }
  return EFI_SUCCESS;
}