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