/** @file

  Serial instance of Manageability Transport Library

  Copyright (c) 2024, ARM Limited. All rights reserved.<BR>
  Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include <Uefi.h>
#include <IndustryStandard/Mctp.h>
#include <Library/SerialPortLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include <Library/DebugLib.h>
#include <Library/ManageabilityTransportHelperLib.h>
#include <Library/ManageabilityTransportMctpLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/TimerLib.h>

#include "ManageabilityTransportSerial.h"

extern MANAGEABILITY_TRANSPORT_SERIAL_HARDWARE_INFO  mSerialHardwareInfo;
extern MANAGEABILITY_TRANSPORT_SERIAL                *mSingleSessionToken;

IPMI_SERIAL_SPECIAL_CHAR  mIpmiSerialSpecialChar[] = {
  { BASIC_MODE_START,     BASIC_MODE_START_ENCODED_BYTE     }, /* start */
  { BASIC_MODE_STOP,      BASIC_MODE_STOP_ENCODED_BYTE      }, /* stop */
  { BASIC_MODE_HANDSHAKE, BASIC_MODE_HANDSHAKE_ENCODED_BYTE }, /* packet handshake */
  { BASIC_MODE_ESCAPE,    BASIC_MODE_ESCAPE_ENCODED_BYTE    }, /* data escape */
  { BASIC_MODE_ESC_CHAR,  BASIC_MODE_ESC_CHAR_ENCODED_BYTE  }  /* escape */
};

UINT8  mNumberOfEscapeCharacters = ARRAY_SIZE (mIpmiSerialSpecialChar);

/**
  Return escaped character for the given one

  @param[in]      Character           Character data.

  @retval         Character           Return escaped character if it is.
                                      Otherwise, return the given one.
**/
static
UINT8
IpmiSerialGetEscapedCharacter (
  UINT8  Character
  )
{
  UINT8  Index;

  for (Index = 0; Index < mNumberOfEscapeCharacters; Index++) {
    if (mIpmiSerialSpecialChar[Index].Character == Character) {
      return mIpmiSerialSpecialChar[Index].Escape;
    }
  }

  return Character;
}

/**
  Return unescaped character for the given one

  @param[in]      Character           Character data.

  @retval         Character           Return unescaped character if it is.
                                      Otherwise, return the given one.
**/
static
UINT8
IpmiSerialGetUnescapedCharacter (
  UINT8  Character
  )
{
  UINT8  Index;

  for (Index = 0; Index < mNumberOfEscapeCharacters; Index++) {
    if (mIpmiSerialSpecialChar[Index].Escape == Character) {
      return mIpmiSerialSpecialChar[Index].Character;
    }
  }

  return Character;
}

/**
  Parse IPMI Serial incoming data in basic mode format to IPMI message

  @param[in]        Buffer                Data buffer with data byte escaped.
  @param[in]        BufferSize            Data buffer size.
  @param[out]       ResponseData          Data buffer without data byte escaped.
  @param[in, out]   ResponseDataSize      Data buffer size.

  @retval           EFI_SUCCESS           The command byte stream was successfully
                                          submit to the device and a response was
                                          successfully received.
  @retval           EFI_PROTOCOL_ERROR    The command byte stream cannot encode
                                          successfully.
  @retval           EFI_OUT_OF_RESOURCES  The resource allocation is out of resource or
                                          data size error.
**/
EFI_STATUS
IpmiSerialParseIncomingBuffer (
  IN        UINT8   *Buffer,
  IN        UINT32  BufferSize,
  OUT       UINT8   *ResponseData,
  IN OUT    UINT32  *ResponseDataSize
  )
{
  UINT8   *ResponsePtr;
  UINT8   Character;
  UINT8   UnescapedCharacter;
  UINT32  Count;
  UINT32  Index;
  UINT8   CtxState;
  UINT8   CtxEscape;

  if ((BufferSize == 0) || (Buffer == NULL)) {
    DEBUG ((DEBUG_ERROR, "Buffer Data insufficient. \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  if ((ResponseDataSize == NULL) ||
      (BufferSize > *ResponseDataSize) ||
      (ResponseData == NULL))
  {
    DEBUG ((DEBUG_ERROR, "Response Data insufficient. \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  CtxState    = MSG_IDLE;
  CtxEscape   = 0;
  ResponsePtr = ResponseData;
  Count       = 0;
  for (Index = 0; Index < BufferSize; Index++) {
    Character = Buffer[Index];
    if ((Character == BASIC_MODE_START) && (CtxState == MSG_IDLE)) {
      // START
      CtxState  = MSG_IN_PROGRESS;
      CtxEscape = 0;
    } else if (CtxState != MSG_IN_PROGRESS) {
      continue;
    } else if (CtxEscape != 0) {
      UnescapedCharacter = IpmiSerialGetUnescapedCharacter (Character);

      if (UnescapedCharacter == Character) {
        // error, then reset
        CtxState = MSG_IDLE;
        continue;
      }

      *ResponsePtr++ = UnescapedCharacter;
      Count++;
      CtxEscape = 0;
    } else if (Character == BASIC_MODE_ESCAPE) {
      CtxEscape = 1;
      continue;
    } else if (Character == BASIC_MODE_STOP) {
      // STOP
      CtxState          = MSG_IDLE;
      *ResponseDataSize = Count;
      return EFI_SUCCESS;
    } else if (Character == BASIC_MODE_HANDSHAKE) {
      // just skip it
      continue;
    } else if (CtxState == MSG_IN_PROGRESS) {
      *ResponsePtr++ = Character;
      Count++;
    }
  }

  return EFI_PROTOCOL_ERROR;
}

/**
  This function writes/sends data to the Serial port.
  Basic mode message fields in IPMI spec 2.0 Figure 14.

  @param[in]      TransmitHeader        Serial packet header.
  @param[in]      TransmitHeaderSize    Serial packet header size in byte.
  @param[in]      TransmitTrailer       Serial packet trailer.
  @param[in]      TransmitTrailerSize   Serial packet trailer size in byte.
  @param[in]      RequestData           Command Request Data, could be NULL.
                                        RequestDataSize must be zero, if RequestData
                                        is NULL.
  @param[in]      RequestDataSize       Size of Command Request Data.

  @retval         EFI_SUCCESS           The command byte stream was successfully
                                        submit to the device and a response was
                                        successfully received.
  @retval         EFI_NOT_FOUND         The command was not successfully sent to the
                                        device or a response was not successfully
                                        received from the device.
  @retval         EFI_NOT_READY         Ipmi Device is not ready for Ipmi command
                                        access.
  @retval         EFI_DEVICE_ERROR      Ipmi Device hardware error.
  @retval         EFI_TIMEOUT           The command time out.
  @retval         EFI_UNSUPPORTED       The command was not successfully sent to
                                        the device.
  @retval         EFI_OUT_OF_RESOURCES  The resource allocation is out of resource or
                                        data size error.
**/
EFI_STATUS
SerialTransportWrite (
  IN  MANAGEABILITY_TRANSPORT_HEADER   TransmitHeader,
  IN  UINT16                           TransmitHeaderSize,
  IN  MANAGEABILITY_TRANSPORT_TRAILER  TransmitTrailer OPTIONAL,
  IN  UINT16                           TransmitTrailerSize,
  IN  UINT8                            *RequestData OPTIONAL,
  IN  UINT32                           RequestDataSize
  )
{
  EFI_STATUS          Status;
  IPMI_SERIAL_HEADER  *HeaderPtr;
  UINT8               *BufferPtr;
  UINT8               *Buffer;
  UINT32              BufferLength;
  UINT8               *Request;
  UINT32              RequestLength;
  UINT8               RetryCount;
  UINT32              Index;
  UINT8               Character;
  UINT8               EscapedCharacterCount;
  UINT8               NetFunction;

  // Validation on RequestData and RequestDataSize.
  if (((RequestData == NULL) && (RequestDataSize != 0)) ||
      ((RequestData != NULL) && (RequestDataSize == 0))
      )
  {
    DEBUG ((DEBUG_ERROR, "%a: Mismatched values of RequestData or RequestDataSize.\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  // Validation on TransmitHeader and TransmitHeaderSize.
  if (((TransmitHeader == NULL) && (TransmitHeaderSize != 0)) ||
      ((TransmitHeader != NULL) && (TransmitHeaderSize == 0))
      )
  {
    DEBUG ((DEBUG_ERROR, "%a: Mismatched values of TransmitHeader or TransmitHeaderSize.\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  // Validation on TransmitHeader and TransmitHeaderSize.
  if (((TransmitTrailer == NULL) && (TransmitTrailerSize != 0)) ||
      ((TransmitTrailer != NULL) && (TransmitTrailerSize == 0))
      )
  {
    DEBUG ((DEBUG_ERROR, "%a: Mismatched values of TransmitTrailer or TransmitTrailerSize.\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  NetFunction = ((MANAGEABILITY_IPMI_TRANSPORT_HEADER *)TransmitHeader)->NetFn;
  ASSERT (NetFunction <= MANAGEABILITY_IPMI_NET_FUNC_MAX);

  BufferLength = RequestDataSize + IPMI_SERIAL_MIN_REQUEST_LENGTH;
  Buffer       = AllocateZeroPool (BufferLength);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  HeaderPtr = (IPMI_SERIAL_HEADER *)Buffer;

  // Fill IPMI Serial basic format data bytes
  HeaderPtr->ResponderAddress  = IPMI_SERIAL_RS_ADDRESS;
  HeaderPtr->ResponderNetFnLun = (UINT8)((NetFunction << 2) | (IPMI_SERIAL_RS_LUN & IPMI_MAX_LUN));
  HeaderPtr->CheckSum          = CalculateCheckSum8 (&Buffer[0], IPMI_SERIAL_CONNECTION_HEADER_LENGTH - 1);
  HeaderPtr->RequesterAddress  = IPMI_SERIAL_RQ_ADDRESS;
  HeaderPtr->RequesterSeqLun   = IPMI_SERIAL_RQ_LUN;
  HeaderPtr->Command           = ((MANAGEABILITY_IPMI_TRANSPORT_HEADER *)TransmitHeader)->Command;

  // Calculate data checksum
  if ((RequestData != NULL) && (RequestDataSize > 0)) {
    CopyMem (HeaderPtr->Data, RequestData, RequestDataSize);
    Buffer[BufferLength - 1] = CalculateCheckSum8 (
                                 &Buffer[IPMI_SERIAL_CONNECTION_HEADER_LENGTH],
                                 RequestDataSize + IPMI_SERIAL_REQUEST_DATA_HEADER_LENGTH
                                 );
  } else {
    Buffer[BufferLength - 1] = CalculateCheckSum8 (&Buffer[IPMI_SERIAL_CONNECTION_HEADER_LENGTH], IPMI_SERIAL_REQUEST_DATA_HEADER_LENGTH);
  }

  // Calculate escaped character count
  EscapedCharacterCount = 0;
  for (Index = 0; Index < BufferLength; Index++) {
    if (IpmiSerialGetEscapedCharacter (Buffer[Index]) != Buffer[Index]) {
      EscapedCharacterCount++;
    }
  }

  // Allocate memory buffer include escaped characters
  RequestLength = BufferLength + EscapedCharacterCount + 2; // start + stop byte
  Request       = AllocateZeroPool (RequestLength);
  if (Request == NULL) {
    DEBUG ((DEBUG_ERROR, "Out Of Resource \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  BufferPtr = Request;

  // start character
  *BufferPtr++ = BASIC_MODE_START;

  // Fill the request data with data byte escaped
  for (Index = 0; Index < BufferLength; Index++) {
    Character = IpmiSerialGetEscapedCharacter (Buffer[Index]);
    if (Character != Buffer[Index]) {
      *BufferPtr++ = BASIC_MODE_ESCAPE;
    }

    *BufferPtr++ = Character;
  }

  // stop character
  *BufferPtr++ = BASIC_MODE_STOP;

  //
  // Write Request
  //
  RetryCount = 0;
  while (TRUE) {
    Status = SerialPortWrite (Request, RequestLength);
    if (Status == RequestLength) {
      break;
    }

    if (++RetryCount > IPMI_SERIAL_RETRY_COUNT) {
      DEBUG ((DEBUG_ERROR, "%a: Write Request error %r\n", __func__, Status));
      break;
    }

    MicroSecondDelay (IPMI_SERIAL_REQUEST_RETRY_INTERVAL);
  }

  FreePool (Buffer);
  FreePool (Request);

  return EFI_SUCCESS;
}

/**
  Read Serial response from BMC.

  @param[out]        ResponseData      Command Response Data.
  @param[in, out]    ResponseDataSize  Size of Command Response Data.

  @retval EFI_SUCCESS                  The command byte stream was successfully submit to the device
                                       and a response was successfully received.
  @retval EFI_PROTOCOL_ERROR           The command byte stream cannot encode
                                       successfully.
**/
EFI_STATUS
SerialReadResponse (
  OUT    UINT8   *ResponseData,
  IN OUT UINT32  *ResponseDataSize
  )
{
  EFI_STATUS  Status;
  UINT8       Character;
  UINT8       Buffer[IPMI_SERIAL_MAXIMUM_PACKET_SIZE_IN_BYTES];
  UINT32      BufferSize;
  UINT8       ReadBuffer[IPMI_SERIAL_MAXIMUM_PACKET_SIZE_IN_BYTES];
  UINT32      ReadBytes;
  UINT32      RetryCount;

  ASSERT (ResponseData != NULL && ResponseDataSize != NULL);

  //
  // Keep polling until retryCount timeout
  //
  RetryCount = 0;
  ReadBytes  = 0;
  while (ReadBytes < IPMI_SERIAL_MAXIMUM_PACKET_SIZE_IN_BYTES) {
    if (++RetryCount > IPMI_SERIAL_RETRY_COUNT) {
      break;
    }

    while (SerialPortPoll ()) {
      SerialPortRead (&Character, sizeof (Character));
      ReadBuffer[ReadBytes++] = Character;
    }

    MicroSecondDelay (IPMI_SERIAL_RESPONSE_RETRY_INTERVAL);
  }

  // Parse IPMI Serial format request data
  BufferSize = sizeof (Buffer);
  Status     = IpmiSerialParseIncomingBuffer (
                 ReadBuffer,
                 ReadBytes,
                 Buffer,
                 &BufferSize
                 );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Parse Response Error\n"));
    return Status;
  }

  // Header checksum verify
  if (CalculateCheckSum8 (Buffer, IPMI_SERIAL_CONNECTION_HEADER_LENGTH) != 0) {
    DEBUG ((DEBUG_ERROR, "Bad checksum - header\n"));
    return EFI_PROTOCOL_ERROR;
  }

  // Data checksum verify
  if (CalculateCheckSum8 (
        &Buffer[IPMI_SERIAL_CONNECTION_HEADER_LENGTH],
        BufferSize - IPMI_SERIAL_CONNECTION_HEADER_LENGTH
        ) != 0)
  {
    DEBUG ((DEBUG_ERROR, "Bad checksum - data byte\n"));
    return EFI_PROTOCOL_ERROR;
  }

  *ResponseDataSize = BufferSize - (sizeof (IPMI_SERIAL_HEADER) + 1); // Header (6) + Checksum (1)
  CopyMem (ResponseData, &Buffer[sizeof (IPMI_SERIAL_HEADER)], *ResponseDataSize);

  return Status;
}

/**
  This function sends/receives data from Serial port.

  @param [out       DataBytes             Buffer to hold the read Data.
  @param [in, out]  Length                Number of Bytes read from Serial port.
  @retval           EFI_SUCCESS           The command byte stream was
                                          successfully submit to the device and
                                          a response was successfully received.
  @retval           EFI_NOT_FOUND         The command was not successfully sent
                                          to the device or a response was not
                                          successfully received from the
                                          device.
  @retval           EFI_NOT_READY         Ipmi Device is not ready for Ipmi
                                          command access.
  @retval           EFI_OUT_OF_RESOURCES  The resource allocation is out of
                                          resource or data size error.
  @retval           EFI_PROTOCOL_ERROR    The command byte stream cannot encode
                                          successfully.
**/
EFI_STATUS
SerialTransportRead (
  OUT    UINT8   *DataByte,
  IN OUT UINT32  *Length
  )
{
  EFI_STATUS  Status;

  if ((DataByte == NULL) || (*Length == 0)) {
    DEBUG ((DEBUG_ERROR, "%a: Either DataByte is NULL or Length is 0.\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  Status = SerialReadResponse (DataByte, Length);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Read Response error %r\n", __func__, Status));
    *Length = 0;
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  This function checks the Serial response data according to
  manageability protocol.

  @param[in]      ResponseData        Pointer to response data.
  @param[in]      ResponseDataSize    Size of response data.
  @param[out]     AdditionalStatus    Pointer to receive the additional status.

  @retval         EFI_SUCCESS         Serial response header is checked without error
  @retval         EFI_DEVICE_ERROR    Serial response header has problem.
**/
EFI_STATUS
SerialCheckResponseData (
  IN UINT8                                       *ResponseData,
  IN UINT32                                      ResponseDataSize,
  OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS  *AdditionalStatus
  )
{
  EFI_STATUS  Status;
  CHAR16      *CompletionCodeStr;

  Status            = EFI_SUCCESS;
  *AdditionalStatus = MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_NO_ERRORS;
  if (CompareGuid (&gManageabilityProtocolIpmiGuid, mSingleSessionToken->Token.ManageabilityProtocolSpecification)) {
    //
    // For IPMI Serial
    // Check and print Completion Code
    //
    Status = IpmiHelperCheckCompletionCode (*ResponseData, &CompletionCodeStr, AdditionalStatus);
    if (!EFI_ERROR (Status)) {
      DEBUG ((DEBUG_MANAGEABILITY_INFO, "Cc: %02x %s.\n", *((UINT8 *)ResponseData), CompletionCodeStr));
    } else if (Status == EFI_NOT_FOUND) {
      DEBUG ((DEBUG_ERROR, "Cc: %02x not defined in IpmiCompletionCodeMapping or invalid.\n", *((UINT8 *)ResponseData)));
    }
  }

  return Status;
}

/**
  This service communicates with BMC using Serial protocol.

  @param[in]      TransmitHeader        Serial packet header.
  @param[in]      TransmitHeaderSize    Serial packet header size in byte.
  @param[in]      TransmitTrailer       Serial packet trailer.
  @param[in]      TransmitTrailerSize   Serial packet trailer size in byte.
  @param[in]      RequestData           Command Request Data.
  @param[in]      RequestDataSize       Size of Command Request Data.
  @param[out]     ResponseData          Command Response Data. The completion
                                        code is the first byte of response
                                        data.
  @param[in, out] ResponseDataSize      Size of Command Response Data.
  @param[out]     AdditionalStatus       Additional status of this transaction.

  @retval         EFI_SUCCESS           The command byte stream was
                                        successfully submit to the device and a
                                        response was successfully received.
  @retval         EFI_NOT_FOUND         The command was not successfully sent
                                        to the device or a response was not
                                        successfully received from the device.
  @retval         EFI_NOT_READY         Ipmi Device is not ready for Ipmi
                                        command access.
  @retval         EFI_DEVICE_ERROR      Ipmi Device hardware error.
  @retval         EFI_TIMEOUT           The command time out.
  @retval         EFI_UNSUPPORTED       The command was not successfully sent to
                                        the device.
  @retval         EFI_OUT_OF_RESOURCES  The resource allocation is out of
                                        resource or data size error.
**/
EFI_STATUS
EFIAPI
SerialTransportSendCommand (
  IN  MANAGEABILITY_TRANSPORT_HEADER              TransmitHeader OPTIONAL,
  IN  UINT16                                      TransmitHeaderSize,
  IN  MANAGEABILITY_TRANSPORT_TRAILER             TransmitTrailer OPTIONAL,
  IN  UINT16                                      TransmitTrailerSize,
  IN  UINT8                                       *RequestData OPTIONAL,
  IN  UINT32                                      RequestDataSize,
  OUT UINT8                                       *ResponseData OPTIONAL,
  IN  OUT UINT32                                  *ResponseDataSize OPTIONAL,
  OUT  MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS  *AdditionalStatus
  )
{
  EFI_STATUS  Status;

  if ((RequestData != NULL) && (RequestDataSize == 0)) {
    DEBUG ((DEBUG_ERROR, "%a: Mismatched values of RequestData and RequestDataSize\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  if ((ResponseData != NULL) && ((ResponseDataSize != NULL) && (*ResponseDataSize == 0))) {
    DEBUG ((DEBUG_ERROR, "%a: Mismatched values of ResponseData and ResponseDataSize\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  if (AdditionalStatus == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: AdditionalStatus is NULL.\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  // Print out the request payloads.
  if ((TransmitHeader != NULL) && (TransmitHeaderSize != 0)) {
    HelperManageabilityDebugPrint ((VOID *)TransmitHeader, (UINT32)TransmitHeaderSize, "Serial Transmit Header:\n");
  }

  if (RequestData != NULL) {
    HelperManageabilityDebugPrint ((VOID *)RequestData, RequestDataSize, "Serial Request Data:\n");
  }

  if ((TransmitTrailer != NULL) && (TransmitTrailerSize != 0)) {
    HelperManageabilityDebugPrint ((VOID *)TransmitTrailer, (UINT32)TransmitTrailerSize, "Serial Transmit Trailer:\n");
  }

  if ((TransmitHeader != NULL) || (RequestData != NULL)) {
    Status = SerialTransportWrite (
               TransmitHeader,
               TransmitHeaderSize,
               TransmitTrailer,
               TransmitTrailerSize,
               RequestData,
               RequestDataSize
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Serial Write Failed with Status(%r)\n", Status));
      return Status;
    }
  }

  if ((ResponseData != NULL) && (ResponseDataSize != NULL) && (*ResponseDataSize != 0)) {
    Status = SerialTransportRead (ResponseData, ResponseDataSize);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Serial response read Failed with Status(%r)\n", Status));
    }

    // Print out the response payloads.
    if (*ResponseDataSize != 0) {
      HelperManageabilityDebugPrint ((VOID *)ResponseData, (UINT32)*ResponseDataSize, "Serial Response Data:\n");
      Status = SerialCheckResponseData (ResponseData, *ResponseDataSize, AdditionalStatus);
    } else {
      DEBUG ((DEBUG_ERROR, "No response, can't determine Completion Code.\n"));
    }
  } else {
    *ResponseDataSize = 0;
  }

  return Status;
}
