]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
OvmfPkg/AcpiPlatformDxe: Use local variable in CloudHvAcpi.c
[mirror_edk2.git] / OvmfPkg / AcpiPlatformDxe / CloudHvAcpi.c
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
23 EFI_STATUS
24 EFIAPI
25 InstallCloudHvTablesTdx (
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 for (UINTN i = 0; i < CurrentTable->Length; i++) {
57 DEBUG ((DEBUG_INFO, " %x", *((UINT8 *)CurrentTable + i)));
58 }
59
60 DEBUG ((DEBUG_INFO, "\n"));
61 }
62
63 Hob.Raw = GET_NEXT_HOB (Hob.Raw);
64 Hob.Guid = (EFI_HOB_GUID_TYPE *)GetNextGuidHob (&gUefiOvmfPkgTdxAcpiHobGuid, Hob.Raw);
65 }
66
67 //
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.
70 //
71 if (DsdtTable == NULL) {
72 DEBUG ((DEBUG_INFO, "%a: no DSDT found\n", __FUNCTION__));
73 ASSERT (FALSE);
74 }
75
76 Status = AcpiProtocol->InstallAcpiTable (
77 AcpiProtocol,
78 DsdtTable,
79 DsdtTable->Length,
80 &TableHandle
81 );
82 if (EFI_ERROR (Status)) {
83 ASSERT_EFI_ERROR (Status);
84 return Status;
85 }
86
87 //
88 // Install a protocol to notify that the ACPI table provided by CH is
89 // ready.
90 //
91 ChAcpiHandle = NULL;
92 gBS->InstallProtocolInterface (
93 &ChAcpiHandle,
94 &gQemuAcpiTableNotifyProtocolGuid,
95 EFI_NATIVE_INTERFACE,
96 NULL
97 );
98
99 return EFI_SUCCESS;
100 }
101
102 // Get the ACPI tables from EBDA start
103 EFI_STATUS
104 EFIAPI
105 InstallCloudHvTables (
106 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
107 )
108 {
109 EFI_STATUS Status;
110 UINTN TableHandle;
111
112 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
113 VOID *CurrentTableEntry;
114 UINTN CurrentTablePointer;
115 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
116 UINTN Index;
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;
123
124 Fadt2Table = NULL;
125 DsdtTable = NULL;
126 TableHandle = 0;
127 NumberOfTableEntries = 0;
128 AcpiRsdpStructurePtr = NULL;
129 PVHResetVectorData = NULL;
130 pvh_start_info = NULL;
131
132 PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
133 if (PVHResetVectorData == 0) {
134 return EFI_NOT_FOUND;
135 }
136
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;
139
140 // If XSDT table is found, just install its tables.
141 // Otherwise, try to find and install the RSDT tables.
142 //
143 if (AcpiRsdpStructurePtr->XsdtAddress) {
144 //
145 // Retrieve the addresses of XSDT and
146 // calculate the number of its table entries.
147 //
148 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
149 AcpiRsdpStructurePtr->XsdtAddress;
150 NumberOfTableEntries = (Xsdt->Length -
151 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
152 sizeof (UINT64);
153
154 //
155 // Install ACPI tables found in XSDT.
156 //
157 for (Index = 0; Index < NumberOfTableEntries; Index++) {
158 //
159 // Get the table entry from XSDT
160 //
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;
166
167 //
168 // Install the XSDT tables
169 //
170 Status = AcpiProtocol->InstallAcpiTable (
171 AcpiProtocol,
172 CurrentTable,
173 CurrentTable->Length,
174 &TableHandle
175 );
176
177 if (EFI_ERROR (Status)) {
178 ASSERT_EFI_ERROR (Status);
179 return Status;
180 }
181
182 //
183 // Get the X-DSDT table address from the table FADT
184 //
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;
189 }
190 }
191 } else {
192 return EFI_NOT_FOUND;
193 }
194
195 //
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.
198 //
199 if (DsdtTable == NULL) {
200 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));
201 ASSERT (FALSE);
202 CpuDeadLoop ();
203 }
204
205 Status = AcpiProtocol->InstallAcpiTable (
206 AcpiProtocol,
207 DsdtTable,
208 DsdtTable->Length,
209 &TableHandle
210 );
211 if (EFI_ERROR (Status)) {
212 ASSERT_EFI_ERROR (Status);
213 return Status;
214 }
215
216 return EFI_SUCCESS;
217 }