/** @file
  Install Acpi tables for Cloud Hypervisor

  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <IndustryStandard/Acpi63.h>
#include <Protocol/AcpiTable.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/DebugLib.h>

/**
   Find Acpi table Protocol and return it

   @return AcpiTable  Protocol, which is used to handle Acpi Table, on SUCCESS or NULL on FAILURE.

**/
STATIC
EFI_ACPI_TABLE_PROTOCOL *
FindAcpiTableProtocol (
  VOID
  )
{
  EFI_STATUS              Status;
  EFI_ACPI_TABLE_PROTOCOL *AcpiTable;

  Status = gBS->LocateProtocol (
                  &gEfiAcpiTableProtocolGuid,
                  NULL,
                  (VOID**)&AcpiTable
                  );
  ASSERT_EFI_ERROR (Status);
  return AcpiTable;
}

/** Install Acpi tables for Cloud Hypervisor

  @param [in]  AcpiProtocol  Acpi Protocol which is used to install Acpi tables

  @return EFI_SUCCESS            The table was successfully inserted.
  @return EFI_INVALID_PARAMETER  Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL
                                 and the size field embedded in the ACPI table pointed
                                 by AcpiTablePtr or DsdtPtr are not in sync.
  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.
  @return EFI_NOT_FOUND          DSDT table not found.
**/
EFI_STATUS
EFIAPI
InstallCloudHvAcpiTables (
  IN     EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol
  )
{
  UINTN          InstalledKey;
  UINTN          TableSize;
  UINTN          AcpiTableLength;
  UINT64         RsdpPtr;
  UINT64         XsdtPtr;
  UINT64         TableOffset;
  UINT64         AcpiTablePtr;
  UINT64         *DsdtPtr;
  EFI_STATUS     Status;

  if (AcpiProtocol == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  RsdpPtr = PcdGet64 (PcdCloudHvAcpiRsdpBaseAddress);
  XsdtPtr = ((EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER *)RsdpPtr)->XsdtAddress;
  AcpiTableLength = ((EFI_ACPI_COMMON_HEADER *)XsdtPtr)->Length;
  TableOffset = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
  DsdtPtr = NULL;

  while (TableOffset < AcpiTableLength) {
    AcpiTablePtr = *(UINT64 *)(XsdtPtr + TableOffset);
    TableSize = ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Length;

    //
    // Install ACPI tables from XSDT
    //
    Status = AcpiProtocol->InstallAcpiTable (
                             AcpiProtocol,
                             (VOID *)AcpiTablePtr,
                             TableSize,
                             &InstalledKey
                             );
    if (EFI_ERROR (Status)) {
        return Status;
    }

    //
    // Get DSDT from FADT
    //
    if ((DsdtPtr == NULL) &&
        (EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE ==
         ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Signature)) {
      DsdtPtr = (UINT64 *)((EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *)AcpiTablePtr)->XDsdt;
    }

    TableOffset += sizeof (UINT64);
  } // while

  if (DsdtPtr == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));
    return EFI_NOT_FOUND;
  }

  //
  // Install DSDT table
  //
  TableSize = ((EFI_ACPI_COMMON_HEADER *)DsdtPtr)->Length;
  Status = AcpiProtocol->InstallAcpiTable (
                           AcpiProtocol,
                           DsdtPtr,
                           TableSize,
                           &InstalledKey
                           );

  return Status;
}

/** Entry point for Cloud Hypervisor Platform Dxe

  @param [in]  ImageHandle  Handle for this image.
  @param [in]  SystemTable  Pointer to the EFI system table.

  @return EFI_SUCCESS            The table was successfully inserted.
  @return EFI_INVALID_PARAMETER  Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL
                                 and the size field embedded in the ACPI table pointed to
                                 by AcpiTablePtr or DsdtPtr are not in sync.
  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.
  @return EFI_NOT_FOUND          DSDT table not found
**/
EFI_STATUS
EFIAPI
CloudHvAcpiPlatformEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                         Status;

  Status = InstallCloudHvAcpiTables (FindAcpiTableProtocol ());

  if (EFI_ERROR (Status)) {
     DEBUG ((
       DEBUG_ERROR,
       "%a: Fail to install Acpi table: %r\n",
       __FUNCTION__,
       Status
       ));
     CpuDeadLoop ();
  }

  return EFI_SUCCESS;
}
