]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add ACPI drivers:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 20 Mar 2009 20:58:47 +0000 (20:58 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 20 Mar 2009 20:58:47 +0000 (20:58 +0000)
* Universal/Acpi/AcpiTableDxe
  Implementation of EFI_ACPI_TABLE_PROTOCOL
  (MdePkg/Include/Protocol/AcpiTable.h)
* Universal/Acpi/AcpiPlatformDxe
  Sample "ACPI Platform Driver" which populates the
  system ACPI tables by reading them from an
  FFS file and using EFI_ACPI_TABLE_PROTOCOL
  to make them available to the system.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7917 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatform.c [new file with mode: 0755]
MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf [new file with mode: 0755]
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.c [new file with mode: 0755]
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h [new file with mode: 0755]
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf [new file with mode: 0755]
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c [new file with mode: 0755]

index 9fab0b92b8763f9c301f7cb3f9ea3687c52b6cdb..98dbf0f2e0dcac42eb2c3618e7544be292390a71 100644 (file)
   MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf\r
   MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf\r
 \r
+  MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf\r
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf\r
+\r
 [Components.IA32, Components.X64]\r
   MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf\r
   MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
diff --git a/MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatform.c b/MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatform.c
new file mode 100755 (executable)
index 0000000..f7d7485
--- /dev/null
@@ -0,0 +1,254 @@
+/** @file\r
+  Sample ACPI Platform Driver\r
+\r
+  Copyright (c) 2008 - 2009, Intel Corporation<BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/ \r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/AcpiTable.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+/**\r
+  Locate the first instance of a protocol.  If the protocol requested is an\r
+  FV protocol, then it will return the first FV that contains the ACPI table\r
+  storage file.\r
+\r
+  @param  Protocol      The protocol to find.\r
+  @param  Instance      Return pointer to the first instance of the protocol\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateFvInstanceWithTables (\r
+  OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  EFI_FV_FILETYPE               FileType;\r
+  UINT32                        FvStatus;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINTN                         Size;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
+\r
+  FvStatus = 0;\r
+\r
+  //\r
+  // Locate protocol.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Defined errors at this time are not found and out of resources.\r
+    //\r
+    return Status;\r
+  }\r
+\r
+\r
+\r
+  //\r
+  // Looking for FV with ACPI storage file\r
+  //\r
+\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // See if it has the ACPI storage file\r
+    //\r
+    Status = FvInstance->ReadFile (\r
+                           FvInstance,\r
+                           FixedPcdGetPtr (PcdAcpiTableStorageFile),\r
+                           NULL,\r
+                           &Size,\r
+                           &FileType,\r
+                           &Attributes,\r
+                           &FvStatus\r
+                           );\r
+\r
+    //\r
+    // If we found it, then we are done\r
+    //\r
+    if (Status == EFI_SUCCESS) {\r
+      *Instance = FvInstance;\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Our exit status is determined by the success of the previous operations\r
+  // If the protocol was found, Instance already points to it.\r
+  //\r
+\r
+  //\r
+  // Free any allocated buffers\r
+  //\r
+  gBS->FreePool (HandleBuffer);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  This function calculates and updates an UINT8 checksum.\r
+\r
+  @param  Buffer          Pointer to buffer to checksum\r
+  @param  Size            Number of bytes to checksum\r
+\r
+**/\r
+VOID\r
+AcpiPlatformChecksum (\r
+  IN UINT8      *Buffer,\r
+  IN UINTN      Size\r
+  )\r
+{\r
+  UINTN ChecksumOffset;\r
+\r
+  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
+\r
+  //\r
+  // Set checksum to 0 first\r
+  //\r
+  Buffer[ChecksumOffset] = 0;\r
+\r
+  //\r
+  // Update checksum value\r
+  //\r
+  Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);\r
+}\r
+\r
+\r
+/**\r
+  Entrypoint of Acpi Platform driver.\r
+\r
+  @param  ImageHandle\r
+  @param  SystemTable\r
+\r
+  @return EFI_SUCCESS\r
+  @return EFI_LOAD_ERROR\r
+  @return EFI_OUT_OF_RESOURCES\r
+\r
+**/\r
+EFI_STATUS\r
+AcpiPlatformEntryPoint (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *FwVol;\r
+  INTN                           Instance;\r
+  EFI_ACPI_COMMON_HEADER         *CurrentTable;\r
+  UINTN                          TableHandle;\r
+  UINT32                         FvStatus;\r
+  UINTN                          TableSize;\r
+  UINTN                          Size;\r
+\r
+  Instance     = 0;\r
+  CurrentTable = NULL;\r
+  TableHandle  = 0;\r
+\r
+  //\r
+  // Find the AcpiTable protocol\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Locate the firmware volume protocol\r
+  //\r
+  Status = LocateFvInstanceWithTables (&FwVol);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Read tables from the storage file.\r
+  //\r
+  while (Status == EFI_SUCCESS) {\r
+\r
+    Status = FwVol->ReadSection (\r
+                      FwVol,\r
+                      FixedPcdGetPtr (PcdAcpiTableStorageFile),\r
+                      EFI_SECTION_RAW,\r
+                      Instance,\r
+                      (VOID**) &CurrentTable,\r
+                      &Size,\r
+                      &FvStatus\r
+                      );\r
+    if (!EFI_ERROR(Status)) {\r
+      //\r
+      // Add the table\r
+      //\r
+      TableHandle = 0;\r
+\r
+      TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;\r
+      ASSERT (Size >= TableSize);\r
+\r
+      //\r
+      // Checksum ACPI table\r
+      //\r
+      AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);\r
+\r
+      //\r
+      // Install ACPI table\r
+      //\r
+      Status = AcpiTable->InstallAcpiTable (\r
+                            AcpiTable,\r
+                            CurrentTable,\r
+                            TableSize,\r
+                            &TableHandle\r
+                            );\r
+      if (EFI_ERROR(Status)) {\r
+        return EFI_ABORTED;\r
+      }\r
+\r
+      //\r
+      // Increment the instance\r
+      //\r
+      Instance++;\r
+      CurrentTable = NULL;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
new file mode 100755 (executable)
index 0000000..14b9e10
--- /dev/null
@@ -0,0 +1,55 @@
+#/** @file\r
+#  Sample ACPI Platform Driver\r
+#\r
+#  Copyright (c) 2008 - 2009, Intel Corporation. <BR>\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = AcpiPlatform\r
+  FILE_GUID                      = cb933912-df8f-4305-b1f9-7b44fa11395c\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+  ENTRY_POINT                    = AcpiPlatformEntryPoint\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  AcpiPlatform.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiLib\r
+  DxeServicesLib\r
+  PcdLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+\r
+[Protocols]\r
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[FixedPcd.common]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile\r
+\r
+[Depex]\r
+  gEfiAcpiTableProtocolGuid\r
+\r
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.c
new file mode 100755 (executable)
index 0000000..773c0f7
--- /dev/null
@@ -0,0 +1,77 @@
+/** @file\r
+  ACPI Table Protocol Driver\r
+\r
+  Copyright (c) 2006, 2008, 2009, Intel Corporation<BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+//\r
+// Includes\r
+//\r
+#include "AcpiTable.h"\r
+\r
+//\r
+// Handle to install ACPI Table Protocol\r
+//\r
+EFI_HANDLE    mHandle = NULL;\r
+\r
+/**\r
+  Entry point of the ACPI table driver.\r
+  Creates and initializes an instance of the ACPI Table\r
+  Protocol and installs it on a new handle.\r
+\r
+  @param  ImageHandle   A handle for the image that is initializing this driver.\r
+  @param  SystemTable   A pointer to the EFI system table.\r
+\r
+  @return EFI_SUCCESS           Driver initialized successfully.\r
+  @return EFI_LOAD_ERROR        Failed to Initialize or has been loaded.\r
+  @return EFI_OUT_OF_RESOURCES  Could not allocate needed resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeAcpiTableDxe (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_ACPI_TABLE_INSTANCE   *PrivateData;\r
+\r
+  //\r
+  // Initialize our protocol\r
+  //\r
+  PrivateData = AllocateZeroPool (sizeof (EFI_ACPI_TABLE_INSTANCE));\r
+  ASSERT (PrivateData);\r
+  PrivateData->Signature = EFI_ACPI_TABLE_SIGNATURE;\r
+\r
+  //\r
+  // Call all constructors per produced protocols\r
+  //\r
+  Status = AcpiTableAcpiTableConstructor (PrivateData);\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (PrivateData);\r
+    return EFI_LOAD_ERROR;\r
+  }\r
+\r
+  //\r
+  // Install ACPI Table protocol\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &mHandle,\r
+                  &gEfiAcpiTableProtocolGuid,\r
+                  &PrivateData->AcpiTableProtocol,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
new file mode 100755 (executable)
index 0000000..3c40709
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+  ACPI Table Protocol Driver\r
+\r
+  Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ACPI_TABLE_H_\r
+#define _ACPI_TABLE_H_\r
+\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/AcpiTable.h>\r
+#include <Guid/Acpi.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+//\r
+// Statements that include other files\r
+//\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+//\r
+// From Protocol/AcpiSupport.h\r
+//\r
+\r
+//\r
+// ACPI Version bitmap definition:\r
+//\r
+// EFI_ACPI_TABLE_VERSION_1_0B - ACPI Version 1.0b\r
+// EFI_ACPI_TABLE_VERSION_2_0 - ACPI Version 2.0\r
+// EFI_ACPI_TABLE_VERSION_3_0 - ACPI Version 3.0\r
+// EFI_ACPI_TABLE_VERSION_NONE - No ACPI Versions.  This might be used\r
+//  to create memory-based operation regions or other information\r
+//  that is not part of the ACPI "tree" but must still be found\r
+//  in ACPI memory space and/or managed by the core ACPI driver.\r
+//\r
+// Note that EFI provides discrete GUIDs for each version of ACPI\r
+// that is supported.  It is expected that each EFI GUIDed\r
+// version of ACPI will also have a corresponding bitmap\r
+// definition.  This allows maintenance of separate ACPI trees\r
+// for each distinctly different version of ACPI.\r
+//\r
+#define EFI_ACPI_TABLE_VERSION      UINT32\r
+\r
+#define EFI_ACPI_TABLE_VERSION_NONE (1 << 0)\r
+#define EFI_ACPI_TABLE_VERSION_1_0B (1 << 1)\r
+#define EFI_ACPI_TABLE_VERSION_2_0  (1 << 2)\r
+#define EFI_ACPI_TABLE_VERSION_3_0  (1 << 3)\r
+\r
+//\r
+// Private Driver Data\r
+//\r
+//\r
+// ACPI Table Linked List Signature.\r
+//\r
+#define EFI_ACPI_TABLE_LIST_SIGNATURE SIGNATURE_32 ('E', 'A', 'T', 'L')\r
+\r
+//\r
+// ACPI Table Linked List Entry definition.\r
+//\r
+//  Signature must be set to EFI_ACPI_TABLE_LIST_SIGNATURE\r
+//  Link is the linked list data.\r
+//  Version is the versions of the ACPI tables that this table belongs in.\r
+//  Table is a pointer to the table.\r
+//  PageAddress is the address of the pages allocated for the table.\r
+//  NumberOfPages is the number of pages allocated at PageAddress.\r
+//  Handle is used to identify a particular table.\r
+//\r
+typedef struct {\r
+  UINT32                  Signature;\r
+  LIST_ENTRY              Link;\r
+  EFI_ACPI_TABLE_VERSION  Version;\r
+  EFI_ACPI_COMMON_HEADER  *Table;\r
+  EFI_PHYSICAL_ADDRESS    PageAddress;\r
+  UINTN                   NumberOfPages;\r
+  UINTN                   Handle;\r
+} EFI_ACPI_TABLE_LIST;\r
+\r
+//\r
+// Containment record for linked list.\r
+//\r
+#define EFI_ACPI_TABLE_LIST_FROM_LINK(_link)  CR (_link, EFI_ACPI_TABLE_LIST, Link, EFI_ACPI_TABLE_LIST_SIGNATURE)\r
+\r
+//\r
+// The maximum number of tables this driver supports\r
+//\r
+#define EFI_ACPI_MAX_NUM_TABLES 20\r
+\r
+//\r
+// ACPI table information used to initialize tables.\r
+//\r
+#define EFI_ACPI_OEM_ID           "INTEL "\r
+#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('E', 'D', 'K', '2', ' ', ' ', ' ', ' ')\r
+#define EFI_ACPI_OEM_REVISION     0x00000002\r
+#define EFI_ACPI_CREATOR_ID       0x20202020\r
+#define EFI_ACPI_CREATOR_REVISION 0x01000013\r
+\r
+//\r
+// Protocol private structure definition\r
+//\r
+//\r
+// ACPI support protocol instance signature definition.\r
+//\r
+#define EFI_ACPI_TABLE_SIGNATURE  SIGNATURE_32 ('S', 'T', 'A', 'E')\r
+\r
+//\r
+// ACPI support protocol instance data structure\r
+//\r
+typedef struct {\r
+  UINTN                                         Signature;\r
+  EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp1;                 // Pointer to RSD_PTR structure\r
+  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp3;                 // Pointer to RSD_PTR structure\r
+  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt1;                 // Pointer to RSDT table header\r
+  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt3;                 // Pointer to RSDT table header\r
+  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt;                  // Pointer to XSDT table header\r
+  EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE     *Fadt1;                 // Pointer to FADT table header\r
+  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE     *Fadt3;                 // Pointer to FADT table header\r
+  EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs1;                 // Pointer to FACS table header\r
+  EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs3;                 // Pointer to FACS table header\r
+  EFI_ACPI_DESCRIPTION_HEADER                   *Dsdt1;                 // Pointer to DSDT table header\r
+  EFI_ACPI_DESCRIPTION_HEADER                   *Dsdt3;                 // Pointer to DSDT table header\r
+  LIST_ENTRY                                TableList;\r
+  UINTN                                         NumberOfTableEntries1;  // Number of ACPI 1.0 tables\r
+  UINTN                                         NumberOfTableEntries3;  // Number of ACPI 3.0 tables\r
+  UINTN                                         CurrentHandle;\r
+  BOOLEAN                                       TablesInstalled1;       // ACPI 1.0 tables published\r
+  BOOLEAN                                       TablesInstalled3;       // ACPI 3.0 tables published\r
+  EFI_ACPI_TABLE_PROTOCOL                       AcpiTableProtocol;\r
+} EFI_ACPI_TABLE_INSTANCE;\r
+\r
+//\r
+// ACPI table protocol instance containing record macro\r
+//\r
+#define EFI_ACPI_TABLE_INSTANCE_FROM_THIS(a) \\r
+  CR (a, \\r
+      EFI_ACPI_TABLE_INSTANCE, \\r
+      AcpiTableProtocol, \\r
+      EFI_ACPI_TABLE_SIGNATURE \\r
+      )\r
+\r
+//\r
+// Protocol Constructor functions\r
+//\r
+\r
+/**\r
+  Constructor for the ACPI support protocol.  Initializes instance\r
+  data.\r
+\r
+  @param  AcpiTableInstance       Instance to construct\r
+\r
+  @return EFI_SUCCESS             Instance initialized.\r
+  @return EFI_OUT_OF_RESOURCES    Unable to allocate required resources.\r
+\r
+**/\r
+EFI_STATUS\r
+AcpiTableAcpiTableConstructor (\r
+  EFI_ACPI_TABLE_INSTANCE                 *AcpiTableInstance\r
+  );\r
+\r
+\r
+/**\r
+  Entry point of the ACPI table driver.\r
+  Creates and initializes an instance of the ACPI Table \r
+  Protocol and installs it on a new handle.\r
+\r
+  @param  ImageHandle   A handle for the image that is initializing this driver\r
+  @param  SystemTable   A pointer to the EFI system table\r
+\r
+  @return EFI_SUCCESS           Driver initialized successfully\r
+  @return EFI_LOAD_ERROR        Failed to Initialize or has been loaded \r
+  @return EFI_OUT_OF_RESOURCES  Could not allocate needed resources\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeAcpiTableDxe (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
new file mode 100755 (executable)
index 0000000..4eb4b57
--- /dev/null
@@ -0,0 +1,60 @@
+#/** @file\r
+#  ACPI Table Protocol Driver\r
+#\r
+#  Copyright (c) 2006, 2008, 2009 Intel Corporation<BR> All rights\r
+#  reserved. This program and the accompanying materials are\r
+#  licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = AcpiTableDxe\r
+  FILE_GUID                      = 506533a6-e626-4500-b14f-17939c0e5b60\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = InitializeAcpiTableDxe\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  AcpiTableProtocol.c\r
+  AcpiTable.h\r
+  AcpiTable.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  UefiDriverEntryPoint\r
+  BaseMemoryLib\r
+  UefiLib\r
+  DebugLib\r
+  BaseLib\r
+  PcdLib\r
+\r
+[Guids]\r
+  gEfiAcpi10TableGuid                           # ALWAYS_CONSUMED\r
+  gEfiAcpiTableGuid\r
+\r
+[Protocols]\r
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_PRODUCED\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
new file mode 100755 (executable)
index 0000000..febfde1
--- /dev/null
@@ -0,0 +1,1703 @@
+/** @file\r
+  ACPI Table Protocol Implementation\r
+\r
+  Copyright (c) 2006, 2008, 2009, Intel Corporation<BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+//\r
+// Includes\r
+//\r
+#include "AcpiTable.h"\r
+\r
+\r
+/**\r
+  This function adds an ACPI table to the table list.  It will detect FACS and\r
+  allocate the correct type of memory and properly align the table.\r
+\r
+  @param  AcpiTableInstance         Instance of the protocol.\r
+  @param  Table                     Table to add.\r
+  @param  Checksum                  Does the table require checksumming.\r
+  @param  Version                   The version of the list to add the table to.\r
+  @param  Handle                    Pointer for returning the handle.\r
+\r
+  @return EFI_SUCCESS               The function completed successfully.\r
+  @return EFI_OUT_OF_RESOURCES      Could not allocate a required resource.\r
+  @return EFI_ABORTED               The table is a duplicate of a table that is required\r
+                                    to be unique.\r
+\r
+**/\r
+EFI_STATUS\r
+AddTableToList (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN VOID                                 *Table,\r
+  IN BOOLEAN                              Checksum,\r
+  IN EFI_ACPI_TABLE_VERSION               Version,\r
+  OUT UINTN                               *Handle\r
+  );\r
+\r
+/**\r
+  This function finds and removes the table specified by the handle.\r
+\r
+  @param  AcpiTableInstance  Instance of the protocol.\r
+  @param  Version            Bitmask of which versions to remove.\r
+  @param  Handle             Table to remove.\r
+\r
+  @return EFI_SUCCESS    The function completed successfully.\r
+  @return EFI_ABORTED    An error occurred.\r
+  @return EFI_NOT_FOUND  Handle not found in table list.\r
+\r
+**/\r
+EFI_STATUS\r
+RemoveTableFromList (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN EFI_ACPI_TABLE_VERSION               Version,\r
+  IN UINTN                                Handle\r
+  );\r
+\r
+/**\r
+  This function calculates and updates an UINT8 checksum.\r
+\r
+  @param  Buffer          Pointer to buffer to checksum\r
+  @param  Size            Number of bytes to checksum\r
+  @param  ChecksumOffset  Offset to place the checksum result in\r
+\r
+  @return EFI_SUCCESS             The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+AcpiPlatformChecksum (\r
+  IN VOID       *Buffer,\r
+  IN UINTN      Size,\r
+  IN UINTN      ChecksumOffset\r
+  );\r
+\r
+/**\r
+  Checksum all versions of the common tables, RSDP, RSDT, XSDT.\r
+\r
+  @param  AcpiTableInstance  Protocol instance private data.\r
+\r
+  @return EFI_SUCCESS        The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+ChecksumCommonTables (\r
+  IN OUT EFI_ACPI_TABLE_INSTANCE          *AcpiTableInstance\r
+  );\r
+\r
+//\r
+// Protocol function implementations.\r
+//\r
+\r
+/**\r
+  This function adds, removes, or updates ACPI tables.  If the address is not\r
+  null and the handle value is null, the table is added.  If both the address and \r
+  handle are not null, the table at handle is updated with the table at address.\r
+  If the address is null and the handle is not, the table at handle is deleted.\r
+\r
+  @param  AcpiTableInstance  Instance of the protocol.\r
+  @param  Table              Pointer to a table.\r
+  @param  Checksum           Boolean indicating if the checksum should be calculated.\r
+  @param  Version            Version(s) to set.\r
+  @param  Handle             Handle of the table.\r
+\r
+  @return EFI_SUCCESS             The function completed successfully.\r
+  @return EFI_INVALID_PARAMETER   Both the Table and *Handle were NULL.\r
+  @return EFI_ABORTED             Could not complete the desired request.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetAcpiTable (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN VOID                                 *Table OPTIONAL,\r
+  IN BOOLEAN                              Checksum,\r
+  IN EFI_ACPI_TABLE_VERSION               Version,\r
+  IN OUT UINTN                            *Handle\r
+  )\r
+{\r
+  UINTN                     SavedHandle;\r
+  EFI_STATUS                Status;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (Handle);\r
+\r
+  //\r
+  // Initialize locals\r
+  //\r
+  //\r
+  // Determine desired action\r
+  //\r
+  if (*Handle == 0) {\r
+    if (Table == NULL) {\r
+      //\r
+      // Invalid parameter combination\r
+      //\r
+      return EFI_INVALID_PARAMETER;\r
+    } else {\r
+      //\r
+      // Add table\r
+      //\r
+      Status = AddTableToList (AcpiTableInstance, Table, Checksum, Version, Handle);\r
+    }\r
+  } else {\r
+    if (Table != NULL) {\r
+      //\r
+      // Update table\r
+      //\r
+      //\r
+      // Delete the table list entry\r
+      //\r
+      Status = RemoveTableFromList (AcpiTableInstance, Version, *Handle);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Should not get an error here ever, but abort if we do.\r
+        //\r
+        return EFI_ABORTED;\r
+      }\r
+      //\r
+      // Set the handle to replace the table at the same handle\r
+      //\r
+      SavedHandle                         = AcpiTableInstance->CurrentHandle;\r
+      AcpiTableInstance->CurrentHandle  = *Handle;\r
+\r
+      //\r
+      // Add the table\r
+      //\r
+      Status = AddTableToList (AcpiTableInstance, Table, Checksum, Version, Handle);\r
+\r
+      //\r
+      // Restore the saved current handle\r
+      //\r
+      AcpiTableInstance->CurrentHandle = SavedHandle;\r
+    } else {\r
+      //\r
+      // Delete table\r
+      //\r
+      Status = RemoveTableFromList (AcpiTableInstance, Version, *Handle);\r
+    }\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Should not get an error here ever, but abort if we do.\r
+    //\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function publishes the specified versions of the ACPI tables by\r
+  installing EFI configuration table entries for them.  Any combination of\r
+  table versions can be published.\r
+\r
+  @param  AcpiTableInstance  Instance of the protocol.\r
+  @param  Version            Version(s) to publish.\r
+\r
+  @return EFI_SUCCESS  The function completed successfully.\r
+  @return EFI_ABORTED  The function could not complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PublishTables (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN EFI_ACPI_TABLE_VERSION               Version\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINT32                    *CurrentRsdtEntry;\r
+  VOID                      *CurrentXsdtEntry;\r
+  UINT64                    Buffer64;\r
+\r
+  //\r
+  // Reorder tables as some operating systems don't seem to find the\r
+  // FADT correctly if it is not in the first few entries\r
+  //\r
+\r
+  //\r
+  // Add FADT as the first entry\r
+  //\r
+  if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+    CurrentRsdtEntry  = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
+    *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt1;\r
+  }\r
+  if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+      (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+    CurrentRsdtEntry  = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt3 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
+    *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt3;\r
+    CurrentXsdtEntry  = (VOID *) ((UINT8 *) AcpiTableInstance->Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
+    //\r
+    // Add entry to XSDT, XSDT expects 64 bit pointers, but\r
+    // the table pointers in XSDT are not aligned on 8 byte boundary.\r
+    //\r
+    Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Fadt3;\r
+    CopyMem (\r
+      CurrentXsdtEntry,\r
+      &Buffer64,\r
+      sizeof (UINT64)\r
+      );\r
+  }\r
+\r
+  //\r
+  // Do checksum again because Dsdt/Xsdt is updated.\r
+  //\r
+  ChecksumCommonTables (AcpiTableInstance);\r
+\r
+  //\r
+  // Add the RSD_PTR to the system table and store that we have installed the\r
+  // tables.\r
+  //\r
+  if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) &&\r
+      !AcpiTableInstance->TablesInstalled1) {\r
+    Status = gBS->InstallConfigurationTable (&gEfiAcpi10TableGuid, AcpiTableInstance->Rsdp1);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_ABORTED;\r
+    }\r
+\r
+    AcpiTableInstance->TablesInstalled1 = TRUE;\r
+  }\r
+\r
+  if (((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+       (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) &&\r
+      !AcpiTableInstance->TablesInstalled3) {\r
+    Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, AcpiTableInstance->Rsdp3);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_ABORTED;\r
+    }\r
+\r
+    AcpiTableInstance->TablesInstalled3= TRUE;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Installs an ACPI table into the RSDT/XSDT.\r
+\r
+  @param  This                 Protocol instance pointer.\r
+  @param  AcpiTableBuffer      A pointer to a buffer containing the ACPI table to be installed.\r
+  @param  AcpiTableBufferSize  Specifies the size, in bytes, of the AcpiTableBuffer buffer.\r
+  @param  TableKey             Reurns a key to refer to the ACPI table.\r
+\r
+  @return EFI_SUCCESS            The table was successfully inserted.\r
+  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize \r
+                                 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer\r
+                                 are not in sync.\r
+  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InstallAcpiTable (\r
+  IN CONST EFI_ACPI_TABLE_PROTOCOL                    *This,\r
+  IN CONST VOID                                       *AcpiTableBuffer,\r
+  IN       UINTN                                      AcpiTableBufferSize,\r
+  OUT      UINTN                                      *TableKey\r
+  )\r
+{\r
+  EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;\r
+  EFI_STATUS                Status;\r
+  VOID                      *AcpiTableBufferConst;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  if ((AcpiTableBuffer == NULL) || (TableKey == NULL)\r
+     || (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTableBuffer)->Length != AcpiTableBufferSize)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Get the instance of the ACPI table protocol\r
+  //\r
+  AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);\r
+\r
+  //\r
+  // Install the ACPI table\r
+  //\r
+  AcpiTableBufferConst = AllocateCopyPool (AcpiTableBufferSize,AcpiTableBuffer);\r
+  *TableKey = 0;\r
+  Status = SetAcpiTable (\r
+             AcpiTableInstance,\r
+             AcpiTableBufferConst,\r
+             FALSE,\r
+             EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0,\r
+             TableKey\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = PublishTables (\r
+               AcpiTableInstance,\r
+               EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0\r
+               );\r
+  }\r
+  FreePool (AcpiTableBufferConst);\r
+  \r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Removes an ACPI table from the RSDT/XSDT.\r
+\r
+  @param  This      Protocol instance pointer.\r
+  @param  TableKey  Specifies the table to uninstall.  The key was returned from InstallAcpiTable().\r
+\r
+  @return EFI_SUCCESS    The table was successfully uninstalled.\r
+  @return EFI_NOT_FOUND  TableKey does not refer to a valid key for a table entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UninstallAcpiTable (\r
+  IN CONST EFI_ACPI_TABLE_PROTOCOL                    *This,\r
+  IN UINTN                                            TableKey\r
+  )\r
+{\r
+  EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;\r
+  EFI_STATUS                Status;\r
+\r
+  //\r
+  // Get the instance of the ACPI table protocol\r
+  //\r
+  AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);\r
+\r
+  //\r
+  // Uninstall the ACPI table\r
+  //\r
+  Status = SetAcpiTable (\r
+             AcpiTableInstance,\r
+             NULL,\r
+             FALSE,\r
+             EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0,\r
+             &TableKey\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = PublishTables (\r
+               AcpiTableInstance,\r
+               EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0\r
+               );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  This function adds an ACPI table to the table list.  It will detect FACS and\r
+  allocate the correct type of memory and properly align the table.\r
+\r
+  @param  AcpiTableInstance         Instance of the protocol.\r
+  @param  Table                     Table to add.\r
+  @param  Checksum                  Does the table require checksumming.\r
+  @param  Version                   The version of the list to add the table to.\r
+  @param  Handle                    Pointer for returning the handle.\r
+\r
+  @return EFI_SUCCESS               The function completed successfully.\r
+  @return EFI_OUT_OF_RESOURCES      Could not allocate a required resource.\r
+  @return EFI_ABORTED               The table is a duplicate of a table that is required\r
+                                    to be unique.\r
+\r
+**/\r
+EFI_STATUS\r
+AddTableToList (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN VOID                                 *Table,\r
+  IN BOOLEAN                              Checksum,\r
+  IN EFI_ACPI_TABLE_VERSION               Version,\r
+  OUT UINTN                               *Handle\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_ACPI_TABLE_LIST *CurrentTableList;\r
+  UINT32              CurrentTableSignature;\r
+  UINT32              CurrentTableSize;\r
+  UINT32              *CurrentRsdtEntry;\r
+  VOID                *CurrentXsdtEntry;\r
+  UINT64              Buffer64;\r
+  BOOLEAN             AddToRsdt;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (AcpiTableInstance);\r
+  ASSERT (Table);\r
+  ASSERT (Handle);\r
+\r
+  //\r
+  // Init locals\r
+  //\r
+  AddToRsdt = TRUE;\r
+\r
+  //\r
+  // Create a new list entry\r
+  //\r
+  CurrentTableList = AllocatePool (sizeof (EFI_ACPI_TABLE_LIST));\r
+  ASSERT (CurrentTableList);\r
+\r
+  //\r
+  // Determine table type and size\r
+  //\r
+  CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table)->Signature;\r
+  CurrentTableSize      = ((EFI_ACPI_COMMON_HEADER *) Table)->Length;\r
+\r
+  //\r
+  // Allocate a buffer for the table.  All tables are allocated in the lower 32 bits of address space\r
+  // for backwards compatibility with ACPI 1.0 OS.\r
+  //\r
+  // This is done because ACPI 1.0 pointers are 32 bit values.\r
+  // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.\r
+  // There is no architectural reason these should be below 4GB, it is purely\r
+  // for convenience of implementation that we force memory below 4GB.\r
+  //\r
+  CurrentTableList->PageAddress   = 0xFFFFFFFF;\r
+  CurrentTableList->NumberOfPages = EFI_SIZE_TO_PAGES (CurrentTableSize);\r
+\r
+  //\r
+  // Allocation memory type depends on the type of the table\r
+  //\r
+  if (CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE || \r
+      CurrentTableSignature == EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {\r
+    //\r
+    // Allocate memory for the FACS.  This structure must be aligned\r
+    // on a 64 byte boundary and must be ACPI NVS memory.\r
+    // Using AllocatePages should ensure that it is always aligned.\r
+    //\r
+    ASSERT ((EFI_PAGE_SIZE % 64) == 0);\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiACPIMemoryNVS,\r
+                    CurrentTableList->NumberOfPages,\r
+                    &CurrentTableList->PageAddress\r
+                    );\r
+  } else {\r
+    //\r
+    // All other tables are ACPI reclaim memory, no alignment requirements.\r
+    //\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiACPIReclaimMemory,\r
+                    CurrentTableList->NumberOfPages,\r
+                    &CurrentTableList->PageAddress\r
+                    );\r
+  }\r
+  //\r
+  // Check return value from memory alloc.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (CurrentTableList);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Update the table pointer with the allocated memory start\r
+  //\r
+  CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *) (UINTN) CurrentTableList->PageAddress;\r
+\r
+  //\r
+  // Initialize the table contents\r
+  //\r
+  CurrentTableList->Signature = EFI_ACPI_TABLE_LIST_SIGNATURE;\r
+  CopyMem (CurrentTableList->Table, Table, CurrentTableSize);\r
+  CurrentTableList->Handle  = AcpiTableInstance->CurrentHandle++;\r
+  *Handle                   = CurrentTableList->Handle;\r
+  CurrentTableList->Version = Version;\r
+\r
+  //\r
+  // Update internal pointers if this is a required table.  If it is a required\r
+  // table and a table of that type already exists, return an error.\r
+  //\r
+  // Calculate the checksum if the table is not FACS.\r
+  //\r
+  switch (CurrentTableSignature) {\r
+\r
+  case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
+    //\r
+    // We don't add the FADT in the standard way because some\r
+    // OS expect the FADT to be early in the table list.\r
+    // So we always add it as the first element in the list.\r
+    //\r
+    AddToRsdt = FALSE;\r
+\r
+    //\r
+    // Check that the table has not been previously added.\r
+    //\r
+    if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Fadt1 != NULL) ||\r
+        ((Version & EFI_ACPI_TABLE_VERSION_2_0)  != 0 && AcpiTableInstance->Fadt3 != NULL) ||\r
+        ((Version & EFI_ACPI_TABLE_VERSION_3_0)  != 0 && AcpiTableInstance->Fadt3 != NULL)\r
+        ) {\r
+      gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
+      gBS->FreePool (CurrentTableList);\r
+      return EFI_ABORTED;\r
+    }\r
+    //\r
+    // Add the table to the appropriate table version\r
+    //\r
+    if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+      //\r
+      // Save a pointer to the table\r
+      //\r
+      AcpiTableInstance->Fadt1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) CurrentTableList->Table;\r
+\r
+      //\r
+      // Update pointers in FADT.  If tables don't exist this will put NULL pointers there.\r
+      //\r
+      AcpiTableInstance->Fadt1->FirmwareCtrl  = (UINT32) (UINTN) AcpiTableInstance->Facs1;\r
+      AcpiTableInstance->Fadt1->Dsdt          = (UINT32) (UINTN) AcpiTableInstance->Dsdt1;\r
+\r
+      //\r
+      // RSDP OEM information is updated to match the FADT OEM information\r
+      //\r
+      CopyMem (\r
+        &AcpiTableInstance->Rsdp1->OemId,\r
+        &AcpiTableInstance->Fadt1->Header.OemId,\r
+        6\r
+        );\r
+\r
+      //\r
+      // RSDT OEM information is updated to match the FADT OEM information.\r
+      //\r
+      CopyMem (\r
+        &AcpiTableInstance->Rsdt1->OemId,\r
+        &AcpiTableInstance->Fadt1->Header.OemId,\r
+        6\r
+        );\r
+\r
+      CopyMem (\r
+        &AcpiTableInstance->Rsdt1->OemTableId,\r
+        &AcpiTableInstance->Fadt1->Header.OemTableId,\r
+        sizeof (UINT64)\r
+        );\r
+      AcpiTableInstance->Rsdt1->OemRevision = AcpiTableInstance->Fadt1->Header.OemRevision;\r
+    }\r
+\r
+    if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+        (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+      //\r
+      // Save a pointer to the table\r
+      //\r
+      AcpiTableInstance->Fadt3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) CurrentTableList->Table;\r
+\r
+      //\r
+      // Update pointers in FADT.  If tables don't exist this will put NULL pointers there.\r
+      //\r
+      if (AcpiTableInstance->Fadt3 != NULL) {\r
+        AcpiTableInstance->Fadt3->FirmwareCtrl  = (UINT32) (UINTN) AcpiTableInstance->Facs3;\r
+        Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;\r
+        CopyMem (\r
+          &AcpiTableInstance->Fadt3->XFirmwareCtrl,\r
+          &Buffer64,\r
+          sizeof (UINT64)\r
+          );\r
+        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
+        Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
+        CopyMem (\r
+          &AcpiTableInstance->Fadt3->XDsdt,\r
+          &Buffer64,\r
+          sizeof (UINT64)\r
+          );\r
+      }\r
+      //\r
+      // RSDP OEM information is updated to match the FADT OEM information\r
+      //\r
+      CopyMem (\r
+        &AcpiTableInstance->Rsdp3->OemId,\r
+        &AcpiTableInstance->Fadt3->Header.OemId,\r
+        6\r
+        );\r
+\r
+      //\r
+      // RSDT OEM information is updated to match FADT OEM information.\r
+      //\r
+      CopyMem (\r
+        &AcpiTableInstance->Rsdt3->OemId,\r
+        &AcpiTableInstance->Fadt3->Header.OemId,\r
+        6\r
+        );\r
+      CopyMem (\r
+        &AcpiTableInstance->Rsdt3->OemTableId,\r
+        &AcpiTableInstance->Fadt3->Header.OemTableId,\r
+        sizeof (UINT64)\r
+        );\r
+      AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
+\r
+      //\r
+      // XSDT OEM information is updated to match FADT OEM information.\r
+      //\r
+      CopyMem (\r
+        &AcpiTableInstance->Xsdt->OemId,\r
+        &AcpiTableInstance->Fadt3->Header.OemId,\r
+        6\r
+        );\r
+      CopyMem (\r
+        &AcpiTableInstance->Xsdt->OemTableId,\r
+        &AcpiTableInstance->Fadt3->Header.OemTableId,\r
+        sizeof (UINT64)\r
+        );\r
+      AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
+    }    \r
+    //\r
+    // Checksum the table\r
+    //\r
+    if (Checksum) {\r
+      AcpiPlatformChecksum (\r
+        CurrentTableList->Table,\r
+        CurrentTableList->Table->Length,\r
+        OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+        Checksum)\r
+        );\r
+    }\r
+    break;\r
+\r
+  case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
+    //\r
+    // Check that the table has not been previously added.\r
+    //\r
+    if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Facs1 != NULL) ||\r
+        ((Version & EFI_ACPI_TABLE_VERSION_2_0)  != 0 && AcpiTableInstance->Facs3 != NULL) ||\r
+        ((Version & EFI_ACPI_TABLE_VERSION_3_0)  != 0 && AcpiTableInstance->Facs3 != NULL)\r
+        ) {\r
+      gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
+      gBS->FreePool (CurrentTableList);\r
+      return EFI_ABORTED;\r
+    }\r
+    //\r
+    // FACS is referenced by FADT and is not part of RSDT\r
+    //\r
+    AddToRsdt = FALSE;\r
+\r
+    //\r
+    // Add the table to the appropriate table version\r
+    //\r
+    if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+      //\r
+      // Save a pointer to the table\r
+      //\r
+      AcpiTableInstance->Facs1 = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;\r
+\r
+      //\r
+      // If FADT already exists, update table pointers.\r
+      //\r
+      if (AcpiTableInstance->Fadt1 != NULL) {\r
+        AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs1;\r
+\r
+        //\r
+        // Checksum FADT table\r
+        //\r
+        AcpiPlatformChecksum (\r
+          AcpiTableInstance->Fadt1,\r
+          AcpiTableInstance->Fadt1->Header.Length,\r
+          OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+          Checksum)\r
+          );\r
+      }\r
+    }\r
+\r
+    if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+        (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+      //\r
+      // Save a pointer to the table\r
+      //\r
+      AcpiTableInstance->Facs3 = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;\r
+\r
+      //\r
+      // If FADT already exists, update table pointers.\r
+      //\r
+      if (AcpiTableInstance->Fadt3 != NULL) {\r
+        AcpiTableInstance->Fadt3->FirmwareCtrl  = (UINT32) (UINTN) AcpiTableInstance->Facs3;\r
+        Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;\r
+        CopyMem (\r
+          &AcpiTableInstance->Fadt3->XFirmwareCtrl,\r
+          &Buffer64,\r
+          sizeof (UINT64)\r
+          );\r
+\r
+        //\r
+        // Checksum FADT table\r
+        //\r
+        AcpiPlatformChecksum (\r
+          AcpiTableInstance->Fadt3,\r
+          AcpiTableInstance->Fadt3->Header.Length,\r
+          OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+          Checksum)\r
+          );\r
+      }\r
+    }\r
+\r
+    break;\r
+\r
+  case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
+    //\r
+    // Check that the table has not been previously added.\r
+    //\r
+    if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Dsdt1 != NULL) ||\r
+        ((Version & EFI_ACPI_TABLE_VERSION_2_0)  != 0 && AcpiTableInstance->Dsdt3 != NULL) ||\r
+        ((Version & EFI_ACPI_TABLE_VERSION_3_0)  != 0 && AcpiTableInstance->Dsdt3 != NULL)\r
+        ) {\r
+      gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
+      gBS->FreePool (CurrentTableList);\r
+      return EFI_ABORTED;\r
+    }\r
+    //\r
+    // DSDT is referenced by FADT and is not part of RSDT\r
+    //\r
+    AddToRsdt = FALSE;\r
+\r
+    //\r
+    // Add the table to the appropriate table version\r
+    //\r
+    if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+      //\r
+      // Save a pointer to the table\r
+      //\r
+      AcpiTableInstance->Dsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;\r
+\r
+      //\r
+      // If FADT already exists, update table pointers.\r
+      //\r
+      if (AcpiTableInstance->Fadt1 != NULL) {\r
+        AcpiTableInstance->Fadt1->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt1;\r
+\r
+        //\r
+        // Checksum FADT table\r
+        //\r
+        AcpiPlatformChecksum (\r
+          AcpiTableInstance->Fadt1,\r
+          AcpiTableInstance->Fadt1->Header.Length,\r
+          OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+          Checksum)\r
+          );\r
+      }\r
+    }\r
+    \r
+    if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+        (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+      //\r
+      // Save a pointer to the table\r
+      //\r
+      AcpiTableInstance->Dsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;\r
+\r
+      //\r
+      // If FADT already exists, update table pointers.\r
+      //\r
+      if (AcpiTableInstance->Fadt3 != NULL) {\r
+        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
+        Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
+        CopyMem (\r
+          &AcpiTableInstance->Fadt3->XDsdt,\r
+          &Buffer64,\r
+          sizeof (UINT64)\r
+          );\r
+\r
+        //\r
+        // Checksum FADT table\r
+        //\r
+        AcpiPlatformChecksum (\r
+          AcpiTableInstance->Fadt3,\r
+          AcpiTableInstance->Fadt3->Header.Length,\r
+          OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+          Checksum)\r
+          );\r
+      }\r
+    }        \r
+    //\r
+    // Checksum the table\r
+    //\r
+    if (Checksum) {\r
+      AcpiPlatformChecksum (\r
+        CurrentTableList->Table,\r
+        CurrentTableList->Table->Length,\r
+        OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+        Checksum)\r
+        );\r
+    }\r
+    break;\r
+\r
+  default:\r
+    //\r
+    // Checksum the table\r
+    //\r
+    if (Checksum) {\r
+      AcpiPlatformChecksum (\r
+        CurrentTableList->Table,\r
+        CurrentTableList->Table->Length,\r
+        OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+        Checksum)\r
+        );\r
+    }\r
+    break;\r
+  }\r
+  //\r
+  // Add the table to the current list of tables\r
+  //\r
+  InsertTailList (&AcpiTableInstance->TableList, &CurrentTableList->Link);\r
+\r
+  //\r
+  // Add the table to RSDT and/or XSDT table entry lists.\r
+  //\r
+  //\r
+  // Add to ACPI 1.0b table tree\r
+  //\r
+  if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+    CurrentRsdtEntry = (UINT32 *)\r
+      (\r
+        (UINT8 *) AcpiTableInstance->Rsdt1 +\r
+        sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+        AcpiTableInstance->NumberOfTableEntries1 *\r
+        sizeof (UINT32)\r
+      );\r
+\r
+    //\r
+    // Add entry to the RSDT unless its the FACS or DSDT\r
+    //\r
+    if (AddToRsdt) {\r
+      *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;\r
+\r
+      //\r
+      // Update RSDT length\r
+      //\r
+      AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);\r
+\r
+      AcpiTableInstance->NumberOfTableEntries1++;\r
+    }\r
+\r
+    ASSERT (AcpiTableInstance->NumberOfTableEntries1 <= EFI_ACPI_MAX_NUM_TABLES);\r
+  }\r
+  //\r
+  // Add to ACPI 2.0/3.0  table tree\r
+  //\r
+  if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+      (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+    if (AddToRsdt) {\r
+      //\r
+      // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
+      // If it becomes necessary to maintain separate table lists, changes will be required.\r
+      //\r
+      CurrentRsdtEntry = (UINT32 *)\r
+        (\r
+          (UINT8 *) AcpiTableInstance->Rsdt3 +\r
+          sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+          AcpiTableInstance->NumberOfTableEntries3 *\r
+          sizeof (UINT32)\r
+        );\r
+\r
+      //\r
+      // This pointer must not be directly dereferenced as the XSDT entries may not\r
+      // be 64 bit aligned resulting in a possible fault.  Use CopyMem to update.\r
+      //\r
+      CurrentXsdtEntry = (VOID *)\r
+        (\r
+          (UINT8 *) AcpiTableInstance->Xsdt +\r
+          sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+          AcpiTableInstance->NumberOfTableEntries3 *\r
+          sizeof (UINT64)\r
+        );\r
+\r
+      //\r
+      // Add entry to the RSDT\r
+      //\r
+      *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;\r
+\r
+      //\r
+      // Update RSDT length\r
+      //\r
+      AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);\r
+\r
+      //\r
+      // Add entry to XSDT, XSDT expects 64 bit pointers, but\r
+      // the table pointers in XSDT are not aligned on 8 byte boundary.\r
+      //\r
+      Buffer64 = (UINT64) (UINTN) CurrentTableList->Table;\r
+      CopyMem (\r
+        CurrentXsdtEntry,\r
+        &Buffer64,\r
+        sizeof (UINT64)\r
+        );\r
+\r
+      //\r
+      // Update length\r
+      //\r
+      AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);\r
+\r
+      AcpiTableInstance->NumberOfTableEntries3++;\r
+    }\r
+\r
+    ASSERT (AcpiTableInstance->NumberOfTableEntries3 <= EFI_ACPI_MAX_NUM_TABLES);\r
+  }\r
+\r
+  ChecksumCommonTables (AcpiTableInstance);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function finds the table specified by the handle and returns a pointer to it.\r
+  If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are\r
+  undefined.\r
+\r
+  @param  Handle      Table to find.\r
+  @param  TableList   Table list to search\r
+  @param  Table       Pointer to table found. \r
+\r
+  @return EFI_SUCCESS    The function completed successfully.\r
+  @return EFI_NOT_FOUND  No table found matching the handle specified.\r
+\r
+**/\r
+EFI_STATUS\r
+FindTableByHandle (\r
+  IN UINTN                                Handle,\r
+  IN LIST_ENTRY                       *TableList,\r
+  OUT EFI_ACPI_TABLE_LIST                 **Table\r
+  )\r
+{\r
+  LIST_ENTRY      *CurrentLink;\r
+  EFI_ACPI_TABLE_LIST *CurrentTable;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (Table);\r
+\r
+  //\r
+  // Find the table\r
+  //\r
+  CurrentLink = TableList->ForwardLink;\r
+\r
+  while (CurrentLink != TableList) {\r
+    CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);\r
+    if (CurrentTable->Handle == Handle) {\r
+      //\r
+      // Found handle, so return this table.\r
+      //\r
+      *Table = CurrentTable;\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    CurrentLink = CurrentLink->ForwardLink;\r
+  }\r
+  //\r
+  // Table not found\r
+  //\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+  This function removes a basic table from the RSDT and/or XSDT.\r
+  For Acpi 1.0 tables, pass in the Rsdt.\r
+  For Acpi 2.0 tables, pass in both Rsdt and Xsdt.\r
+\r
+  @param  Table                 Pointer to table found. \r
+  @param  NumberOfTableEntries  Current number of table entries in the RSDT/XSDT\r
+  @param  Rsdt                  Pointer to the RSDT to remove from\r
+  @param  Xsdt                  Pointer to the Xsdt to remove from\r
+\r
+  @return EFI_SUCCESS            The function completed successfully.\r
+  @return EFI_INVALID_PARAMETER  The table was not found in both Rsdt and Xsdt.\r
+\r
+**/\r
+EFI_STATUS\r
+RemoveTableFromRsdt (\r
+  IN OUT EFI_ACPI_TABLE_LIST              * Table,\r
+  IN OUT UINTN                            *NumberOfTableEntries,\r
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Rsdt,\r
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Xsdt OPTIONAL\r
+  )\r
+{\r
+  UINT32  *CurrentRsdtEntry;\r
+  VOID    *CurrentXsdtEntry;\r
+  UINT64  CurrentTablePointer64;\r
+  UINTN   Index;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (Table);\r
+  ASSERT (NumberOfTableEntries);\r
+  ASSERT (Rsdt);\r
+\r
+  //\r
+  // Find the table entry in the RSDT and XSDT\r
+  //\r
+  for (Index = 0; Index < *NumberOfTableEntries; Index++) {\r
+    //\r
+    // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
+    // If it becomes necessary to maintain separate table lists, changes will be required.\r
+    //\r
+    CurrentRsdtEntry = (UINT32 *) ((UINT8 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));\r
+    if (Xsdt != NULL) {\r
+      //\r
+      // This pointer must not be directly dereferenced as the XSDT entries may not\r
+      // be 64 bit aligned resulting in a possible fault.  Use CopyMem to update.\r
+      //\r
+      CurrentXsdtEntry = (VOID *) ((UINT8 *) Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT64));\r
+\r
+      //\r
+      // Read the entry value out of the XSDT\r
+      //\r
+      CopyMem (&CurrentTablePointer64, CurrentXsdtEntry, sizeof (UINT64));\r
+    } else {\r
+      //\r
+      // Initialize to NULL\r
+      //\r
+      CurrentXsdtEntry      = 0;\r
+      CurrentTablePointer64 = 0;\r
+    }\r
+    //\r
+    // Check if we have found the corresponding entry in both RSDT and XSDT\r
+    //\r
+    if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&\r
+        ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)\r
+        ) {\r
+      //\r
+      // Found entry, so copy all following entries and shrink table\r
+      // We actually copy all + 1 to copy the initialized value of memory over\r
+      // the last entry.\r
+      //\r
+      CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));\r
+      Rsdt->Length = Rsdt->Length - sizeof (UINT32);\r
+      if (Xsdt != NULL) {\r
+        CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64));\r
+        Xsdt->Length = Xsdt->Length - sizeof (UINT64);\r
+      }\r
+      break;\r
+    } else if (Index + 1 == *NumberOfTableEntries) {\r
+      //\r
+      // At the last entry, and table not found\r
+      //\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  //\r
+  // Checksum the tables\r
+  //\r
+  AcpiPlatformChecksum (\r
+    Rsdt,\r
+    Rsdt->Length,\r
+    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+    Checksum)\r
+    );\r
+\r
+  if (Xsdt != NULL) {\r
+    AcpiPlatformChecksum (\r
+      Xsdt,\r
+      Xsdt->Length,\r
+      OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+      Checksum)\r
+      );\r
+  }\r
+  //\r
+  // Decrement the number of tables\r
+  //\r
+  (*NumberOfTableEntries)--;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function removes a table and frees any associated memory.\r
+\r
+  @param  AcpiTableInstance  Instance of the protocol.\r
+  @param  Version            Version(s) to delete.\r
+  @param  Table              Pointer to table found.\r
+\r
+  @return EFI_SUCCESS  The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+DeleteTable (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN EFI_ACPI_TABLE_VERSION               Version,\r
+  IN OUT EFI_ACPI_TABLE_LIST              *Table\r
+  )\r
+{\r
+  UINT32  CurrentTableSignature;\r
+  BOOLEAN RemoveFromRsdt;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (AcpiTableInstance);\r
+  ASSERT (Table);\r
+\r
+  //\r
+  // Init locals\r
+  //\r
+  RemoveFromRsdt        = TRUE;\r
+  CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table->Table)->Signature;\r
+\r
+  //\r
+  // Basic tasks to accomplish delete are:\r
+  //   Determine removal requirements (in RSDT/XSDT or not)\r
+  //   Remove entry from RSDT/XSDT\r
+  //   Remove any table references to the table\r
+  //   If no one is using the table\r
+  //      Free the table (removing pointers from private data and tables)\r
+  //      Remove from list\r
+  //      Free list structure\r
+  //\r
+  //\r
+  // Determine if this table is in the RSDT or XSDT\r
+  //\r
+  if ((CurrentTableSignature == EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||\r
+      (CurrentTableSignature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||\r
+      (CurrentTableSignature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)\r
+      ) {\r
+    RemoveFromRsdt = FALSE;\r
+  }\r
+  //\r
+  // We don't remove the FADT in the standard way because some\r
+  // OS expect the FADT to be early in the table list.\r
+  // So we always put it as the first element in the list.\r
+  //\r
+  if (CurrentTableSignature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {\r
+    RemoveFromRsdt = FALSE;\r
+  }\r
+\r
+  //\r
+  // Remove the table from RSDT and XSDT\r
+  //\r
+  if (Table->Table != NULL) {\r
+    //\r
+    // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt\r
+    //\r
+    if (Version & EFI_ACPI_TABLE_VERSION_NONE & Table->Version) {\r
+      //\r
+      // Remove this version from the table\r
+      //\r
+      Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_NONE;\r
+    }\r
+\r
+    if (Version & EFI_ACPI_TABLE_VERSION_1_0B & Table->Version) {\r
+      //\r
+      // Remove this version from the table\r
+      //\r
+      Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_1_0B;\r
+\r
+      //\r
+      // Remove from Rsdt.  We don't care about the return value because it is\r
+      // acceptable for the table to not exist in Rsdt.\r
+      // We didn't add some tables so we don't remove them.\r
+      //\r
+      if (RemoveFromRsdt) {\r
+        RemoveTableFromRsdt (\r
+          Table,\r
+          &AcpiTableInstance->NumberOfTableEntries1,\r
+          AcpiTableInstance->Rsdt1,\r
+          NULL\r
+          );\r
+      }\r
+    }\r
+\r
+    if ((Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) ||\r
+        (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version)) {\r
+      //\r
+      // Remove this version from the table\r
+      //\r
+      if (Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) {\r
+        Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_2_0;\r
+      }      \r
+      if (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version) {\r
+        Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_3_0;\r
+      }\r
+      \r
+      //\r
+      // Remove from Rsdt and Xsdt.  We don't care about the return value\r
+      // because it is acceptable for the table to not exist in Rsdt/Xsdt.\r
+      // We didn't add some tables so we don't remove them.\r
+      //\r
+      if (RemoveFromRsdt) {\r
+        RemoveTableFromRsdt (\r
+          Table,\r
+          &AcpiTableInstance->NumberOfTableEntries3,\r
+          AcpiTableInstance->Rsdt3,\r
+          AcpiTableInstance->Xsdt\r
+          );\r
+      }\r
+    }    \r
+    //\r
+    // Free the table, clean up any dependent tables and our private data pointers.\r
+    //\r
+    switch (Table->Table->Signature) {\r
+\r
+    case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
+      if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+        AcpiTableInstance->Fadt1 = NULL;\r
+      }\r
+\r
+      if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+          (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+        AcpiTableInstance->Fadt3 = NULL;\r
+      }\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
+      if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+        AcpiTableInstance->Facs1 = NULL;\r
+\r
+        //\r
+        // Update FADT table pointers\r
+        //\r
+        if (AcpiTableInstance->Fadt1 != NULL) {\r
+          AcpiTableInstance->Fadt1->FirmwareCtrl = 0;\r
+\r
+          //\r
+          // Checksum table\r
+          //\r
+          AcpiPlatformChecksum (\r
+            AcpiTableInstance->Fadt1,\r
+            AcpiTableInstance->Fadt1->Header.Length,\r
+            OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+            Checksum)\r
+            );\r
+        }\r
+      }\r
+\r
+      if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+          (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+        AcpiTableInstance->Facs3 = NULL;\r
+\r
+        //\r
+        // Update FADT table pointers\r
+        //\r
+        if (AcpiTableInstance->Fadt3 != NULL) {\r
+          AcpiTableInstance->Fadt3->FirmwareCtrl = 0;\r
+          ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));\r
+\r
+          //\r
+          // Checksum table\r
+          //\r
+          AcpiPlatformChecksum (\r
+            AcpiTableInstance->Fadt3,\r
+            AcpiTableInstance->Fadt3->Header.Length,\r
+            OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+            Checksum)\r
+            );\r
+        }\r
+      }    \r
+      break;\r
+\r
+    case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
+      if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+        AcpiTableInstance->Dsdt1 = NULL;\r
+\r
+        //\r
+        // Update FADT table pointers\r
+        //\r
+        if (AcpiTableInstance->Fadt1 != NULL) {\r
+          AcpiTableInstance->Fadt1->Dsdt = 0;\r
+\r
+          //\r
+          // Checksum table\r
+          //\r
+          AcpiPlatformChecksum (\r
+            AcpiTableInstance->Fadt1,\r
+            AcpiTableInstance->Fadt1->Header.Length,\r
+            OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+            Checksum)\r
+            );\r
+        }\r
+      }\r
+\r
+      \r
+      if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
+          (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+        AcpiTableInstance->Dsdt3 = NULL;\r
+\r
+        //\r
+        // Update FADT table pointers\r
+        //\r
+        if (AcpiTableInstance->Fadt3 != NULL) {\r
+          AcpiTableInstance->Fadt3->Dsdt = 0;\r
+          ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));\r
+\r
+          //\r
+          // Checksum table\r
+          //\r
+          AcpiPlatformChecksum (\r
+            AcpiTableInstance->Fadt3,\r
+            AcpiTableInstance->Fadt3->Header.Length,\r
+            OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+            Checksum)\r
+            );\r
+        }\r
+      }\r
+      break;\r
+\r
+    default:\r
+      //\r
+      // Do nothing\r
+      //\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // If no version is using this table anymore, remove and free list entry.\r
+  //\r
+  if (Table->Version == 0) {\r
+    //\r
+    // Free the Table\r
+    //\r
+    gBS->FreePages (Table->PageAddress, Table->NumberOfPages);\r
+    RemoveEntryList (&(Table->Link));\r
+    gBS->FreePool (Table);\r
+  }\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function finds and removes the table specified by the handle.\r
+\r
+  @param  AcpiTableInstance  Instance of the protocol.\r
+  @param  Version            Bitmask of which versions to remove.\r
+  @param  Handle             Table to remove.\r
+\r
+  @return EFI_SUCCESS    The function completed successfully.\r
+  @return EFI_ABORTED    An error occurred.\r
+  @return EFI_NOT_FOUND  Handle not found in table list.\r
+\r
+**/\r
+EFI_STATUS\r
+RemoveTableFromList (\r
+  IN EFI_ACPI_TABLE_INSTANCE              *AcpiTableInstance,\r
+  IN EFI_ACPI_TABLE_VERSION               Version,\r
+  IN UINTN                                Handle\r
+  )\r
+{\r
+  EFI_ACPI_TABLE_LIST *Table;\r
+  EFI_STATUS          Status;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (AcpiTableInstance);\r
+\r
+  //\r
+  // Find the table\r
+  //\r
+  Status = FindTableByHandle (\r
+            Handle,\r
+            &AcpiTableInstance->TableList,\r
+            &Table\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  //\r
+  // Remove the table\r
+  //\r
+  Status = DeleteTable (AcpiTableInstance, Version, Table);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Completed successfully\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function calculates and updates an UINT8 checksum.\r
+\r
+  @param  Buffer          Pointer to buffer to checksum\r
+  @param  Size            Number of bytes to checksum\r
+  @param  ChecksumOffset  Offset to place the checksum result in\r
+\r
+  @return EFI_SUCCESS             The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+AcpiPlatformChecksum (\r
+  IN VOID       *Buffer,\r
+  IN UINTN      Size,\r
+  IN UINTN      ChecksumOffset\r
+  )\r
+{\r
+  UINT8 Sum;\r
+  UINT8 *Ptr;\r
+\r
+  Sum = 0;\r
+  //\r
+  // Initialize pointer\r
+  //\r
+  Ptr = Buffer;\r
+\r
+  //\r
+  // set checksum to 0 first\r
+  //\r
+  Ptr[ChecksumOffset] = 0;\r
+\r
+  //\r
+  // add all content of buffer\r
+  //\r
+  while ((Size--) != 0) {\r
+    Sum = (UINT8) (Sum + (*Ptr++));\r
+  }\r
+  //\r
+  // set checksum\r
+  //\r
+  Ptr                 = Buffer;\r
+  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Checksum all versions of the common tables, RSDP, RSDT, XSDT.\r
+\r
+  @param  AcpiTableInstance  Protocol instance private data.\r
+\r
+  @return EFI_SUCCESS        The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+ChecksumCommonTables (\r
+  IN OUT EFI_ACPI_TABLE_INSTANCE                   *AcpiTableInstance\r
+  )\r
+{\r
+  //\r
+  // RSDP ACPI 1.0 checksum for 1.0 table.  This is only the first 20 bytes of the structure\r
+  //\r
+  AcpiPlatformChecksum (\r
+    AcpiTableInstance->Rsdp1,\r
+    sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
+    OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
+    Checksum)\r
+    );\r
+\r
+  //\r
+  // RSDP ACPI 1.0 checksum for 2.0/3.0 table.  This is only the first 20 bytes of the structure\r
+  //\r
+  AcpiPlatformChecksum (\r
+    AcpiTableInstance->Rsdp3,\r
+    sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
+    OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
+    Checksum)\r
+    );\r
+\r
+  //\r
+  // RSDP ACPI 2.0/3.0 checksum, this is the entire table\r
+  //\r
+  AcpiPlatformChecksum (\r
+    AcpiTableInstance->Rsdp3,\r
+    sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
+    OFFSET_OF (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
+    ExtendedChecksum)\r
+    );\r
+\r
+  //\r
+  // RSDT checksums\r
+  //\r
+  AcpiPlatformChecksum (\r
+    AcpiTableInstance->Rsdt1,\r
+    AcpiTableInstance->Rsdt1->Length,\r
+    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+    Checksum)\r
+    );\r
+\r
+  AcpiPlatformChecksum (\r
+    AcpiTableInstance->Rsdt3,\r
+    AcpiTableInstance->Rsdt3->Length,\r
+    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+    Checksum)\r
+    );\r
+\r
+  //\r
+  // XSDT checksum\r
+  //\r
+  AcpiPlatformChecksum (\r
+    AcpiTableInstance->Xsdt,\r
+    AcpiTableInstance->Xsdt->Length,\r
+    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+    Checksum)\r
+    );\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Constructor for the ACPI table protocol.  Initializes instance\r
+  data.\r
+\r
+  @param  AcpiTableInstance   Instance to construct\r
+\r
+  @return EFI_SUCCESS             Instance initialized.\r
+  @return EFI_OUT_OF_RESOURCES    Unable to allocate required resources.\r
+\r
+**/\r
+EFI_STATUS\r
+AcpiTableAcpiTableConstructor (\r
+  EFI_ACPI_TABLE_INSTANCE                   *AcpiTableInstance\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT64                CurrentData;\r
+  UINTN                 TotalSize;\r
+  UINT8                 *Pointer;\r
+  EFI_PHYSICAL_ADDRESS  PageAddress;\r
+\r
+  //\r
+  // Check for invalid input parameters\r
+  //\r
+  ASSERT (AcpiTableInstance);\r
+\r
+  InitializeListHead (&AcpiTableInstance->TableList);\r
+  AcpiTableInstance->CurrentHandle              = 1;\r
+\r
+  AcpiTableInstance->AcpiTableProtocol.InstallAcpiTable   = InstallAcpiTable;\r
+  AcpiTableInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;\r
+  //\r
+  // Create RSDP, RSDT, XSDT structures\r
+  // Allocate all buffers\r
+  //\r
+  TotalSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +\r
+      sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +\r
+      sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 1.0 RSDT\r
+      EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32) +\r
+      sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 RSDT\r
+      EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32) +\r
+      sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT\r
+      EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT64);\r
+\r
+  //\r
+  // Allocate memory in the lower 32 bit of address range for\r
+  // compatibility with ACPI 1.0 OS.\r
+  //\r
+  // This is done because ACPI 1.0 pointers are 32 bit values.\r
+  // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.\r
+  // There is no architectural reason these should be below 4GB, it is purely\r
+  // for convenience of implementation that we force memory below 4GB.\r
+  //\r
+  PageAddress = 0xFFFFFFFF;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiACPIReclaimMemory,\r
+                  EFI_SIZE_TO_PAGES (TotalSize),\r
+                  &PageAddress\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Pointer = (UINT8 *) (UINTN) PageAddress;\r
+  ZeroMem (Pointer, TotalSize);\r
+\r
+  AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;\r
+  Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+  AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;\r
+  Pointer += sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+\r
+  AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+  Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
+  AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+  Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
+\r
+  AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+\r
+  //\r
+  // Initialize RSDP\r
+  //\r
+  CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
+  CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));\r
+  CopyMem (AcpiTableInstance->Rsdp1->OemId, EFI_ACPI_OEM_ID, 6);\r
+  AcpiTableInstance->Rsdp1->Reserved    = EFI_ACPI_RESERVED_BYTE;\r
+  AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
+\r
+  CurrentData = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
+  CopyMem (&AcpiTableInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));\r
+  CopyMem (AcpiTableInstance->Rsdp3->OemId, EFI_ACPI_OEM_ID, 6);\r
+  AcpiTableInstance->Rsdp3->Revision    = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;\r
+  AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
+  AcpiTableInstance->Rsdp3->Length      = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+  CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;\r
+  CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r
+  SetMem (AcpiTableInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);\r
+\r
+  //\r
+  // Initialize Rsdt\r
+  //\r
+  // Note that we "reserve" one entry for the FADT so it can always be\r
+  // at the beginning of the list of tables.  Some OS don't seem\r
+  // to find it correctly if it is too far down the list.\r
+  //\r
+  AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
+  AcpiTableInstance->Rsdt1->Length    = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
+  AcpiTableInstance->Rsdt1->Revision  = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
+  CopyMem (AcpiTableInstance->Rsdt1->OemId, EFI_ACPI_OEM_ID, 6);\r
+  CurrentData = EFI_ACPI_OEM_TABLE_ID;\r
+  CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));\r
+  AcpiTableInstance->Rsdt1->OemRevision     = EFI_ACPI_OEM_REVISION;\r
+  AcpiTableInstance->Rsdt1->CreatorId       = EFI_ACPI_CREATOR_ID;\r
+  AcpiTableInstance->Rsdt1->CreatorRevision = EFI_ACPI_CREATOR_REVISION;\r
+  //\r
+  // We always reserve first one for FADT\r
+  //\r
+  AcpiTableInstance->NumberOfTableEntries1  = 1;\r
+  AcpiTableInstance->Rsdt1->Length          = AcpiTableInstance->Rsdt1->Length + sizeof(UINT32);\r
+\r
+  AcpiTableInstance->Rsdt3->Signature       = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
+  AcpiTableInstance->Rsdt3->Length          = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
+  AcpiTableInstance->Rsdt3->Revision        = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
+  CopyMem (AcpiTableInstance->Rsdt3->OemId, EFI_ACPI_OEM_ID, 6);\r
+  CurrentData = EFI_ACPI_OEM_TABLE_ID;\r
+  CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));\r
+  AcpiTableInstance->Rsdt3->OemRevision     = EFI_ACPI_OEM_REVISION;\r
+  AcpiTableInstance->Rsdt3->CreatorId       = EFI_ACPI_CREATOR_ID;\r
+  AcpiTableInstance->Rsdt3->CreatorRevision = EFI_ACPI_CREATOR_REVISION;\r
+  //\r
+  // We always reserve first one for FADT\r
+  //\r
+  AcpiTableInstance->NumberOfTableEntries3  = 1;\r
+  AcpiTableInstance->Rsdt3->Length          = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);\r
+\r
+  //\r
+  // Initialize Xsdt\r
+  //\r
+  AcpiTableInstance->Xsdt->Signature  = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
+  AcpiTableInstance->Xsdt->Length     = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
+  AcpiTableInstance->Xsdt->Revision   = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
+  CopyMem (AcpiTableInstance->Xsdt->OemId, EFI_ACPI_OEM_ID, 6);\r
+  CurrentData = EFI_ACPI_OEM_TABLE_ID;\r
+  CopyMem (&AcpiTableInstance->Xsdt->OemTableId, &CurrentData, sizeof (UINT64));\r
+  AcpiTableInstance->Xsdt->OemRevision      = EFI_ACPI_OEM_REVISION;\r
+  AcpiTableInstance->Xsdt->CreatorId        = EFI_ACPI_CREATOR_ID;\r
+  AcpiTableInstance->Xsdt->CreatorRevision  = EFI_ACPI_CREATOR_REVISION;\r
+  //\r
+  // We always reserve first one for FADT\r
+  //\r
+  AcpiTableInstance->Xsdt->Length           = AcpiTableInstance->Xsdt->Length + sizeof(UINT64);\r
+\r
+  ChecksumCommonTables (AcpiTableInstance);\r
+\r
+  //\r
+  // Completed successfully\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r