https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			423 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			423 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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);
 | 
						|
}
 |