2 OVMF ACPI Cloud Hypervisor support
4 Copyright (c) 2021, Intel Corporation. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <IndustryStandard/CloudHv.h> // CLOUDHV_RSDP_ADDRESS
11 #include <IndustryStandard/Xen/arch-x86/hvm/start_info.h> // hvm_start_info
12 #include <Library/BaseLib.h> // CpuDeadLoop()
13 #include <Library/DebugLib.h> // DEBUG()
14 #include <Library/PcdLib.h> // PcdGet32()
16 #include "AcpiPlatform.h"
18 // Get the ACPI tables from EBDA start
21 InstallCloudHvTables (
22 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
28 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
29 VOID
*CurrentTableEntry
;
30 UINTN CurrentTablePointer
;
31 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
33 UINTN NumberOfTableEntries
;
34 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
35 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
36 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*AcpiRsdpStructurePtr
;
37 UINT32
*PVHResetVectorData
;
38 struct hvm_start_info
*pvh_start_info
;
43 NumberOfTableEntries
= 0;
44 AcpiRsdpStructurePtr
= NULL
;
45 PVHResetVectorData
= NULL
;
46 pvh_start_info
= NULL
;
48 PVHResetVectorData
= (VOID
*)(UINTN
)PcdGet32 (PcdXenPvhStartOfDayStructPtr
);
49 if (PVHResetVectorData
== 0) {
53 pvh_start_info
= (struct hvm_start_info
*)(UINTN
)PVHResetVectorData
[0];
54 AcpiRsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)(UINTN
)pvh_start_info
->rsdp_paddr
;
56 // If XSDT table is found, just install its tables.
57 // Otherwise, try to find and install the RSDT tables.
59 if (AcpiRsdpStructurePtr
->XsdtAddress
) {
61 // Retrieve the addresses of XSDT and
62 // calculate the number of its table entries.
64 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)
65 AcpiRsdpStructurePtr
->XsdtAddress
;
66 NumberOfTableEntries
= (Xsdt
->Length
-
67 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
71 // Install ACPI tables found in XSDT.
73 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
75 // Get the table entry from XSDT
77 CurrentTableEntry
= (VOID
*)((UINT8
*)Xsdt
+
78 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
79 Index
* sizeof (UINT64
));
80 CurrentTablePointer
= (UINTN
)*(UINT64
*)CurrentTableEntry
;
81 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)CurrentTablePointer
;
84 // Install the XSDT tables
86 Status
= AcpiProtocol
->InstallAcpiTable (
93 if (EFI_ERROR (Status
)) {
94 ASSERT_EFI_ERROR (Status
);
99 // Get the X-DSDT table address from the table FADT
101 if (!AsciiStrnCmp ((CHAR8
*)&CurrentTable
->Signature
, "FACP", 4)) {
102 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
103 (UINTN
)CurrentTablePointer
;
104 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)Fadt2Table
->XDsdt
;
108 return EFI_NOT_FOUND
;
112 // Install DSDT table. If we reached this point without finding the DSDT,
113 // then we're out of sync with the hypervisor, and cannot continue.
115 if (DsdtTable
== NULL
) {
116 DEBUG ((DEBUG_ERROR
, "%a: no DSDT found\n", __FUNCTION__
));
121 Status
= AcpiProtocol
->InstallAcpiTable (
127 if (EFI_ERROR (Status
)) {
128 ASSERT_EFI_ERROR (Status
);