]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.c
Fix one bug in PeiExtractGuidedSectionLib to convert the address after hob start...
[mirror_edk2.git] / MdePkg / Library / PeiExtractGuidedSectionLib / PeiExtractGuidedSectionLib.c
1 /*++
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PeiExtractGuidedSectionLib.c
15
16 Abstract:
17
18 Provide generic extract guided section functions.
19
20 --*/
21
22 #include <PiPei.h>
23
24 #include <Library/DebugLib.h>
25 #include <Library/PcdLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/HobLib.h>
28 #include <Library/ExtractGuidedSectionLib.h>
29
30 #define PEI_EXTRACT_HANDLER_INFO_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'H', 'I')
31
32 typedef struct {
33 UINT32 Signature;
34 UINT32 NumberOfExtractHandler;
35 GUID *ExtractHandlerGuidTable;
36 EXTRACT_GUIDED_SECTION_DECODE_HANDLER *ExtractDecodeHandlerTable;
37 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;
38 } PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO;
39
40 /**
41 Build guid hob for the global memory to store the registered guid and Handler list.
42 If GuidHob exists, HandlerInfo will be directly got from Guid hob data.
43
44 @param[in, out] InfoPointer Pointer to pei handler info structure.
45
46 @retval RETURN_SUCCESS Build Guid hob for the global memory space to store guid and funciton tables.
47 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated.
48 **/
49 RETURN_STATUS
50 EFIAPI
51 PeiGetExtractGuidedSectionHandlerInfo (
52 IN OUT PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO **InfoPointer
53 )
54 {
55 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
56 EFI_PEI_HOB_POINTERS Hob;
57
58 //
59 // First try to get handler info from guid hob specified by CallerId.
60 //
61 Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GetHobList ());
62 while (Hob.Raw != NULL) {
63 if (CompareGuid (&(Hob.Guid->Name), &gEfiCallerIdGuid)) {
64 HandlerInfo = (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *) GET_GUID_HOB_DATA (Hob.Guid);
65 if (HandlerInfo->Signature == PEI_EXTRACT_HANDLER_INFO_SIGNATURE) {
66 //
67 // Update Table Pointer when hob start address is changed.
68 //
69 if (HandlerInfo->ExtractHandlerGuidTable != (GUID *) (HandlerInfo + 1)) {
70 HandlerInfo->ExtractHandlerGuidTable = (GUID *) (HandlerInfo + 1);
71 HandlerInfo->ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (
72 (UINT8 *)HandlerInfo->ExtractHandlerGuidTable +
73 PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)
74 );
75 HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (
76 (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable +
77 PcdGet32 (PcdMaximumGuidedExtractHandler) *
78 sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER)
79 );
80 }
81 //
82 // Return HandlerInfo pointer.
83 //
84 *InfoPointer = HandlerInfo;
85 return EFI_SUCCESS;
86 }
87 }
88 Hob.Raw = GET_NEXT_HOB (Hob);
89 Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, Hob.Raw);
90 }
91
92 //
93 // If Guid Hob is not found, Build CallerId Guid hob to store Handler Info
94 //
95 HandlerInfo = BuildGuidHob (
96 &gEfiCallerIdGuid,
97 sizeof (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO) +
98 PcdGet32 (PcdMaximumGuidedExtractHandler) *
99 (sizeof (GUID) + sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) + sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER))
100 );
101 if (HandlerInfo == NULL) {
102 //
103 // No enough resource to build guid hob.
104 //
105 return EFI_OUT_OF_RESOURCES;
106 }
107 HandlerInfo->Signature = PEI_EXTRACT_HANDLER_INFO_SIGNATURE;
108 HandlerInfo->NumberOfExtractHandler = 0;
109 HandlerInfo->ExtractHandlerGuidTable = (GUID *) (HandlerInfo + 1);
110 HandlerInfo->ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (
111 (UINT8 *)HandlerInfo->ExtractHandlerGuidTable +
112 PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)
113 );
114 HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (
115 (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable +
116 PcdGet32 (PcdMaximumGuidedExtractHandler) *
117 sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER)
118 );
119
120 *InfoPointer = HandlerInfo;
121 return EFI_SUCCESS;
122 }
123
124 /**
125 Get the supported exract guided section Handler guid list.
126 If ExtractHandlerGuidTable = NULL, then ASSERT.
127
128 @param[in, out] ExtractHandlerGuidTable The extract Handler guid pointer list.
129
130 @retval return the number of the supported extract guided Handler.
131 **/
132 UINTN
133 EFIAPI
134 ExtractGuidedSectionGetGuidList (
135 IN OUT GUID **ExtractHandlerGuidTable
136 )
137 {
138 EFI_STATUS Status;
139 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
140
141 ASSERT (ExtractHandlerGuidTable != NULL);
142
143 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
144 if (EFI_ERROR (Status)) {
145 return Status;
146 }
147
148 *ExtractHandlerGuidTable = HandlerInfo->ExtractHandlerGuidTable;
149 return HandlerInfo->NumberOfExtractHandler;
150 }
151
152 /**
153 Register Guided Section Extract and GetInfo handler.
154
155 @param[in] SectionGuid The guid matches this Extraction function.
156 @param[in] GetInfoHandler Function to get info from guided section.
157 @param[in] DecodeHandler Function to extract guided section.
158
159 @retval RETURN_SUCCESS Register Guided Section Extract function successfully.
160 @retval RETURN_OUT_OF_RESOURCES Resource is not enough to register new function.
161 @retval RETURN_INVALID_PARAMETER Input pointer to Guid value is not valid.
162 **/
163 RETURN_STATUS
164 EFIAPI
165 ExtractGuidedSectionRegisterHandlers (
166 IN CONST GUID *SectionGuid,
167 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler,
168 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler
169 )
170 {
171 EFI_STATUS Status;
172 UINT32 Index;
173 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
174
175 //
176 // Check input paramter.
177 //
178 if (SectionGuid == NULL) {
179 return RETURN_INVALID_PARAMETER;
180 }
181
182 //
183 // Get the registered handler information
184 //
185 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
186 if (EFI_ERROR (Status)) {
187 return Status;
188 }
189
190 //
191 // Search the match registered GetInfo handler for the input guided section.
192 //
193 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
194 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {
195 break;
196 }
197 }
198
199 //
200 // If the guided handler has been registered before, only update its handler.
201 //
202 if (Index < HandlerInfo->NumberOfExtractHandler) {
203 HandlerInfo->ExtractDecodeHandlerTable [Index] = DecodeHandler;
204 HandlerInfo->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;
205 return RETURN_SUCCESS;
206 }
207
208 //
209 // Check the global table is enough to contain new Handler.
210 //
211 if (HandlerInfo->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {
212 return RETURN_OUT_OF_RESOURCES;
213 }
214
215 //
216 // Register new Handler and guid value.
217 //
218 CopyGuid (HandlerInfo->ExtractHandlerGuidTable + HandlerInfo->NumberOfExtractHandler, SectionGuid);
219 HandlerInfo->ExtractDecodeHandlerTable [HandlerInfo->NumberOfExtractHandler] = DecodeHandler;
220 HandlerInfo->ExtractGetInfoHandlerTable [HandlerInfo->NumberOfExtractHandler++] = GetInfoHandler;
221
222 return RETURN_SUCCESS;
223 }
224
225 /**
226 Get information from the guided section. This function first gets the guid value
227 from guided section header, then match this guid in the registered extract Handler list
228 to its corresponding getinfo Handler.
229 If not found, RETURN_INVALID_PARAMETER will be return.
230 If found, it will call the getinfo Handler to get the required size and attribute.
231
232 It will ASSERT () if the pointer to OutputBufferSize is NULL.
233 It will ASSERT () if the pointer to ScratchBufferSize is NULL.
234 It will ASSERT () if the pointer to SectionAttribute is NULL.
235
236 @param[in] InputSection Buffer containing the input GUIDed section to be processed.
237 @param[out] OutputBufferSize The size of OutputBuffer.
238 @param[out] ScratchBufferSize The size of ScratchBuffer.
239 @param[out] SectionAttribute The attribute of the input guided section.
240
241 @retval RETURN_SUCCESS Get the required information successfully.
242 @retval RETURN_INVALID_PARAMETER The input data can't be parsed correctly.
243 The GUID in InputSection does not match any registered guid list.
244
245 **/
246 RETURN_STATUS
247 EFIAPI
248 ExtractGuidedSectionGetInfo (
249 IN CONST VOID *InputSection,
250 OUT UINT32 *OutputBufferSize,
251 OUT UINT32 *ScratchBufferSize,
252 OUT UINT16 *SectionAttribute
253 )
254 {
255 UINT32 Index;
256 EFI_STATUS Status;
257 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
258
259 //
260 // Check input paramter
261 //
262 if (InputSection == NULL) {
263 return RETURN_INVALID_PARAMETER;
264 }
265
266 ASSERT (OutputBufferSize != NULL);
267 ASSERT (ScratchBufferSize != NULL);
268 ASSERT (SectionAttribute != NULL);
269
270 //
271 // Get the registered handler information.
272 //
273 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
274 if (EFI_ERROR (Status)) {
275 return Status;
276 }
277
278 //
279 // Search the match registered GetInfo handler for the input guided section.
280 //
281 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
282 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
283 break;
284 }
285 }
286
287 //
288 // Not found, the input guided section is not supported.
289 //
290 if (Index == HandlerInfo->NumberOfExtractHandler) {
291 return RETURN_INVALID_PARAMETER;
292 }
293
294 //
295 // Call the match handler to getinfo for the input section data.
296 //
297 return HandlerInfo->ExtractGetInfoHandlerTable [Index] (
298 InputSection,
299 OutputBufferSize,
300 ScratchBufferSize,
301 SectionAttribute
302 );
303 }
304
305 /**
306 Extract data from the guided section. This function first gets the guid value
307 from guided section header, then match this guid in the registered extract Handler list
308 to its corresponding extract Handler.
309 If not found, RETURN_INVALID_PARAMETER will be return.
310 If found, it will call this extract Handler to get output data and AuthenticationStatus.
311
312 It will ASSERT () if the pointer to OutputBuffer is NULL.
313 It will ASSERT () if the pointer to AuthenticationStatus is NULL.
314
315 @param[in] InputSection Buffer containing the input GUIDed section to be processed.
316 @param[out] OutputBuffer OutputBuffer to point the start of the section's contents
317 if guided data is not required prcessing. Otherwise,
318 OutputBuffer to contain the output data, which is
319 allocated by the caller.
320 @param[out] ScratchBuffer A pointer to a caller-allocated buffer for function internal use.
321 @param[out] AuthenticationStatus
322 A pointer to a caller-allocated UINT32 that indicates the
323 authentication status of the output buffer.
324
325 @retval RETURN_SUCCESS Get the output data, size and AuthenticationStatus successfully.
326 @retval RETURN_INVALID_PARAMETER The input data can't be parsed correctly.
327 The GUID in InputSection does not match any registered guid list.
328
329 **/
330 RETURN_STATUS
331 EFIAPI
332 ExtractGuidedSectionDecode (
333 IN CONST VOID *InputSection,
334 OUT VOID **OutputBuffer,
335 OUT VOID *ScratchBuffer, OPTIONAL
336 OUT UINT32 *AuthenticationStatus
337 )
338 {
339 UINT32 Index;
340 EFI_STATUS Status;
341 PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
342
343 if (InputSection == NULL) {
344 return RETURN_INVALID_PARAMETER;
345 }
346
347 ASSERT (OutputBuffer != NULL);
348 ASSERT (AuthenticationStatus != NULL);
349
350 Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
351 if (EFI_ERROR (Status)) {
352 return Status;
353 }
354
355 //
356 // Search the match registered GetInfo handler for the input guided section.
357 //
358 for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
359 if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
360 break;
361 }
362 }
363
364 //
365 // Not found, the input guided section is not supported.
366 //
367 if (Index == HandlerInfo->NumberOfExtractHandler) {
368 return RETURN_INVALID_PARAMETER;
369 }
370
371 //
372 // Call the match handler to getinfo for the input section data.
373 //
374 return HandlerInfo->ExtractDecodeHandlerTable [Index] (
375 InputSection,
376 OutputBuffer,
377 ScratchBuffer,
378 AuthenticationStatus
379 );
380 }