/** @file
  FDT client library for motorola,mc146818 RTC driver

  Copyright (c) 2020, ARM Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/FdtClient.h>

/** RTC Index register is at offset 0x0
*/
#define RTC_INDEX_REG_OFFSET  0x0ULL

/** RTC Target register is at offset 0x1
*/
#define RTC_TARGET_REG_OFFSET  0x1ULL

/** Add the RTC controller address range to the memory map.

  @param [in]  ImageHandle  The handle to the image.
  @param [in]  RtcPageBase  Base address of the RTC controller.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
  @retval EFI_NOT_FOUND           Flash device not found.
**/
STATIC
EFI_STATUS
KvmtoolRtcMapMemory (
  IN EFI_HANDLE            ImageHandle,
  IN EFI_PHYSICAL_ADDRESS  RtcPageBase
  )
{
  EFI_STATUS  Status;

  Status = gDS->AddMemorySpace (
                  EfiGcdMemoryTypeMemoryMappedIo,
                  RtcPageBase,
                  EFI_PAGE_SIZE,
                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "Failed to add memory space. Status = %r\n",
      Status
      ));
    return Status;
  }

  Status = gDS->AllocateMemorySpace (
                  EfiGcdAllocateAddress,
                  EfiGcdMemoryTypeMemoryMappedIo,
                  0,
                  EFI_PAGE_SIZE,
                  &RtcPageBase,
                  ImageHandle,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "Failed to allocate memory space. Status = %r\n",
      Status
      ));
    gDS->RemoveMemorySpace (
           RtcPageBase,
           EFI_PAGE_SIZE
           );
    return Status;
  }

  Status = gDS->SetMemorySpaceAttributes (
                  RtcPageBase,
                  EFI_PAGE_SIZE,
                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "Failed to set memory attributes. Status = %r\n",
      Status
      ));
    gDS->FreeMemorySpace (
           RtcPageBase,
           EFI_PAGE_SIZE
           );
    gDS->RemoveMemorySpace (
           RtcPageBase,
           EFI_PAGE_SIZE
           );
  }

  return Status;
}

/** Entrypoint for KvmtoolRtcFdtClientLib.

  Locate the RTC node in the DT and update the Index and
  Target register base addresses in the respective PCDs.
  Add the RTC memory region to the memory map.
  Disable the RTC node as the RTC is owned by UEFI.

  @param [in]  ImageHandle  The handle to the image.
  @param [in]  SystemTable  Pointer to the System Table.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
  @retval EFI_NOT_FOUND           Flash device not found.
**/
EFI_STATUS
EFIAPI
KvmtoolRtcFdtClientLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS           Status;
  FDT_CLIENT_PROTOCOL  *FdtClient;
  INT32                Node;
  CONST UINT32         *Reg;
  UINT32               RegSize;
  UINT64               RegBase;
  UINT64               Range;
  RETURN_STATUS        PcdStatus;

  Status = gBS->LocateProtocol (
                  &gFdtClientProtocolGuid,
                  NULL,
                  (VOID **)&FdtClient
                  );
  ASSERT_EFI_ERROR (Status);

  Status = FdtClient->FindCompatibleNode (
                        FdtClient,
                        "motorola,mc146818",
                        &Node
                        );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: No 'motorola,mc146818' compatible DT node found\n",
      __func__
      ));
    return Status;
  }

  Status = FdtClient->GetNodeProperty (
                        FdtClient,
                        Node,
                        "reg",
                        (CONST VOID **)&Reg,
                        &RegSize
                        );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: No 'reg' property found in 'motorola,mc146818' compatible DT node\n",
      __func__
      ));
    return Status;
  }

  ASSERT (RegSize == 16);

  RegBase = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
  Range   = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
  DEBUG ((
    DEBUG_INFO,
    "Found motorola,mc146818 RTC @ 0x%Lx Range = 0x%x\n",
    RegBase,
    Range
    ));

  // The address range must cover the RTC Index and the Target registers.
  ASSERT (Range >= 0x2);

  // RTC Index register is at offset 0x0
  PcdStatus = PcdSet64S (
                PcdRtcIndexRegister64,
                (RegBase + RTC_INDEX_REG_OFFSET)
                );
  ASSERT_RETURN_ERROR (PcdStatus);

  // RTC Target register is at offset 0x1
  PcdStatus = PcdSet64S (
                PcdRtcTargetRegister64,
                (RegBase + RTC_TARGET_REG_OFFSET)
                );
  ASSERT_RETURN_ERROR (PcdStatus);

  Status = KvmtoolRtcMapMemory (ImageHandle, (RegBase & ~EFI_PAGE_MASK));
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "Failed to map memory for motorola,mc146818. Status = %r\n",
      Status
      ));
    return Status;
  }

  //
  // UEFI takes ownership of the RTC hardware, and exposes its functionality
  // through the UEFI Runtime Services GetTime, SetTime, etc. This means we
  // need to disable it in the device tree to prevent the OS from attaching
  // its device driver as well.
  //
  Status = FdtClient->SetNodeProperty (
                        FdtClient,
                        Node,
                        "status",
                        "disabled",
                        sizeof ("disabled")
                        );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_WARN,
      "Failed to set motorola,mc146818 status to 'disabled', Status = %r\n",
      Status
      ));
  }

  return EFI_SUCCESS;
}
