/** @file
*  FDT client driver
*
*  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
*
*  SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/HobLib.h>
#include <libfdt.h>

#include <Guid/Fdt.h>
#include <Guid/FdtHob.h>
#include <Guid/PlatformHasDeviceTree.h>

#include <Protocol/FdtClient.h>

STATIC VOID  *mDeviceTreeBase;

STATIC
EFI_STATUS
EFIAPI
GetNodeProperty (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  INT32                Node,
  IN  CONST CHAR8          *PropertyName,
  OUT CONST VOID           **Prop,
  OUT UINT32               *PropSize OPTIONAL
  )
{
  INT32  Len;

  ASSERT (mDeviceTreeBase != NULL);
  ASSERT (Prop != NULL);

  *Prop = fdt_getprop (mDeviceTreeBase, Node, PropertyName, &Len);
  if (*Prop == NULL) {
    return EFI_NOT_FOUND;
  }

  if (PropSize != NULL) {
    *PropSize = Len;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
SetNodeProperty (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  INT32                Node,
  IN  CONST CHAR8          *PropertyName,
  IN  CONST VOID           *Prop,
  IN  UINT32               PropSize
  )
{
  INT32  Ret;

  ASSERT (mDeviceTreeBase != NULL);

  Ret = fdt_setprop (mDeviceTreeBase, Node, PropertyName, Prop, PropSize);
  if (Ret != 0) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

STATIC
BOOLEAN
IsNodeEnabled (
  INT32  Node
  )
{
  CONST CHAR8  *NodeStatus;
  INT32        Len;

  //
  // A missing status property implies 'ok' so ignore any errors that
  // may occur here. If the status property is present, check whether
  // it is set to 'ok' or 'okay', anything else is treated as 'disabled'.
  //
  NodeStatus = fdt_getprop (mDeviceTreeBase, Node, "status", &Len);
  if (NodeStatus == NULL) {
    return TRUE;
  }

  if ((Len >= 5) && (AsciiStrCmp (NodeStatus, "okay") == 0)) {
    return TRUE;
  }

  if ((Len >= 3) && (AsciiStrCmp (NodeStatus, "ok") == 0)) {
    return TRUE;
  }

  return FALSE;
}

STATIC
EFI_STATUS
EFIAPI
FindNextCompatibleNode (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  CONST CHAR8          *CompatibleString,
  IN  INT32                PrevNode,
  OUT INT32                *Node
  )
{
  INT32        Prev, Next;
  CONST CHAR8  *Type, *Compatible;
  INT32        Len;

  ASSERT (mDeviceTreeBase != NULL);
  ASSERT (Node != NULL);

  for (Prev = PrevNode; ; Prev = Next) {
    Next = fdt_next_node (mDeviceTreeBase, Prev, NULL);
    if (Next < 0) {
      break;
    }

    if (!IsNodeEnabled (Next)) {
      continue;
    }

    Type = fdt_getprop (mDeviceTreeBase, Next, "compatible", &Len);
    if (Type == NULL) {
      continue;
    }

    //
    // A 'compatible' node may contain a sequence of NUL terminated
    // compatible strings so check each one
    //
    for (Compatible = Type; Compatible < Type + Len && *Compatible;
         Compatible += 1 + AsciiStrLen (Compatible))
    {
      if (AsciiStrCmp (CompatibleString, Compatible) == 0) {
        *Node = Next;
        return EFI_SUCCESS;
      }
    }
  }

  return EFI_NOT_FOUND;
}

STATIC
EFI_STATUS
EFIAPI
FindCompatibleNode (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  CONST CHAR8          *CompatibleString,
  OUT INT32                *Node
  )
{
  return FindNextCompatibleNode (This, CompatibleString, 0, Node);
}

STATIC
EFI_STATUS
EFIAPI
FindCompatibleNodeProperty (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  CONST CHAR8          *CompatibleString,
  IN  CONST CHAR8          *PropertyName,
  OUT CONST VOID           **Prop,
  OUT UINT32               *PropSize OPTIONAL
  )
{
  EFI_STATUS  Status;
  INT32       Node;

  Status = FindCompatibleNode (This, CompatibleString, &Node);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return GetNodeProperty (This, Node, PropertyName, Prop, PropSize);
}

STATIC
EFI_STATUS
EFIAPI
FindCompatibleNodeReg (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  CONST CHAR8          *CompatibleString,
  OUT CONST VOID           **Reg,
  OUT UINTN                *AddressCells,
  OUT UINTN                *SizeCells,
  OUT UINT32               *RegSize
  )
{
  EFI_STATUS  Status;

  ASSERT (RegSize != NULL);

  //
  // Get the 'reg' property of this node. For now, we will assume
  // 8 byte quantities for base and size, respectively.
  // TODO use #cells root properties instead
  //
  Status = FindCompatibleNodeProperty (
             This,
             CompatibleString,
             "reg",
             Reg,
             RegSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((*RegSize % 16) != 0) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: '%a' compatible node has invalid 'reg' property (size == 0x%x)\n",
      __func__,
      CompatibleString,
      *RegSize
      ));
    return EFI_NOT_FOUND;
  }

  *AddressCells = 2;
  *SizeCells    = 2;

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
FindNextMemoryNodeReg (
  IN  FDT_CLIENT_PROTOCOL  *This,
  IN  INT32                PrevNode,
  OUT INT32                *Node,
  OUT CONST VOID           **Reg,
  OUT UINTN                *AddressCells,
  OUT UINTN                *SizeCells,
  OUT UINT32               *RegSize
  )
{
  INT32        Prev, Next;
  CONST CHAR8  *DeviceType;
  INT32        Len;
  EFI_STATUS   Status;

  ASSERT (mDeviceTreeBase != NULL);
  ASSERT (Node != NULL);

  for (Prev = PrevNode; ; Prev = Next) {
    Next = fdt_next_node (mDeviceTreeBase, Prev, NULL);
    if (Next < 0) {
      break;
    }

    if (!IsNodeEnabled (Next)) {
      DEBUG ((DEBUG_WARN, "%a: ignoring disabled memory node\n", __func__));
      continue;
    }

    DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len);
    if ((DeviceType != NULL) && (AsciiStrCmp (DeviceType, "memory") == 0)) {
      //
      // Get the 'reg' property of this memory node. For now, we will assume
      // 8 byte quantities for base and size, respectively.
      // TODO use #cells root properties instead
      //
      Status = GetNodeProperty (This, Next, "reg", Reg, RegSize);
      if (EFI_ERROR (Status)) {
        DEBUG ((
          DEBUG_WARN,
          "%a: ignoring memory node with no 'reg' property\n",
          __func__
          ));
        continue;
      }

      if ((*RegSize % 16) != 0) {
        DEBUG ((
          DEBUG_WARN,
          "%a: ignoring memory node with invalid 'reg' property (size == 0x%x)\n",
          __func__,
          *RegSize
          ));
        continue;
      }

      *Node         = Next;
      *AddressCells = 2;
      *SizeCells    = 2;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

STATIC
EFI_STATUS
EFIAPI
FindMemoryNodeReg (
  IN  FDT_CLIENT_PROTOCOL  *This,
  OUT INT32                *Node,
  OUT CONST VOID           **Reg,
  OUT UINTN                *AddressCells,
  OUT UINTN                *SizeCells,
  OUT UINT32               *RegSize
  )
{
  return FindNextMemoryNodeReg (
           This,
           0,
           Node,
           Reg,
           AddressCells,
           SizeCells,
           RegSize
           );
}

STATIC
EFI_STATUS
EFIAPI
GetOrInsertChosenNode (
  IN  FDT_CLIENT_PROTOCOL  *This,
  OUT INT32                *Node
  )
{
  INT32  NewNode;

  ASSERT (mDeviceTreeBase != NULL);
  ASSERT (Node != NULL);

  NewNode = fdt_path_offset (mDeviceTreeBase, "/chosen");
  if (NewNode < 0) {
    NewNode = fdt_add_subnode (mDeviceTreeBase, 0, "/chosen");
  }

  if (NewNode < 0) {
    return EFI_OUT_OF_RESOURCES;
  }

  *Node = NewNode;

  return EFI_SUCCESS;
}

STATIC FDT_CLIENT_PROTOCOL  mFdtClientProtocol = {
  GetNodeProperty,
  SetNodeProperty,
  FindCompatibleNode,
  FindNextCompatibleNode,
  FindCompatibleNodeProperty,
  FindCompatibleNodeReg,
  FindMemoryNodeReg,
  FindNextMemoryNodeReg,
  GetOrInsertChosenNode,
};

STATIC
VOID
EFIAPI
OnPlatformHasDeviceTree (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS  Status;
  VOID        *Interface;
  VOID        *DeviceTreeBase;

  Status = gBS->LocateProtocol (
                  &gEdkiiPlatformHasDeviceTreeGuid,
                  NULL,                             // Registration
                  &Interface
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  DeviceTreeBase = Context;
  DEBUG ((
    DEBUG_INFO,
    "%a: exposing DTB @ 0x%p to OS\n",
    __func__,
    DeviceTreeBase
    ));
  Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase);
  ASSERT_EFI_ERROR (Status);

  gBS->CloseEvent (Event);
}

EFI_STATUS
EFIAPI
InitializeFdtClientDxe (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  VOID        *Hob;
  VOID        *DeviceTreeBase;
  EFI_STATUS  Status;
  EFI_EVENT   PlatformHasDeviceTreeEvent;
  VOID        *Registration;

  Hob = GetFirstGuidHob (&gFdtHobGuid);
  if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64))) {
    return EFI_NOT_FOUND;
  }

  DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);

  if (fdt_check_header (DeviceTreeBase) != 0) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: No DTB found @ 0x%p\n",
      __func__,
      DeviceTreeBase
      ));
    return EFI_NOT_FOUND;
  }

  mDeviceTreeBase = DeviceTreeBase;

  DEBUG ((DEBUG_INFO, "%a: DTB @ 0x%p\n", __func__, mDeviceTreeBase));

  //
  // Register a protocol notify for the EDKII Platform Has Device Tree
  // Protocol.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  OnPlatformHasDeviceTree,
                  DeviceTreeBase,             // Context
                  &PlatformHasDeviceTreeEvent
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: CreateEvent(): %r\n", __func__, Status));
    return Status;
  }

  Status = gBS->RegisterProtocolNotify (
                  &gEdkiiPlatformHasDeviceTreeGuid,
                  PlatformHasDeviceTreeEvent,
                  &Registration
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: RegisterProtocolNotify(): %r\n",
      __func__,
      Status
      ));
    goto CloseEvent;
  }

  //
  // Kick the event; the protocol could be available already.
  //
  Status = gBS->SignalEvent (PlatformHasDeviceTreeEvent);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: SignalEvent(): %r\n", __func__, Status));
    goto CloseEvent;
  }

  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gFdtClientProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mFdtClientProtocol
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: InstallProtocolInterface(): %r\n",
      __func__,
      Status
      ));
    goto CloseEvent;
  }

  return Status;

CloseEvent:
  gBS->CloseEvent (PlatformHasDeviceTreeEvent);
  return Status;
}
