• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
CustomGuidedSectionExtract(IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI * This,IN CONST VOID * InputSection,OUT VOID ** OutputBuffer,OUT UINTN * OutputSize,OUT UINT32 * AuthenticationStatus)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
SectionExtractionPeiEntry(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)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 }
275