/** @file
*
*  Copyright (c) 2014-2015, ARM Limited. All rights reserved.
*  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
*
*  SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/

#include <Uefi.h>

#include <Library/AcpiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>

#include <Protocol/AcpiSystemDescriptionTable.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/FirmwareVolume2.h>

#include <IndustryStandard/Acpi.h>

/**
  Locate and Install the ACPI tables from the Firmware Volume if it verifies
  the function condition.

  @param  AcpiFile                Guid of the ACPI file into the Firmware Volume
  @param  CheckAcpiTableFunction  Function that checks if the ACPI table should be installed

  @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
LocateAndInstallAcpiFromFvConditional (
  IN CONST EFI_GUID         *AcpiFile,
  IN EFI_LOCATE_ACPI_CHECK  CheckAcpiTableFunction
  )
{
  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;
  BOOLEAN                        Valid;
  BOOLEAN                        FoundAcpiFile;

  FoundAcpiFile = FALSE;

  // 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)) {
        break;
      }

      FoundAcpiFile = TRUE;

      AcpiTableKey  = 0;
      AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Length;
      ASSERT (SectionSize >= AcpiTableSize);

      DEBUG ((
        DEBUG_INFO,
        "- 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)
        ));

      // Is the ACPI table valid?
      if (CheckAcpiTableFunction != NULL) {
        Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable);
      } else {
        Valid = TRUE;
      }

      // Install the ACPI Table
      if (Valid) {
        Status = AcpiProtocol->InstallAcpiTable (
                                 AcpiProtocol,
                                 AcpiTable,
                                 AcpiTableSize,
                                 &AcpiTableKey
                                 );
      }

      // Free memory allocated by ReadSection
      gBS->FreePool (AcpiTable);

      // Increment the section instance
      SectionInstance++;
    }
  }

FREE_HANDLE_BUFFER:
  //
  // Free any allocated buffers
  //
  gBS->FreePool (HandleBuffer);

  return (FoundAcpiFile ? EFI_SUCCESS : EFI_NOT_FOUND);
}

/**
  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
  )
{
  return LocateAndInstallAcpiFromFvConditional (AcpiFile, NULL);
}

/**
  This function calculates and updates a UINT8 checksum
  in an ACPI description table header.

  @param  Buffer          Pointer to buffer to checksum
  @param  Size            Number of bytes to checksum

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.

**/
EFI_STATUS
EFIAPI
AcpiUpdateChecksum (
  IN OUT  UINT8  *Buffer,
  IN      UINTN  Size
  )
{
  UINTN  ChecksumOffset;

  if ((Buffer == NULL) || (Size == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);

  //
  // Set checksum to 0 first
  //
  Buffer[ChecksumOffset] = 0;

  //
  // Update checksum value
  //
  Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);

  return EFI_SUCCESS;
}

/**
  This function uses the ACPI SDT protocol to search an ACPI table
  with a given signature.

  @param  AcpiTableSdtProtocol    Pointer to ACPI SDT protocol.
  @param  TableSignature          ACPI table signature.
  @param  Index                   The zero-based index of the table where to search the table.
                                  The index will be updated to the next instance if the table
                                  is found with the matched TableSignature.
  @param  Table                   Pointer to the table.
  @param  TableKey                Pointer to the table key.

  @return EFI_SUCCESS             The function completed successfully.
  @return EFI_INVALID_PARAMETER   At least one of parameters is invalid.
  @retval EFI_NOT_FOUND           The requested index is too large and a table was not found.

**/
EFI_STATUS
EFIAPI
AcpiLocateTableBySignature (
  IN      EFI_ACPI_SDT_PROTOCOL        *AcpiSdtProtocol,
  IN      UINT32                       TableSignature,
  IN OUT  UINTN                        *Index,
  OUT     EFI_ACPI_DESCRIPTION_HEADER  **Table,
  OUT     UINTN                        *TableKey
  )
{
  EFI_STATUS              Status;
  EFI_ACPI_SDT_HEADER     *TempTable;
  EFI_ACPI_TABLE_VERSION  TableVersion;
  UINTN                   TableIndex;

  if (  (AcpiSdtProtocol == NULL)
     || (Table == NULL)
     || (TableKey == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_SUCCESS;

  //
  // Search for ACPI Table with matching signature
  //
  TableVersion = 0;
  TableIndex   = *Index;
  while (!EFI_ERROR (Status)) {
    Status = AcpiSdtProtocol->GetAcpiTable (
                                TableIndex,
                                &TempTable,
                                &TableVersion,
                                TableKey
                                );
    if (!EFI_ERROR (Status)) {
      TableIndex++;

      if (((EFI_ACPI_DESCRIPTION_HEADER *)TempTable)->Signature == TableSignature) {
        *Table = (EFI_ACPI_DESCRIPTION_HEADER *)TempTable;
        *Index = TableIndex;
        break;
      }
    }
  }

  return Status;
}

/**
  This function updates the integer value of an AML Object.

  @param  AcpiSdtProtocol         Pointer to ACPI SDT protocol.
  @param  TableHandle             Points to the table representing the starting point
                                  for the object path search.
  @param  AsciiObjectPath         Pointer to the ACPI path of the object being updated.
  @param  Value                   New value to write to the object.

  @return EFI_SUCCESS             The function completed successfully.
  @return EFI_INVALID_PARAMETER   At least one of parameters is invalid or the data type
                                  of the ACPI object is not an integer value.
  @retval EFI_NOT_FOUND           The object is not found with the given path.
  @retval EFI_UNSUPPORTED         The object uses ZeroOp/OneOp encoding and cannot be
                                  safely updated to a value other than 0 or 1.

  @attention  IMPORTANT LIMITATION:
      If the original ASL code uses Name (XXX, 0) or Name (XXX, 1),
      the iASL compiler optimizes it to 1-byte ZeroOp/OneOp encoding.
      This function CANNOT safely update such objects to values other than 0 or 1,
      because there is no space to expand to BytePrefix encoding (2 bytes).

      WORKAROUND: In ASL source, use an initial value >= 2, e.g.:
          Name (_STA, 0xF)    // Forces BytePrefix encoding, reserves 2 bytes
      instead of:
          Name (_STA, 0x0)    // Optimized to ZeroOp, only 1 byte!

**/
EFI_STATUS
EFIAPI
AcpiAmlObjectUpdateInteger (
  IN  EFI_ACPI_SDT_PROTOCOL  *AcpiSdtProtocol,
  IN  EFI_ACPI_HANDLE        TableHandle,
  IN  CHAR8                  *AsciiObjectPath,
  IN  UINTN                  Value
  )
{
  EFI_STATUS          Status;
  EFI_ACPI_HANDLE     ObjectHandle;
  EFI_ACPI_HANDLE     DataHandle;
  EFI_ACPI_DATA_TYPE  DataType;
  UINT8               *Buffer;
  UINTN               BufferSize;
  UINTN               DataSize;

  if ((AcpiSdtProtocol == NULL) || (AsciiObjectPath == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ObjectHandle = NULL;
  DataHandle   = NULL;

  Status = AcpiSdtProtocol->FindPath (TableHandle, AsciiObjectPath, &ObjectHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = AcpiSdtProtocol->GetOption (ObjectHandle, 0, &DataType, (VOID *)&Buffer, &BufferSize);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
  ASSERT (Buffer != NULL);

  if (Buffer[0] != AML_NAME_OP) {
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  //
  // Get handle of data object
  //
  Status = AcpiSdtProtocol->GetChild (ObjectHandle, &DataHandle);
  ASSERT_EFI_ERROR (Status);

  Status = AcpiSdtProtocol->GetOption (DataHandle, 0, &DataType, (VOID *)&Buffer, &BufferSize);
  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
  ASSERT (Buffer != NULL);

  if ((Buffer[0] == AML_ZERO_OP) || (Buffer[0] == AML_ONE_OP)) {
    //
    // ZeroOp (0x00) and OneOp (0x01) are optimized 1-byte encodings where
    // the value is implicit in the opcode itself.
    //
    // Only values 0 and 1 can be updated safely because they can be represented
    // using the same 1-byte encoding.
    //
    // Values >= 2 require BytePrefix encoding (opcode + data), which
    // needs 2 bytes total. Since the ACPI table is byte-exact encoding with
    // no reserved space, we CANNOT expand from 1 byte to 2 bytes.
    //
    // Attempting to do so (as the original code did) would silently
    // corrupt the AML byte stream, causing subsequent ACPI name segments
    // to be misinterpreted as data bytes, ultimately leading to kernel
    // crashes when the OS parses the corrupted ACPI table.
    //
    if ((Value == 0) || (Value == 1)) {
      UINT8  Opcode;

      Opcode = (Value == 0) ? AML_ZERO_OP : AML_ONE_OP;
      Status = AcpiSdtProtocol->SetOption (
                                  DataHandle,
                                  0,
                                  &Opcode,
                                  sizeof (UINT8)
                                  );
      ASSERT_EFI_ERROR (Status);
    } else {
      DEBUG ((
        DEBUG_ERROR,
        "ACPI: ERROR: Cannot update object '%a' from ZeroOp/OneOp to 0x%lx\n"
        "ACPI:        No space to expand to BytePrefix encoding.\n"
        "ACPI:        FIX: In ASL source, use an initial value >= 2 to\n"
        "ACPI:             force BytePrefix, e.g. Name (_STA, 0xF)\n",
        AsciiObjectPath,
        Value
        ));
      ASSERT (FALSE);
      Status = EFI_UNSUPPORTED;
      goto Exit;
    }
  } else {
    //
    // Check the size of data object
    //
    switch (Buffer[0]) {
      case AML_BYTE_PREFIX:
        DataSize = sizeof (UINT8);
        break;

      case AML_WORD_PREFIX:
        DataSize = sizeof (UINT16);
        break;

      case AML_DWORD_PREFIX:
        DataSize = sizeof (UINT32);
        break;

      case AML_QWORD_PREFIX:
        DataSize = sizeof (UINT64);
        break;

      default:
        // The data type of the ACPI object is not an integer
        Status = EFI_INVALID_PARAMETER;
        goto Exit;
    }

    Status = AcpiSdtProtocol->SetOption (DataHandle, 1, (VOID *)&Value, DataSize);
    ASSERT_EFI_ERROR (Status);
  }

Exit:
  AcpiSdtProtocol->Close (DataHandle);
  AcpiSdtProtocol->Close (ObjectHandle);

  return Status;
}
