/** @file
*  Virtio FDT client protocol driver for virtio,mmio DT node
*
*  Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>
*
*  This program and the accompanying materials are
*  licensed and made available under the terms and conditions of the BSD License
*  which accompanies this distribution.  The full text of the license may be found at
*  http://opensource.org/licenses/bsd-license.php
*
*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/VirtioMmioDeviceLib.h>

#include <Guid/VirtioMmioTransport.h>

#include <Protocol/FdtClient.h>

#pragma pack (1)
typedef struct {
  VENDOR_DEVICE_PATH                  Vendor;
  UINT64                              PhysBase;
  EFI_DEVICE_PATH_PROTOCOL            End;
} VIRTIO_TRANSPORT_DEVICE_PATH;
#pragma pack ()

EFI_STATUS
EFIAPI
InitializeVirtioFdtDxe (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS                     Status, FindNodeStatus;
  FDT_CLIENT_PROTOCOL            *FdtClient;
  INT32                          Node;
  CONST UINT64                   *Reg;
  UINT32                         RegSize;
  VIRTIO_TRANSPORT_DEVICE_PATH   *DevicePath;
  EFI_HANDLE                     Handle;
  UINT64                         RegBase;

  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
                  (VOID **)&FdtClient);
  ASSERT_EFI_ERROR (Status);

  for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,
                                     "virtio,mmio", &Node);
       !EFI_ERROR (FindNodeStatus);
       FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,
                                     "virtio,mmio", Node, &Node)) {

    Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",
                          (CONST VOID **)&Reg, &RegSize);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",
        __FUNCTION__, Status));
      continue;
    }

    ASSERT (RegSize == 16);

    //
    // Create a unique device path for this transport on the fly
    //
    RegBase = SwapBytes64 (*Reg);
    DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
                                  HARDWARE_DEVICE_PATH,
                                  HW_VENDOR_DP,
                                  sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));
    if (DevicePath == NULL) {
      DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
      continue;
    }

    CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);
    DevicePath->PhysBase = RegBase;
    SetDevicePathNodeLength (&DevicePath->Vendor,
      sizeof (*DevicePath) - sizeof (DevicePath->End));
    SetDevicePathEndNode (&DevicePath->End);

    Handle = NULL;
    Status = gBS->InstallProtocolInterface (&Handle,
                     &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
                     DevicePath);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
        "protocol on a new handle (Status == %r)\n",
        __FUNCTION__, Status));
      FreePool (DevicePath);
      continue;
    }

    Status = VirtioMmioInstallDevice (RegBase, Handle);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "%a: Failed to install VirtIO transport @ 0x%Lx "
        "on handle %p (Status == %r)\n", __FUNCTION__, RegBase,
        Handle, Status));

      Status = gBS->UninstallProtocolInterface (Handle,
                      &gEfiDevicePathProtocolGuid, DevicePath);
      ASSERT_EFI_ERROR (Status);
      FreePool (DevicePath);
      continue;
    }
  }

  if (EFI_ERROR (FindNodeStatus) && FindNodeStatus != EFI_NOT_FOUND) {
     DEBUG ((EFI_D_ERROR, "%a: Error occurred while iterating DT nodes "
       "(FindNodeStatus == %r)\n", __FUNCTION__, FindNodeStatus));
  }

  return EFI_SUCCESS;
}
