]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
OvmfPkg/AcpiPlatformDxe: Refactor QemuAcpiTableNotifyProtocol
[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
e254c71e 92 gBS->InstallProtocolInterface (\r
f81273f7 93 &ChAcpiHandle,\r
e254c71e
SB
94 &gQemuAcpiTableNotifyProtocolGuid,\r
95 EFI_NATIVE_INTERFACE,\r
43b3ca6b 96 NULL\r
e254c71e
SB
97 );\r
98\r
99 return EFI_SUCCESS;\r
100}\r
101\r
7594c5bf
SB
102// Get the ACPI tables from EBDA start\r
103EFI_STATUS\r
104EFIAPI\r
105InstallCloudHvTables (\r
106 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
107 )\r
108{\r
109 EFI_STATUS Status;\r
110 UINTN TableHandle;\r
111\r
d50d9e55
SB
112 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
113 VOID *CurrentTableEntry;\r
114 UINTN CurrentTablePointer;\r
115 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;\r
116 UINTN Index;\r
117 UINTN NumberOfTableEntries;\r
118 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;\r
119 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;\r
120 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *AcpiRsdpStructurePtr;\r
121 UINT32 *PVHResetVectorData;\r
122 struct hvm_start_info *pvh_start_info;\r
7594c5bf
SB
123\r
124 Fadt2Table = NULL;\r
125 DsdtTable = NULL;\r
126 TableHandle = 0;\r
127 NumberOfTableEntries = 0;\r
d50d9e55
SB
128 AcpiRsdpStructurePtr = NULL;\r
129 PVHResetVectorData = NULL;\r
130 pvh_start_info = NULL;\r
131\r
132 PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);\r
133 if (PVHResetVectorData == 0) {\r
134 return EFI_NOT_FOUND;\r
135 }\r
136\r
137 pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];\r
138 AcpiRsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)pvh_start_info->rsdp_paddr;\r
7594c5bf
SB
139\r
140 // If XSDT table is found, just install its tables.\r
141 // Otherwise, try to find and install the RSDT tables.\r
142 //\r
143 if (AcpiRsdpStructurePtr->XsdtAddress) {\r
144 //\r
145 // Retrieve the addresses of XSDT and\r
146 // calculate the number of its table entries.\r
147 //\r
148 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)\r
149 AcpiRsdpStructurePtr->XsdtAddress;\r
150 NumberOfTableEntries = (Xsdt->Length -\r
151 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
152 sizeof (UINT64);\r
153\r
154 //\r
155 // Install ACPI tables found in XSDT.\r
156 //\r
157 for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
158 //\r
159 // Get the table entry from XSDT\r
160 //\r
161 CurrentTableEntry = (VOID *)((UINT8 *)Xsdt +\r
162 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
163 Index * sizeof (UINT64));\r
164 CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;\r
165 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;\r
166\r
167 //\r
168 // Install the XSDT tables\r
169 //\r
170 Status = AcpiProtocol->InstallAcpiTable (\r
171 AcpiProtocol,\r
172 CurrentTable,\r
173 CurrentTable->Length,\r
174 &TableHandle\r
175 );\r
176\r
177 if (EFI_ERROR (Status)) {\r
178 ASSERT_EFI_ERROR (Status);\r
179 return Status;\r
180 }\r
181\r
182 //\r
183 // Get the X-DSDT table address from the table FADT\r
184 //\r
185 if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {\r
186 Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
187 (UINTN)CurrentTablePointer;\r
188 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->XDsdt;\r
189 }\r
190 }\r
191 } else {\r
192 return EFI_NOT_FOUND;\r
193 }\r
194\r
195 //\r
196 // Install DSDT table. If we reached this point without finding the DSDT,\r
197 // then we're out of sync with the hypervisor, and cannot continue.\r
198 //\r
199 if (DsdtTable == NULL) {\r
200 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));\r
201 ASSERT (FALSE);\r
202 CpuDeadLoop ();\r
203 }\r
204\r
205 Status = AcpiProtocol->InstallAcpiTable (\r
206 AcpiProtocol,\r
207 DsdtTable,\r
208 DsdtTable->Length,\r
209 &TableHandle\r
210 );\r
211 if (EFI_ERROR (Status)) {\r
212 ASSERT_EFI_ERROR (Status);\r
213 return Status;\r
214 }\r
215\r
216 return EFI_SUCCESS;\r
217}\r