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 paramter.
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