/** @file
  Basic serial IO abstraction for GDB

  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Library/GdbSerialLib.h>
#include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Library/DebugLib.h>


//---------------------------------------------
// UART Register Offsets
//---------------------------------------------
#define BAUD_LOW_OFFSET         0x00
#define BAUD_HIGH_OFFSET        0x01
#define IER_OFFSET              0x01
#define LCR_SHADOW_OFFSET       0x01
#define FCR_SHADOW_OFFSET       0x02
#define IR_CONTROL_OFFSET       0x02
#define FCR_OFFSET              0x02
#define EIR_OFFSET              0x02
#define BSR_OFFSET              0x03
#define LCR_OFFSET              0x03
#define MCR_OFFSET              0x04
#define LSR_OFFSET              0x05
#define MSR_OFFSET              0x06

//---------------------------------------------
// UART Register Bit Defines
//---------------------------------------------
#define LSR_TXRDY               0x20U
#define LSR_RXDA                0x01U
#define DLAB                    0x01U
#define ENABLE_FIFO             0x01U
#define CLEAR_FIFOS             0x06U



// IO Port Base for the UART
UINTN gPort;


/**
  The constructor function initializes the UART.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
RETURN_STATUS
EFIAPI
GdbSerialLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  UINT64    BaudRate;
  UINT8     DataBits;
  UINT8     Parity;
  UINT8     StopBits;

  gPort = (UINTN)PcdGet32 (PcdGdbUartPort);

  BaudRate = PcdGet64 (PcdGdbBaudRate);
  Parity   = PcdGet8 (PcdGdbParity);
  DataBits = PcdGet8 (PcdGdbDataBits);
  StopBits = PcdGet8 (PcdGdbStopBits);

  return GdbSerialInit (BaudRate, Parity, DataBits, StopBits);
}



/**
  Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
  data buts, and stop bits on a serial device. This call is optional as the serial
  port will be set up with defaults base on PCD values.

  @param  BaudRate         The requested baud rate. A BaudRate value of 0 will use the the
                           device's default interface speed.
  @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 configured.
  @retval EFI_DEVICE_ERROR The serial device could not be configured.

**/
RETURN_STATUS
EFIAPI
GdbSerialInit (
  IN UINT64     BaudRate,
  IN UINT8      Parity,
  IN UINT8      DataBits,
  IN UINT8      StopBits
  )
{
  UINTN           Divisor;
  UINT8           OutputData;
  UINT8           Data;
  UINT8           BreakSet = 0;

  //
  // We assume the UART has been turned on to decode gPort address range
  //

  //
  // Map 5..8 to 0..3
  //
  Data = (UINT8) (DataBits - (UINT8)5);

  //
  // Calculate divisor for baud generator
  //
  Divisor = 115200/(UINTN)BaudRate;

  //
  // Set communications format
  //
  OutputData = (UINT8)((DLAB << 7) | ((BreakSet << 6) | ((Parity << 3) | ((StopBits << 2) | Data))));
  IoWrite8 (gPort + LCR_OFFSET, OutputData);

  //
  // Configure baud rate
  //
  IoWrite8 (gPort + BAUD_HIGH_OFFSET, (UINT8)(Divisor >> 8));
  IoWrite8 (gPort + BAUD_LOW_OFFSET, (UINT8)(Divisor & 0xff));


  //
  // Switch back to bank 0
  //
  OutputData = (UINT8)((~DLAB<<7)|((BreakSet<<6)|((Parity<<3)|((StopBits<<2)| Data))));
  IoWrite8 (gPort + LCR_OFFSET, OutputData);

  // Not sure this is the right place to enable the FIFOs....
  // We probably need the FIFO enabled to not drop input
  IoWrite8 (gPort + FCR_SHADOW_OFFSET, ENABLE_FIFO);


  // Configure the UART hardware here
  return RETURN_SUCCESS;
}


/**
  Check to see if a character is available from GDB. Do not read the character as that is
  done via GdbGetChar().

  @return TRUE  - Character available
  @return FALSE - Character not available

**/
BOOLEAN
EFIAPI
GdbIsCharAvailable (
  VOID
  )
{
  UINT8   Data;

  Data = IoRead8 (gPort + LSR_OFFSET);

  return ((Data & LSR_RXDA) == LSR_RXDA);
}


/**
  Get a character from GDB. This function must be able to run in interrupt context.

  @return A character from GDB

**/
CHAR8
EFIAPI
GdbGetChar (
  VOID
  )
{
  UINT8   Data;
  CHAR8   Char;

  // Wait for the serial port to be ready
  do {
    Data = IoRead8 (gPort + LSR_OFFSET);
  } while ((Data & LSR_RXDA) == 0);

  Char = IoRead8 (gPort);

  // Make this an EFI_D_INFO after we get everything debugged.
  DEBUG ((EFI_D_ERROR, "<%c<", Char));
  return Char;
}


/**
  Send a character to GDB. This function must be able to run in interrupt context.


  @param  Char    Send a character to GDB

**/

VOID
EFIAPI
GdbPutChar (
  IN  CHAR8   Char
  )
{
  UINT8   Data;

  // Make this an EFI_D_INFO after we get everything debugged.
  DEBUG ((EFI_D_ERROR, ">%c>", Char));

  // Wait for the serial port to be ready
  do {
    Data = IoRead8 (gPort + LSR_OFFSET);
  } while ((Data & LSR_TXRDY) == 0);

  IoWrite8 (gPort, Char);
}

/**
  Send an ASCII string to GDB. This function must be able to run in interrupt context.


  @param  String    Send a string to GDB

**/

VOID
GdbPutString (
  IN CHAR8  *String
  )
{
  while (*String != '\0') {
    GdbPutChar (*String);
    String++;
  }
}




