VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.c@ 57260

Last change on this file since 57260 was 48674, checked in by vboxsync, 11 years ago

EFI: Export newly imported tinaocore UEFI sources to OSE.

  • Property svn:eol-style set to native
File size: 20.4 KB
Line 
1/** @file
2 Provide generic extract guided section functions for PEI phase.
3
4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include <PiPei.h>
16
17#include <Library/DebugLib.h>
18#include <Library/PcdLib.h>
19#include <Library/BaseMemoryLib.h>
20#include <Library/HobLib.h>
21#include <Library/ExtractGuidedSectionLib.h>
22
23#define PEI_EXTRACT_HANDLER_INFO_SIGNATURE SIGNATURE_32 ('P', 'E', 'H', 'I')
24
25typedef struct {
26 UINT32 Signature;
27 UINT32 NumberOfExtractHandler;
28 GUID *ExtractHandlerGuidTable;
29 EXTRACT_GUIDED_SECTION_DECODE_HANDLER *ExtractDecodeHandlerTable;
30 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;
31} PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO;
32
33/**
34 Build guid hob for the global memory to store the registered guid and Handler list.
35 If GuidHob exists, HandlerInfo will be directly got from Guid hob data.
36
37 @param[in, out] InfoPointer The pointer to pei handler information structure.
38
39 @retval RETURN_SUCCESS Build Guid hob for the global memory space to store guid and function tables.
40 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated.
41**/
42RETURN_STATUS
43PeiGetExtractGuidedSectionHandlerInfo (
44 IN OUT PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO **InfoPointer
45 )
46{
47 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
48 EFI_PEI_HOB_POINTERS Hob;
49
50 //
51 // First try to get handler information from guid hob specified by CallerId.
52 //
53 Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GetHobList ());
54 while (Hob.Raw != NULL) {
55 if (CompareGuid (&(Hob.Guid->Name), &gEfiCallerIdGuid)) {
56 HandlerInfo = (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *) GET_GUID_HOB_DATA (Hob.Guid);
57 if (HandlerInfo->Signature == PEI_EXTRACT_HANDLER_INFO_SIGNATURE) {
58 //
59 // Update Table Pointer when hob start address is changed.
60 //
61 if (HandlerInfo->ExtractHandlerGuidTable != (GUID *) (HandlerInfo + 1)) {
62 HandlerInfo->ExtractHandlerGuidTable = (GUID *) (HandlerInfo + 1);
63 HandlerInfo->ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (
64 (UINT8 *)HandlerInfo->ExtractHandlerGuidTable +
65 PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)
66 );
67 HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (
68 (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable +
69 PcdGet32 (PcdMaximumGuidedExtractHandler) *
70 sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)
71 );
72 }
73 //
74 // Return HandlerInfo pointer.
75 //
76 *InfoPointer = HandlerInfo;
77 return EFI_SUCCESS;
78 }
79 }
80 Hob.Raw = GET_NEXT_HOB (Hob);
81 Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, Hob.Raw);
82 }
83
84 //
85 // If Guid Hob is not found, Build CallerId Guid hob to store Handler Info
86 //
87 HandlerInfo = BuildGuidHob (
88 &gEfiCallerIdGuid,
89 sizeof (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO) +
90 PcdGet32 (PcdMaximumGuidedExtractHandler) *
91 (sizeof (GUID) + sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) + sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER))
92 );
93 if (HandlerInfo == NULL) {
94 //
95 // No enough resource to build guid hob.
96 //
97 *InfoPointer = NULL;
98 return EFI_OUT_OF_RESOURCES;
99 }
100 //
101 // Init HandlerInfo structure
102 //
103 HandlerInfo->Signature = PEI_EXTRACT_HANDLER_INFO_SIGNATURE;
104 HandlerInfo->NumberOfExtractHandler = 0;
105 HandlerInfo->ExtractHandlerGuidTable = (GUID *) (HandlerInfo + 1);
106 HandlerInfo->ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (
107 (UINT8 *)HandlerInfo->ExtractHandlerGuidTable +
108 PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)
109 );
110 HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (
111 (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable +
112 PcdGet32 (PcdMaximumGuidedExtractHandler) *
113 sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)
114 );
115 //
116 // return the created HandlerInfo.
117 //
118 *InfoPointer = HandlerInfo;
119 return EFI_SUCCESS;
120}
121
122/**
123 Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().
124
125 Sets ExtractHandlerGuidTable so it points at a callee allocated array of registered GUIDs.
126 The total number of GUIDs in the array are returned. Since the array of GUIDs is callee allocated
127 and caller must treat this array of GUIDs as read-only data.
128 If ExtractHandlerGuidTable is NULL, then ASSERT().
129
130 @param[out] ExtractHandlerGuidTable A pointer to the array of GUIDs that have been registered through
131 ExtractGuidedSectionRegisterHandlers().
132
133 @return the number of the supported extract guided Handler.
134
135**/
136UINTN
137EFIAPI
138ExtractGuidedSectionGetGuidList (
139 OUT GUID **ExtractHandlerGuidTable
140 )
141{
142 EFI_STATUS Status;
143 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
144
145 ASSERT (ExtractHandlerGuidTable != NULL);
146
147 //
148 // Get all registered handler information
149 //
150 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
151 if (EFI_ERROR (Status)) {
152 *ExtractHandlerGuidTable = NULL;
153 return 0;
154 }
155
156 //
157 // Get GuidTable and Table Number
158 //
159 ASSERT (HandlerInfo != NULL);
160 *ExtractHandlerGuidTable = HandlerInfo->ExtractHandlerGuidTable;
161 return HandlerInfo->NumberOfExtractHandler;
162}
163
164/**
165 Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER
166 for a specific GUID section type.
167
168 Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.
169 If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.
170 If there are not enough resources available to register the handlers then RETURN_OUT_OF_RESOURCES is returned.
171
172 If SectionGuid is NULL, then ASSERT().
173 If GetInfoHandler is NULL, then ASSERT().
174 If DecodeHandler is NULL, then ASSERT().
175
176 @param[in] SectionGuid A pointer to the GUID associated with the the handlers
177 of the GUIDed section type being registered.
178 @param[in] GetInfoHandler The pointer to a function that examines a GUIDed section and returns the
179 size of the decoded buffer and the size of an optional scratch buffer
180 required to actually decode the data in a GUIDed section.
181 @param[in] DecodeHandler The pointer to a function that decodes a GUIDed section into a caller
182 allocated output buffer.
183
184 @retval RETURN_SUCCESS The handlers were registered.
185 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to register the handlers.
186
187**/
188RETURN_STATUS
189EFIAPI
190ExtractGuidedSectionRegisterHandlers (
191 IN CONST GUID *SectionGuid,
192 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler,
193 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler
194 )
195{
196 EFI_STATUS Status;
197 UINT32 Index;
198 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
199
200 //
201 // Check input paramter
202 //
203 ASSERT (SectionGuid != NULL);
204 ASSERT (GetInfoHandler != NULL);
205 ASSERT (DecodeHandler != NULL);
206
207
208
209 //
210 // Get the registered handler information
211 //
212 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
213 if (EFI_ERROR (Status)) {
214 return Status;
215 }
216
217 //
218 // Search the match registered GetInfo handler for the input guided section.
219 //
220 ASSERT (HandlerInfo != NULL);
221 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
222 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {
223 //
224 // If the guided handler has been registered before, only update its handler.
225 //
226 HandlerInfo->ExtractDecodeHandlerTable [Index] = DecodeHandler;
227 HandlerInfo->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;
228 return RETURN_SUCCESS;
229 }
230 }
231
232 //
233 // Check the global table is enough to contain new Handler.
234 //
235 if (HandlerInfo->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {
236 return RETURN_OUT_OF_RESOURCES;
237 }
238
239 //
240 // Register new Handler and guid value.
241 //
242 CopyGuid (HandlerInfo->ExtractHandlerGuidTable + HandlerInfo->NumberOfExtractHandler, SectionGuid);
243 HandlerInfo->ExtractDecodeHandlerTable [HandlerInfo->NumberOfExtractHandler] = DecodeHandler;
244 HandlerInfo->ExtractGetInfoHandlerTable [HandlerInfo->NumberOfExtractHandler++] = GetInfoHandler;
245
246 return RETURN_SUCCESS;
247}
248
249/**
250 Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type
251 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().
252 The selected handler is used to retrieve and return the size of the decoded buffer and the size of an
253 optional scratch buffer required to actually decode the data in a GUIDed section.
254
255 Examines a GUIDed section specified by InputSection.
256 If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),
257 then RETURN_UNSUPPORTED is returned.
258 If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler
259 of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()
260 is used to retrieve the OututBufferSize, ScratchSize, and Attributes values. The return status from the handler of
261 type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned.
262
263 If InputSection is NULL, then ASSERT().
264 If OutputBufferSize is NULL, then ASSERT().
265 If ScratchBufferSize is NULL, then ASSERT().
266 If SectionAttribute is NULL, then ASSERT().
267
268 @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.
269 @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required if the buffer
270 specified by InputSection were decoded.
271 @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space if the buffer specified by
272 InputSection were decoded.
273 @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes field of
274 EFI_GUID_DEFINED_SECTION in the PI Specification.
275
276 @retval RETURN_SUCCESS Get the required information successfully.
277 @retval RETURN_UNSUPPORTED The GUID from the section specified by InputSection does not match any of
278 the GUIDs registered with ExtractGuidedSectionRegisterHandlers().
279 @retval Others The return status from the handler associated with the GUID retrieved from
280 the section specified by InputSection.
281
282**/
283RETURN_STATUS
284EFIAPI
285ExtractGuidedSectionGetInfo (
286 IN CONST VOID *InputSection,
287 OUT UINT32 *OutputBufferSize,
288 OUT UINT32 *ScratchBufferSize,
289 OUT UINT16 *SectionAttribute
290 )
291{
292 UINT32 Index;
293 EFI_STATUS Status;
294 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
295 EFI_GUID *SectionDefinitionGuid;
296
297 //
298 // Check input paramter
299 //
300 ASSERT (InputSection != NULL);
301 ASSERT (OutputBufferSize != NULL);
302 ASSERT (ScratchBufferSize != NULL);
303 ASSERT (SectionAttribute != NULL);
304
305 //
306 // Get all registered handler information.
307 //
308 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
309 if (EFI_ERROR (Status)) {
310 return Status;
311 }
312
313 if (IS_SECTION2 (InputSection)) {
314 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);
315 } else {
316 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);
317 }
318
319 //
320 // Search the match registered GetInfo handler for the input guided section.
321 //
322 ASSERT (HandlerInfo != NULL);
323 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
324 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {
325 //
326 // Call the match handler to get information for the input section data.
327 //
328 return HandlerInfo->ExtractGetInfoHandlerTable [Index] (
329 InputSection,
330 OutputBufferSize,
331 ScratchBufferSize,
332 SectionAttribute
333 );
334 }
335 }
336
337 //
338 // Not found, the input guided section is not supported.
339 //
340 return RETURN_UNSUPPORTED;
341}
342
343/**
344 Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type
345 EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().
346 The selected handler is used to decode the data in a GUIDed section and return the result in a caller
347 allocated output buffer.
348
349 Decodes the GUIDed section specified by InputSection.
350 If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),
351 then RETURN_UNSUPPORTED is returned.
352 If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler
353 of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()
354 is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this
355 decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the data in InputSection,
356 then OutputBuffer is set to point at the data in InputSection. Otherwise, the decoded data will be placed in caller
357 allocated buffer specified by OutputBuffer. This function is responsible for computing the EFI_AUTH_STATUS_PLATFORM_OVERRIDE
358 bit of in AuthenticationStatus. The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned.
359
360 If InputSection is NULL, then ASSERT().
361 If OutputBuffer is NULL, then ASSERT().
362 If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
363 If AuthenticationStatus is NULL, then ASSERT().
364
365 @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.
366 @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation.
367 @param[in] ScratchBuffer A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation.
368 @param[out] AuthenticationStatus
369 A pointer to the authentication status of the decoded output buffer. See the definition
370 of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI
371 Specification.
372
373 @retval RETURN_SUCCESS The buffer specified by InputSection was decoded.
374 @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.
375 @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.
376
377**/
378RETURN_STATUS
379EFIAPI
380ExtractGuidedSectionDecode (
381 IN CONST VOID *InputSection,
382 OUT VOID **OutputBuffer,
383 IN VOID *ScratchBuffer, OPTIONAL
384 OUT UINT32 *AuthenticationStatus
385 )
386{
387 UINT32 Index;
388 EFI_STATUS Status;
389 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
390 EFI_GUID *SectionDefinitionGuid;
391
392 //
393 // Check input parameter
394 //
395 ASSERT (InputSection != NULL);
396 ASSERT (OutputBuffer != NULL);
397 ASSERT (AuthenticationStatus != NULL);
398
399 //
400 // Get all registered handler information.
401 //
402 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
403 if (EFI_ERROR (Status)) {
404 return Status;
405 }
406
407 if (IS_SECTION2 (InputSection)) {
408 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);
409 } else {
410 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);
411 }
412
413 //
414 // Search the match registered Extract handler for the input guided section.
415 //
416 ASSERT (HandlerInfo != NULL);
417 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
418 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {
419 //
420 // Call the match handler to extract raw data for the input guided section.
421 //
422 return HandlerInfo->ExtractDecodeHandlerTable [Index] (
423 InputSection,
424 OutputBuffer,
425 ScratchBuffer,
426 AuthenticationStatus
427 );
428 }
429 }
430
431 //
432 // Not found, the input guided section is not supported.
433 //
434 return RETURN_UNSUPPORTED;
435}
436
437/**
438 Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and
439 EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.
440
441 Retrieves the handlers associated with SectionGuid and returns them in
442 GetInfoHandler and DecodeHandler.
443
444 If the GUID value specified by SectionGuid has not been registered, then
445 return RETURN_NOT_FOUND.
446
447 If SectionGuid is NULL, then ASSERT().
448
449 @param[in] SectionGuid A pointer to the GUID associated with the handlersof the GUIDed
450 section type being retrieved.
451 @param[out] GetInfoHandler Pointer to a function that examines a GUIDed section and returns
452 the size of the decoded buffer and the size of an optional scratch
453 buffer required to actually decode the data in a GUIDed section.
454 This is an optional parameter that may be NULL. If it is NULL, then
455 the previously registered handler is not returned.
456 @param[out] DecodeHandler Pointer to a function that decodes a GUIDed section into a caller
457 allocated output buffer. This is an optional parameter that may be NULL.
458 If it is NULL, then the previously registered handler is not returned.
459
460 @retval RETURN_SUCCESS The handlers were retrieved.
461 @retval RETURN_NOT_FOUND No handlers have been registered with the specified GUID.
462
463**/
464RETURN_STATUS
465EFIAPI
466ExtractGuidedSectionGetHandlers (
467 IN CONST GUID *SectionGuid,
468 OUT EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *GetInfoHandler, OPTIONAL
469 OUT EXTRACT_GUIDED_SECTION_DECODE_HANDLER *DecodeHandler OPTIONAL
470 )
471{
472 EFI_STATUS Status;
473 UINT32 Index;
474 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
475
476 //
477 // Check input parameter
478 //
479 ASSERT (SectionGuid != NULL);
480
481 //
482 // Get the registered handler information
483 //
484 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
485 if (EFI_ERROR (Status)) {
486 return Status;
487 }
488
489 //
490 // Search the match registered GetInfo handler for the input guided section.
491 //
492 ASSERT (HandlerInfo != NULL);
493 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
494 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {
495
496 //
497 // If the guided handler has been registered before, then return the registered handlers.
498 //
499 if (GetInfoHandler != NULL) {
500 *GetInfoHandler = HandlerInfo->ExtractGetInfoHandlerTable[Index];
501 }
502 if (DecodeHandler != NULL) {
503 *DecodeHandler = HandlerInfo->ExtractDecodeHandlerTable[Index];
504 }
505 return RETURN_SUCCESS;
506 }
507 }
508 return RETURN_NOT_FOUND;
509}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette