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 } 275