]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxePiLib/DxePiLib.c
Update Hob Instance to remove the unused InternalHobLib.h file.
[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
166152e8 19#include <Library/DxePiLib.h>\r
1c280088 20#include <Protocol/FirmwareVolume2.h>\r
21#include <Protocol/LoadedImage.h>\r
22\r
23\r
24/**\r
166152e8 25 Identify the device handle from which the Image is loaded from. As this device handle is passed to\r
26 GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL \r
27 protocol instance should be located succesfully by calling gBS->HandleProtocol ().\r
1c280088 28\r
166152e8 29 This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed\r
30 on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.\r
31 \r
32 If ImageHandle is NULL, then ASSERT ();\r
33 If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();\r
34 \r
35 @param ImageHandle The firmware allocated handle for UEFI image.\r
1c280088 36\r
166152e8 37 @retval EFI_HANDLE The device handle from which the Image is loaded from.\r
1c280088 38\r
39**/\r
166152e8 40EFI_HANDLE\r
41InternalImageHandleToFvHandle (\r
42 EFI_HANDLE ImageHandle\r
43 )\r
44{\r
45 EFI_STATUS Status;\r
46 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
47 \r
48 ASSERT (ImageHandle != NULL);\r
49\r
50 Status = gBS->HandleProtocol (\r
51 (EFI_HANDLE *) ImageHandle,\r
52 &gEfiLoadedImageProtocolGuid,\r
53 (VOID **) &LoadedImage\r
54 );\r
55\r
56 ASSERT_EFI_ERROR (Status);\r
57\r
58 return LoadedImage->DeviceHandle;\r
59\r
60}\r
61\r
62/**\r
63 Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware \r
64 Section type and instance number from the specified Firmware Volume.\r
65 \r
66 This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to \r
67 carry out the Firmware Volume read operation. The function then reads the Firmware Section found sepcifed \r
68 by NameGuid, SectionType and Instance. \r
69 \r
70 The search order for the section specified by SectionType within a Firmware File is defined by\r
71 EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization \r
72 Shared Architectural Elements for detailes.\r
73 \r
74 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
75 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
76 read Firmware Section data from the Firmware File. If no such section specified is found to match , \r
77 EFI_NOT_FOUND is returned.\r
78 \r
79 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
80 by this function. This function can be only called at TPL_NOTIFY and below.\r
81 \r
82 If FvHandle is NULL, then ASSERT ();\r
83 If NameGuid is NULL, then ASSERT();\r
84 If Buffer is NULL, then ASSERT();\r
85 If Size is NULL, then ASSERT().\r
86\r
87 @param FvHandle The device handle that contains a instance of EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
88 @param NameGuid The GUID name of a Firmware File.\r
89 @param SectionType The Firmware Section type.\r
90 @param Instance The instance number of Firmware Section to read from starting from 0.\r
91 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
92 @param Size On output, the size of Buffer.\r
93 \r
94 @retval EFI_SUCCESS The image is found and data and size is returned.\r
95 @retval EFI_UNSUPPORTED FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.\r
96 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
97 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
98 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
99 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
100 \r
f80b0830 101**/\r
1c280088 102EFI_STATUS\r
166152e8 103GetSectionFromFv (\r
104 IN EFI_HANDLE FvHandle,\r
105 IN CONST EFI_GUID *NameGuid,\r
106 IN EFI_SECTION_TYPE SectionType,\r
107 IN UINTN Instance,\r
108 OUT VOID **Buffer,\r
109 OUT UINTN *Size\r
1c280088 110 )\r
111{\r
166152e8 112 EFI_STATUS Status;\r
113 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
114 UINT32 AuthenticationStatus;\r
115\r
116 ASSERT (FvHandle != NULL);\r
117\r
118 Status = gBS->HandleProtocol (\r
119 FvHandle,\r
120 &gEfiFirmwareVolume2ProtocolGuid,\r
121 (VOID **) &Fv\r
122 );\r
123 if (EFI_ERROR (Status)) {\r
124 return Status;\r
125 }\r
1c280088 126\r
127 //\r
128 // Read desired section content in NameGuid file\r
129 //\r
130 *Buffer = NULL;\r
131 *Size = 0;\r
132 Status = Fv->ReadSection (\r
133 Fv,\r
134 NameGuid,\r
135 SectionType,\r
136 0,\r
137 Buffer,\r
138 Size,\r
139 &AuthenticationStatus\r
140 );\r
141\r
142 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
143 //\r
166152e8 144 // Try reading PE32 section, if the required section is TE type \r
1c280088 145 //\r
146 *Buffer = NULL;\r
147 *Size = 0;\r
148 Status = Fv->ReadSection (\r
149 Fv,\r
150 NameGuid,\r
151 EFI_SECTION_PE32,\r
152 0,\r
153 Buffer,\r
154 Size,\r
155 &AuthenticationStatus\r
156 );\r
157 }\r
158\r
1c280088 159 return Status;\r
160}\r
161\r
b0d803fe 162\r
b0d803fe 163\r
f80b0830 164/**\r
165 Allocate and fill a buffer from the Firmware Section identified by a Firmware File GUID name and a Firmware \r
166 Section type and instance number from any Firmware Volumes in the system.\r
167 \r
168 The function will read the first Firmware Section sepcifed by NameGuid, SectionType and Instance by searching\r
169 for all Firmware Volumes in the system. \r
170\r
171 The search order for Firmware Volumes in the system is determistic but abitrary if no new Firmware Volume is installed\r
172 into the system. The search order for the section specified by SectionType within a Firmware File is defined by\r
173 EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization \r
174 Shared Architectural Elements for detailes.\r
175 \r
176 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
177 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
178 read Firmware Section data from the Firmware File. If no such section specified is found to match , \r
179 EFI_NOT_FOUND is returned.\r
180\r
181 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
182 by this function. This function can only be called at TPL_NOTIFY and below.\r
183 \r
184 If NameGuid is NULL, then ASSERT();\r
185 If Buffer is NULL, then ASSERT();\r
186 If Size is NULL, then ASSERT().\r
187 \r
188 @param NameGuid The GUID name of a Firmware File.\r
189 @param SectionType The Firmware Section type.\r
190 @param Instance The instance number of Firmware Section to read from starting from 0.\r
191 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
192 @param Size On output, the size of Buffer.\r
193 \r
194 @retval EFI_SUCCESS The image is found and data and size is returned.\r
195 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
196 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
197 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
198 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
199 \r
200**/\r
b0d803fe 201EFI_STATUS\r
202EFIAPI\r
166152e8 203PiLibGetSectionFromAnyFv (\r
b0d803fe 204 IN CONST EFI_GUID *NameGuid,\r
205 IN EFI_SECTION_TYPE SectionType,\r
206 IN UINTN Instance,\r
207 OUT VOID **Buffer,\r
208 OUT UINTN *Size\r
209 )\r
210{\r
211 EFI_STATUS Status;\r
212 EFI_HANDLE *HandleBuffer;\r
213 UINTN HandleCount;\r
214 UINTN Index;\r
215 EFI_HANDLE FvHandle;\r
216 EFI_TPL OldTpl;\r
217\r
218 //\r
219 // Search the FV that contain the caller's FFS first.\r
220 // FV builder can choose to build FFS into the this FV\r
221 // so that this implementation of GetSectionFromAnyFv\r
222 // will locate the FFS faster.\r
223 //\r
166152e8 224 FvHandle = InternalImageHandleToFvHandle (gImageHandle);\r
b0d803fe 225 Status = GetSectionFromFv (\r
226 FvHandle,\r
227 NameGuid,\r
228 SectionType,\r
229 Instance,\r
230 Buffer,\r
231 Size\r
232 );\r
233 if (!EFI_ERROR (Status)) {\r
234 return EFI_SUCCESS;\r
235 }\r
236\r
237 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
238 \r
239 HandleBuffer = NULL;\r
240 Status = gBS->LocateHandleBuffer (\r
241 ByProtocol,\r
242 &gEfiFirmwareVolume2ProtocolGuid,\r
243 NULL,\r
244 &HandleCount,\r
245 &HandleBuffer\r
246 );\r
247 if (EFI_ERROR (Status)) {\r
248 goto Done;\r
249 }\r
250\r
251 for (Index = 0; Index < HandleCount; ++Index) {\r
252 //\r
253 // Skip the FV that contain the caller's FFS\r
254 //\r
255 if (HandleBuffer[Index] == FvHandle) {\r
256 continue;\r
257 }\r
258\r
259 Status = GetSectionFromFv (\r
260 HandleBuffer[Index], \r
261 NameGuid, \r
262 SectionType, \r
263 Instance,\r
264 Buffer, \r
265 Size\r
266 );\r
267\r
268 if (!EFI_ERROR (Status)) {\r
269 goto Done;\r
270 }\r
271 }\r
272\r
273 if (Index == HandleCount) {\r
274 Status = EFI_NOT_FOUND;\r
275 }\r
276\r
277Done:\r
278 \r
279 gBS->RestoreTPL (OldTpl);\r
280 \r
281 if (HandleBuffer != NULL) { \r
282 FreePool(HandleBuffer);\r
283 }\r
284 return Status;\r
285 \r
286}\r
287\r
f80b0830 288/**\r
289 Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware \r
290 Section type and instance number from the same Firmware Volume with the caller's FFS.\r
291 \r
292 This functions first locates the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance for same Firmrware Volume\r
293 which also contains the FFS of the caller in order to carry out the Firmware Volume read operation. \r
294 The function then reads the Firmware Section found sepcifed by NameGuid, SectionType and Instance. \r
295 \r
296 The search order for the section specified by SectionType within a Firmware File is defined by\r
297 EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization \r
298 Shared Architectural Elements for detailes.\r
299 \r
300 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
301 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
302 read Firmware Section data from the Firmware File. If no such section specified is found to match , \r
303 EFI_NOT_FOUND is returned.\r
304 \r
305 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
306 by this function. This function can be only called at TPL_NOTIFY and below.\r
307 \r
308 If FvHandle is NULL, then ASSERT ();\r
309 If NameGuid is NULL, then ASSERT();\r
310 If Buffer is NULL, then ASSERT();\r
311 If Size is NULL, then ASSERT().\r
312\r
313 @param NameGuid The GUID name of a Firmware File.\r
314 @param SectionType The Firmware Section type.\r
315 @param Instance The instance number of Firmware Section to read from starting from 0.\r
316 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
317 @param Size On output, the size of Buffer.\r
318 \r
319 @retval EFI_SUCCESS The image is found and data and size is returned.\r
320 @retval EFI_UNSUPPORTED FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.\r
321 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
322 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
323 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
324 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
325 \r
326**/\r
b0d803fe 327EFI_STATUS\r
328EFIAPI\r
166152e8 329PiLibGetSectionFromCurrentFv (\r
b0d803fe 330 IN CONST EFI_GUID *NameGuid,\r
331 IN EFI_SECTION_TYPE SectionType,\r
332 IN UINTN Instance,\r
333 OUT VOID **Buffer,\r
334 OUT UINTN *Size\r
335 )\r
336{\r
337 return GetSectionFromFv(\r
166152e8 338 InternalImageHandleToFvHandle(gImageHandle),\r
b0d803fe 339 NameGuid,\r
340 SectionType,\r
341 Instance,\r
342 Buffer,\r
343 Size\r
344 );\r
345}\r
346\r
347\r
f80b0830 348/**\r
349 Allocate and fill a buffer from the first Firmware Section in the same Firmware File as the caller of this function.\r
350 \r
351 The function will read the first Firmware Section found sepcifed by NameGuid and SectionType from the \r
352 Firmware Volume specified by FvHandle. On this FvHandle, an EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance \r
353 should be located succesfully in order to carry out the Firmware Volume operations.\r
354 \r
355 The search order for the section type specified by SectionType in the Firmware File is using a depth-first \r
356 and left-to-right algorithm through all sections. The first section found to match SectionType will be returned. \r
357 \r
358 If SectionType is EFI_SECTION_PE32, EFI_SECTION_PE32 will be used as Firmware Section type \r
359 to read Firmware Section data from the Firmware File. If no such section exists, the function will try \r
360 to read a Firmware File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.\r
361 \r
362 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
363 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
364 read Firmware Section data from the Firmware File. If no such section exists, the function will try to read a Firmware \r
365 File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.\r
366 \r
367 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
368 by this function. This function can only be called at TPL_NOTIFY and below.\r
369 \r
370 If FvHandle is NULL and WithinImage is TRUE, then ASSERT ();\r
371 If NameGuid is NULL, then ASSERT();\r
372 If Buffer is NULL, then ASSERT();\r
373 If Size is NULL, then ASSERT().\r
374 \r
375 @param NameGuid The GUID name of a Firmware File.\r
376 @param SectionType The Firmware Section type.\r
377 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
378 @param Size On output, the size of Buffer.\r
379 \r
380 @retval EFI_SUCCESS The image is found and data and size is returned.\r
381 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
382 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
383 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
384 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
385 \r
386**/\r
b0d803fe 387EFI_STATUS\r
388EFIAPI\r
166152e8 389PiLibGetSectionFromCurrentFfs (\r
b0d803fe 390 IN EFI_SECTION_TYPE SectionType,\r
391 IN UINTN Instance,\r
392 OUT VOID **Buffer,\r
393 OUT UINTN *Size\r
394 )\r
395{\r
396 return GetSectionFromFv(\r
166152e8 397 InternalImageHandleToFvHandle(gImageHandle),\r
b0d803fe 398 &gEfiCallerIdGuid,\r
399 SectionType,\r
400 Instance,\r
401 Buffer,\r
402 Size\r
403 );\r
404}\r
405\r