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 Status
= gBS
->InstallProtocolInterface (
94 &gQemuAcpiTableNotifyProtocolGuid
,
98 if (EFI_ERROR (Status
)) {
99 ASSERT_EFI_ERROR (Status
);
106 // Get the ACPI tables from EBDA start
109 InstallCloudHvTables (
110 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
116 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
117 VOID
*CurrentTableEntry
;
118 UINTN CurrentTablePointer
;
119 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
121 UINTN NumberOfTableEntries
;
122 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
123 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
124 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*AcpiRsdpStructurePtr
;
125 UINT32
*PVHResetVectorData
;
126 struct hvm_start_info
*pvh_start_info
;
131 NumberOfTableEntries
= 0;
132 AcpiRsdpStructurePtr
= NULL
;
133 PVHResetVectorData
= NULL
;
134 pvh_start_info
= NULL
;
136 PVHResetVectorData
= (VOID
*)(UINTN
)PcdGet32 (PcdXenPvhStartOfDayStructPtr
);
137 if (PVHResetVectorData
== 0) {
138 return EFI_NOT_FOUND
;
141 pvh_start_info
= (struct hvm_start_info
*)(UINTN
)PVHResetVectorData
[0];
142 AcpiRsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)(UINTN
)pvh_start_info
->rsdp_paddr
;
144 // If XSDT table is found, just install its tables.
145 // Otherwise, try to find and install the RSDT tables.
147 if (AcpiRsdpStructurePtr
->XsdtAddress
) {
149 // Retrieve the addresses of XSDT and
150 // calculate the number of its table entries.
152 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)
153 AcpiRsdpStructurePtr
->XsdtAddress
;
154 NumberOfTableEntries
= (Xsdt
->Length
-
155 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
159 // Install ACPI tables found in XSDT.
161 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
163 // Get the table entry from XSDT
165 CurrentTableEntry
= (VOID
*)((UINT8
*)Xsdt
+
166 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
167 Index
* sizeof (UINT64
));
168 CurrentTablePointer
= (UINTN
)*(UINT64
*)CurrentTableEntry
;
169 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)CurrentTablePointer
;
172 // Install the XSDT tables
174 Status
= AcpiProtocol
->InstallAcpiTable (
177 CurrentTable
->Length
,
181 if (EFI_ERROR (Status
)) {
182 ASSERT_EFI_ERROR (Status
);
187 // Get the X-DSDT table address from the table FADT
189 if (!AsciiStrnCmp ((CHAR8
*)&CurrentTable
->Signature
, "FACP", 4)) {
190 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
191 (UINTN
)CurrentTablePointer
;
192 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)Fadt2Table
->XDsdt
;
196 return EFI_NOT_FOUND
;
200 // Install DSDT table. If we reached this point without finding the DSDT,
201 // then we're out of sync with the hypervisor, and cannot continue.
203 if (DsdtTable
== NULL
) {
204 DEBUG ((DEBUG_ERROR
, "%a: no DSDT found\n", __FUNCTION__
));
209 Status
= AcpiProtocol
->InstallAcpiTable (
215 if (EFI_ERROR (Status
)) {
216 ASSERT_EFI_ERROR (Status
);