]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxePiLib/DxePiLib.c
Make the module pass CYGWIN GCC build
[mirror_edk2.git] / MdePkg / Library / DxePiLib / DxePiLib.c
CommitLineData
1c280088 1/** @file\r
2 Mde PI library functions.\r
3\r
4 Copyright (c) 2007, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18#include <Library/UefiBootServicesTableLib.h>\r
b0d803fe 19#include <Library/PiLib.h>\r
1c280088 20#include <Protocol/FirmwareVolume2.h>\r
21#include <Protocol/LoadedImage.h>\r
22\r
23\r
24/**\r
25 Internal function which read the image specified by Firmware File GUID name and \r
26 the Firmware Section tyep from a specified Firmware Volume \r
27\r
28\r
29 @param Fv The Firmware Volume Protocol instance.\r
30 @param NameGuid The GUID name of a Firmware File.\r
31 @param SectionType The Firmware Section type.\r
32 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
33 @param Size On output, the size of Buffer.\r
34\r
35 @retval EFI_SUCCESS The image is found and data and size is returned.\r
36 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
37 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
38 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
39 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
40\r
41**/\r
42STATIC\r
43EFI_STATUS\r
b0d803fe 44InternalGetImageFromFv (\r
1c280088 45 IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,\r
46 IN CONST EFI_GUID *NameGuid,\r
47 IN EFI_SECTION_TYPE SectionType,\r
48 OUT VOID **Buffer,\r
49 OUT UINTN *Size\r
50 )\r
51{\r
52 EFI_STATUS Status;\r
53 EFI_FV_FILETYPE FileType;\r
54 EFI_FV_FILE_ATTRIBUTES Attributes;\r
55 UINT32 AuthenticationStatus;\r
56\r
57 //\r
58 // Read desired section content in NameGuid file\r
59 //\r
60 *Buffer = NULL;\r
61 *Size = 0;\r
62 Status = Fv->ReadSection (\r
63 Fv,\r
64 NameGuid,\r
65 SectionType,\r
66 0,\r
67 Buffer,\r
68 Size,\r
69 &AuthenticationStatus\r
70 );\r
71\r
72 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
73 //\r
74 // Try reading PE32 section, since the TE section does not exist\r
75 //\r
76 *Buffer = NULL;\r
77 *Size = 0;\r
78 Status = Fv->ReadSection (\r
79 Fv,\r
80 NameGuid,\r
81 EFI_SECTION_PE32,\r
82 0,\r
83 Buffer,\r
84 Size,\r
85 &AuthenticationStatus\r
86 );\r
87 }\r
88\r
89 if (EFI_ERROR (Status) && \r
90 ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {\r
91 //\r
92 // Try reading raw file, since the desired section does not exist\r
93 //\r
94 *Buffer = NULL;\r
95 *Size = 0;\r
96 Status = Fv->ReadFile (\r
97 Fv,\r
98 NameGuid,\r
99 Buffer,\r
100 Size,\r
101 &FileType,\r
102 &Attributes,\r
103 &AuthenticationStatus\r
104 );\r
105 }\r
106\r
107 return Status;\r
108}\r
109\r
110/**\r
111 Allocate and fill a buffer with an image identified by a Firmware File GUID name and a Firmware Section type. \r
112 The Firmware Volumes to search for the Firmware File can be specified to be either all Firmware Volumes \r
113 in the system, or the Firmware Volume which contains the Firmware File specified by an image handle.\r
114\r
115 If ImageHandle is NULL, all Firmware Volumes in the system will be searched. If ImageHandle is not NULL, \r
116 ImageHandle is interpreted as EFI_PEI_FILE_HANDLE for the implementation of this function for PEI phase. \r
117 The input parameter ImageHandle is interpreted as EFI_HANDLE, on which an EFI_LOADED_IMAGE_PROTOCOL \r
118 is installed, for the implementation of this function for DXE phase. The search always starts from the FV \r
119 identified by ImageHandle. If WithinImageFv is TRUE, search will only be performed on the first FV. If WithinImageFv \r
120 is FALSE, search will continue on other FVs if it fails on the first FV. The search order of Firmware Volumes is \r
121 deterministic but arbitrary if no new firmware volume is added into the system between each search. \r
122 \r
123 The search order for the section type specified by SectionType in the Firmware File is using a depth-first \r
124 and left-to-right algorithm through all sections. The first section found to match SectionType will be returned. \r
125 \r
126 If SectionType is EFI_SECTION_PE32, EFI_SECTION_PE32 will be used as Firmware Section type \r
127 to read Firmware Section data from the Firmware File. If no such section exists, the function will try \r
128 to read a Firmware File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.\r
129 \r
130 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
131 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
132 read Firmware Section data from the Firmware File. If no such section exists, the function will try to read a Firmware \r
133 File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.\r
134 \r
135 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
136 by this function. This function can only be called at TPL_NOTIFY and below.\r
137 \r
138 If ImageHandle is NULL and WithinImage is TRUE, then ASSERT ();\r
139 If NameGuid is NULL, then ASSERT();\r
140 If Buffer is NULL, then ASSERT();\r
141 If Size is NULL, then ASSERT().\r
142\r
143 @param NameGuid The GUID name of a Firmware File.\r
144 @param SectionType The Firmware Section type.\r
145 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
146 @param Size On output, the size of Buffer.\r
147\r
148 @retval EFI_SUCCESS The image is found and data and size is returned.\r
149 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
150 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
151 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
152 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
153\r
154**/\r
155\r
156EFI_STATUS\r
157EFIAPI\r
158GetSectionFromFvFile (\r
159 IN CONST VOID *ImageHandle,\r
160 IN CONST EFI_GUID *NameGuid,\r
161 IN EFI_SECTION_TYPE SectionType,\r
162 OUT VOID **Buffer,\r
163 OUT UINTN *Size,\r
164 IN BOOLEAN WithinImageFv\r
165 )\r
166{\r
167 EFI_STATUS Status;\r
168 EFI_HANDLE *HandleBuffer;\r
169 UINTN HandleCount;\r
170 UINTN Index;\r
171 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
172 EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;\r
173 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
174\r
175 ASSERT (NameGuid != NULL);\r
176 ASSERT (Buffer != NULL);\r
177 ASSERT (Size != NULL);\r
178 ASSERT (!(ImageHandle == NULL && WithinImageFv));\r
179\r
180 Status = EFI_NOT_FOUND;\r
181 ImageFv = NULL;\r
182 if (ImageHandle != NULL) {\r
183 Status = gBS->HandleProtocol (\r
184 (EFI_HANDLE *) ImageHandle,\r
185 &gEfiLoadedImageProtocolGuid,\r
186 (VOID **) &LoadedImage\r
187 );\r
188 if (EFI_ERROR (Status)) {\r
189 return Status;\r
190 }\r
191 Status = gBS->HandleProtocol (\r
192 LoadedImage->DeviceHandle,\r
193 &gEfiFirmwareVolume2ProtocolGuid,\r
194 (VOID **) &ImageFv\r
195 );\r
196 if (!EFI_ERROR (Status)) {\r
b0d803fe 197 Status = InternalGetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);\r
1c280088 198 }\r
199 }\r
200\r
201 if (Status == EFI_SUCCESS || WithinImageFv) {\r
202 return Status;\r
203 }\r
204\r
205 HandleBuffer = NULL;\r
206 Status = gBS->LocateHandleBuffer (\r
207 ByProtocol,\r
208 &gEfiFirmwareVolume2ProtocolGuid,\r
209 NULL,\r
210 &HandleCount,\r
211 &HandleBuffer\r
212 );\r
213 if (EFI_ERROR (Status)) {\r
214 goto Done;\r
215 }\r
216\r
217 //\r
218 // Find desired image in all Fvs\r
219 //\r
220 for (Index = 0; Index < HandleCount; ++Index) {\r
221 Status = gBS->HandleProtocol (\r
222 HandleBuffer[Index],\r
223 &gEfiFirmwareVolume2ProtocolGuid,\r
224 (VOID**)&Fv\r
225 );\r
226\r
227 if (EFI_ERROR (Status)) {\r
228 goto Done;\r
229 }\r
230\r
231 if (ImageFv != NULL && Fv == ImageFv) {\r
232 continue;\r
233 }\r
234\r
b0d803fe 235 Status = InternalGetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);\r
1c280088 236\r
237 if (!EFI_ERROR (Status)) {\r
238 goto Done;\r
239 }\r
240 }\r
241\r
242 //\r
243 // Not found image\r
244 //\r
245 if (Index == HandleCount) {\r
246 Status = EFI_NOT_FOUND;\r
247 }\r
248\r
249Done:\r
250\r
251 if (HandleBuffer != NULL) { \r
252 FreePool(HandleBuffer);\r
253 }\r
254\r
255 return Status;\r
256}\r
257\r
b0d803fe 258EFI_HANDLE\r
259EFIAPI\r
260ImageHandleToFvHandle (\r
261 EFI_HANDLE ImageHandle\r
262 )\r
263{\r
264 EFI_STATUS Status;\r
265 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
266 \r
267 ASSERT (ImageHandle != NULL);\r
268\r
269 Status = gBS->HandleProtocol (\r
270 (EFI_HANDLE *) ImageHandle,\r
271 &gEfiLoadedImageProtocolGuid,\r
272 (VOID **) &LoadedImage\r
273 );\r
274\r
275 ASSERT_EFI_ERROR (Status);\r
276\r
277 return LoadedImage->DeviceHandle;\r
278\r
279}\r
280\r
281EFI_STATUS\r
282EFIAPI\r
283GetSectionFromAnyFv (\r
284 IN CONST EFI_GUID *NameGuid,\r
285 IN EFI_SECTION_TYPE SectionType,\r
286 IN UINTN Instance,\r
287 OUT VOID **Buffer,\r
288 OUT UINTN *Size\r
289 )\r
290{\r
291 EFI_STATUS Status;\r
292 EFI_HANDLE *HandleBuffer;\r
293 UINTN HandleCount;\r
294 UINTN Index;\r
295 EFI_HANDLE FvHandle;\r
296 EFI_TPL OldTpl;\r
297\r
298 //\r
299 // Search the FV that contain the caller's FFS first.\r
300 // FV builder can choose to build FFS into the this FV\r
301 // so that this implementation of GetSectionFromAnyFv\r
302 // will locate the FFS faster.\r
303 //\r
304 FvHandle = ImageHandleToFvHandle (gImageHandle);\r
305 Status = GetSectionFromFv (\r
306 FvHandle,\r
307 NameGuid,\r
308 SectionType,\r
309 Instance,\r
310 Buffer,\r
311 Size\r
312 );\r
313 if (!EFI_ERROR (Status)) {\r
314 return EFI_SUCCESS;\r
315 }\r
316\r
317 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
318 \r
319 HandleBuffer = NULL;\r
320 Status = gBS->LocateHandleBuffer (\r
321 ByProtocol,\r
322 &gEfiFirmwareVolume2ProtocolGuid,\r
323 NULL,\r
324 &HandleCount,\r
325 &HandleBuffer\r
326 );\r
327 if (EFI_ERROR (Status)) {\r
328 goto Done;\r
329 }\r
330\r
331 for (Index = 0; Index < HandleCount; ++Index) {\r
332 //\r
333 // Skip the FV that contain the caller's FFS\r
334 //\r
335 if (HandleBuffer[Index] == FvHandle) {\r
336 continue;\r
337 }\r
338\r
339 Status = GetSectionFromFv (\r
340 HandleBuffer[Index], \r
341 NameGuid, \r
342 SectionType, \r
343 Instance,\r
344 Buffer, \r
345 Size\r
346 );\r
347\r
348 if (!EFI_ERROR (Status)) {\r
349 goto Done;\r
350 }\r
351 }\r
352\r
353 if (Index == HandleCount) {\r
354 Status = EFI_NOT_FOUND;\r
355 }\r
356\r
357Done:\r
358 \r
359 gBS->RestoreTPL (OldTpl);\r
360 \r
361 if (HandleBuffer != NULL) { \r
362 FreePool(HandleBuffer);\r
363 }\r
364 return Status;\r
365 \r
366}\r
367\r
368EFI_STATUS\r
369EFIAPI\r
370GetSectionFromFv (\r
371 IN EFI_HANDLE FvHandle,\r
372 IN CONST EFI_GUID *NameGuid,\r
373 IN EFI_SECTION_TYPE SectionType,\r
374 IN UINTN Instance,\r
375 OUT VOID **Buffer,\r
376 OUT UINTN *Size\r
377 )\r
378{\r
379 EFI_STATUS Status;\r
380 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
381 UINT32 AuthenticationStatus;\r
382\r
383 ASSERT (FvHandle != NULL);\r
384\r
385 Status = gBS->HandleProtocol (\r
386 FvHandle,\r
387 &gEfiFirmwareVolume2ProtocolGuid,\r
388 (VOID **) &Fv\r
389 );\r
390 if (EFI_ERROR (Status)) {\r
391 return Status;\r
392 }\r
393\r
394 //\r
395 // Read desired section content in NameGuid file\r
396 //\r
397 *Buffer = NULL;\r
398 *Size = 0;\r
399 Status = Fv->ReadSection (\r
400 Fv,\r
401 NameGuid,\r
402 SectionType,\r
403 0,\r
404 Buffer,\r
405 Size,\r
406 &AuthenticationStatus\r
407 );\r
408\r
409 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
410 //\r
411 // Try reading PE32 section, if the required section is TE type \r
412 //\r
413 *Buffer = NULL;\r
414 *Size = 0;\r
415 Status = Fv->ReadSection (\r
416 Fv,\r
417 NameGuid,\r
418 EFI_SECTION_PE32,\r
419 0,\r
420 Buffer,\r
421 Size,\r
422 &AuthenticationStatus\r
423 );\r
424 }\r
425\r
426 return Status;\r
427}\r
428\r
429\r
430EFI_STATUS\r
431EFIAPI\r
432GetSectionFromCurrentFv (\r
433 IN CONST EFI_GUID *NameGuid,\r
434 IN EFI_SECTION_TYPE SectionType,\r
435 IN UINTN Instance,\r
436 OUT VOID **Buffer,\r
437 OUT UINTN *Size\r
438 )\r
439{\r
440 return GetSectionFromFv(\r
441 ImageHandleToFvHandle(gImageHandle),\r
442 NameGuid,\r
443 SectionType,\r
444 Instance,\r
445 Buffer,\r
446 Size\r
447 );\r
448}\r
449\r
450\r
451\r
452EFI_STATUS\r
453EFIAPI\r
454GetSectionFromCurrentFfs (\r
455 IN EFI_SECTION_TYPE SectionType,\r
456 IN UINTN Instance,\r
457 OUT VOID **Buffer,\r
458 OUT UINTN *Size\r
459 )\r
460{\r
461 return GetSectionFromFv(\r
462 ImageHandleToFvHandle(gImageHandle),\r
463 &gEfiCallerIdGuid,\r
464 SectionType,\r
465 Instance,\r
466 Buffer,\r
467 Size\r
468 );\r
469}\r
470\r