+ EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;\r
+ UINT8 *XenAcpiPtr;\r
+ UINT8 Sum;\r
+\r
+ //\r
+ // Detect the RSDP structure\r
+ //\r
+ for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;\r
+ XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;\r
+ XenAcpiPtr += 0x10) {\r
+\r
+ RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)\r
+ (UINTN) XenAcpiPtr;\r
+\r
+ if (!AsciiStrnCmp ((CHAR8 *) &RsdpStructurePtr->Signature, "RSD PTR ", 8)) {\r
+ //\r
+ // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.\r
+ // This is only the first 20 bytes of the structure\r
+ //\r
+ Sum = CalculateTableChecksum (\r
+ RsdpStructurePtr,\r
+ sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
+ );\r
+ if (Sum != 0) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ if (RsdpStructurePtr->Revision >= 2) {\r
+ //\r
+ // RSDP ACPI 2.0/3.0 checksum, this is the entire table\r
+ //\r
+ Sum = CalculateTableChecksum (\r
+ RsdpStructurePtr,\r
+ sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
+ );\r
+ if (Sum != 0) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+ *RsdpPtr = RsdpStructurePtr;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables\r
+ into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed\r
+ ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.\r
+\r
+ @param AcpiProtocol Protocol instance pointer.\r
+\r
+ @return EFI_SUCCESS The table was successfully inserted.\r
+ @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is\r
+ NULL, or AcpiTableBufferSize and the size\r
+ field embedded in the ACPI table pointed to\r
+ by AcpiTableBuffer 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
+InstallXenTables (\r
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN TableHandle;\r
+\r
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
+ VOID *CurrentTableEntry;\r
+ UINTN CurrentTablePointer;\r
+ EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;\r
+ UINTN Index;\r
+ UINTN NumberOfTableEntries;\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;\r
+ EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table;\r
+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;\r
+ EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;\r
+ EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;\r
+\r
+ Fadt2Table = NULL;\r
+ Fadt1Table = NULL;\r
+ Facs2Table = NULL;\r
+ Facs1Table = NULL;\r
+ DsdtTable = NULL;\r
+ TableHandle = 0;\r
+ NumberOfTableEntries = 0;\r
+\r
+ //\r
+ // Try to find Xen ACPI tables\r
+ //\r
+ Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // If XSDT table is find, just install its tables. \r
+ // Otherwise, try to find and install the RSDT tables.\r
+ //\r
+ if (XenAcpiRsdpStructurePtr->XsdtAddress) {\r
+ //\r
+ // Retrieve the addresses of XSDT and \r
+ // calculate the number of its table entries.\r
+ //\r
+ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
+ XenAcpiRsdpStructurePtr->XsdtAddress;\r
+ NumberOfTableEntries = (Xsdt->Length -\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
+ sizeof (UINT64);\r
+\r
+ //\r
+ // Install ACPI tables found in XSDT.\r
+ //\r
+ for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
+ //\r
+ // Get the table entry from XSDT\r
+ //\r
+ CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+ Index * sizeof (UINT64));\r
+ CurrentTablePointer = *(UINT64 *)CurrentTableEntry;\r
+ CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
+\r
+ //\r
+ // Install the XSDT tables\r
+ //\r
+ Status = InstallAcpiTable (\r
+ AcpiProtocol,\r
+ CurrentTable,\r
+ CurrentTable->Length,\r
+ &TableHandle\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the FACS and DSDT table address from the table FADT\r
+ //\r
+ if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
+ Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
+ (UINTN) CurrentTablePointer;\r
+ Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
+ (UINTN) Fadt2Table->FirmwareCtrl;\r
+ DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt2Table->Dsdt;\r
+ }\r
+ }\r
+ }\r
+ else if (XenAcpiRsdpStructurePtr->RsdtAddress) {\r
+ //\r
+ // Retrieve the addresses of RSDT and\r
+ // calculate the number of its table entries.\r
+ //\r
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
+ XenAcpiRsdpStructurePtr->RsdtAddress;\r
+ NumberOfTableEntries = (Rsdt->Length -\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / \r
+ sizeof (UINT32);\r
+\r
+ //\r
+ // Install ACPI tables found in XSDT.\r
+ //\r
+ for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
+ //\r
+ // Get the table entry from RSDT\r
+ //\r
+ CurrentTableEntry = (UINT32 *) ((UINT8 *) Rsdt +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+ Index * sizeof (UINT32));\r
+ CurrentTablePointer = *(UINT32 *)CurrentTableEntry;\r
+ CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
+\r
+ //\r
+ // Install the RSDT tables\r
+ //\r
+ Status = InstallAcpiTable (\r
+ AcpiProtocol,\r
+ CurrentTable,\r
+ CurrentTable->Length,\r
+ &TableHandle\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the FACS and DSDT table address from the table FADT\r
+ //\r
+ if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
+ Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
+ (UINTN) CurrentTablePointer;\r
+ Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
+ (UINTN) Fadt1Table->FirmwareCtrl;\r
+ DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt1Table->Dsdt;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Install the FACS table.\r
+ //\r
+ if (Fadt2Table) {\r
+ //\r
+ // FACS 2.0\r
+ //\r
+ Status = InstallAcpiTable (\r
+ AcpiProtocol,\r
+ Facs2Table,\r
+ Facs2Table->Length,\r
+ &TableHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+ else if (Fadt1Table) {\r
+ //\r
+ // FACS 1.0\r
+ //\r
+ Status = InstallAcpiTable (\r
+ AcpiProtocol,\r
+ Facs1Table,\r
+ Facs1Table->Length,\r
+ &TableHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Install DSDT table.\r
+ //\r
+ Status = InstallAcpiTable (\r
+ AcpiProtocol,\r
+ DsdtTable,\r
+ DsdtTable->Length,\r
+ &TableHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r