+/**\r
+ If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.\r
+\r
+ @param AcpiTableInstance ACPI table protocol instance data structure.\r
+\r
+ @return EFI_SUCCESS reallocate the table beffer successfully.\r
+ @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.\r
+\r
+**/\r
+EFI_STATUS\r
+ReallocateAcpiTableBuffer (\r
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
+ )\r
+{\r
+ UINTN NewMaxTableNumber;\r
+ UINTN TotalSize;\r
+ UINT8 *Pointer;\r
+ EFI_PHYSICAL_ADDRESS PageAddress;\r
+ EFI_ACPI_TABLE_INSTANCE TempPrivateData;\r
+ EFI_STATUS Status;\r
+ UINT64 CurrentData;\r
+ \r
+ CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE)); \r
+ //\r
+ // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES\r
+ //\r
+ NewMaxTableNumber = mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES;\r
+ //\r
+ // Create RSDP, RSDT, XSDT structures and 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
+ NewMaxTableNumber * sizeof (UINT32) +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
+ NewMaxTableNumber * sizeof (UINT32) +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
+ NewMaxTableNumber * 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) + NewMaxTableNumber * sizeof (UINT32));\r
+ AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+ Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
+\r
+ AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+\r
+ //\r
+ // Initialize RSDP\r
+ //\r
+ CopyMem (AcpiTableInstance->Rsdp1, TempPrivateData.Rsdp1, sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)); \r
+ AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
+ \r
+ CopyMem (AcpiTableInstance->Rsdp3, TempPrivateData.Rsdp3, sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER)); \r
+ AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
+ CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;\r
+ CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r