/** @file
  This module provides help function for finding ACPI table.

  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiLibInternal.h"
#include <IndustryStandard/Acpi.h>
#include <Guid/Acpi.h>

/**
  This function scans ACPI table in XSDT/RSDT.

  @param Sdt                    ACPI XSDT/RSDT.
  @param TablePointerSize       Size of table pointer: 8(XSDT) or 4(RSDT).
  @param Signature              ACPI table signature.
  @param PreviousTable          Pointer to previous returned table to locate
                                next table, or NULL to locate first table.
  @param PreviousTableLocated   Pointer to the indicator about whether the
                                previous returned table could be located, or
                                NULL if PreviousTable is NULL.

  If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().
  If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().

  @return ACPI table or NULL if not found.

**/
EFI_ACPI_COMMON_HEADER *
ScanTableInSDT (
  IN  EFI_ACPI_DESCRIPTION_HEADER  *Sdt,
  IN  UINTN                        TablePointerSize,
  IN  UINT32                       Signature,
  IN  EFI_ACPI_COMMON_HEADER       *PreviousTable  OPTIONAL,
  OUT BOOLEAN                      *PreviousTableLocated OPTIONAL
  )
{
  UINTN                   Index;
  UINTN                   EntryCount;
  UINT64                  EntryPtr;
  UINTN                   BasePtr;
  EFI_ACPI_COMMON_HEADER  *Table;

  if (PreviousTableLocated != NULL) {
    ASSERT (PreviousTable != NULL);
    *PreviousTableLocated = FALSE;
  } else {
    ASSERT (PreviousTable == NULL);
  }

  if (Sdt == NULL) {
    return NULL;
  }

  EntryCount = (Sdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / TablePointerSize;

  BasePtr = (UINTN)(Sdt + 1);
  for (Index = 0; Index < EntryCount; Index++) {
    EntryPtr = 0;
    CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * TablePointerSize), TablePointerSize);
    Table = (EFI_ACPI_COMMON_HEADER *)((UINTN)(EntryPtr));
    if ((Table != NULL) && (Table->Signature == Signature)) {
      if (PreviousTable != NULL) {
        if (Table == PreviousTable) {
          *PreviousTableLocated = TRUE;
        } else if (*PreviousTableLocated) {
          //
          // Return next table.
          //
          return Table;
        }
      } else {
        //
        // Return first table.
        //
        return Table;
      }
    }
  }

  return NULL;
}

/**
  To locate FACS in FADT.

  @param Fadt   FADT table pointer.

  @return FACS table pointer or NULL if not found.

**/
EFI_ACPI_COMMON_HEADER *
LocateAcpiFacsFromFadt (
  IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE  *Fadt
  )
{
  EFI_ACPI_COMMON_HEADER  *Facs;
  UINT64                  Data64;

  if (Fadt == NULL) {
    return NULL;
  }

  if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
    Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->FirmwareCtrl;
  } else {
    CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof (UINT64));
    if (Data64 != 0) {
      Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Data64;
    } else {
      Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->FirmwareCtrl;
    }
  }

  return Facs;
}

/**
  To locate DSDT in FADT.

  @param Fadt   FADT table pointer.

  @return DSDT table pointer or NULL if not found.

**/
EFI_ACPI_COMMON_HEADER *
LocateAcpiDsdtFromFadt (
  IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE  *Fadt
  )
{
  EFI_ACPI_COMMON_HEADER  *Dsdt;
  UINT64                  Data64;

  if (Fadt == NULL) {
    return NULL;
  }

  if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
    Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->Dsdt;
  } else {
    CopyMem (&Data64, &Fadt->XDsdt, sizeof (UINT64));
    if (Data64 != 0) {
      Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Data64;
    } else {
      Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->Dsdt;
    }
  }

  return Dsdt;
}

/**
  To locate ACPI table in ACPI ConfigurationTable.

  @param AcpiGuid               The GUID used to get ACPI ConfigurationTable.
  @param Signature              ACPI table signature.
  @param PreviousTable          Pointer to previous returned table to locate
                                next table, or NULL to locate first table.
  @param PreviousTableLocated   Pointer to the indicator to return whether the
                                previous returned table could be located or not,
                                or NULL if PreviousTable is NULL.

  If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().
  If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().
  If AcpiGuid is NULL, then ASSERT().

  @return ACPI table or NULL if not found.

**/
EFI_ACPI_COMMON_HEADER *
LocateAcpiTableInAcpiConfigurationTable (
  IN  EFI_GUID                *AcpiGuid,
  IN  UINT32                  Signature,
  IN  EFI_ACPI_COMMON_HEADER  *PreviousTable  OPTIONAL,
  OUT BOOLEAN                 *PreviousTableLocated OPTIONAL
  )
{
  EFI_STATUS                                    Status;
  EFI_ACPI_COMMON_HEADER                        *Table;
  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt;
  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt;
  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE     *Fadt;

  if (PreviousTableLocated != NULL) {
    ASSERT (PreviousTable != NULL);
    *PreviousTableLocated = FALSE;
  } else {
    ASSERT (PreviousTable == NULL);
  }

  Rsdp = NULL;
  //
  // Get ACPI ConfigurationTable (RSD_PTR)
  //
  Status = EfiGetSystemConfigurationTable (AcpiGuid, (VOID **)&Rsdp);
  if (EFI_ERROR (Status) || (Rsdp == NULL)) {
    return NULL;
  }

  Table = NULL;

  //
  // Search XSDT
  //
  if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;
    if (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
      ASSERT (PreviousTable == NULL);
      //
      // It is to locate DSDT,
      // need to locate FADT first.
      //
      Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (
                                                            Xsdt,
                                                            sizeof (UINT64),
                                                            EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
                                                            NULL,
                                                            NULL
                                                            );
      Table = LocateAcpiDsdtFromFadt (Fadt);
    } else if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
      ASSERT (PreviousTable == NULL);
      //
      // It is to locate FACS,
      // need to locate FADT first.
      //
      Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (
                                                            Xsdt,
                                                            sizeof (UINT64),
                                                            EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
                                                            NULL,
                                                            NULL
                                                            );
      Table = LocateAcpiFacsFromFadt (Fadt);
    } else {
      Table = ScanTableInSDT (
                Xsdt,
                sizeof (UINT64),
                Signature,
                PreviousTable,
                PreviousTableLocated
                );
    }
  }

  if (Table != NULL) {
    return Table;
  } else if ((PreviousTableLocated != NULL) &&
             *PreviousTableLocated)
  {
    //
    // PreviousTable could be located in XSDT,
    // but next table could not be located in XSDT.
    //
    return NULL;
  }

  //
  // Search RSDT
  //
  Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
  if (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
    ASSERT (PreviousTable == NULL);
    //
    // It is to locate DSDT,
    // need to locate FADT first.
    //
    Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (
                                                          Rsdt,
                                                          sizeof (UINT32),
                                                          EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
                                                          NULL,
                                                          NULL
                                                          );
    Table = LocateAcpiDsdtFromFadt (Fadt);
  } else if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
    ASSERT (PreviousTable == NULL);
    //
    // It is to locate FACS,
    // need to locate FADT first.
    //
    Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (
                                                          Rsdt,
                                                          sizeof (UINT32),
                                                          EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
                                                          NULL,
                                                          NULL
                                                          );
    Table = LocateAcpiFacsFromFadt (Fadt);
  } else {
    Table = ScanTableInSDT (
              Rsdt,
              sizeof (UINT32),
              Signature,
              PreviousTable,
              PreviousTableLocated
              );
  }

  return Table;
}

/**
  This function locates next ACPI table in XSDT/RSDT based on Signature and
  previous returned Table.

  If PreviousTable is NULL:
  This function will locate the first ACPI table in XSDT/RSDT based on
  Signature in gEfiAcpi20TableGuid system configuration table first, and then
  gEfiAcpi10TableGuid system configuration table.
  This function will locate in XSDT first, and then RSDT.
  For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in
  FADT.
  For FACS, this function will locate XFirmwareCtrl in FADT first, and then
  FirmwareCtrl in FADT.

  If PreviousTable is not NULL:
  1. If it could be located in XSDT in gEfiAcpi20TableGuid system configuration
     table, then this function will just locate next table in XSDT in
     gEfiAcpi20TableGuid system configuration table.
  2. If it could be located in RSDT in gEfiAcpi20TableGuid system configuration
     table, then this function will just locate next table in RSDT in
     gEfiAcpi20TableGuid system configuration table.
  3. If it could be located in RSDT in gEfiAcpi10TableGuid system configuration
     table, then this function will just locate next table in RSDT in
     gEfiAcpi10TableGuid system configuration table.

  It's not supported that PreviousTable is not NULL but PreviousTable->Signature
  is not same with Signature, NULL will be returned.

  @param Signature          ACPI table signature.
  @param PreviousTable      Pointer to previous returned table to locate next
                            table, or NULL to locate first table.

  @return Next ACPI table or NULL if not found.

**/
EFI_ACPI_COMMON_HEADER *
EFIAPI
EfiLocateNextAcpiTable (
  IN UINT32                  Signature,
  IN EFI_ACPI_COMMON_HEADER  *PreviousTable OPTIONAL
  )
{
  EFI_ACPI_COMMON_HEADER  *Table;
  BOOLEAN                 TempPreviousTableLocated;
  BOOLEAN                 *PreviousTableLocated;

  if (PreviousTable != NULL) {
    if (PreviousTable->Signature != Signature) {
      //
      // PreviousTable->Signature is not same with Signature.
      //
      return NULL;
    } else if ((Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) ||
               (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||
               (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE))
    {
      //
      // There is only one FADT/DSDT/FACS table,
      // so don't try to locate next one.
      //
      return NULL;
    }

    PreviousTableLocated  = &TempPreviousTableLocated;
    *PreviousTableLocated = FALSE;
  } else {
    PreviousTableLocated = NULL;
  }

  Table = LocateAcpiTableInAcpiConfigurationTable (
            &gEfiAcpi20TableGuid,
            Signature,
            PreviousTable,
            PreviousTableLocated
            );
  if (Table != NULL) {
    return Table;
  } else if ((PreviousTableLocated != NULL) &&
             *PreviousTableLocated)
  {
    //
    // PreviousTable could be located in gEfiAcpi20TableGuid system
    // configuration table, but next table could not be located in
    // gEfiAcpi20TableGuid system configuration table.
    //
    return NULL;
  }

  return LocateAcpiTableInAcpiConfigurationTable (
           &gEfiAcpi10TableGuid,
           Signature,
           PreviousTable,
           PreviousTableLocated
           );
}

/**
  This function locates first ACPI table in XSDT/RSDT based on Signature.

  This function will locate the first ACPI table in XSDT/RSDT based on
  Signature in gEfiAcpi20TableGuid system configuration table first, and then
  gEfiAcpi10TableGuid system configuration table.
  This function will locate in XSDT first, and then RSDT.
  For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in
  FADT.
  For FACS, this function will locate XFirmwareCtrl in FADT first, and then
  FirmwareCtrl in FADT.

  @param Signature          ACPI table signature.

  @return First ACPI table or NULL if not found.

**/
EFI_ACPI_COMMON_HEADER *
EFIAPI
EfiLocateFirstAcpiTable (
  IN UINT32  Signature
  )
{
  return EfiLocateNextAcpiTable (Signature, NULL);
}
