VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c

Last change on this file was 105670, checked in by vboxsync, 5 months ago

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1/** @file
2 OVMF ACPI Cloud Hypervisor support
3
4 Copyright (c) 2021, Intel Corporation. All rights reserved.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
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>
20
21#include "AcpiPlatform.h"
22
23EFI_STATUS
24EFIAPI
25InstallCloudHvTablesTdx (
26 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
27 )
28{
29 EFI_STATUS Status;
30 UINTN TableHandle;
31 EFI_HANDLE ChAcpiHandle;
32
33 EFI_PEI_HOB_POINTERS Hob;
34 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
35 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
36
37 DsdtTable = NULL;
38 TableHandle = 0;
39
40 Hob.Guid = (EFI_HOB_GUID_TYPE *)GetFirstGuidHob (&gUefiOvmfPkgTdxAcpiHobGuid);
41
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;
46 } else {
47 //
48 // Install the tables
49 //
50 Status = AcpiProtocol->InstallAcpiTable (
51 AcpiProtocol,
52 CurrentTable,
53 CurrentTable->Length,
54 &TableHandle
55 );
56 if (EFI_ERROR (Status)) {
57 ASSERT_EFI_ERROR (Status);
58 return Status;
59 }
60
61 for (UINTN i = 0; i < CurrentTable->Length; i++) {
62 DEBUG ((DEBUG_INFO, " %x", *((UINT8 *)CurrentTable + i)));
63 }
64
65 DEBUG ((DEBUG_INFO, "\n"));
66 }
67
68 Hob.Raw = GET_NEXT_HOB (Hob.Raw);
69 Hob.Guid = (EFI_HOB_GUID_TYPE *)GetNextGuidHob (&gUefiOvmfPkgTdxAcpiHobGuid, Hob.Raw);
70 }
71
72 //
73 // Install DSDT table. If we reached this point without finding the DSDT,
74 // then we're out of sync with the hypervisor, and cannot continue.
75 //
76 if (DsdtTable == NULL) {
77 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __func__));
78 ASSERT (FALSE);
79 CpuDeadLoop ();
80 }
81
82 Status = AcpiProtocol->InstallAcpiTable (
83 AcpiProtocol,
84 DsdtTable,
85 DsdtTable->Length,
86 &TableHandle
87 );
88 if (EFI_ERROR (Status)) {
89 ASSERT_EFI_ERROR (Status);
90 return Status;
91 }
92
93 //
94 // Install a protocol to notify that the ACPI table provided by CH is
95 // ready.
96 //
97 ChAcpiHandle = NULL;
98 Status = gBS->InstallProtocolInterface (
99 &ChAcpiHandle,
100 &gQemuAcpiTableNotifyProtocolGuid,
101 EFI_NATIVE_INTERFACE,
102 NULL
103 );
104 if (EFI_ERROR (Status)) {
105 ASSERT_EFI_ERROR (Status);
106 return Status;
107 }
108
109 return EFI_SUCCESS;
110}
111
112// Get the ACPI tables from EBDA start
113EFI_STATUS
114EFIAPI
115InstallCloudHvTables (
116 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
117 )
118{
119 EFI_STATUS Status;
120 UINTN TableHandle;
121
122 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
123 VOID *CurrentTableEntry;
124 UINTN CurrentTablePointer;
125 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
126 UINTN Index;
127 UINTN NumberOfTableEntries;
128 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;
129 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
130 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *AcpiRsdpStructurePtr;
131 UINT32 *PVHResetVectorData;
132 struct hvm_start_info *pvh_start_info;
133
134 Fadt2Table = NULL;
135 DsdtTable = NULL;
136 TableHandle = 0;
137 NumberOfTableEntries = 0;
138 AcpiRsdpStructurePtr = NULL;
139 PVHResetVectorData = NULL;
140 pvh_start_info = NULL;
141
142 PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
143 if (PVHResetVectorData == 0) {
144 return EFI_NOT_FOUND;
145 }
146
147 pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];
148 AcpiRsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)pvh_start_info->rsdp_paddr;
149
150 // If XSDT table is found, just install its tables.
151 // Otherwise, try to find and install the RSDT tables.
152 //
153 if (AcpiRsdpStructurePtr->XsdtAddress) {
154 //
155 // Retrieve the addresses of XSDT and
156 // calculate the number of its table entries.
157 //
158 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
159 AcpiRsdpStructurePtr->XsdtAddress;
160 NumberOfTableEntries = (Xsdt->Length -
161 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
162 sizeof (UINT64);
163
164 //
165 // Install ACPI tables found in XSDT.
166 //
167 for (Index = 0; Index < NumberOfTableEntries; Index++) {
168 //
169 // Get the table entry from XSDT
170 //
171 CurrentTableEntry = (VOID *)((UINT8 *)Xsdt +
172 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
173 Index * sizeof (UINT64));
174 CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;
175 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;
176
177 //
178 // Install the XSDT tables
179 //
180 Status = AcpiProtocol->InstallAcpiTable (
181 AcpiProtocol,
182 CurrentTable,
183 CurrentTable->Length,
184 &TableHandle
185 );
186
187 if (EFI_ERROR (Status)) {
188 ASSERT_EFI_ERROR (Status);
189 return Status;
190 }
191
192 //
193 // Get the X-DSDT table address from the table FADT
194 //
195 if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {
196 Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
197 (UINTN)CurrentTablePointer;
198 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->XDsdt;
199 }
200 }
201 } else {
202 return EFI_NOT_FOUND;
203 }
204
205 //
206 // Install DSDT table. If we reached this point without finding the DSDT,
207 // then we're out of sync with the hypervisor, and cannot continue.
208 //
209 if (DsdtTable == NULL) {
210 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __func__));
211 ASSERT (FALSE);
212 CpuDeadLoop ();
213 }
214
215 Status = AcpiProtocol->InstallAcpiTable (
216 AcpiProtocol,
217 DsdtTable,
218 DsdtTable->Length,
219 &TableHandle
220 );
221 if (EFI_ERROR (Status)) {
222 ASSERT_EFI_ERROR (Status);
223 return Status;
224 }
225
226 return EFI_SUCCESS;
227}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette