c4a3508fbd2b91998a78205034a83744de350577
[mirror_edk2.git] / MdeModulePkg / Universal / SectionExtractionPei / SectionExtractionPei.c
1 /** @file
2 Section Extraction PEIM
3
4 Copyright (c) 2013 - 2014, 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 #include <Ppi/GuidedSectionExtraction.h>
17 #include <Library/DebugLib.h>
18 #include <Library/ExtractGuidedSectionLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/PeiServicesLib.h>
21
22 /**
23 The ExtractSection() function processes the input section and
24 returns a pointer to the section contents. If the section being
25 extracted does not require processing (if the section
26 GuidedSectionHeader.Attributes has the
27 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
28 OutputBuffer is just updated to point to the start of the
29 section's contents. Otherwise, *Buffer must be allocated
30 from PEI permanent memory.
31
32 @param This Indicates the
33 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
34 Buffer containing the input GUIDed section to be
35 processed. OutputBuffer OutputBuffer is
36 allocated from PEI permanent memory and contains
37 the new section stream.
38 @param InputSection A pointer to the input buffer, which contains
39 the input section to be processed.
40 @param OutputBuffer A pointer to a caller-allocated buffer, whose
41 size is specified by the contents of OutputSize.
42 @param OutputSize A pointer to a caller-allocated
43 UINTN in which the size of *OutputBuffer
44 allocation is stored. If the function
45 returns anything other than EFI_SUCCESS,
46 the value of OutputSize is undefined.
47 @param AuthenticationStatus A pointer to a caller-allocated
48 UINT32 that indicates the
49 authentication status of the
50 output buffer. If the input
51 section's GuidedSectionHeader.
52 Attributes field has the
53 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
54 bit as clear,
55 AuthenticationStatus must return
56 zero. These bits reflect the
57 status of the extraction
58 operation. If the function
59 returns anything other than
60 EFI_SUCCESS, the value of
61 AuthenticationStatus is
62 undefined.
63
64 @retval EFI_SUCCESS The InputSection was
65 successfully processed and the
66 section contents were returned.
67
68 @retval EFI_OUT_OF_RESOURCES The system has insufficient
69 resources to process the request.
70
71 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
72 not match this instance of the
73 GUIDed Section Extraction PPI.
74
75 **/
76 EFI_STATUS
77 EFIAPI
78 CustomGuidedSectionExtract (
79 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
80 IN CONST VOID *InputSection,
81 OUT VOID **OutputBuffer,
82 OUT UINTN *OutputSize,
83 OUT UINT32 *AuthenticationStatus
84 );
85
86 //
87 // Module global for the Section Extraction PPI instance
88 //
89 CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
90 CustomGuidedSectionExtract
91 };
92
93 /**
94 The ExtractSection() function processes the input section and
95 returns a pointer to the section contents. If the section being
96 extracted does not require processing (if the section
97 GuidedSectionHeader.Attributes has the
98 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
99 OutputBuffer is just updated to point to the start of the
100 section's contents. Otherwise, *Buffer must be allocated
101 from PEI permanent memory.
102
103 @param This Indicates the
104 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
105 Buffer containing the input GUIDed section to be
106 processed. OutputBuffer OutputBuffer is
107 allocated from PEI permanent memory and contains
108 the new section stream.
109 @param InputSection A pointer to the input buffer, which contains
110 the input section to be processed.
111 @param OutputBuffer A pointer to a caller-allocated buffer, whose
112 size is specified by the contents of OutputSize.
113 @param OutputSize A pointer to a caller-allocated
114 UINTN in which the size of *OutputBuffer
115 allocation is stored. If the function
116 returns anything other than EFI_SUCCESS,
117 the value of OutputSize is undefined.
118 @param AuthenticationStatus A pointer to a caller-allocated
119 UINT32 that indicates the
120 authentication status of the
121 output buffer. If the input
122 section's GuidedSectionHeader.
123 Attributes field has the
124 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
125 bit as clear,
126 AuthenticationStatus must return
127 zero. These bits reflect the
128 status of the extraction
129 operation. If the function
130 returns anything other than
131 EFI_SUCCESS, the value of
132 AuthenticationStatus is
133 undefined.
134
135 @retval EFI_SUCCESS The InputSection was
136 successfully processed and the
137 section contents were returned.
138
139 @retval EFI_OUT_OF_RESOURCES The system has insufficient
140 resources to process the request.
141
142 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
143 not match this instance of the
144 GUIDed Section Extraction PPI.
145
146 **/
147 EFI_STATUS
148 EFIAPI
149 CustomGuidedSectionExtract (
150 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
151 IN CONST VOID *InputSection,
152 OUT VOID **OutputBuffer,
153 OUT UINTN *OutputSize,
154 OUT UINT32 *AuthenticationStatus
155 )
156 {
157 EFI_STATUS Status;
158 UINT8 *ScratchBuffer;
159 UINT32 ScratchBufferSize;
160 UINT32 OutputBufferSize;
161 UINT16 SectionAttribute;
162
163 //
164 // Init local variable
165 //
166 ScratchBuffer = NULL;
167
168 //
169 // Call GetInfo to get the size and attribute of input guided section data.
170 //
171 Status = ExtractGuidedSectionGetInfo (
172 InputSection,
173 &OutputBufferSize,
174 &ScratchBufferSize,
175 &SectionAttribute
176 );
177
178 if (EFI_ERROR (Status)) {
179 DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
180 return Status;
181 }
182
183 if (ScratchBufferSize != 0) {
184 //
185 // Allocate scratch buffer
186 //
187 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
188 if (ScratchBuffer == NULL) {
189 return EFI_OUT_OF_RESOURCES;
190 }
191 }
192
193 if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
194 //
195 // Allocate output buffer
196 //
197 *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
198 if (*OutputBuffer == NULL) {
199 return EFI_OUT_OF_RESOURCES;
200 }
201 DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
202 //
203 // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
204 // skip EFI section header to make section data at page alignment.
205 //
206 *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
207 }
208
209 Status = ExtractGuidedSectionDecode (
210 InputSection,
211 OutputBuffer,
212 ScratchBuffer,
213 AuthenticationStatus
214 );
215 if (EFI_ERROR (Status)) {
216 //
217 // Decode failed
218 //
219 DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
220 return Status;
221 }
222
223 *OutputSize = (UINTN) OutputBufferSize;
224
225 return EFI_SUCCESS;
226 }
227
228 /**
229 Main entry for Section Extraction PEIM driver.
230
231 This routine registers the Section Extraction PPIs that have been registered
232 with the Section Extraction Library.
233
234 @param FileHandle Handle of the file being invoked.
235 @param PeiServices Describes the list of possible PEI Services.
236
237 @retval EFI_SUCCESS The entry point is executed successfully.
238 @retval other Some error occurs when executing this entry point.
239
240 **/
241 EFI_STATUS
242 EFIAPI
243 SectionExtractionPeiEntry (
244 IN EFI_PEI_FILE_HANDLE FileHandle,
245 IN CONST EFI_PEI_SERVICES **PeiServices
246 )
247 {
248 EFI_STATUS Status;
249 EFI_GUID *ExtractHandlerGuidTable;
250 UINTN ExtractHandlerNumber;
251 EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
252
253 //
254 // Get custom extract guided section method guid list
255 //
256 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
257
258 //
259 // Install custom extraction guid PPI
260 //
261 if (ExtractHandlerNumber > 0) {
262 GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
263 ASSERT (GuidPpi != NULL);
264 while (ExtractHandlerNumber-- > 0) {
265 GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
266 GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;
267 GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];
268 Status = PeiServicesInstallPpi (GuidPpi++);
269 ASSERT_EFI_ERROR (Status);
270 }
271 }
272
273 return EFI_SUCCESS;
274 }