1 /** @file
2
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4
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 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/ExtractGuidedSectionLib.h>
19 #include <Library/PcdLib.h>
20 #include <Library/PrePiLib.h>
21
22 #define PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID { 0x385A982C, 0x2F49, 0x4043, { 0xA5, 0x1E, 0x49, 0x01, 0x02, 0x5C, 0x8B, 0x6B }}
23
24 typedef struct {
25 UINT32 NumberOfExtractHandler;
26 GUID *ExtractHandlerGuidTable;
27 EXTRACT_GUIDED_SECTION_DECODE_HANDLER *ExtractDecodeHandlerTable;
28 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;
29 } PRE_PI_EXTRACT_GUIDED_SECTION_DATA;
30
31 PRE_PI_EXTRACT_GUIDED_SECTION_DATA *
GetSavedData(VOID)32 GetSavedData (
33 VOID
34 )
35 {
36 EFI_HOB_GUID_TYPE *GuidHob;
37 GUID SavedDataGuid = PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID;
38
39 GuidHob = GetFirstGuidHob(&SavedDataGuid);
40 GuidHob++;
41
42 return (PRE_PI_EXTRACT_GUIDED_SECTION_DATA *)GuidHob;
43 }
44
45 RETURN_STATUS
46 EFIAPI
ExtractGuidedSectionRegisterHandlers(IN CONST GUID * SectionGuid,IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler,IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler)47 ExtractGuidedSectionRegisterHandlers (
48 IN CONST GUID *SectionGuid,
49 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler,
50 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler
51 )
52 {
53 PRE_PI_EXTRACT_GUIDED_SECTION_DATA *SavedData;
54 UINT32 Index;
55 //
56 // Check input parameter.
57 //
58 if (SectionGuid == NULL) {
59 return RETURN_INVALID_PARAMETER;
60 }
61
62 SavedData = GetSavedData();
63
64 //
65 // Search the match registered GetInfo handler for the input guided section.
66 //
67 for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) {
68 if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], SectionGuid)) {
69 break;
70 }
71 }
72
73 //
74 // If the guided handler has been registered before, only update its handler.
75 //
76 if (Index < SavedData->NumberOfExtractHandler) {
77 SavedData->ExtractDecodeHandlerTable [Index] = DecodeHandler;
78 SavedData->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;
79 return RETURN_SUCCESS;
80 }
81
82 //
83 // Check the global table is enough to contain new Handler.
84 //
85 if (SavedData->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {
86 return RETURN_OUT_OF_RESOURCES;
87 }
88
89 //
90 // Register new Handler and guid value.
91 //
92 CopyGuid (&SavedData->ExtractHandlerGuidTable [SavedData->NumberOfExtractHandler], SectionGuid);
93 SavedData->ExtractDecodeHandlerTable [SavedData->NumberOfExtractHandler] = DecodeHandler;
94 SavedData->ExtractGetInfoHandlerTable [SavedData->NumberOfExtractHandler++] = GetInfoHandler;
95
96 return RETURN_SUCCESS;
97 }
98
99 UINTN
100 EFIAPI
ExtractGuidedSectionGetGuidList(IN OUT GUID ** ExtractHandlerGuidTable)101 ExtractGuidedSectionGetGuidList (
102 IN OUT GUID **ExtractHandlerGuidTable
103 )
104 {
105 PRE_PI_EXTRACT_GUIDED_SECTION_DATA *SavedData;
106
107 ASSERT(ExtractHandlerGuidTable != NULL);
108
109 SavedData = GetSavedData();
110
111 *ExtractHandlerGuidTable = SavedData->ExtractHandlerGuidTable;
112 return SavedData->NumberOfExtractHandler;
113 }
114
115 RETURN_STATUS
116 EFIAPI
ExtractGuidedSectionGetInfo(IN CONST VOID * InputSection,OUT UINT32 * OutputBufferSize,OUT UINT32 * ScratchBufferSize,OUT UINT16 * SectionAttribute)117 ExtractGuidedSectionGetInfo (
118 IN CONST VOID *InputSection,
119 OUT UINT32 *OutputBufferSize,
120 OUT UINT32 *ScratchBufferSize,
121 OUT UINT16 *SectionAttribute
122 )
123 {
124 PRE_PI_EXTRACT_GUIDED_SECTION_DATA *SavedData;
125 UINT32 Index;
126
127 if (InputSection == NULL) {
128 return RETURN_INVALID_PARAMETER;
129 }
130
131 ASSERT (OutputBufferSize != NULL);
132 ASSERT (ScratchBufferSize != NULL);
133 ASSERT (SectionAttribute != NULL);
134
135 SavedData = GetSavedData();
136
137 //
138 // Search the match registered GetInfo handler for the input guided section.
139 //
140 for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) {
141 if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
142 break;
143 }
144 }
145
146 //
147 // Not found, the input guided section is not supported.
148 //
149 if (Index == SavedData->NumberOfExtractHandler) {
150 return RETURN_INVALID_PARAMETER;
151 }
152
153 //
154 // Call the match handler to getinfo for the input section data.
155 //
156 return SavedData->ExtractGetInfoHandlerTable [Index] (
157 InputSection,
158 OutputBufferSize,
159 ScratchBufferSize,
160 SectionAttribute
161 );
162 }
163
164 RETURN_STATUS
165 EFIAPI
ExtractGuidedSectionDecode(IN CONST VOID * InputSection,OUT VOID ** OutputBuffer,OUT VOID * ScratchBuffer,OPTIONAL OUT UINT32 * AuthenticationStatus)166 ExtractGuidedSectionDecode (
167 IN CONST VOID *InputSection,
168 OUT VOID **OutputBuffer,
169 OUT VOID *ScratchBuffer, OPTIONAL
170 OUT UINT32 *AuthenticationStatus
171 )
172 {
173 PRE_PI_EXTRACT_GUIDED_SECTION_DATA *SavedData;
174 UINT32 Index;
175
176 if (InputSection == NULL) {
177 return RETURN_INVALID_PARAMETER;
178 }
179
180 ASSERT (OutputBuffer != NULL);
181 ASSERT (AuthenticationStatus != NULL);
182
183 SavedData = GetSavedData();
184
185 //
186 // Search the match registered GetInfo handler for the input guided section.
187 //
188 for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) {
189 if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
190 break;
191 }
192 }
193
194 //
195 // Not found, the input guided section is not supported.
196 //
197 if (Index == SavedData->NumberOfExtractHandler) {
198 return RETURN_INVALID_PARAMETER;
199 }
200
201 //
202 // Call the match handler to getinfo for the input section data.
203 //
204 return SavedData->ExtractDecodeHandlerTable [Index] (
205 InputSection,
206 OutputBuffer,
207 ScratchBuffer,
208 AuthenticationStatus
209 );
210 }
211
212 RETURN_STATUS
213 EFIAPI
ExtractGuidedSectionLibConstructor(VOID)214 ExtractGuidedSectionLibConstructor (
215 VOID
216 )
217 {
218 PRE_PI_EXTRACT_GUIDED_SECTION_DATA SavedData;
219 GUID HobGuid = PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID;
220
221 //
222 // Allocate global pool space to store the registered handler and its guid value.
223 //
224 SavedData.ExtractHandlerGuidTable = (GUID *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(GUID));
225 if (SavedData.ExtractHandlerGuidTable == NULL) {
226 return RETURN_OUT_OF_RESOURCES;
227 }
228
229 SavedData.ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(EXTRACT_GUIDED_SECTION_DECODE_HANDLER));
230 if (SavedData.ExtractDecodeHandlerTable == NULL) {
231 return RETURN_OUT_OF_RESOURCES;
232 }
233
234 SavedData.ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER));
235 if (SavedData.ExtractGetInfoHandlerTable == NULL) {
236 return RETURN_OUT_OF_RESOURCES;
237 }
238
239 //
240 // the initialized number is Zero.
241 //
242 SavedData.NumberOfExtractHandler = 0;
243
244 BuildGuidDataHob(&HobGuid, &SavedData, sizeof(SavedData));
245
246 return RETURN_SUCCESS;
247 }
248