/** @file
*
*  Copyright (c) 2014, ARM Limited. All rights reserved.
*
*  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 <Uefi.h>

#include <Library/AcpiLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>

#include <Protocol/AcpiTable.h>
#include <Protocol/FirmwareVolume2.h>

#include <IndustryStandard/Acpi.h>

/**
  Locate and Install the ACPI tables from the Firmware Volume

  @param  AcpiFile              Guid of the ACPI file into the Firmware Volume

  @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
LocateAndInstallAcpiFromFv (
  IN CONST EFI_GUID* AcpiFile
  )
{
  EFI_STATUS                    Status;
  EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol;
  EFI_HANDLE                    *HandleBuffer;
  UINTN                         NumberOfHandles;
  UINT32                        FvStatus;
  UINTN                         Index;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
  INTN                          SectionInstance;
  UINTN                         SectionSize;
  EFI_ACPI_COMMON_HEADER       *AcpiTable;
  UINTN                         AcpiTableSize;
  UINTN                         AcpiTableKey;

  // Ensure the ACPI Table is present
  Status = gBS->LocateProtocol (
                  &gEfiAcpiTableProtocolGuid,
                  NULL,
                  (VOID**)&AcpiProtocol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FvStatus        = 0;
  SectionInstance = 0;

  // Locate all the Firmware Volume protocols.
  Status = gBS->LocateHandleBuffer (
                   ByProtocol,
                   &gEfiFirmwareVolume2ProtocolGuid,
                   NULL,
                   &NumberOfHandles,
                   &HandleBuffer
                   );
  if (EFI_ERROR (Status)) {
    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
                     );
    if (EFI_ERROR (Status)) {
      goto FREE_HANDLE_BUFFER;
    }

    while (Status == EFI_SUCCESS) {
      // AcpiTable must be allocated by ReadSection (ie: AcpiTable == NULL)
      AcpiTable = NULL;

      // See if it has the ACPI storage file
      Status = FvInstance->ReadSection (
                        FvInstance,
                        AcpiFile,
                        EFI_SECTION_RAW,
                        SectionInstance,
                        (VOID**) &AcpiTable,
                        &SectionSize,
                        &FvStatus
                        );
      if (!EFI_ERROR (Status)) {
        AcpiTableKey = 0;
        AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Length;
        ASSERT (SectionSize >= AcpiTableSize);

        DEBUG ((EFI_D_ERROR, "- Found '%c%c%c%c' ACPI Table\n",
            (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature & 0xFF),
            ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 8) & 0xFF),
            ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 16) & 0xFF),
            ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 24) & 0xFF)));

        // Install the ACPI Table
        Status = AcpiProtocol->InstallAcpiTable (
                               AcpiProtocol,
                               AcpiTable,
                               AcpiTableSize,
                               &AcpiTableKey
                               );
        // Free memory allocated by ReadSection
        gBS->FreePool (AcpiTable);

        if (EFI_ERROR (Status)) {
          break;
        }

        // Increment the section instance
        SectionInstance++;
      }
    }
  }

FREE_HANDLE_BUFFER:
  //
  // Free any allocated buffers
  //
  gBS->FreePool (HandleBuffer);

  return EFI_SUCCESS;
}
