/** @file
  Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol

  Copyright (C) 2016, Linaro Ltd. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>

#include <Protocol/AcpiTable.h>
#include <Protocol/FdtClient.h>

#include <IndustryStandard/Acpi.h>

/**
  Get the address of Xen ACPI Root System Description Pointer (RSDP)
  structure.

  @param  RsdpStructurePtr   Return pointer to RSDP structure

  @return EFI_SUCCESS        Find Xen RSDP structure successfully.
  @return EFI_NOT_FOUND      Don't find Xen RSDP structure.
  @return EFI_ABORTED        Find Xen RSDP structure, but it's not integrated.

**/
STATIC
EFI_STATUS
EFIAPI
GetXenArmAcpiRsdp (
  OUT   EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  **RsdpPtr
  )
{
  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *RsdpStructurePtr;
  EFI_STATUS                                    Status;
  FDT_CLIENT_PROTOCOL                           *FdtClient;
  CONST UINT64                                  *Reg;
  UINT32                                        RegSize;
  UINTN                                         AddressCells, SizeCells;
  UINT64                                        RegBase;
  UINT8                                         Sum;

  RsdpStructurePtr = NULL;
  FdtClient        = NULL;
  //
  // Get the RSDP structure address from DeviceTree
  //
  Status = gBS->LocateProtocol (
                  &gFdtClientProtocolGuid,
                  NULL,
                  (VOID **)&FdtClient
                  );
  ASSERT_EFI_ERROR (Status);

  Status = FdtClient->FindCompatibleNodeReg (
                        FdtClient,
                        "xen,guest-acpi",
                        (CONST VOID **)&Reg,
                        &AddressCells,
                        &SizeCells,
                        &RegSize
                        );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_WARN,
      "%a: No 'xen,guest-acpi' compatible DT node found\n",
      __func__
      ));
    return EFI_NOT_FOUND;
  }

  ASSERT (AddressCells == 2);
  ASSERT (SizeCells == 2);
  ASSERT (RegSize == 2 * sizeof (UINT64));

  RegBase          = SwapBytes64 (Reg[0]);
  RsdpStructurePtr =
    (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)RegBase;

  if (RsdpStructurePtr && (RsdpStructurePtr->Revision >= 2)) {
    Sum = CalculateSum8 (
            (CONST UINT8 *)RsdpStructurePtr,
            sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
            );
    if (Sum != 0) {
      return EFI_ABORTED;
    }
  }

  *RsdpPtr = RsdpStructurePtr;
  return EFI_SUCCESS;
}

/**
  Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
  into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
  ACPI tables are: FACP, APIC, GTDT, DSDT.

  @param  AcpiProtocol           Protocol instance pointer.

  @return EFI_SUCCESS            The table was successfully inserted.
  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableHandle is
                                 NULL, or AcpiTableBufferSize and the size
                                 field embedded in the ACPI table pointed to
                                 by AcpiTableBuffer are not in sync.
  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.

**/
STATIC
EFI_STATUS
EFIAPI
InstallXenArmTables (
  IN   EFI_ACPI_TABLE_PROTOCOL  *AcpiProtocol
  )
{
  EFI_STATUS                                    Status;
  UINTN                                         TableHandle;
  VOID                                          *CurrentTableEntry;
  UINTN                                         CurrentTablePointer;
  EFI_ACPI_DESCRIPTION_HEADER                   *CurrentTable;
  UINTN                                         Index;
  UINTN                                         NumberOfTableEntries;
  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *XenAcpiRsdpStructurePtr;
  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt;
  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE     *FadtTable;
  EFI_ACPI_DESCRIPTION_HEADER                   *DsdtTable;
  EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *FacsTable;

  XenAcpiRsdpStructurePtr = NULL;
  FadtTable               = NULL;
  DsdtTable               = NULL;
  FacsTable               = NULL;
  TableHandle             = 0;
  NumberOfTableEntries    = 0;

  //
  // Try to find Xen ARM ACPI tables
  //
  Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "%a: No RSDP table found\n", __func__));
    return Status;
  }

  //
  // If XSDT table is find, just install its tables.
  //
  if (XenAcpiRsdpStructurePtr->XsdtAddress) {
    //
    // Retrieve the addresses of XSDT and
    // calculate the number of its table entries.
    //
    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
           XenAcpiRsdpStructurePtr->XsdtAddress;
    NumberOfTableEntries = (Xsdt->Length -
                            sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
                           sizeof (UINT64);
    //
    // Install ACPI tables found in XSDT.
    //
    for (Index = 0; Index < NumberOfTableEntries; Index++) {
      //
      // Get the table entry from XSDT
      //
      CurrentTableEntry = (VOID *)((UINT8 *)Xsdt +
                                   sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
                                   Index * sizeof (UINT64));
      CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;
      CurrentTable        = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;

      //
      // Install the XSDT tables
      //
      Status = AcpiProtocol->InstallAcpiTable (
                               AcpiProtocol,
                               CurrentTable,
                               CurrentTable->Length,
                               &TableHandle
                               );

      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Get the FACS and DSDT table address from the table FADT
      //
      if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {
        FadtTable = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
                    (UINTN)CurrentTablePointer;
        DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)FadtTable->Dsdt;
        FacsTable = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)
                    (UINTN)FadtTable->FirmwareCtrl;
      }
    }
  }

  //
  // Install DSDT table.
  //
  if (DsdtTable != NULL) {
    Status = AcpiProtocol->InstallAcpiTable (
                             AcpiProtocol,
                             DsdtTable,
                             DsdtTable->Length,
                             &TableHandle
                             );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Install FACS table.
  //
  if (FacsTable != NULL) {
    Status = AcpiProtocol->InstallAcpiTable (
                             AcpiProtocol,
                             FacsTable,
                             FacsTable->Length,
                             &TableHandle
                             );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

STATIC
EFI_ACPI_TABLE_PROTOCOL *
FindAcpiTableProtocol (
  VOID
  )
{
  EFI_STATUS               Status;
  EFI_ACPI_TABLE_PROTOCOL  *AcpiTable;

  AcpiTable = NULL;
  Status    = gBS->LocateProtocol (
                     &gEfiAcpiTableProtocolGuid,
                     NULL,
                     (VOID **)&AcpiTable
                     );
  ASSERT_EFI_ERROR (Status);
  return AcpiTable;
}

/**
  Entrypoint of Xen ARM Acpi Platform driver.

  @param  ImageHandle
  @param  SystemTable

  @return EFI_SUCCESS
  @return EFI_LOAD_ERROR
  @return EFI_OUT_OF_RESOURCES

**/
EFI_STATUS
EFIAPI
XenAcpiPlatformEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = InstallXenArmTables (FindAcpiTableProtocol ());
  return Status;
}
