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 * 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 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 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 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 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 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