/** @file
  bhyve ACPI Platform Driver

  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>
  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "AcpiPlatform.h"

#include <Library/AcpiPlatformLib.h> // InstallAcpiTablesFromMemory()

#define BHYVE_ACPI_PHYSICAL_ADDRESS  ((UINTN)0x000F2400)
#define BHYVE_BIOS_PHYSICAL_END      ((UINTN)0x00100000)

EFI_STATUS
EFIAPI
InstallAcpiTable (
  IN   EFI_ACPI_TABLE_PROTOCOL  *AcpiProtocol,
  IN   VOID                     *AcpiTableBuffer,
  IN   UINTN                    AcpiTableBufferSize,
  OUT  UINTN                    *TableKey
  )
{
  return AcpiProtocol->InstallAcpiTable (
                         AcpiProtocol,
                         AcpiTableBuffer,
                         AcpiTableBufferSize,
                         TableKey
                         );
}

/**
  Locate the first instance of a protocol.  If the protocol requested is an
  FV protocol, then it will return the first FV that contains the ACPI table
  storage file.

  @param  Instance      Return pointer to the first instance of the protocol

  @return EFI_SUCCESS           The function completed successfully.
  @return EFI_NOT_FOUND         The protocol could not be located.
  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.

**/
EFI_STATUS
LocateFvInstanceWithTables (
  OUT EFI_FIRMWARE_VOLUME2_PROTOCOL  **Instance
  )
{
  EFI_STATUS                     Status;
  EFI_HANDLE                     *HandleBuffer;
  UINTN                          NumberOfHandles;
  EFI_FV_FILETYPE                FileType;
  UINT32                         FvStatus;
  EFI_FV_FILE_ATTRIBUTES         Attributes;
  UINTN                          Size;
  UINTN                          Index;
  EFI_FIRMWARE_VOLUME2_PROTOCOL  *FvInstance;

  FvStatus = 0;

  //
  // Locate protocol.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareVolume2ProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    //
    // Defined errors at this time are not found and out of resources.
    //
    return Status;
  }

  //
  // Looking for FV with ACPI storage file
  //
  for (Index = 0; Index < NumberOfHandles; Index++) {
    //
    // Get the protocol on this handle
    // This should not fail because of LocateHandleBuffer
    //
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiFirmwareVolume2ProtocolGuid,
                    (VOID **)&FvInstance
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // See if it has the ACPI storage file
    //
    Status = FvInstance->ReadFile (
                           FvInstance,
                           (EFI_GUID *)PcdGetPtr (PcdAcpiTableStorageFile),
                           NULL,
                           &Size,
                           &FileType,
                           &Attributes,
                           &FvStatus
                           );

    //
    // If we found it, then we are done
    //
    if (Status == EFI_SUCCESS) {
      *Instance = FvInstance;
      break;
    }
  }

  //
  // Our exit status is determined by the success of the previous operations
  // If the protocol was found, Instance already points to it.
  //

  //
  // Free any allocated buffers
  //
  gBS->FreePool (HandleBuffer);

  return Status;
}

/**
  Find ACPI tables in an FV and install them.

  This is now a fall-back path. Normally, we will search for tables provided
  by the VMM first.

  If that fails, we use this function to load the ACPI tables from an FV. The
  sources for the FV based tables is located under OvmfPkg/Bhyve/AcpiTables.

  @param  AcpiTable     Protocol instance pointer

**/
EFI_STATUS
EFIAPI
InstallOvmfFvTables (
  IN  EFI_ACPI_TABLE_PROTOCOL  *AcpiTable
  )
{
  EFI_STATUS                         Status;
  EFI_FIRMWARE_VOLUME2_PROTOCOL      *FwVol;
  INTN                               Instance;
  EFI_ACPI_COMMON_HEADER             *CurrentTable;
  UINTN                              TableHandle;
  UINT32                             FvStatus;
  UINTN                              TableSize;
  UINTN                              Size;
  EFI_ACPI_TABLE_INSTALL_ACPI_TABLE  TableInstallFunction;

  Instance     = 0;
  CurrentTable = NULL;
  TableHandle  = 0;

  TableInstallFunction = BhyveInstallAcpiTable;

  //
  // set FwVol (and use an ASSERT() below) to suppress incorrect
  // compiler/analyzer warnings
  //
  FwVol = NULL;
  //
  // Locate the firmware volume protocol
  //
  Status = LocateFvInstanceWithTables (&FwVol);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  ASSERT (FwVol != NULL);

  //
  // Read tables from the storage file.
  //
  while (Status == EFI_SUCCESS) {
    Status = FwVol->ReadSection (
                      FwVol,
                      (EFI_GUID *)PcdGetPtr (PcdAcpiTableStorageFile),
                      EFI_SECTION_RAW,
                      Instance,
                      (VOID **)&CurrentTable,
                      &Size,
                      &FvStatus
                      );
    if (!EFI_ERROR (Status)) {
      //
      // Add the table
      //
      TableHandle = 0;

      TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)CurrentTable)->Length;
      ASSERT (Size >= TableSize);

      //
      // Install ACPI table
      //
      Status = TableInstallFunction (
                 AcpiTable,
                 CurrentTable,
                 TableSize,
                 &TableHandle
                 );

      //
      // Free memory allocated by ReadSection
      //
      gBS->FreePool (CurrentTable);

      if (EFI_ERROR (Status)) {
        return EFI_ABORTED;
      }

      //
      // Increment the instance
      //
      Instance++;
      CurrentTable = NULL;
    }
  }

  return EFI_SUCCESS;
}

/**
  Effective entrypoint of Acpi Platform driver.

  @param  ImageHandle
  @param  SystemTable

  @return EFI_SUCCESS
  @return EFI_LOAD_ERROR
  @return EFI_OUT_OF_RESOURCES

**/
EFI_STATUS
EFIAPI
InstallAcpiTables (
  IN   EFI_ACPI_TABLE_PROTOCOL  *AcpiTable
  )
{
  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
  EFI_STATUS                                    Status;

  Status = InstallQemuFwCfgTables (AcpiTable);
  if (!EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

  Status = GetAcpiRsdpFromMemory (
             BHYVE_ACPI_PHYSICAL_ADDRESS,
             BHYVE_BIOS_PHYSICAL_END,
             &Rsdp
             );
  if (!EFI_ERROR (Status)) {
    Status = InstallAcpiTablesFromRsdp (
               AcpiTable,
               Rsdp
               );
    if (!EFI_ERROR (Status)) {
      return EFI_SUCCESS;
    }
  }

  if (EFI_ERROR (Status)) {
    DEBUG (
      (
       DEBUG_WARN,
       "%a: unable to install bhyve's ACPI tables (%r)\n",
       __func__,
       Status
      )
      );
  }

  Status = InstallOvmfFvTables (AcpiTable);

  return Status;
}
