EmbeddedPkg: Introduced AcpiLib

AcpiLib is a library to help working with ACPI Tables.

In this initial implementation, the library provides:
- a helper function to locate and install the ACPI Tables within
  a Firmware Volume
- Some helper macros to initialize some ACPI structures

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Graeme Gregory <graeme.gregory@linaro.org>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16650 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index b13693c..a3a136d 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -98,6 +98,7 @@
 

   EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf

 

+  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf

   FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf

 

   # Networking Requirements

diff --git a/EmbeddedPkg/Include/Library/AcpiLib.h b/EmbeddedPkg/Include/Library/AcpiLib.h
new file mode 100644
index 0000000..3eaa1d5
--- /dev/null
+++ b/EmbeddedPkg/Include/Library/AcpiLib.h
@@ -0,0 +1,62 @@
+/** @file

+  Helper Library for ACPI

+

+  Copyright (c) 2014, ARM Ltd. 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.

+

+**/

+

+#ifndef __ACPI_LIB_H__

+#define __ACPI_LIB_H__

+

+#include <Uefi.h>

+

+//

+// Macros for the Generic Address Space

+//

+#define NULL_GAS               { EFI_ACPI_5_0_SYSTEM_MEMORY,  0, 0, EFI_ACPI_5_0_UNDEFINED, 0L }

+#define ARM_GAS8(Address)      { EFI_ACPI_5_0_SYSTEM_MEMORY,  8, 0, EFI_ACPI_5_0_BYTE,      Address }

+#define ARM_GAS16(Address)     { EFI_ACPI_5_0_SYSTEM_MEMORY, 16, 0, EFI_ACPI_5_0_WORD,      Address }

+#define ARM_GAS32(Address)     { EFI_ACPI_5_0_SYSTEM_MEMORY, 32, 0, EFI_ACPI_5_0_DWORD,     Address }

+#define ARM_GASN(Address)      { EFI_ACPI_5_0_SYSTEM_MEMORY,  0, 0, EFI_ACPI_5_0_DWORD,     Address }

+

+//

+// Macros for the Multiple APIC Description Table (MADT)

+//

+#define EFI_ACPI_5_0_GIC_DISTRIBUTOR_INIT(GicDistHwId, GicDistBase, GicDistVector) \

+  { \

+    EFI_ACPI_5_0_GICD, sizeof (EFI_ACPI_5_0_GIC_DISTRIBUTOR_STRUCTURE), EFI_ACPI_RESERVED_WORD, \

+    GicDistHwId, GicDistBase, GicDistVector, EFI_ACPI_RESERVED_DWORD \

+  }

+

+// Note the parking protocol is configured by UEFI if required

+#define EFI_ACPI_5_0_GIC_STRUCTURE_INIT(GicId, AcpiCpuId, Flags, PmuIrq, GicBase) \

+  { \

+    EFI_ACPI_5_0_GIC, sizeof (EFI_ACPI_5_0_GIC_STRUCTURE), EFI_ACPI_RESERVED_WORD, \

+    GicId, AcpiCpuId, Flags, 0, PmuIrq, 0, GicBase \

+  }

+

+

+/**

+  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

+  );

+

+#endif // __ACPI_LIB_H__

diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
new file mode 100644
index 0000000..4090055
--- /dev/null
+++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
@@ -0,0 +1,146 @@
+/** @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;

+}

diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
new file mode 100644
index 0000000..5080c50
--- /dev/null
+++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
@@ -0,0 +1,36 @@
+#/** @file

+#

+#  Copyright (c) 2014, ARM Ltd. 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.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = AcpiLib

+  FILE_GUID                      = 24b9d62c-5a36-417b-94b6-38dbaea90dcf

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = AcpiLib

+

+[Sources.common]

+  AcpiLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+

+[LibraryClasses]

+  DebugLib

+  UefiBootServicesTableLib

+

+[Protocols]

+  gEfiAcpiTableProtocolGuid

+  gEfiFirmwareVolume2ProtocolGuid