/** @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);

  // 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;
}
