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/Acpi.h> // EFI_ACPI_DESCRIPTION_HEADER
11 #include <IndustryStandard/CloudHv.h> // CLOUDHV_RSDP_ADDRESS
12 #include <IndustryStandard/Xen/arch-x86/hvm/start_info.h> // hvm_start_info
13 #include <Library/BaseLib.h> // CpuDeadLoop()
14 #include <Library/DebugLib.h> // DEBUG()
15 #include <Library/PcdLib.h> // PcdGet32()
16 #include <Library/HobLib.h> // GetFirstGuidHob(), GetNextGuidHob()
17 #include <Library/UefiBootServicesTableLib.h> // gBS
18 #include <Protocol/AcpiSystemDescriptionTable.h>
19 #include <Protocol/AcpiTable.h>
21 #include "AcpiPlatform.h"
25 InstallCloudHvTablesTdx (
26 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
31 EFI_HANDLE ChAcpiHandle
;
33 EFI_PEI_HOB_POINTERS Hob
;
34 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
35 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
40 Hob
.Guid
= (EFI_HOB_GUID_TYPE
*)GetFirstGuidHob (&gUefiOvmfPkgTdxAcpiHobGuid
);
42 while (Hob
.Guid
!= NULL
) {
43 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)(&Hob
.Guid
->Name
+ 1);
44 if (!AsciiStrnCmp ((CHAR8
*)&CurrentTable
->Signature
, "DSDT", 4)) {
45 DsdtTable
= CurrentTable
;
50 Status
= AcpiProtocol
->InstallAcpiTable (
56 for (UINTN i
= 0; i
< CurrentTable
->Length
; i
++) {
57 DEBUG ((DEBUG_INFO
, " %x", *((UINT8
*)CurrentTable
+ i
)));
60 DEBUG ((DEBUG_INFO
, "\n"));
63 Hob
.Raw
= GET_NEXT_HOB (Hob
.Raw
);
64 Hob
.Guid
= (EFI_HOB_GUID_TYPE
*)GetNextGuidHob (&gUefiOvmfPkgTdxAcpiHobGuid
, Hob
.Raw
);
68 // Install DSDT table. If we reached this point without finding the DSDT,
69 // then we're out of sync with the hypervisor, and cannot continue.
71 if (DsdtTable
== NULL
) {
72 DEBUG ((DEBUG_INFO
, "%a: no DSDT found\n", __FUNCTION__
));
76 Status
= AcpiProtocol
->InstallAcpiTable (
82 if (EFI_ERROR (Status
)) {
83 ASSERT_EFI_ERROR (Status
);
88 // Install a protocol to notify that the ACPI table provided by CH is
92 gBS
->InstallProtocolInterface (
94 &gQemuAcpiTableNotifyProtocolGuid
,
102 // Get the ACPI tables from EBDA start
105 InstallCloudHvTables (
106 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
112 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
113 VOID
*CurrentTableEntry
;
114 UINTN CurrentTablePointer
;
115 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
117 UINTN NumberOfTableEntries
;
118 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
119 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
120 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*AcpiRsdpStructurePtr
;
121 UINT32
*PVHResetVectorData
;
122 struct hvm_start_info
*pvh_start_info
;
127 NumberOfTableEntries
= 0;
128 AcpiRsdpStructurePtr
= NULL
;
129 PVHResetVectorData
= NULL
;
130 pvh_start_info
= NULL
;
132 PVHResetVectorData
= (VOID
*)(UINTN
)PcdGet32 (PcdXenPvhStartOfDayStructPtr
);
133 if (PVHResetVectorData
== 0) {
134 return EFI_NOT_FOUND
;
137 pvh_start_info
= (struct hvm_start_info
*)(UINTN
)PVHResetVectorData
[0];
138 AcpiRsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)(UINTN
)pvh_start_info
->rsdp_paddr
;
140 // If XSDT table is found, just install its tables.
141 // Otherwise, try to find and install the RSDT tables.
143 if (AcpiRsdpStructurePtr
->XsdtAddress
) {
145 // Retrieve the addresses of XSDT and
146 // calculate the number of its table entries.
148 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)
149 AcpiRsdpStructurePtr
->XsdtAddress
;
150 NumberOfTableEntries
= (Xsdt
->Length
-
151 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
155 // Install ACPI tables found in XSDT.
157 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
159 // Get the table entry from XSDT
161 CurrentTableEntry
= (VOID
*)((UINT8
*)Xsdt
+
162 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
163 Index
* sizeof (UINT64
));
164 CurrentTablePointer
= (UINTN
)*(UINT64
*)CurrentTableEntry
;
165 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)CurrentTablePointer
;
168 // Install the XSDT tables
170 Status
= AcpiProtocol
->InstallAcpiTable (
173 CurrentTable
->Length
,
177 if (EFI_ERROR (Status
)) {
178 ASSERT_EFI_ERROR (Status
);
183 // Get the X-DSDT table address from the table FADT
185 if (!AsciiStrnCmp ((CHAR8
*)&CurrentTable
->Signature
, "FACP", 4)) {
186 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
187 (UINTN
)CurrentTablePointer
;
188 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)Fadt2Table
->XDsdt
;
192 return EFI_NOT_FOUND
;
196 // Install DSDT table. If we reached this point without finding the DSDT,
197 // then we're out of sync with the hypervisor, and cannot continue.
199 if (DsdtTable
== NULL
) {
200 DEBUG ((DEBUG_ERROR
, "%a: no DSDT found\n", __FUNCTION__
));
205 Status
= AcpiProtocol
->InstallAcpiTable (
211 if (EFI_ERROR (Status
)) {
212 ASSERT_EFI_ERROR (Status
);