/** @file
  Header File for HECI Init Lib functionality

 @copyright
  INTEL CONFIDENTIAL
  Copyright 1999 - 2018 Intel Corporation.

  The source code contained or described herein and all documents related to the
  source code ("Material") are owned by Intel Corporation or its suppliers or
  licensors. Title to the Material remains with Intel Corporation or its suppliers
  and licensors. The Material may contain trade secrets and proprietary and
  confidential information of Intel Corporation and its suppliers and licensors,
  and is protected by worldwide copyright and trade secret laws and treaty
  provisions. No part of the Material may be used, copied, reproduced, modified,
  published, uploaded, posted, transmitted, distributed, or disclosed in any way
  without Intel's prior express written permission.

  No license under any patent, copyright, trade secret or other intellectual
  property right is granted to or conferred upon you by disclosure or delivery
  of the Materials, either expressly, by implication, inducement, estoppel or
  otherwise. Any license under such intellectual property rights must be
  express and approved by Intel in writing.

  Unless otherwise agreed by Intel in writing, you may not remove or alter
  this notice or any other notice embedded in Materials by Intel or
  Intel's suppliers or licensors in any way.

  This file contains an 'Intel Peripheral Driver' and is uniquely identified as
  "Intel Reference Module" and is licensed for Intel CPUs and chipsets under
  the terms of your license agreement with Intel or your vendor. This file may
  be modified by the user, subject to additional terms of the license agreement.

@par Specification
**/

#ifndef _HECI_INIT_LIB_H
#define _HECI_INIT_LIB_H

#include <Mbp.h>
#include <SeCChipset.h>
#include <Protocol/Heci2Pm.h>

#define B_EXCLUSION BIT8

UINT32
MmIoReadDword (
  UINTN a
  );

VOID
MmIoWriteDword (
  UINTN  a,
  UINT32 b
  );

//-------------------------------------------------------------------------------------------------------
// Function Prototype declarations
//-------------------------------------------------------------------------------------------------------

EFI_STATUS
WaitForSECReady (
  VOID
  );

EFI_STATUS
EFIAPI
HeciReset (
  IN      HECI_DEVICE      HeciDev
  );

EFI_STATUS
HeciTakeOwnerShip (
  VOID
  );

/**
  Determines if the HECI device is present and, if present, initializes it for
  use by the BIOS.

  @param[in]  HECI Device

  @retval  EFI_STATUS
**/
EFI_STATUS
InitializeHeciPrivate (
  IN HECI_DEVICE                  HeciDev
  );


/**
  This function gets HECI device PCI base address and checks for HECI device availability and provides HECI Device MBAR
  after enabling Device specific BME, MSE and SERR.

  @param[in]  HECI Device Number

  @retval Corresponding HECI Device MBAR
**/
UINTN
CheckAndFixHeciForAccess(
  IN HECI_DEVICE       HeciDev
  );

/**
  Function sends one messsage through the HECI buffer.

  @param[in,out]  Message         Pointer to the message buffer.
  @param[in]      Length          Length of the message in bytes.
  @param[in,out]  RecLength       Length of the message response in bytes.
  @param[in]      HostAddress     Address of the sending entity.
  @param[in]      SeCAddress      Address of the SEC entity that should receive the message.
  @param[in]      SendWithAck     Indicates if the send should wait for an acknowledgement.

  @return EFI_STATUS

**/
EFI_STATUS
EFIAPI
Heci2Send (
  IN OUT  UINT32   *Message,
  IN      UINT32   Length,
  IN OUT  UINT32   *RecLength,
  IN      UINT8    HostAddress,
  IN      UINT8    SeCAddress,
  IN      BOOLEAN  SendWithAck
  );

EFI_STATUS
EFIAPI
Heci2SendwoACK(
  IN OUT  UINT32  *Message,
  IN    UINT32  Length,
  IN OUT  UINT32  *RecLength,
  IN    UINT8   HostAddress,
  IN    UINT8   SeCAddress
  );

EFI_STATUS
EFIAPI
HeciSendwoACK(
  IN OUT  UINT32  *Message,
  IN    UINT32  Length,
  IN OUT  UINT32  *RecLength,
  IN    UINT8   HostAddress,
  IN    UINT8   SeCAddress
  );

EFI_STATUS
HeciGetBootDevice(
  MBP_CURRENT_BOOT_MEDIA    *BootMediaData
  );

/**
  Checks if HECI reset has occured.

  @param[in]     HECI Device Number

  @retval TRUE   HECI reset occurred
  @retval FALSE  No HECI reset occurred
**/
BOOLEAN
CheckForHeciReset(
  IN HECI_DEVICE                  HeciDev
  );

/**
  DumpBuffer_HECI

  @param[in] Buffer1

  @retval    None
**/
VOID
DumpBuffer_HECI (
  VOID *Buffer1,
  UINT8 Buffersize
  );

/**
  Function sends one messsage through the HECI circular buffer and waits
  for the corresponding ACK message.

  @param[in,out]  Message     - Pointer to the message buffer.
  @param[in]      SendLength  - Length of the message in bytes.
  @param[in,out]  RecLength   - Length of the message response in bytes.
  @param[in]      HostAddress - Address of the sending entity.
  @param[in]      SeCAddress   - Address of the ME entity that should receive the message.

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
HeciSendwACK (
  IN      HECI_DEVICE   HeciDev,
  IN OUT  UINT32        *Message,
  IN OUT  UINT32        Length,
  IN OUT  UINT32        *RecLength,
  IN      UINT8         HostAddress,
  IN      UINT8         SeCAddress
  );

/**
  Activates HECI2 power management.
  If the HECI2 device is idle, this function will make it active.

  @param[out]    IsHeci2Idle     Indicates whether the HECI2 device is idle
  @param[out]    Heci2PmProtocol Set to the instance of the EFI_HECI2_PM_PROTOCOL found

  @return        EFI_SUCCESS     HECI2 was successfully transitioned to active.
  @return        EFI_NOT_FOUND   A protocol instance of EFI_HECI2_PM_PROTOCOL could not be found.
**/
EFI_STATUS
EFIAPI
ActivateHeci2Pm (
  OUT  BOOLEAN                *IsHeci2Idle,
  OUT  EFI_HECI2_PM_PROTOCOL  **Heci2PmProtocol
  );

/**
  Receives a message from CSE through the HECI circular buffer.

  @param[in]      HeciDev      The HECI device to use for the receive operation.
  @param[in]      Blocking     Indicates if the HECI transaction should be blocking
  @param[out]     Message      A pointer to a message buffer filled for the caller
  @param[out]     Length       The length of data in the message buffer

  @retval         EFI_SUCCESS  The message was received from CSE successfully.
  @retval         Others       An error occurred receiving the message from CSE.
**/
EFI_STATUS
EFIAPI
HeciReceive (
  IN      HECI_DEVICE   HeciDev,
  IN      UINT32        Blocking,
  OUT     UINT32        *MessageBody,
  OUT     UINT32        *Length
  );

/**
  Sends one messsage (of any length) through the HECI circular buffer.

  @param[in]  HeciDev       The HECI device to use for the send operation.
  @param[in]  Message       Pointer to the message data buffer to be sent.
  @param[in]  Length        Length of the message in the buffer in bytes.
  @param[in]  HostAddress   The address of the host processor.
  @param[in]  SeCAddress    Address of the ME subsystem the message is being sent to.

  @retval     EFI_SUCCESS   The message was sent successfully.
  @retval     Others        An error occurred sending the message.
**/
EFI_STATUS
EFIAPI
HeciSend (
  IN     HECI_DEVICE    HeciDev,
  IN     UINT32        *Message,
  IN     UINT32         Length,
  IN     UINT8          HostAddress,
  IN     UINT8          SeCAddress
  );

/**
  Function forces a reinit of the heci interface by following the reset heci interface via host algorithm
    in HPS 0.90 doc 4-17-06 njy

  @param[in]  none

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
ResetHeciInterface (
  IN      HECI_DEVICE      HeciDev
  );

/**
  Determines if the HECI device is present and, if present, initializes it for
  use by the BIOS.

  @param[in] None

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
HeciInitialize (
  IN  HECI_DEVICE      HeciDev
  );

/**
  Heci Re-initializes it for Host

  @param[in] None

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
HeciReInitialize (
  IN      HECI_DEVICE      HeciDev
  );

/**
  SeC reset and waiting for ready

  @param[in]  Delay - The biggest waiting time

  @retval  EFI_TIMEOUT - Time out
  @retval  EFI_SUCCESS - SeC ready
**/
EFI_STATUS
EFIAPI
SeCResetWait (
  IN  HECI_DEVICE   HeciDev,
  IN  UINT32        Delay
  );

/**
  Return SEC Status

  @param[in]  SeCStatus pointer for status report

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
HeciGetSeCStatus (
  IN UINT32                     *SeCStatus
  );

/**
  Return SEC Status

  @param[in]  SeCStatus pointer for status report

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
HeciGetSeCMode (
  IN  HECI_DEVICE               HeciDev,
  IN UINT32                     *SeCMode
  );

/**
  Function sends bios2ish bin file to CSE through HECI circular buffer and waits
  for the corresponding ACK message.

  @param[in]  Message     - Pointer to the send message buffer.
  @param[out]  Message     - Pointer to the receive message buffer.
  @param[in]      SendLength  - Length of the message in bytes.
  @param[in,out]  RecLength   - Length of the message response in bytes.
  @param[in]      HostAddress - Address of the sending entity.
  @param[in]      SeCAddress   - Address of the ME entity that should receive the message.

  @retval  EFI_STATUS
**/
EFI_STATUS
EFIAPI
HeciIshSendwAck (
  IN   HECI_DEVICE   HeciDev,
  IN   VOID          *SendMessage,
  OUT  VOID          *ReceiveMessage,
  IN   UINT32        SendLength,
  IN OUT  UINT32     *RecLength,
  IN      UINT8      HostAddress,
  IN      UINT8      SeCAddress
  );

#endif
