]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
OvmfPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / OvmfPkg / AcpiPlatformDxe / AcpiPlatform.c
... / ...
CommitLineData
1/** @file\r
2 OVMF ACPI Platform Driver\r
3\r
4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "AcpiPlatform.h"\r
10\r
11EFI_STATUS\r
12EFIAPI\r
13InstallAcpiTable (\r
14 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
15 IN VOID *AcpiTableBuffer,\r
16 IN UINTN AcpiTableBufferSize,\r
17 OUT UINTN *TableKey\r
18 )\r
19{\r
20 return AcpiProtocol->InstallAcpiTable (\r
21 AcpiProtocol,\r
22 AcpiTableBuffer,\r
23 AcpiTableBufferSize,\r
24 TableKey\r
25 );\r
26}\r
27\r
28\r
29/**\r
30 Locate the first instance of a protocol. If the protocol requested is an\r
31 FV protocol, then it will return the first FV that contains the ACPI table\r
32 storage file.\r
33\r
34 @param Instance Return pointer to the first instance of the protocol\r
35\r
36 @return EFI_SUCCESS The function completed successfully.\r
37 @return EFI_NOT_FOUND The protocol could not be located.\r
38 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.\r
39\r
40**/\r
41EFI_STATUS\r
42LocateFvInstanceWithTables (\r
43 OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance\r
44 )\r
45{\r
46 EFI_STATUS Status;\r
47 EFI_HANDLE *HandleBuffer;\r
48 UINTN NumberOfHandles;\r
49 EFI_FV_FILETYPE FileType;\r
50 UINT32 FvStatus;\r
51 EFI_FV_FILE_ATTRIBUTES Attributes;\r
52 UINTN Size;\r
53 UINTN Index;\r
54 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
55\r
56 FvStatus = 0;\r
57\r
58 //\r
59 // Locate protocol.\r
60 //\r
61 Status = gBS->LocateHandleBuffer (\r
62 ByProtocol,\r
63 &gEfiFirmwareVolume2ProtocolGuid,\r
64 NULL,\r
65 &NumberOfHandles,\r
66 &HandleBuffer\r
67 );\r
68 if (EFI_ERROR (Status)) {\r
69 //\r
70 // Defined errors at this time are not found and out of resources.\r
71 //\r
72 return Status;\r
73 }\r
74\r
75 //\r
76 // Looking for FV with ACPI storage file\r
77 //\r
78 for (Index = 0; Index < NumberOfHandles; Index++) {\r
79 //\r
80 // Get the protocol on this handle\r
81 // This should not fail because of LocateHandleBuffer\r
82 //\r
83 Status = gBS->HandleProtocol (\r
84 HandleBuffer[Index],\r
85 &gEfiFirmwareVolume2ProtocolGuid,\r
86 (VOID**) &FvInstance\r
87 );\r
88 ASSERT_EFI_ERROR (Status);\r
89\r
90 //\r
91 // See if it has the ACPI storage file\r
92 //\r
93 Status = FvInstance->ReadFile (\r
94 FvInstance,\r
95 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
96 NULL,\r
97 &Size,\r
98 &FileType,\r
99 &Attributes,\r
100 &FvStatus\r
101 );\r
102\r
103 //\r
104 // If we found it, then we are done\r
105 //\r
106 if (Status == EFI_SUCCESS) {\r
107 *Instance = FvInstance;\r
108 break;\r
109 }\r
110 }\r
111\r
112 //\r
113 // Our exit status is determined by the success of the previous operations\r
114 // If the protocol was found, Instance already points to it.\r
115 //\r
116\r
117 //\r
118 // Free any allocated buffers\r
119 //\r
120 gBS->FreePool (HandleBuffer);\r
121\r
122 return Status;\r
123}\r
124\r
125\r
126/**\r
127 Find ACPI tables in an FV and install them. \r
128\r
129 This is now a fall-back path. Normally, we will search for tables provided\r
130 by the VMM first.\r
131\r
132 If that fails, we use this function to load the ACPI tables from an FV. The\r
133 sources for the FV based tables is located under OvmfPkg/AcpiTables.\r
134\r
135 @param AcpiTable Protocol instance pointer \r
136\r
137**/\r
138EFI_STATUS\r
139EFIAPI\r
140InstallOvmfFvTables (\r
141 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable\r
142 )\r
143{\r
144 EFI_STATUS Status;\r
145 EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;\r
146 INTN Instance;\r
147 EFI_ACPI_COMMON_HEADER *CurrentTable;\r
148 UINTN TableHandle;\r
149 UINT32 FvStatus;\r
150 UINTN TableSize;\r
151 UINTN Size;\r
152 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;\r
153\r
154 Instance = 0;\r
155 CurrentTable = NULL;\r
156 TableHandle = 0;\r
157\r
158 if (QemuDetected ()) {\r
159 TableInstallFunction = QemuInstallAcpiTable;\r
160 } else {\r
161 TableInstallFunction = InstallAcpiTable;\r
162 }\r
163\r
164 //\r
165 // Locate the firmware volume protocol\r
166 //\r
167 Status = LocateFvInstanceWithTables (&FwVol);\r
168 if (EFI_ERROR (Status)) {\r
169 return EFI_ABORTED;\r
170 }\r
171 //\r
172 // Read tables from the storage file.\r
173 //\r
174 while (Status == EFI_SUCCESS) {\r
175\r
176 Status = FwVol->ReadSection (\r
177 FwVol,\r
178 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
179 EFI_SECTION_RAW,\r
180 Instance,\r
181 (VOID**) &CurrentTable,\r
182 &Size,\r
183 &FvStatus\r
184 );\r
185 if (!EFI_ERROR (Status)) {\r
186 //\r
187 // Add the table\r
188 //\r
189 TableHandle = 0;\r
190\r
191 TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;\r
192 ASSERT (Size >= TableSize);\r
193\r
194 //\r
195 // Install ACPI table\r
196 //\r
197 Status = TableInstallFunction (\r
198 AcpiTable,\r
199 CurrentTable,\r
200 TableSize,\r
201 &TableHandle\r
202 );\r
203\r
204 //\r
205 // Free memory allocated by ReadSection\r
206 //\r
207 gBS->FreePool (CurrentTable);\r
208\r
209 if (EFI_ERROR (Status)) {\r
210 return EFI_ABORTED;\r
211 }\r
212\r
213 //\r
214 // Increment the instance\r
215 //\r
216 Instance++;\r
217 CurrentTable = NULL;\r
218 }\r
219 }\r
220\r
221 return EFI_SUCCESS;\r
222}\r
223\r
224/**\r
225 Effective entrypoint of Acpi Platform driver.\r
226\r
227 @param ImageHandle\r
228 @param SystemTable\r
229\r
230 @return EFI_SUCCESS\r
231 @return EFI_LOAD_ERROR\r
232 @return EFI_OUT_OF_RESOURCES\r
233\r
234**/\r
235EFI_STATUS\r
236EFIAPI\r
237InstallAcpiTables (\r
238 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable\r
239 )\r
240{\r
241 EFI_STATUS Status;\r
242\r
243 if (XenDetected ()) {\r
244 Status = InstallXenTables (AcpiTable);\r
245 } else {\r
246 Status = InstallQemuFwCfgTables (AcpiTable);\r
247 }\r
248\r
249 if (EFI_ERROR (Status)) {\r
250 Status = InstallOvmfFvTables (AcpiTable);\r
251 }\r
252\r
253 return Status;\r
254}\r
255\r