/** @file
  Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system
  running GDB. One console for error information and another console for user input/output.

  Basic packet format is $packet-data#checksum. So every command has 4 bytes of overhead: $,
  #, 0, 0. The 0 and 0 are the ascii characters for the checksum.


  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <GdbStubInternal.h>

//
// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
// here we need to wait for the periodic callback to do this.
//
BOOLEAN  gCtrlCBreakFlag = FALSE;

//
// If the periodic callback is called while we are processing an F packet we need
// to let the callback know to not read from the serial stream as it could steal
// characters from the F response packet
//
BOOLEAN  gProcessingFPacket = FALSE;

/**
  Process a control-C break message.

  Currently a place holder, remove the ASSERT when it gets implemented.

  @param  ErrNo   Error information from the F reply packet or other source

**/
VOID
GdbCtrlCBreakMessage (
  IN  UINTN  ErrNo
  )
{
  // See D.10.5 of gdb.pdf
  // This should look like a break message. Should look like SIGINT

  /* TODO: Make sure if we should do anything with ErrNo */
  // Turn on the global Ctrl-C flag.
  gCtrlCBreakFlag = TRUE;
}

/**
  Parse the F reply packet and extract the return value and an ErrNo if it exists.

  @param  Packet  Packet to parse like an F reply packet
  @param  ErrNo   Buffer to hold Count bytes that were read

  @retval -1      Error, not a valid F reply packet
  @retval other   Return the return code from the F reply packet

**/
INTN
GdbParseFReplyPacket (
  IN  CHAR8  *Packet,
  OUT UINTN  *ErrNo
  )
{
  INTN  RetCode;

  if (Packet[0] != 'F') {
    // A valid response would be an F packet
    return -1;
  }

  RetCode = AsciiStrHexToUintn (&Packet[1]);

  // Find 1st comma
  for ( ; *Packet != '\0' && *Packet != ','; Packet++) {
  }

  if (*Packet == '\0') {
    *ErrNo = 0;
    return RetCode;
  }

  *ErrNo = AsciiStrHexToUintn (++Packet);

  // Find 2nd comma
  for ( ; *Packet != '\0' && *Packet != ','; Packet++) {
  }

  if (*Packet == '\0') {
    return RetCode;
  }

  if (*(++Packet) == 'C') {
    GdbCtrlCBreakMessage (*ErrNo);
  }

  return RetCode;
}

/**
  Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
  the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.

  @param  FileDescriptor   Device to talk to.
  @param  Buffer           Buffer to hold Count bytes that were read
  @param  Count            Number of bytes to transfer.

  @retval -1               Error
  @retval {other}          Number of bytes read.

**/
INTN
GdbRead (
  IN  INTN   FileDescriptor,
  OUT VOID   *Buffer,
  IN  UINTN  Count
  )
{
  CHAR8    Packet[128];
  UINTN    Size;
  INTN     RetCode;
  UINTN    ErrNo;
  BOOLEAN  ReceiveDone = FALSE;

  // Send:
  // "Fread,XX,YYYYYYYY,XX
  //
  // XX - FileDescriptor in ASCII
  // YYYYYYYY - Buffer address in ASCII
  // XX - Count in ASCII
  // SS - check sum
  //
  Size = AsciiSPrint (Packet, sizeof (Packet), "Fread,%x,%x,%x", FileDescriptor, Buffer, Count);
  // Packet array is too small if you got this ASSERT
  ASSERT (Size < sizeof (Packet));

  gProcessingFPacket = TRUE;
  SendPacket (Packet);
  Print ((CHAR16 *)L"Packet sent..\n");

  do {
    // Reply:
    ReceivePacket (Packet, sizeof (Packet));
    Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);

    // Process GDB commands
    switch (Packet[0]) {
      // Write memory command.
      // M addr,length:XX...
      case    'M':
        WriteToMemory (Packet);
        break;

      // Fretcode, errno, Ctrl-C flag
      // retcode - Count read
      case    'F':
        // Once target receives F reply packet that means the previous
        // transactions are finished.
        ReceiveDone = TRUE;
        break;

      // Send empty buffer
      default:
        SendNotSupported ();
        break;
    }
  } while (ReceiveDone == FALSE);

  RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
  Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);

  if (ErrNo > 0) {
    // Send error to the host if there is any.
    SendError ((UINT8)ErrNo);
  }

  gProcessingFPacket = FALSE;

  return RetCode;
}

/**
  Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
  nothing was written. On error -1 is returned.

  @param  FileDescriptor   Device to talk to.
  @param  Buffer           Buffer to hold Count bytes that are to be written
  @param  Count            Number of bytes to transfer.

  @retval -1               Error
  @retval {other}          Number of bytes written.

**/
INTN
GdbWrite (
  IN  INTN        FileDescriptor,
  OUT CONST VOID  *Buffer,
  IN  UINTN       Count
  )
{
  CHAR8    Packet[128];
  UINTN    Size;
  INTN     RetCode;
  UINTN    ErrNo;
  BOOLEAN  ReceiveDone = FALSE;

  // Send:
  // #Fwrite,XX,YYYYYYYY,XX$SS
  //
  // XX - FileDescriptor in ASCII
  // YYYYYYYY - Buffer address in ASCII
  // XX - Count in ASCII
  // SS - check sum
  //
  Size = AsciiSPrint (Packet, sizeof (Packet), "Fwrite,%x,%x,%x", FileDescriptor, Buffer, Count);
  // Packet array is too small if you got this ASSERT
  ASSERT (Size < sizeof (Packet));

  SendPacket (Packet);
  Print ((CHAR16 *)L"Packet sent..\n");

  do {
    // Reply:
    ReceivePacket (Packet, sizeof (Packet));
    Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);

    // Process GDB commands
    switch (Packet[0]) {
      // Read memory command.
      // m addr,length.
      case    'm':
        ReadFromMemory (Packet);
        break;

      // Fretcode, errno, Ctrl-C flag
      // retcode - Count read
      case    'F':
        // Once target receives F reply packet that means the previous
        // transactions are finished.
        ReceiveDone = TRUE;
        break;

      // Send empty buffer
      default:
        SendNotSupported ();
        break;
    }
  } while (ReceiveDone == FALSE);

  RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
  Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);

  // Send error to the host if there is any.
  if (ErrNo > 0) {
    SendError ((UINT8)ErrNo);
  }

  return RetCode;
}

/**
  Reset the serial device.

  @param  This              Protocol instance pointer.

  @retval EFI_SUCCESS       The device was reset.
  @retval EFI_DEVICE_ERROR  The serial device could not be reset.

**/
EFI_STATUS
EFIAPI
GdbSerialReset (
  IN EFI_SERIAL_IO_PROTOCOL  *This
  )
{
  return EFI_SUCCESS;
}

/**
  Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
  data buts, and stop bits on a serial device.

  @param  This             Protocol instance pointer.
  @param  BaudRate         The requested baud rate. A BaudRate value of 0 will use the the
                           device's default interface speed.
  @param  ReceiveFifoDepth The requested depth of the FIFO on the receive side of the
                           serial interface. A ReceiveFifoDepth value of 0 will use
                           the device's default FIFO depth.
  @param  Timeout          The requested time out for a single character in microseconds.
                           This timeout applies to both the transmit and receive side of the
                           interface. A Timeout value of 0 will use the device's default time
                           out value.
  @param  Parity           The type of parity to use on this serial device. A Parity value of
                           DefaultParity will use the device's default parity value.
  @param  DataBits         The number of data bits to use on the serial device. A DataBits
                           value of 0 will use the device's default data bit setting.
  @param  StopBits         The number of stop bits to use on this serial device. A StopBits
                           value of DefaultStopBits will use the device's default number of
                           stop bits.

  @retval EFI_SUCCESS      The device was reset.
  @retval EFI_DEVICE_ERROR The serial device could not be reset.

**/
EFI_STATUS
EFIAPI
GdbSerialSetAttributes (
  IN EFI_SERIAL_IO_PROTOCOL  *This,
  IN UINT64                  BaudRate,
  IN UINT32                  ReceiveFifoDepth,
  IN UINT32                  Timeout,
  IN EFI_PARITY_TYPE         Parity,
  IN UINT8                   DataBits,
  IN EFI_STOP_BITS_TYPE      StopBits
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Set the control bits on a serial device

  @param  This             Protocol instance pointer.
  @param  Control          Set the bits of Control that are settable.

  @retval EFI_SUCCESS      The new control bits were set on the serial device.
  @retval EFI_UNSUPPORTED  The serial device does not support this operation.
  @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.

**/
EFI_STATUS
EFIAPI
GdbSerialSetControl (
  IN EFI_SERIAL_IO_PROTOCOL  *This,
  IN UINT32                  Control
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Retrieves the status of the control bits on a serial device

  @param  This              Protocol instance pointer.
  @param  Control           A pointer to return the current Control signals from the serial device.

  @retval EFI_SUCCESS       The control bits were read from the serial device.
  @retval EFI_DEVICE_ERROR  The serial device is not functioning correctly.

**/
EFI_STATUS
EFIAPI
GdbSerialGetControl (
  IN EFI_SERIAL_IO_PROTOCOL  *This,
  OUT UINT32                 *Control
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Writes data to a serial device.

  @param  This              Protocol instance pointer.
  @param  BufferSize        On input, the size of the Buffer. On output, the amount of
                            data actually written.
  @param  Buffer            The buffer of data to write

  @retval EFI_SUCCESS       The data was written.
  @retval EFI_DEVICE_ERROR  The device reported an error.
  @retval EFI_TIMEOUT       The data write was stopped due to a timeout.

**/
EFI_STATUS
EFIAPI
GdbSerialWrite (
  IN EFI_SERIAL_IO_PROTOCOL  *This,
  IN OUT UINTN               *BufferSize,
  IN VOID                    *Buffer
  )
{
  GDB_SERIAL_DEV  *SerialDev;
  UINTN           Return;

  SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);

  Return = GdbWrite (SerialDev->OutFileDescriptor, Buffer, *BufferSize);
  if (Return == (UINTN)-1) {
    return EFI_DEVICE_ERROR;
  }

  if (Return != *BufferSize) {
    *BufferSize = Return;
  }

  return EFI_SUCCESS;
}

/**
  Writes data to a serial device.

  @param  This              Protocol instance pointer.
  @param  BufferSize        On input, the size of the Buffer. On output, the amount of
                            data returned in Buffer.
  @param  Buffer            The buffer to return the data into.

  @retval EFI_SUCCESS       The data was read.
  @retval EFI_DEVICE_ERROR  The device reported an error.
  @retval EFI_TIMEOUT       The data write was stopped due to a timeout.

**/
EFI_STATUS
EFIAPI
GdbSerialRead (
  IN EFI_SERIAL_IO_PROTOCOL  *This,
  IN OUT UINTN               *BufferSize,
  OUT VOID                   *Buffer
  )
{
  GDB_SERIAL_DEV  *SerialDev;
  UINTN           Return;

  SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);

  Return = GdbRead (SerialDev->InFileDescriptor, Buffer, *BufferSize);
  if (Return == (UINTN)-1) {
    return EFI_DEVICE_ERROR;
  }

  if (Return != *BufferSize) {
    *BufferSize = Return;
  }

  return EFI_SUCCESS;
}

//
// Template used to initialize the GDB Serial IO protocols
//
GDB_SERIAL_DEV  gdbSerialDevTemplate = {
  GDB_SERIAL_DEV_SIGNATURE,
  NULL,

  { // SerialIo
    SERIAL_IO_INTERFACE_REVISION,
    GdbSerialReset,
    GdbSerialSetAttributes,
    GdbSerialSetControl,
    GdbSerialGetControl,
    GdbSerialWrite,
    GdbSerialRead,
    NULL
  },
  {    // SerialMode
    0, // ControlMask
    0, // Timeout
    0, // BaudRate
    1, // RceiveFifoDepth
    0, // DataBits
    0, // Parity
    0  // StopBits
  },
  {
    {
      {
        HARDWARE_DEVICE_PATH,
        HW_VENDOR_DP,
        {
          (UINT8)(sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)),
          (UINT8)((sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)) >> 8)
        },
      },
      EFI_SERIAL_IO_PROTOCOL_GUID
    },
    0,
    {
      END_DEVICE_PATH_TYPE,
      END_ENTIRE_DEVICE_PATH_SUBTYPE,
      {
        (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
        (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL) >> 8)
      }
    },
  },
  GDB_STDIN,
  GDB_STDOUT
};

/**
  Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.

  These console show up on the remote system running GDB

**/
VOID
GdbInitializeSerialConsole (
  VOID
  )
{
  EFI_STATUS      Status;
  GDB_SERIAL_DEV  *StdOutSerialDev;
  GDB_SERIAL_DEV  *StdErrSerialDev;

  // Use the template to make a copy of the Serial Console private data structure.
  StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
  ASSERT (StdOutSerialDev != NULL);

  // Fixup pointer after the copy
  StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode;

  StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
  ASSERT (StdErrSerialDev != NULL);

  // Fixup pointer and modify stuff that is different for StdError
  StdErrSerialDev->SerialIo.Mode     = &StdErrSerialDev->SerialMode;
  StdErrSerialDev->DevicePath.Index  = 1;
  StdErrSerialDev->OutFileDescriptor = GDB_STDERR;

  // Make a new handle with Serial IO protocol and its device path on it.
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &StdOutSerialDev->Handle,
                  &gEfiSerialIoProtocolGuid,
                  &StdOutSerialDev->SerialIo,
                  &gEfiDevicePathProtocolGuid,
                  &StdOutSerialDev->DevicePath,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  // Make a new handle with Serial IO protocol and its device path on it.
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &StdErrSerialDev->Handle,
                  &gEfiSerialIoProtocolGuid,
                  &StdErrSerialDev->SerialIo,
                  &gEfiDevicePathProtocolGuid,
                  &StdErrSerialDev->DevicePath,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);
}
