/** @file
  Serial Port Parser.

  Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Reference(s):
  - linux/Documentation/devicetree/bindings/serial/serial.yaml
  - linux/Documentation/devicetree/bindings/serial/8250.txt
  - linux/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt
  - linux/Documentation/devicetree/bindings/serial/pl011.yaml
**/

#include <IndustryStandard/DebugPort2Table.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/FdtLib.h>

#include "CmObjectDescUtility.h"
#include "FdtHwInfoParser.h"
#include "Serial/SerialPortParser.h"

/** List of "compatible" property values for serial port nodes.

  Any other "compatible" value is not supported by this module.
*/
STATIC CONST COMPATIBILITY_STR  SerialCompatibleStr[] = {
  { "ns16550a"      },
  { "arm,sbsa-uart" },
  { "arm,pl011"     }
};

/** COMPATIBILITY_INFO structure for the SerialCompatible.
*/
CONST COMPATIBILITY_INFO  SerialCompatibleInfo = {
  ARRAY_SIZE (SerialCompatibleStr),
  SerialCompatibleStr
};

/** 16550 UART compatible strings.

  Any string of this list must be part of SerialCompatible.
*/
STATIC CONST COMPATIBILITY_STR  Serial16550CompatibleStr[] = {
  { "ns16550a" }
};

/** COMPATIBILITY_INFO structure for the Serial16550Compatible.
*/
CONST COMPATIBILITY_INFO  Serial16550CompatibleInfo = {
  ARRAY_SIZE (Serial16550CompatibleStr),
  Serial16550CompatibleStr
};

/** SBSA UART compatible strings.

  Include PL011 as SBSA uart is a subset of PL011.

  Any string of this list must be part of SerialCompatible.
*/
STATIC CONST COMPATIBILITY_STR  SerialSbsaCompatibleStr[] = {
  { "arm,sbsa-uart" },
  { "arm,pl011"     }
};

/** COMPATIBILITY_INFO structure for the SerialSbsaCompatible.
*/
CONST COMPATIBILITY_INFO  SerialSbsaCompatibleInfo = {
  ARRAY_SIZE (SerialSbsaCompatibleStr),
  SerialSbsaCompatibleStr
};

/** Parse a serial port node.

  @param [in]  Fdt               Pointer to a Flattened Device Tree (Fdt).
  @param [in]  SerialPortNode    Offset of a serial-port node.
  @param [in]  SerialPortInfo    The CM_ARCH_COMMON_SERIAL_PORT_INFO to populate.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_UNSUPPORTED         Unsupported.
**/
STATIC
EFI_STATUS
EFIAPI
SerialPortNodeParser (
  IN  CONST VOID                       *Fdt,
  IN  INT32                            SerialPortNode,
  IN  CM_ARCH_COMMON_SERIAL_PORT_INFO  *SerialPortInfo
  )
{
  EFI_STATUS   Status;
  INT32        IntcNode;
  CONST UINT8  *SizeValue;

  INT32  AddressCells;
  INT32  SizeCells;
  INT32  IntCells;

  CONST UINT8  *Data;
  INT32        DataSize;
  UINT8        AccessSize;

  if ((Fdt == NULL) ||
      (SerialPortInfo == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = FdtGetParentAddressInfo (
             Fdt,
             SerialPortNode,
             &AddressCells,
             &SizeCells
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Don't support more than 64 bits and less than 32 bits addresses.
  if ((AddressCells < 1)  ||
      (AddressCells > 2)  ||
      (SizeCells < 1)     ||
      (SizeCells > 2))
  {
    ASSERT (0);
    return EFI_ABORTED;
  }

  Data = FdtGetProp (Fdt, SerialPortNode, "reg", &DataSize);
  if ((Data == NULL) ||
      (DataSize < (INT32)(sizeof (UINT32) *
                          GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells)) - 1))
  {
    // If error or not enough space.
    ASSERT (0);
    return EFI_ABORTED;
  }

  if (AddressCells == 2) {
    SerialPortInfo->BaseAddress = Fdt64ToCpu (*(UINT64 *)Data);
  } else {
    SerialPortInfo->BaseAddress = Fdt32ToCpu (*(UINT32 *)Data);
  }

  SizeValue = Data + (sizeof (UINT32) *
                      GET_DT_REG_SIZE_OFFSET (0, AddressCells, SizeCells));
  if (SizeCells == 2) {
    SerialPortInfo->BaseAddressLength = Fdt64ToCpu (*(UINT64 *)SizeValue);
  } else {
    SerialPortInfo->BaseAddressLength = Fdt32ToCpu (*(UINT32 *)SizeValue);
  }

  // Get the associated interrupt-controller.
  Status = FdtGetIntcParentNode (Fdt, SerialPortNode, &IntcNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    if (Status == EFI_NOT_FOUND) {
      // Should have found the node.
      Status = EFI_ABORTED;
    }

    return Status;
  }

  // Get the number of cells used to encode an interrupt.
  Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Data = FdtGetProp (Fdt, SerialPortNode, "interrupts", &DataSize);
  if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) {
    // If error or not 1 interrupt.
    ASSERT (0);
    return EFI_ABORTED;
  }

  SerialPortInfo->Interrupt = FdtGetInterruptId ((CONST UINT32 *)Data);

  /*
   * In RISC-V, GSI space can be divided among multiple APLIC/PLICs.
   * So, convert the interrupt number in DT to appropriate GSI number
   * using the parent interrupt controller information.
   */
 #if defined (MDE_CPU_RISCV64)
  SerialPortInfo->Interrupt = FdtConvertToGsi (IntcNode, SerialPortInfo->Interrupt);
 #endif

  // Note: clock-frequency is optional for SBSA UART.
  Data = FdtGetProp (Fdt, SerialPortNode, "clock-frequency", &DataSize);
  if (Data != NULL) {
    if (DataSize < sizeof (UINT32)) {
      // If error or not enough space.
      ASSERT (0);
      return EFI_ABORTED;
    } else if (FdtNodeOffsetByPhandle (Fdt, Fdt32ToCpu (*Data)) >= 0) {
      // "clock-frequency" can be a "clocks phandle to refer to the clk used".
      // This is not supported.
      ASSERT (0);
      return EFI_UNSUPPORTED;
    }

    SerialPortInfo->Clock = Fdt32ToCpu (*(UINT32 *)Data);
  }

  if (FdtNodeIsCompatible (Fdt, SerialPortNode, &Serial16550CompatibleInfo)) {
    SerialPortInfo->PortSubtype =
      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS;

    /* reg-io-width:
         description: |
         The size (in bytes) of the IO accesses that should be performed on the
         device. There are some systems that require 32-bit accesses to the
         UART.
    */
    Data = FdtGetProp (Fdt, SerialPortNode, "reg-io-width", &DataSize);
    if (Data != NULL) {
      if (DataSize < sizeof (UINT32)) {
        // If error or not enough space.
        ASSERT (0);
        return EFI_ABORTED;
      }

      AccessSize = Fdt32ToCpu (*(UINT32 *)Data);
      if (AccessSize > EFI_ACPI_6_3_QWORD) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      SerialPortInfo->AccessSize = AccessSize;
    } else {
      // 8250/16550 defaults to byte access.
      SerialPortInfo->AccessSize = EFI_ACPI_6_3_BYTE;
    }
  } else if (FdtNodeIsCompatible (
               Fdt,
               SerialPortNode,
               &SerialSbsaCompatibleInfo
               ))
  {
    SerialPortInfo->PortSubtype =
      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART;
  } else {
    ASSERT (0);
    return EFI_UNSUPPORTED;
  }

  // Set Baudrate to 115200 by default
  SerialPortInfo->BaudRate = 115200;
  return EFI_SUCCESS;
}

/** Find the console serial-port node in the DT.

  This function fetches the node referenced in the "stdout-path"
  property of the "chosen" node.

  @param [in]  Fdt                  Pointer to a Flattened Device Tree (Fdt).
  @param [out] SerialConsoleNode    If success, contains the node offset
                                    of the console serial-port node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           Not found.
**/
STATIC
EFI_STATUS
EFIAPI
GetSerialConsoleNode (
  IN  CONST VOID   *Fdt,
  OUT       INT32  *SerialConsoleNode
  )
{
  CONST CHAR8  *Prop;
  INT32        PropSize;
  CONST CHAR8  *Path;
  INT32        PathLen;
  INT32        ChosenNode;

  if ((Fdt == NULL) ||
      (SerialConsoleNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // The "chosen" node resides at the root of the DT. Fetch it.
  ChosenNode = FdtPathOffset (Fdt, "/chosen");
  if (ChosenNode < 0) {
    return EFI_NOT_FOUND;
  }

  Prop = FdtGetProp (Fdt, ChosenNode, "stdout-path", &PropSize);
  if ((Prop == NULL) || (PropSize < 0)) {
    return EFI_NOT_FOUND;
  }

  // Determine the actual path length, as a colon terminates the path.
  Path = ScanMem8 (Prop, PropSize, ':');
  if (Path == NULL) {
    PathLen = (UINT32)AsciiStrLen (Prop);
  } else {
    PathLen = (INT32)(Path - Prop);
  }

  // Aliases cannot start with a '/', so it must be the actual path.
  if (Prop[0] == '/') {
    *SerialConsoleNode = FdtPathOffsetNameLen (Fdt, Prop, PathLen);
    return EFI_SUCCESS;
  }

  // Lookup the alias, as this contains the actual path.
  Path = FdtGetAliasNameLen (Fdt, Prop, PathLen);
  if (Path == NULL) {
    return EFI_NOT_FOUND;
  }

  *SerialConsoleNode = FdtPathOffset (Fdt, Path);
  return EFI_SUCCESS;
}

/** CM_ARCH_COMMON_SERIAL_PORT_INFO dispatcher function (for a generic serial-port).

  @param [in]  FdtParserHandle A handle to the parser instance.
  @param [in]  GenericSerialInfo  Pointer to a serial port info list.
  @param [in]  NodeCount          Count of serial ports to dispatch.
  @param [in]  SerialObjectId     Serial port object ID.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           Not found.
  @retval EFI_UNSUPPORTED         Unsupported.
**/
STATIC
EFI_STATUS
EFIAPI
SerialPortInfoDispatch (
  IN  CONST FDT_HW_INFO_PARSER_HANDLE  FdtParserHandle,
  IN  CM_ARCH_COMMON_SERIAL_PORT_INFO  *GenericSerialInfo,
  IN  INT32                            NodeCount,
  IN  EARCH_COMMON_OBJECT_ID           SerialObjectId
  )
{
  EFI_STATUS         Status;
  CM_OBJ_DESCRIPTOR  *NewCmObjDesc;

  if ((GenericSerialInfo == NULL) || (NodeCount == 0)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if ((SerialObjectId != EArchCommonObjSerialPortInfo) &&
      (SerialObjectId != EArchCommonObjSerialDebugPortInfo) &&
      (SerialObjectId != EArchCommonObjConsolePortInfo))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Dispatch the Generic Serial ports
  Status = CreateCmObjDesc (
             CREATE_CM_ARCH_COMMON_OBJECT_ID (SerialObjectId),
             NodeCount,
             GenericSerialInfo,
             sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) * NodeCount,
             &NewCmObjDesc
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Add all the CmObjs to the Configuration Manager.
  Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL);
  ASSERT_EFI_ERROR (Status);
  FreeCmObjDesc (NewCmObjDesc);
  return Status;
}

/** CM_ARCH_COMMON_SERIAL_PORT_INFO parser function (for debug/console serial-port).

  This parser expects FdtBranch to be the debug serial-port node.
  At most one CmObj is created.
  The following structure is populated:
  typedef struct EArchCommonSerialPortInfo {
    UINT64  BaseAddress;                      // {Populated}
    UINT32  Interrupt;                        // {Populated}
    UINT64  BaudRate;                         // {default}
    UINT32  Clock;                            // {Populated}
    UINT16  PortSubtype;                      // {Populated}
    UINT64  BaseAddressLength                 // {Populated}
  } CM_ARCH_COMMON_SERIAL_PORT_INFO;

  A parser parses a Device Tree to populate a specific CmObj type. None,
  one or many CmObj can be created by the parser.
  The created CmObj are then handed to the parser's caller through the
  HW_INFO_ADD_OBJECT interface.
  This can also be a dispatcher. I.e. a function that not parsing a
  Device Tree but calling other parsers.

  @param [in]  FdtParserHandle A handle to the parser instance.
  @param [in]  FdtBranch       When searching for DT node name, restrict
                               the search to this Device Tree branch.
  @param [in]  SerialObjectId  ArchCommon Namespace Object ID for the serial
                               port.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           Not found.
  @retval EFI_UNSUPPORTED         Unsupported.
**/
STATIC
EFI_STATUS
EFIAPI
SerialPortInfoParser (
  IN  CONST FDT_HW_INFO_PARSER_HANDLE  FdtParserHandle,
  IN        INT32                      FdtBranch,
  IN        EARCH_COMMON_OBJECT_ID     SerialObjectId
  )
{
  EFI_STATUS                       Status;
  CM_ARCH_COMMON_SERIAL_PORT_INFO  SerialInfo;

  if ((SerialObjectId != EArchCommonObjSerialDebugPortInfo) &&
      (SerialObjectId != EArchCommonObjConsolePortInfo))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ZeroMem (&SerialInfo, sizeof (SerialInfo));

  Status = SerialPortNodeParser (
             FdtParserHandle->Fdt,
             FdtBranch,
             &SerialInfo
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = SerialPortInfoDispatch (
             FdtParserHandle,
             &SerialInfo,
             1,
             SerialObjectId
             );
  ASSERT_EFI_ERROR (Status);
  return Status;
}

/** SerialPort dispatcher.

  This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for
  the following CM_OBJ_ID:
   - EArchCommonObjConsolePortInfo
   - EArchCommonObjSerialDebugPortInfo
   - EArchCommonObjSerialPortInfo

  A parser parses a Device Tree to populate a specific CmObj type. None,
  one or many CmObj can be created by the parser.
  The created CmObj are then handed to the parser's caller through the
  HW_INFO_ADD_OBJECT interface.
  This can also be a dispatcher. I.e. a function that not parsing a
  Device Tree but calling other parsers.

  @param [in]  FdtParserHandle A handle to the parser instance.
  @param [in]  FdtBranch       When searching for DT node name, restrict
                               the search to this Device Tree branch.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           Not found.
  @retval EFI_UNSUPPORTED         Unsupported.
**/
EFI_STATUS
EFIAPI
SerialPortDispatcher (
  IN  CONST FDT_HW_INFO_PARSER_HANDLE  FdtParserHandle,
  IN        INT32                      FdtBranch
  )
{
  EFI_STATUS                       Status;
  INT32                            SerialConsoleNode;
  INT32                            SerialDebugNode;
  INT32                            SerialNode;
  UINT32                           Index;
  UINT32                           SerialNodeCount;
  UINT32                           SerialNodesRemaining;
  CM_ARCH_COMMON_SERIAL_PORT_INFO  *GenericSerialInfo;
  UINT32                           GenericSerialIndex;
  VOID                             *Fdt;

  if (FdtParserHandle == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Fdt = FdtParserHandle->Fdt;

  // Count the number of serial-ports.
  Status = FdtCountCompatNodeInBranch (
             Fdt,
             FdtBranch,
             &SerialCompatibleInfo,
             &SerialNodeCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  if (SerialNodeCount == 0) {
    return EFI_NOT_FOUND;
  }

  // Track remaining nodes separately as SerialNodeCount
  // is used in for loop below and reducing SerialNodeCount
  // would result in the Generic Serial port nodes not
  // being found if the serial console port node is among
  // the first few serial nodes.
  SerialNodesRemaining = SerialNodeCount;

  // Identify the serial console port.
  Status = GetSerialConsoleNode (Fdt, &SerialConsoleNode);
  if (Status == EFI_NOT_FOUND) {
    // No serial console.
    SerialConsoleNode = -1;
  } else if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  } else {
    // Parse the console serial-port.
    Status = SerialPortInfoParser (
               FdtParserHandle,
               SerialConsoleNode,
               EArchCommonObjConsolePortInfo
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    SerialNodesRemaining--;
  }

  GenericSerialInfo = NULL;
  if (SerialNodesRemaining > 1) {
    // We have more than one serial port remaining.
    // This means that the first serial port will
    // be reserved as a debug port, and the remaining
    // will be for general purpose use.
    SerialNodesRemaining--;
    GenericSerialInfo = AllocateZeroPool (
                          SerialNodesRemaining *
                          sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO)
                          );
    if (GenericSerialInfo == NULL) {
      ASSERT (0);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  SerialNode         = FdtBranch;
  SerialDebugNode    = -1;
  GenericSerialIndex = 0;
  for (Index = 0; Index < SerialNodeCount; Index++) {
    // Search the next serial-port node in the branch.
    Status = FdtGetNextCompatNodeInBranch (
               Fdt,
               FdtBranch,
               &SerialCompatibleInfo,
               &SerialNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      if (Status == EFI_NOT_FOUND) {
        // Should have found the node.
        Status = EFI_ABORTED;
      }

      goto exit_handler;
    }

    // Ignore the serial console node.
    if (SerialNode == SerialConsoleNode) {
      continue;
    } else if (SerialDebugNode == -1) {
      // The first serial-port node, not being the console serial-port,
      // will be the debug serial-port.
      SerialDebugNode = SerialNode;
      Status          = SerialPortInfoParser (
                          FdtParserHandle,
                          SerialDebugNode,
                          EArchCommonObjSerialDebugPortInfo
                          );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        goto exit_handler;
      }
    } else {
      if (GenericSerialInfo == NULL) {
        // Should not be possible.
        ASSERT (0);
        Status = EFI_ABORTED;
        goto exit_handler;
      }

      Status = SerialPortNodeParser (
                 Fdt,
                 SerialNode,
                 &GenericSerialInfo[GenericSerialIndex++]
                 );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        goto exit_handler;
      }
    }
  } // for

  if (GenericSerialIndex > 0) {
    Status = SerialPortInfoDispatch (
               FdtParserHandle,
               GenericSerialInfo,
               GenericSerialIndex,
               EArchCommonObjSerialPortInfo
               );
  }

exit_handler:
  if (GenericSerialInfo != NULL) {
    FreePool (GenericSerialInfo);
  }

  return Status;
}
