]>
Commit | Line | Data |
---|---|---|
615c6dd0 | 1 | /** @file\r |
b1f6a7c6 | 2 | Pei Core Firmware File System service routines.\r |
3 | \r | |
890e5417 | 4 | Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r |
cd5ebaa0 | 5 | This program and the accompanying materials \r |
192f6d4c | 6 | are licensed and made available under the terms and conditions of the BSD License \r |
7 | which accompanies this distribution. The full text of the license may be found at \r | |
8 | http://opensource.org/licenses/bsd-license.php \r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r | |
12 | \r | |
615c6dd0 | 13 | **/\r |
192f6d4c | 14 | \r |
3b428ade | 15 | #include "FwVol.h"\r |
192f6d4c | 16 | \r |
fe1e36e5 | 17 | EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList = {\r |
b0d803fe | 18 | (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r |
19 | &gEfiPeiFirmwareVolumeInfoPpiGuid,\r | |
20 | FirmwareVolmeInfoPpiNotifyCallback \r | |
21 | };\r | |
22 | \r | |
890e5417 SZ |
23 | PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {\r |
24 | PEI_FW_VOL_SIGNATURE,\r | |
25 | FALSE,\r | |
26 | {\r | |
27 | PeiFfsFvPpiProcessVolume,\r | |
28 | PeiFfsFvPpiFindFileByType,\r | |
29 | PeiFfsFvPpiFindFileByName,\r | |
30 | PeiFfsFvPpiGetFileInfo,\r | |
31 | PeiFfsFvPpiGetVolumeInfo,\r | |
32 | PeiFfsFvPpiFindSectionByType\r | |
33 | }\r | |
34 | };\r | |
35 | \r | |
36 | PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = {\r | |
37 | PEI_FW_VOL_SIGNATURE,\r | |
38 | TRUE,\r | |
39 | {\r | |
40 | PeiFfsFvPpiProcessVolume,\r | |
41 | PeiFfsFvPpiFindFileByType,\r | |
42 | PeiFfsFvPpiFindFileByName,\r | |
43 | PeiFfsFvPpiGetFileInfo,\r | |
44 | PeiFfsFvPpiGetVolumeInfo,\r | |
45 | PeiFfsFvPpiFindSectionByType\r | |
46 | }\r | |
3b428ade | 47 | };\r |
48 | \r | |
49 | EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList = {\r | |
50 | (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r | |
51 | &gEfiFirmwareFileSystem2Guid,\r | |
890e5417 SZ |
52 | &mPeiFfs2FwVol.Fv\r |
53 | };\r | |
54 | \r | |
55 | EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList = {\r | |
56 | (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r | |
57 | &gEfiFirmwareFileSystem3Guid,\r | |
58 | &mPeiFfs3FwVol.Fv\r | |
3b428ade | 59 | };\r |
60 | \r | |
b1f6a7c6 | 61 | /**\r |
ed299e3c | 62 | Returns the file state set by the highest zero bit in the State field\r |
192f6d4c | 63 | \r |
b1f6a7c6 | 64 | @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY\r |
65 | in the Attributes field.\r | |
66 | @param FfsHeader Pointer to FFS File Header.\r | |
192f6d4c | 67 | \r |
ed299e3c LG |
68 | @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit \r |
69 | in the header State field.\r | |
b1f6a7c6 | 70 | **/\r |
71 | EFI_FFS_FILE_STATE\r | |
72 | GetFileState(\r | |
73 | IN UINT8 ErasePolarity,\r | |
74 | IN EFI_FFS_FILE_HEADER *FfsHeader\r | |
75 | )\r | |
192f6d4c | 76 | {\r |
77 | EFI_FFS_FILE_STATE FileState;\r | |
78 | EFI_FFS_FILE_STATE HighestBit;\r | |
79 | \r | |
80 | FileState = FfsHeader->State;\r | |
81 | \r | |
82 | if (ErasePolarity != 0) {\r | |
83 | FileState = (EFI_FFS_FILE_STATE)~FileState;\r | |
84 | }\r | |
ed299e3c LG |
85 | \r |
86 | //\r | |
87 | // Get file state set by its highest none zero bit.\r | |
88 | //\r | |
192f6d4c | 89 | HighestBit = 0x80;\r |
90 | while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r | |
91 | HighestBit >>= 1;\r | |
92 | }\r | |
93 | \r | |
94 | return HighestBit;\r | |
95 | } \r | |
96 | \r | |
b1f6a7c6 | 97 | /**\r |
98 | Calculates the checksum of the header of a file.\r | |
99 | \r | |
100 | @param FileHeader Pointer to FFS File Header.\r | |
101 | \r | |
102 | @return Checksum of the header.\r | |
b1f6a7c6 | 103 | Zero means the header is good.\r |
104 | Non-zero means the header is bad.\r | |
105 | **/\r | |
192f6d4c | 106 | UINT8\r |
107 | CalculateHeaderChecksum (\r | |
108 | IN EFI_FFS_FILE_HEADER *FileHeader\r | |
109 | )\r | |
192f6d4c | 110 | {\r |
890e5417 | 111 | EFI_FFS_FILE_HEADER2 TestFileHeader;\r |
192f6d4c | 112 | \r |
890e5417 SZ |
113 | if (IS_FFS_FILE2 (FileHeader)) {\r |
114 | CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r | |
115 | //\r | |
116 | // Ingore State and File field in FFS header.\r | |
117 | //\r | |
118 | TestFileHeader.State = 0;\r | |
119 | TestFileHeader.IntegrityCheck.Checksum.File = 0;\r | |
120 | \r | |
121 | return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r | |
122 | } else {\r | |
123 | CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r | |
124 | //\r | |
125 | // Ingore State and File field in FFS header.\r | |
126 | //\r | |
127 | TestFileHeader.State = 0;\r | |
128 | TestFileHeader.IntegrityCheck.Checksum.File = 0;\r | |
129 | \r | |
130 | return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER));\r | |
131 | }\r | |
192f6d4c | 132 | }\r |
133 | \r | |
b1f6a7c6 | 134 | /**\r |
3b428ade | 135 | Find FV handler according to FileHandle in that FV.\r |
b1f6a7c6 | 136 | \r |
137 | @param FileHandle Handle of file image\r | |
3b428ade | 138 | \r |
139 | @return Pointer to instance of PEI_CORE_FV_HANDLE.\r | |
b1f6a7c6 | 140 | **/\r |
3b428ade | 141 | PEI_CORE_FV_HANDLE*\r |
142 | FileHandleToVolume (\r | |
143 | IN EFI_PEI_FILE_HANDLE FileHandle\r | |
b0d803fe | 144 | )\r |
145 | {\r | |
146 | UINTN Index;\r | |
147 | PEI_CORE_INSTANCE *PrivateData;\r | |
148 | EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r | |
149 | \r | |
150 | PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r | |
3b428ade | 151 | \r |
b0d803fe | 152 | for (Index = 0; Index < PrivateData->FvCount; Index++) {\r |
153 | FwVolHeader = PrivateData->Fv[Index].FvHeader;\r | |
67a58d0f | 154 | if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \\r |
155 | ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {\r | |
3b428ade | 156 | return &PrivateData->Fv[Index];\r |
b0d803fe | 157 | }\r |
158 | }\r | |
3b428ade | 159 | return NULL;\r |
b0d803fe | 160 | }\r |
161 | \r | |
b1f6a7c6 | 162 | /**\r |
ed299e3c | 163 | Given the input file pointer, search for the first matching file in the\r |
b1f6a7c6 | 164 | FFS volume as defined by SearchType. The search starts from FileHeader inside\r |
165 | the Firmware Volume defined by FwVolHeader.\r | |
ed299e3c LG |
166 | If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.\r |
167 | If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, \r | |
168 | the first PEIM, or COMBINED PEIM or FV file type FFS file will return. \r | |
b1f6a7c6 | 169 | \r |
170 | @param FvHandle Pointer to the FV header of the volume to search\r | |
171 | @param FileName File name\r | |
172 | @param SearchType Filter to find only files of this type.\r | |
173 | Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r | |
174 | @param FileHandle This parameter must point to a valid FFS volume.\r | |
175 | @param AprioriFile Pointer to AprioriFile image in this FV if has\r | |
b0d803fe | 176 | \r |
b1f6a7c6 | 177 | @return EFI_NOT_FOUND No files matching the search criteria were found\r |
178 | @retval EFI_SUCCESS Success to search given file\r | |
179 | \r | |
180 | **/\r | |
192f6d4c | 181 | EFI_STATUS\r |
3b428ade | 182 | FindFileEx (\r |
b0d803fe | 183 | IN CONST EFI_PEI_FV_HANDLE FvHandle,\r |
184 | IN CONST EFI_GUID *FileName, OPTIONAL\r | |
185 | IN EFI_FV_FILETYPE SearchType,\r | |
186 | IN OUT EFI_PEI_FILE_HANDLE *FileHandle,\r | |
187 | IN OUT EFI_PEI_FV_HANDLE *AprioriFile OPTIONAL\r | |
192f6d4c | 188 | )\r |
192f6d4c | 189 | {\r |
b0d803fe | 190 | EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r |
191 | EFI_FFS_FILE_HEADER **FileHeader;\r | |
192 | EFI_FFS_FILE_HEADER *FfsFileHeader;\r | |
b0d803fe | 193 | UINT32 FileLength;\r |
194 | UINT32 FileOccupiedSize;\r | |
195 | UINT32 FileOffset;\r | |
196 | UINT64 FvLength;\r | |
197 | UINT8 ErasePolarity;\r | |
198 | UINT8 FileState;\r | |
89cd8129 | 199 | UINT8 DataCheckSum;\r |
890e5417 | 200 | BOOLEAN IsFfs3Fv;\r |
3b428ade | 201 | \r |
202 | //\r | |
203 | // Convert the handle of FV to FV header for memory-mapped firmware volume\r | |
204 | //\r | |
205 | FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle;\r | |
b0d803fe | 206 | FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;\r |
192f6d4c | 207 | \r |
890e5417 SZ |
208 | IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);\r |
209 | \r | |
192f6d4c | 210 | FvLength = FwVolHeader->FvLength;\r |
d976bf31 | 211 | if ((FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {\r |
192f6d4c | 212 | ErasePolarity = 1;\r |
213 | } else {\r | |
214 | ErasePolarity = 0;\r | |
215 | }\r | |
216 | \r | |
217 | //\r | |
b0d803fe | 218 | // If FileHeader is not specified (NULL) or FileName is not NULL,\r |
219 | // start with the first file in the firmware volume. Otherwise,\r | |
220 | // start from the FileHeader.\r | |
192f6d4c | 221 | //\r |
b0d803fe | 222 | if ((*FileHeader == NULL) || (FileName != NULL)) {\r |
192f6d4c | 223 | FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r |
224 | } else {\r | |
890e5417 SZ |
225 | if (IS_FFS_FILE2 (*FileHeader)) {\r |
226 | if (!IsFfs3Fv) {\r | |
227 | DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name));\r | |
228 | }\r | |
229 | FileLength = FFS_FILE2_SIZE (*FileHeader);\r | |
230 | ASSERT (FileLength > 0x00FFFFFF);\r | |
231 | } else {\r | |
232 | FileLength = FFS_FILE_SIZE (*FileHeader);\r | |
233 | }\r | |
192f6d4c | 234 | //\r |
192f6d4c | 235 | // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r |
236 | //\r | |
b0d803fe | 237 | FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r |
192f6d4c | 238 | FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r |
239 | }\r | |
e98cd821 | 240 | \r |
192f6d4c | 241 | FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r |
242 | ASSERT (FileOffset <= 0xFFFFFFFF);\r | |
e98cd821 | 243 | \r |
b0d803fe | 244 | while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r |
192f6d4c | 245 | //\r |
246 | // Get FileState which is the highest bit of the State \r | |
247 | //\r | |
248 | FileState = GetFileState (ErasePolarity, FfsFileHeader);\r | |
192f6d4c | 249 | switch (FileState) {\r |
250 | \r | |
890e5417 | 251 | case EFI_FILE_HEADER_CONSTRUCTION:\r |
192f6d4c | 252 | case EFI_FILE_HEADER_INVALID:\r |
890e5417 SZ |
253 | if (IS_FFS_FILE2 (FfsFileHeader)) {\r |
254 | if (!IsFfs3Fv) {\r | |
255 | DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r | |
256 | }\r | |
257 | FileOffset += sizeof (EFI_FFS_FILE_HEADER2);\r | |
258 | FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r | |
259 | } else {\r | |
260 | FileOffset += sizeof (EFI_FFS_FILE_HEADER);\r | |
261 | FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r | |
262 | }\r | |
192f6d4c | 263 | break;\r |
264 | \r | |
265 | case EFI_FILE_DATA_VALID:\r | |
266 | case EFI_FILE_MARKED_FOR_UPDATE:\r | |
b0d803fe | 267 | if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r |
192f6d4c | 268 | ASSERT (FALSE);\r |
e98cd821 | 269 | *FileHeader = NULL;\r |
192f6d4c | 270 | return EFI_NOT_FOUND;\r |
271 | }\r | |
b0d803fe | 272 | \r |
890e5417 SZ |
273 | if (IS_FFS_FILE2 (FfsFileHeader)) {\r |
274 | FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r | |
275 | ASSERT (FileLength > 0x00FFFFFF);\r | |
276 | FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r | |
277 | if (!IsFfs3Fv) {\r | |
278 | DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r | |
279 | FileOffset += FileOccupiedSize;\r | |
280 | FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);\r | |
281 | break;\r | |
282 | }\r | |
283 | } else {\r | |
284 | FileLength = FFS_FILE_SIZE (FfsFileHeader);\r | |
285 | FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r | |
286 | }\r | |
b0d803fe | 287 | \r |
89cd8129 LG |
288 | DataCheckSum = FFS_FIXED_CHECKSUM;\r |
289 | if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {\r | |
890e5417 SZ |
290 | if (IS_FFS_FILE2 (FfsFileHeader)) {\r |
291 | DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof(EFI_FFS_FILE_HEADER2));\r | |
292 | } else {\r | |
293 | DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof(EFI_FFS_FILE_HEADER));\r | |
294 | }\r | |
89cd8129 LG |
295 | }\r |
296 | if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) {\r | |
297 | ASSERT (FALSE);\r | |
298 | *FileHeader = NULL;\r | |
299 | return EFI_NOT_FOUND;\r | |
300 | }\r | |
301 | \r | |
b0d803fe | 302 | if (FileName != NULL) {\r |
303 | if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {\r | |
304 | *FileHeader = FfsFileHeader;\r | |
305 | return EFI_SUCCESS;\r | |
306 | }\r | |
307 | } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r | |
308 | if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r | |
288f9b38 LG |
309 | (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r |
310 | (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { \r | |
b0d803fe | 311 | \r |
312 | *FileHeader = FfsFileHeader;\r | |
313 | return EFI_SUCCESS;\r | |
314 | } else if (AprioriFile != NULL) {\r | |
315 | if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {\r | |
316 | if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {\r | |
317 | *AprioriFile = FfsFileHeader;\r | |
318 | } \r | |
319 | } \r | |
320 | }\r | |
7e181f2f | 321 | } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) && \r |
322 | (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) { \r | |
b0d803fe | 323 | *FileHeader = FfsFileHeader;\r |
324 | return EFI_SUCCESS;\r | |
325 | }\r | |
326 | \r | |
40f26b8f | 327 | FileOffset += FileOccupiedSize; \r |
328 | FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r | |
192f6d4c | 329 | break;\r |
330 | \r | |
331 | case EFI_FILE_DELETED:\r | |
890e5417 SZ |
332 | if (IS_FFS_FILE2 (FfsFileHeader)) {\r |
333 | if (!IsFfs3Fv) {\r | |
334 | DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r | |
335 | }\r | |
336 | FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r | |
337 | ASSERT (FileLength > 0x00FFFFFF);\r | |
338 | } else {\r | |
339 | FileLength = FFS_FILE_SIZE (FfsFileHeader);\r | |
340 | }\r | |
40f26b8f | 341 | FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);\r |
342 | FileOffset += FileOccupiedSize;\r | |
343 | FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r | |
192f6d4c | 344 | break;\r |
345 | \r | |
346 | default:\r | |
e98cd821 | 347 | *FileHeader = NULL;\r |
192f6d4c | 348 | return EFI_NOT_FOUND;\r |
192f6d4c | 349 | } \r |
350 | }\r | |
e98cd821 LG |
351 | \r |
352 | *FileHeader = NULL;\r | |
192f6d4c | 353 | return EFI_NOT_FOUND; \r |
354 | }\r | |
355 | \r | |
b1f6a7c6 | 356 | /**\r |
b1f6a7c6 | 357 | Initialize PeiCore Fv List.\r |
358 | \r | |
b1f6a7c6 | 359 | @param PrivateData - Pointer to PEI_CORE_INSTANCE.\r |
360 | @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.\r | |
b1f6a7c6 | 361 | **/\r |
b0d803fe | 362 | VOID \r |
363 | PeiInitializeFv (\r | |
364 | IN PEI_CORE_INSTANCE *PrivateData,\r | |
365 | IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData\r | |
366 | )\r | |
b0d803fe | 367 | {\r |
3b428ade | 368 | EFI_STATUS Status;\r |
369 | EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r | |
370 | EFI_PEI_FV_HANDLE FvHandle;\r | |
371 | EFI_FIRMWARE_VOLUME_HEADER *BfvHeader;\r | |
372 | \r | |
b0d803fe | 373 | //\r |
3b428ade | 374 | // Install FV_PPI for FFS2 file system.\r |
b0d803fe | 375 | //\r |
3b428ade | 376 | PeiServicesInstallPpi (&mPeiFfs2FvPpiList);\r |
890e5417 SZ |
377 | \r |
378 | //\r | |
379 | // Install FV_PPI for FFS3 file system.\r | |
380 | //\r | |
381 | PeiServicesInstallPpi (&mPeiFfs3FvPpiList);\r | |
382 | \r | |
3b428ade | 383 | BfvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;\r |
384 | \r | |
385 | //\r | |
386 | // The FV_PPI in BFV's format should be installed.\r | |
387 | //\r | |
388 | Status = PeiServicesLocatePpi (\r | |
389 | &BfvHeader->FileSystemGuid,\r | |
390 | 0,\r | |
391 | NULL,\r | |
392 | (VOID**)&FvPpi\r | |
393 | );\r | |
394 | ASSERT_EFI_ERROR (Status);\r | |
395 | \r | |
396 | //\r | |
397 | // Get handle of BFV\r | |
398 | //\r | |
399 | FvPpi->ProcessVolume (\r | |
400 | FvPpi, \r | |
401 | SecCoreData->BootFirmwareVolumeBase,\r | |
402 | (UINTN)BfvHeader->FvLength,\r | |
403 | &FvHandle\r | |
404 | );\r | |
dc6f9b35 | 405 | \r |
406 | //\r | |
407 | // Update internal PEI_CORE_FV array.\r | |
408 | //\r | |
409 | PrivateData->Fv[PrivateData->FvCount].FvHeader = BfvHeader;\r | |
410 | PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r | |
411 | PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r | |
412 | DEBUG ((\r | |
413 | EFI_D_INFO, \r | |
414 | "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r | |
415 | (UINT32) PrivateData->FvCount, \r | |
416 | (VOID *) BfvHeader, \r | |
417 | BfvHeader->FvLength,\r | |
418 | FvHandle\r | |
419 | )); \r | |
420 | PrivateData->FvCount ++;\r | |
421 | \r | |
b0d803fe | 422 | //\r |
423 | // Post a call-back for the FvInfoPPI services to expose\r | |
424 | // additional Fvs to PeiCore.\r | |
425 | //\r | |
426 | Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoList);\r | |
427 | ASSERT_EFI_ERROR (Status);\r | |
428 | \r | |
429 | }\r | |
3b428ade | 430 | \r |
b1f6a7c6 | 431 | /**\r |
432 | Process Firmware Volum Information once FvInfoPPI install.\r | |
ed299e3c LG |
433 | The FV Info will be registered into PeiCore private data structure.\r |
434 | And search the inside FV image, if found, the new FV INFO PPI will be installed.\r | |
b1f6a7c6 | 435 | \r |
ed299e3c | 436 | @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r |
731bd38e | 437 | @param NotifyDescriptor Address of the notification descriptor data structure.\r |
438 | @param Ppi Address of the PPI that was installed.\r | |
b1f6a7c6 | 439 | \r |
ed299e3c | 440 | @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.\r |
6a1ae84a | 441 | @return if not EFI_SUCESS, fail to verify FV.\r |
b1f6a7c6 | 442 | \r |
443 | **/\r | |
b0d803fe | 444 | EFI_STATUS\r |
445 | EFIAPI\r | |
446 | FirmwareVolmeInfoPpiNotifyCallback (\r | |
447 | IN EFI_PEI_SERVICES **PeiServices,\r | |
448 | IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r | |
449 | IN VOID *Ppi\r | |
450 | )\r | |
b0d803fe | 451 | {\r |
3b428ade | 452 | EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;\r |
453 | EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r | |
b0d803fe | 454 | PEI_CORE_INSTANCE *PrivateData;\r |
288f9b38 | 455 | EFI_STATUS Status;\r |
3b428ade | 456 | EFI_PEI_FV_HANDLE FvHandle;\r |
457 | UINTN FvIndex;\r | |
dc6f9b35 | 458 | EFI_PEI_FILE_HANDLE FileHandle;\r |
459 | VOID *DepexData;\r | |
b0d803fe | 460 | \r |
288f9b38 LG |
461 | Status = EFI_SUCCESS;\r |
462 | PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r | |
b0d803fe | 463 | \r |
4140a663 | 464 | if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r |
465 | DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported)));\r | |
97b2c9b5 | 466 | DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));\r |
b0d803fe | 467 | ASSERT (FALSE);\r |
468 | }\r | |
469 | \r | |
3b428ade | 470 | FvInfoPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r |
b0d803fe | 471 | \r |
97b2c9b5 | 472 | //\r |
3b428ade | 473 | // Locate the corresponding FV_PPI according to founded FV's format guid\r |
97b2c9b5 | 474 | //\r |
3b428ade | 475 | Status = PeiServicesLocatePpi (\r |
476 | &FvInfoPpi->FvFormat, \r | |
477 | 0, \r | |
478 | NULL,\r | |
479 | (VOID**)&FvPpi\r | |
480 | );\r | |
481 | if (!EFI_ERROR (Status)) {\r | |
482 | //\r | |
483 | // Process new found FV and get FV handle.\r | |
484 | //\r | |
485 | Status = FvPpi->ProcessVolume (FvPpi, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize, &FvHandle);\r | |
486 | if (EFI_ERROR (Status)) {\r | |
dc6f9b35 | 487 | DEBUG ((EFI_D_ERROR, "Fail to process new found FV, FV may be corrupted!\n"));\r |
6a1ae84a | 488 | return Status;\r |
489 | }\r | |
dc6f9b35 | 490 | \r |
491 | //\r | |
492 | // Check whether the FV has already been processed.\r | |
493 | //\r | |
494 | for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r | |
495 | if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r | |
496 | DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfoPpi->FvInfo));\r | |
497 | return EFI_SUCCESS;\r | |
498 | }\r | |
499 | }\r | |
500 | \r | |
501 | //\r | |
502 | // Update internal PEI_CORE_FV array.\r | |
503 | //\r | |
504 | PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfoPpi->FvInfo;\r | |
505 | PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r | |
506 | PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r | |
507 | DEBUG ((\r | |
508 | EFI_D_INFO, \r | |
509 | "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r | |
510 | (UINT32) PrivateData->FvCount, \r | |
511 | (VOID *) FvInfoPpi->FvInfo, \r | |
512 | FvInfoPpi->FvInfoSize,\r | |
513 | FvHandle\r | |
514 | )); \r | |
515 | PrivateData->FvCount ++;\r | |
516 | \r | |
517 | //\r | |
518 | // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r | |
519 | //\r | |
520 | FileHandle = NULL;\r | |
521 | do {\r | |
522 | Status = FvPpi->FindFileByType (\r | |
523 | FvPpi,\r | |
524 | EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r | |
525 | FvHandle,\r | |
526 | &FileHandle\r | |
527 | );\r | |
528 | if (!EFI_ERROR (Status)) {\r | |
529 | Status = FvPpi->FindSectionByType (\r | |
530 | FvPpi,\r | |
531 | EFI_SECTION_PEI_DEPEX,\r | |
532 | FileHandle,\r | |
533 | (VOID**)&DepexData\r | |
534 | );\r | |
535 | if (!EFI_ERROR (Status)) {\r | |
536 | if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r | |
537 | //\r | |
538 | // Dependency is not satisfied.\r | |
539 | //\r | |
540 | continue;\r | |
541 | }\r | |
542 | }\r | |
543 | \r | |
544 | DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r | |
545 | ProcessFvFile (&PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r | |
546 | }\r | |
547 | } while (FileHandle != NULL);\r | |
3b428ade | 548 | } else {\r |
549 | DEBUG ((EFI_D_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfoPpi->FvInfo));\r | |
6a1ae84a | 550 | \r |
f3358329 | 551 | AddUnknownFormatFvInfo (PrivateData, &FvInfoPpi->FvFormat, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize);\r |
288f9b38 | 552 | }\r |
3b428ade | 553 | \r |
b0d803fe | 554 | return EFI_SUCCESS;\r |
555 | }\r | |
556 | \r | |
b1f6a7c6 | 557 | /**\r |
ed299e3c LG |
558 | Go through the file to search SectionType section. \r |
559 | Search within encapsulation sections (compression and GUIDed) recursively, \r | |
560 | until the match section is found.\r | |
561 | \r | |
3b428ade | 562 | @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r |
563 | @param SectionType Filter to find only section of this type.\r | |
564 | @param Section From where to search.\r | |
565 | @param SectionSize The file size to search.\r | |
566 | @param OutputBuffer A pointer to the discovered section, if successful.\r | |
ed299e3c | 567 | NULL if section not found\r |
890e5417 | 568 | @param IsFfs3Fv Indicates the FV format.\r |
b1f6a7c6 | 569 | \r |
ed299e3c LG |
570 | @return EFI_NOT_FOUND The match section is not found.\r |
571 | @return EFI_SUCCESS The match section is found.\r | |
b1f6a7c6 | 572 | \r |
573 | **/\r | |
b0d803fe | 574 | EFI_STATUS\r |
3b428ade | 575 | ProcessSection (\r |
b0d803fe | 576 | IN CONST EFI_PEI_SERVICES **PeiServices,\r |
577 | IN EFI_SECTION_TYPE SectionType,\r | |
578 | IN EFI_COMMON_SECTION_HEADER *Section,\r | |
579 | IN UINTN SectionSize,\r | |
890e5417 SZ |
580 | OUT VOID **OutputBuffer,\r |
581 | IN BOOLEAN IsFfs3Fv\r | |
b0d803fe | 582 | )\r |
b0d803fe | 583 | {\r |
584 | EFI_STATUS Status;\r | |
585 | UINT32 SectionLength;\r | |
586 | UINT32 ParsedLength;\r | |
b0d803fe | 587 | EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;\r |
b0d803fe | 588 | EFI_PEI_DECOMPRESS_PPI *DecompressPpi;\r |
589 | VOID *PpiOutput;\r | |
590 | UINTN PpiOutputSize;\r | |
288f9b38 LG |
591 | UINTN Index;\r |
592 | UINT32 Authentication;\r | |
593 | PEI_CORE_INSTANCE *PrivateData;\r | |
b0d803fe | 594 | \r |
288f9b38 | 595 | PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r |
b0d803fe | 596 | *OutputBuffer = NULL;\r |
288f9b38 LG |
597 | ParsedLength = 0;\r |
598 | Index = 0;\r | |
599 | Status = EFI_NOT_FOUND;\r | |
600 | PpiOutput = NULL;\r | |
601 | PpiOutputSize = 0;\r | |
b0d803fe | 602 | while (ParsedLength < SectionSize) {\r |
890e5417 SZ |
603 | \r |
604 | if (IS_SECTION2 (Section)) {\r | |
605 | ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);\r | |
606 | if (!IsFfs3Fv) {\r | |
607 | DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));\r | |
608 | SectionLength = SECTION2_SIZE (Section);\r | |
609 | //\r | |
610 | // SectionLength is adjusted it is 4 byte aligned.\r | |
611 | // Go to the next section\r | |
612 | //\r | |
613 | SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r | |
614 | ASSERT (SectionLength != 0);\r | |
615 | ParsedLength += SectionLength;\r | |
616 | Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);\r | |
617 | continue;\r | |
618 | }\r | |
619 | }\r | |
620 | \r | |
b0d803fe | 621 | if (Section->Type == SectionType) {\r |
890e5417 SZ |
622 | if (IS_SECTION2 (Section)) {\r |
623 | *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r | |
624 | } else {\r | |
625 | *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));\r | |
626 | }\r | |
b0d803fe | 627 | return EFI_SUCCESS;\r |
288f9b38 LG |
628 | } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {\r |
629 | //\r | |
630 | // Check the encapsulated section is extracted into the cache data.\r | |
631 | //\r | |
632 | for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {\r | |
633 | if (Section == PrivateData->CacheSection.Section[Index]) {\r | |
634 | PpiOutput = PrivateData->CacheSection.SectionData[Index];\r | |
635 | PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];\r | |
636 | //\r | |
637 | // Search section directly from the cache data.\r | |
638 | //\r | |
3b428ade | 639 | return ProcessSection (\r |
640 | PeiServices,\r | |
641 | SectionType, \r | |
642 | PpiOutput, \r | |
643 | PpiOutputSize, \r | |
890e5417 SZ |
644 | OutputBuffer,\r |
645 | IsFfs3Fv\r | |
3b428ade | 646 | );\r |
b0d803fe | 647 | }\r |
648 | }\r | |
288f9b38 LG |
649 | \r |
650 | Status = EFI_NOT_FOUND;\r | |
651 | if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r | |
890e5417 SZ |
652 | if (IS_SECTION2 (Section)) {\r |
653 | Status = PeiServicesLocatePpi (\r | |
654 | &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid, \r | |
655 | 0, \r | |
656 | NULL, \r | |
657 | (VOID **) &GuidSectionPpi\r | |
658 | );\r | |
659 | } else {\r | |
660 | Status = PeiServicesLocatePpi (\r | |
661 | &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid, \r | |
662 | 0, \r | |
663 | NULL, \r | |
664 | (VOID **) &GuidSectionPpi\r | |
665 | );\r | |
666 | }\r | |
b0d803fe | 667 | if (!EFI_ERROR (Status)) {\r |
288f9b38 | 668 | Status = GuidSectionPpi->ExtractSection (\r |
3b428ade | 669 | GuidSectionPpi,\r |
670 | Section,\r | |
671 | &PpiOutput,\r | |
672 | &PpiOutputSize,\r | |
673 | &Authentication\r | |
674 | );\r | |
288f9b38 LG |
675 | }\r |
676 | } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r | |
677 | Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r | |
678 | if (!EFI_ERROR (Status)) {\r | |
679 | Status = DecompressPpi->Decompress (\r | |
680 | DecompressPpi,\r | |
681 | (CONST EFI_COMPRESSION_SECTION*) Section,\r | |
682 | &PpiOutput,\r | |
683 | &PpiOutputSize\r | |
684 | );\r | |
b0d803fe | 685 | }\r |
686 | }\r | |
288f9b38 LG |
687 | \r |
688 | if (!EFI_ERROR (Status)) {\r | |
689 | //\r | |
690 | // Update cache section data.\r | |
691 | //\r | |
692 | if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r | |
693 | PrivateData->CacheSection.AllSectionCount ++;\r | |
694 | }\r | |
695 | PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section;\r | |
696 | PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;\r | |
697 | PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;\r | |
698 | PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r | |
699 | \r | |
3b428ade | 700 | return ProcessSection (\r |
701 | PeiServices,\r | |
702 | SectionType, \r | |
703 | PpiOutput, \r | |
704 | PpiOutputSize, \r | |
890e5417 SZ |
705 | OutputBuffer,\r |
706 | IsFfs3Fv\r | |
3b428ade | 707 | );\r |
288f9b38 | 708 | }\r |
b0d803fe | 709 | }\r |
710 | \r | |
890e5417 SZ |
711 | if (IS_SECTION2 (Section)) {\r |
712 | SectionLength = SECTION2_SIZE (Section);\r | |
713 | } else {\r | |
714 | SectionLength = SECTION_SIZE (Section);\r | |
715 | }\r | |
b0d803fe | 716 | //\r |
b0d803fe | 717 | // SectionLength is adjusted it is 4 byte aligned.\r |
718 | // Go to the next section\r | |
719 | //\r | |
b0d803fe | 720 | SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r |
721 | ASSERT (SectionLength != 0);\r | |
722 | ParsedLength += SectionLength;\r | |
723 | Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r | |
724 | }\r | |
725 | \r | |
726 | return EFI_NOT_FOUND;\r | |
727 | }\r | |
728 | \r | |
192f6d4c | 729 | \r |
b1f6a7c6 | 730 | /**\r |
3b428ade | 731 | Searches for the next matching section within the specified file.\r |
b1f6a7c6 | 732 | \r |
ed299e3c | 733 | @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r |
b1f6a7c6 | 734 | @param SectionType Filter to find only sections of this type.\r |
735 | @param FileHandle Pointer to the current file to search.\r | |
ed299e3c | 736 | @param SectionData A pointer to the discovered section, if successful.\r |
b1f6a7c6 | 737 | NULL if section not found\r |
738 | \r | |
3b428ade | 739 | @retval EFI_NOT_FOUND The section was not found.\r |
740 | @retval EFI_SUCCESS The section was found.\r | |
b1f6a7c6 | 741 | \r |
742 | **/\r | |
192f6d4c | 743 | EFI_STATUS\r |
744 | EFIAPI\r | |
745 | PeiFfsFindSectionData (\r | |
3b428ade | 746 | IN CONST EFI_PEI_SERVICES **PeiServices,\r |
192f6d4c | 747 | IN EFI_SECTION_TYPE SectionType,\r |
0c2b5da8 | 748 | IN EFI_PEI_FILE_HANDLE FileHandle,\r |
3b428ade | 749 | OUT VOID **SectionData\r |
192f6d4c | 750 | )\r |
192f6d4c | 751 | {\r |
3b428ade | 752 | PEI_CORE_FV_HANDLE *CoreFvHandle;\r |
753 | \r | |
754 | CoreFvHandle = FileHandleToVolume (FileHandle);\r | |
755 | if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r | |
756 | return EFI_NOT_FOUND;\r | |
757 | }\r | |
758 | \r | |
759 | return CoreFvHandle->FvPpi->FindSectionByType (CoreFvHandle->FvPpi, SectionType, FileHandle, SectionData);\r | |
192f6d4c | 760 | }\r |
761 | \r | |
b1f6a7c6 | 762 | /**\r |
3b428ade | 763 | Searches for the next matching file in the firmware volume.\r |
b1f6a7c6 | 764 | \r |
d73d93c3 | 765 | @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r |
b1f6a7c6 | 766 | @param SearchType Filter to find only files of this type.\r |
767 | Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r | |
aa75dfec | 768 | @param FvHandle Handle of firmware volume in which to search.\r |
3b428ade | 769 | @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start\r |
770 | at the beginning of the firmware volume. On exit, points the file handle of the next file\r | |
771 | in the volume or NULL if there are no more files.\r | |
772 | \r | |
773 | @retval EFI_NOT_FOUND The file was not found.\r | |
774 | @retval EFI_NOT_FOUND The header checksum was not zero.\r | |
775 | @retval EFI_SUCCESS The file was found.\r | |
b1f6a7c6 | 776 | \r |
777 | **/\r | |
192f6d4c | 778 | EFI_STATUS\r |
779 | EFIAPI\r | |
780 | PeiFfsFindNextFile (\r | |
0c2b5da8 | 781 | IN CONST EFI_PEI_SERVICES **PeiServices,\r |
782 | IN UINT8 SearchType,\r | |
3b428ade | 783 | IN EFI_PEI_FV_HANDLE FvHandle,\r |
0c2b5da8 | 784 | IN OUT EFI_PEI_FILE_HANDLE *FileHandle\r |
192f6d4c | 785 | )\r |
192f6d4c | 786 | {\r |
3b428ade | 787 | PEI_CORE_FV_HANDLE *CoreFvHandle;\r |
788 | \r | |
789 | CoreFvHandle = FvHandleToCoreHandle (FvHandle);\r | |
790 | \r | |
2f016ba8 | 791 | //\r |
792 | // To make backward compatiblity, if can not find corresponding the handle of FV\r | |
890e5417 | 793 | // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed\r |
2f016ba8 | 794 | // to the address of first byte of FV.\r |
795 | //\r | |
796 | if ((CoreFvHandle == NULL) && FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r | |
797 | return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);\r | |
798 | } \r | |
799 | \r | |
3b428ade | 800 | if ((CoreFvHandle == NULL) || CoreFvHandle->FvPpi == NULL) {\r |
801 | return EFI_NOT_FOUND;\r | |
802 | }\r | |
803 | \r | |
804 | return CoreFvHandle->FvPpi->FindFileByType (CoreFvHandle->FvPpi, SearchType, FvHandle, FileHandle);\r | |
192f6d4c | 805 | }\r |
806 | \r | |
b0d803fe | 807 | \r |
b1f6a7c6 | 808 | /**\r |
ed299e3c | 809 | Search the firmware volumes by index\r |
b1f6a7c6 | 810 | \r |
ed299e3c | 811 | @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r |
3b428ade | 812 | @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware\r |
813 | Volume (BFV).\r | |
814 | @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.\r | |
b1f6a7c6 | 815 | \r |
3b428ade | 816 | @retval EFI_INVALID_PARAMETER VolumeHandle is NULL\r |
817 | @retval EFI_NOT_FOUND The volume was not found.\r | |
818 | @retval EFI_SUCCESS The volume was found.\r | |
b1f6a7c6 | 819 | \r |
820 | **/\r | |
192f6d4c | 821 | EFI_STATUS \r |
822 | EFIAPI\r | |
3b428ade | 823 | PeiFfsFindNextVolume (\r |
2a00326e | 824 | IN CONST EFI_PEI_SERVICES **PeiServices,\r |
192f6d4c | 825 | IN UINTN Instance,\r |
0c2b5da8 | 826 | IN OUT EFI_PEI_FV_HANDLE *VolumeHandle\r |
192f6d4c | 827 | )\r |
192f6d4c | 828 | {\r |
3b428ade | 829 | PEI_CORE_INSTANCE *Private;\r |
830 | PEI_CORE_FV_HANDLE *CoreFvHandle;\r | |
831 | \r | |
3e4c5b49 | 832 | if (VolumeHandle == NULL) {\r |
833 | return EFI_INVALID_PARAMETER;\r | |
834 | }\r | |
835 | \r | |
b0d803fe | 836 | Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r |
2a00326e | 837 | \r |
3b428ade | 838 | CoreFvHandle = FindNextCoreFvHandle (Private, Instance);\r |
839 | if (CoreFvHandle == NULL) {\r | |
840 | *VolumeHandle = NULL;\r | |
841 | return EFI_NOT_FOUND;\r | |
2a00326e | 842 | }\r |
3b428ade | 843 | \r |
844 | *VolumeHandle = CoreFvHandle->FvHandle;\r | |
845 | \r | |
b0d803fe | 846 | return EFI_SUCCESS;\r |
847 | }\r | |
192f6d4c | 848 | \r |
192f6d4c | 849 | \r |
b1f6a7c6 | 850 | /**\r |
ed299e3c | 851 | Find a file within a volume by its name.\r |
b1f6a7c6 | 852 | \r |
ed299e3c LG |
853 | @param FileName A pointer to the name of the file to find within the firmware volume.\r |
854 | @param VolumeHandle The firmware volume to search\r | |
855 | @param FileHandle Upon exit, points to the found file's handle \r | |
856 | or NULL if it could not be found.\r | |
b1f6a7c6 | 857 | \r |
ed299e3c LG |
858 | @retval EFI_SUCCESS File was found.\r |
859 | @retval EFI_NOT_FOUND File was not found.\r | |
860 | @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.\r | |
b1f6a7c6 | 861 | \r |
b1f6a7c6 | 862 | **/\r |
b0d803fe | 863 | EFI_STATUS\r |
864 | EFIAPI \r | |
865 | PeiFfsFindFileByName (\r | |
866 | IN CONST EFI_GUID *FileName,\r | |
867 | IN EFI_PEI_FV_HANDLE VolumeHandle,\r | |
868 | OUT EFI_PEI_FILE_HANDLE *FileHandle\r | |
869 | )\r | |
b0d803fe | 870 | {\r |
3b428ade | 871 | PEI_CORE_FV_HANDLE *CoreFvHandle;\r |
872 | \r | |
b0d803fe | 873 | if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r |
192f6d4c | 874 | return EFI_INVALID_PARAMETER;\r |
875 | }\r | |
3b428ade | 876 | \r |
877 | CoreFvHandle = FvHandleToCoreHandle (VolumeHandle);\r | |
878 | if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r | |
879 | return EFI_NOT_FOUND;\r | |
b0d803fe | 880 | }\r |
3b428ade | 881 | \r |
882 | return CoreFvHandle->FvPpi->FindFileByName (CoreFvHandle->FvPpi, FileName, &VolumeHandle, FileHandle);\r | |
b0d803fe | 883 | }\r |
884 | \r | |
b1f6a7c6 | 885 | /**\r |
b1f6a7c6 | 886 | Returns information about a specific file.\r |
887 | \r | |
3b428ade | 888 | @param FileHandle Handle of the file.\r |
4237d40b | 889 | @param FileInfo Upon exit, points to the file's information.\r |
b1f6a7c6 | 890 | \r |
3b428ade | 891 | @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r |
892 | @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.\r | |
893 | @retval EFI_SUCCESS File information returned.\r | |
b1f6a7c6 | 894 | \r |
895 | **/\r | |
b0d803fe | 896 | EFI_STATUS\r |
897 | EFIAPI \r | |
898 | PeiFfsGetFileInfo (\r | |
899 | IN EFI_PEI_FILE_HANDLE FileHandle,\r | |
900 | OUT EFI_FV_FILE_INFO *FileInfo\r | |
901 | )\r | |
b0d803fe | 902 | {\r |
3b428ade | 903 | PEI_CORE_FV_HANDLE *CoreFvHandle;\r |
904 | \r | |
b0d803fe | 905 | if ((FileHandle == NULL) || (FileInfo == NULL)) {\r |
906 | return EFI_INVALID_PARAMETER;\r | |
907 | }\r | |
908 | \r | |
909 | //\r | |
910 | // Retrieve the FirmwareVolume which the file resides in.\r | |
911 | //\r | |
3b428ade | 912 | CoreFvHandle = FileHandleToVolume (FileHandle);\r |
913 | if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r | |
b0d803fe | 914 | return EFI_INVALID_PARAMETER;\r |
915 | }\r | |
916 | \r | |
3b428ade | 917 | return CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, FileHandle, FileInfo);\r |
b0d803fe | 918 | }\r |
919 | \r | |
920 | \r | |
b1f6a7c6 | 921 | /**\r |
3b428ade | 922 | Returns information about the specified volume.\r |
b1f6a7c6 | 923 | \r |
5a9403b8 | 924 | This function returns information about a specific firmware\r |
925 | volume, including its name, type, attributes, starting address\r | |
926 | and size.\r | |
927 | \r | |
928 | @param VolumeHandle Handle of the volume.\r | |
929 | @param VolumeInfo Upon exit, points to the volume's information.\r | |
930 | \r | |
931 | @retval EFI_SUCCESS Volume information returned.\r | |
932 | @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.\r | |
933 | @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.\r | |
934 | @retval EFI_SUCCESS Information successfully returned.\r | |
935 | @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.\r | |
b1f6a7c6 | 936 | \r |
b1f6a7c6 | 937 | **/\r |
b0d803fe | 938 | EFI_STATUS\r |
939 | EFIAPI \r | |
940 | PeiFfsGetVolumeInfo (\r | |
941 | IN EFI_PEI_FV_HANDLE VolumeHandle,\r | |
942 | OUT EFI_FV_INFO *VolumeInfo\r | |
943 | )\r | |
b0d803fe | 944 | {\r |
3b428ade | 945 | PEI_CORE_FV_HANDLE *CoreHandle;\r |
946 | \r | |
8fdcc412 | 947 | if ((VolumeInfo == NULL) || (VolumeHandle == NULL)) {\r |
b0d803fe | 948 | return EFI_INVALID_PARAMETER;\r |
192f6d4c | 949 | }\r |
288f9b38 | 950 | \r |
3b428ade | 951 | CoreHandle = FvHandleToCoreHandle (VolumeHandle);\r |
952 | \r | |
953 | if ((CoreHandle == NULL) || (CoreHandle->FvPpi == NULL)) {\r | |
288f9b38 LG |
954 | return EFI_INVALID_PARAMETER;\r |
955 | }\r | |
3b428ade | 956 | \r |
957 | return CoreHandle->FvPpi->GetVolumeInfo (CoreHandle->FvPpi, VolumeHandle, VolumeInfo);\r | |
192f6d4c | 958 | }\r |
b0d803fe | 959 | \r |
4c6486b9 | 960 | /**\r |
961 | Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r | |
962 | \r | |
3b428ade | 963 | @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.\r |
97b2c9b5 | 964 | @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.\r |
4c6486b9 | 965 | \r |
966 | @retval EFI_NOT_FOUND FV image can't be found.\r | |
967 | @retval EFI_SUCCESS Successfully to process it.\r | |
968 | @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image\r | |
969 | @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section\r | |
970 | \r | |
971 | **/\r | |
972 | EFI_STATUS\r | |
973 | ProcessFvFile (\r | |
3b428ade | 974 | IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle,\r |
975 | IN EFI_PEI_FILE_HANDLE ParentFvFileHandle\r | |
4c6486b9 | 976 | )\r |
977 | {\r | |
3b428ade | 978 | EFI_STATUS Status;\r |
979 | EFI_FV_INFO ParentFvImageInfo;\r | |
980 | UINT32 FvAlignment;\r | |
981 | VOID *NewFvBuffer;\r | |
982 | EFI_PEI_HOB_POINTERS HobPtr;\r | |
983 | EFI_PEI_FIRMWARE_VOLUME_PPI *ParentFvPpi;\r | |
984 | EFI_PEI_FV_HANDLE ParentFvHandle;\r | |
985 | EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r | |
986 | EFI_FV_FILE_INFO FileInfo;\r | |
b4d856a6 | 987 | UINT64 FvLength;\r |
3b428ade | 988 | \r |
4c6486b9 | 989 | //\r |
990 | // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already\r | |
991 | // been extracted.\r | |
992 | //\r | |
993 | HobPtr.Raw = GetHobList ();\r | |
994 | while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobPtr.Raw)) != NULL) {\r | |
97b2c9b5 | 995 | if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)ParentFvFileHandle)->Name), &HobPtr.FirmwareVolume2->FileName)) {\r |
4c6486b9 | 996 | //\r |
997 | // this FILE has been dispatched, it will not be dispatched again.\r | |
998 | //\r | |
3b428ade | 999 | DEBUG ((EFI_D_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle));\r |
4c6486b9 | 1000 | return EFI_SUCCESS;\r |
1001 | }\r | |
1002 | HobPtr.Raw = GET_NEXT_HOB (HobPtr);\r | |
1003 | }\r | |
1004 | \r | |
3b428ade | 1005 | ParentFvHandle = ParentFvCoreHandle->FvHandle;\r |
1006 | ParentFvPpi = ParentFvCoreHandle->FvPpi;\r | |
1007 | \r | |
4c6486b9 | 1008 | //\r |
1009 | // Find FvImage in FvFile\r | |
1010 | //\r | |
3b428ade | 1011 | Status = ParentFvPpi->FindSectionByType (\r |
1012 | ParentFvPpi,\r | |
1013 | EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r | |
1014 | ParentFvFileHandle,\r | |
1015 | (VOID **)&FvHeader\r | |
1016 | );\r | |
1017 | \r | |
4c6486b9 | 1018 | if (EFI_ERROR (Status)) {\r |
1019 | return Status;\r | |
1020 | }\r | |
97b2c9b5 LG |
1021 | \r |
1022 | //\r | |
3b428ade | 1023 | // FvAlignment must be more than 8 bytes required by FvHeader structure.\r |
4c6486b9 | 1024 | //\r |
b4d856a6 | 1025 | FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r |
4c6486b9 | 1026 | if (FvAlignment < 8) {\r |
1027 | FvAlignment = 8;\r | |
1028 | }\r | |
1029 | \r | |
1030 | //\r | |
1031 | // Check FvImage\r | |
1032 | //\r | |
3b428ade | 1033 | if ((UINTN) FvHeader % FvAlignment != 0) {\r |
b4d856a6 | 1034 | FvLength = ReadUnaligned64 (&FvHeader->FvLength);\r |
1035 | NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment);\r | |
3b428ade | 1036 | if (NewFvBuffer == NULL) {\r |
4c6486b9 | 1037 | return EFI_OUT_OF_RESOURCES;\r |
1038 | }\r | |
b4d856a6 | 1039 | CopyMem (NewFvBuffer, FvHeader, (UINTN) FvLength);\r |
3b428ade | 1040 | FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer;\r |
4c6486b9 | 1041 | }\r |
3b428ade | 1042 | \r |
1043 | Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);\r | |
1044 | ASSERT_EFI_ERROR (Status);\r | |
1045 | \r | |
1046 | Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);\r | |
1047 | ASSERT_EFI_ERROR (Status);\r | |
1048 | \r | |
4c6486b9 | 1049 | //\r |
1050 | // Install FvPpi and Build FvHob\r | |
1051 | //\r | |
187f1a5b | 1052 | PeiServicesInstallFvInfoPpi (\r |
3b428ade | 1053 | &FvHeader->FileSystemGuid,\r |
1054 | (VOID**) FvHeader,\r | |
1055 | (UINT32) FvHeader->FvLength,\r | |
97b2c9b5 | 1056 | &ParentFvImageInfo.FvName,\r |
3b428ade | 1057 | &FileInfo.FileName\r |
4c6486b9 | 1058 | );\r |
1059 | \r | |
1060 | //\r | |
1061 | // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase\r | |
4c6486b9 | 1062 | //\r |
223c22d8 | 1063 | BuildFvHob (\r |
3b428ade | 1064 | (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r |
1065 | FvHeader->FvLength\r | |
18fcd6a7 | 1066 | );\r |
4c6486b9 | 1067 | \r |
1068 | //\r | |
1069 | // Makes the encapsulated volume show up in DXE phase to skip processing of\r | |
1070 | // encapsulated file again.\r | |
1071 | //\r | |
1072 | BuildFv2Hob (\r | |
3b428ade | 1073 | (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r |
1074 | FvHeader->FvLength,\r | |
97b2c9b5 | 1075 | &ParentFvImageInfo.FvName,\r |
3b428ade | 1076 | &FileInfo.FileName\r |
4c6486b9 | 1077 | );\r |
1078 | \r | |
1079 | return EFI_SUCCESS;\r | |
1080 | }\r | |
1081 | \r | |
3b428ade | 1082 | /**\r |
1083 | Process a firmware volume and create a volume handle.\r | |
1084 | \r | |
1085 | Create a volume handle from the information in the buffer. For\r | |
1086 | memory-mapped firmware volumes, Buffer and BufferSize refer to\r | |
1087 | the start of the firmware volume and the firmware volume size.\r | |
1088 | For non memory-mapped firmware volumes, this points to a\r | |
1089 | buffer which contains the necessary information for creating\r | |
1090 | the firmware volume handle. Normally, these values are derived\r | |
1091 | from the EFI_FIRMWARE_VOLUME_INFO_PPI.\r | |
1092 | \r | |
1093 | \r | |
1094 | @param This Points to this instance of the\r | |
1095 | EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1096 | @param Buffer Points to the start of the buffer.\r | |
1097 | @param BufferSize Size of the buffer.\r | |
1098 | @param FvHandle Points to the returned firmware volume\r | |
1099 | handle. The firmware volume handle must\r | |
1100 | be unique within the system. \r | |
1101 | \r | |
1102 | @retval EFI_SUCCESS Firmware volume handle created.\r | |
1103 | @retval EFI_VOLUME_CORRUPTED Volume was corrupt.\r | |
1104 | \r | |
1105 | **/\r | |
1106 | EFI_STATUS\r | |
1107 | EFIAPI\r | |
890e5417 | 1108 | PeiFfsFvPpiProcessVolume (\r |
3b428ade | 1109 | IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r |
1110 | IN VOID *Buffer,\r | |
1111 | IN UINTN BufferSize,\r | |
1112 | OUT EFI_PEI_FV_HANDLE *FvHandle\r | |
1113 | )\r | |
1114 | {\r | |
1115 | EFI_STATUS Status;\r | |
3b428ade | 1116 | \r |
dc6f9b35 | 1117 | ASSERT (FvHandle != NULL);\r |
1118 | \r | |
1119 | if (Buffer == NULL) {\r | |
1120 | return EFI_VOLUME_CORRUPTED;\r | |
1121 | }\r | |
3b428ade | 1122 | \r |
1123 | //\r | |
890e5417 | 1124 | // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped\r |
3b428ade | 1125 | // FV image and the handle is pointed to Fv image's buffer.\r |
1126 | //\r | |
1127 | *FvHandle = (EFI_PEI_FV_HANDLE) Buffer;\r | |
1128 | \r | |
1129 | //\r | |
1130 | // Do verify for given FV buffer.\r | |
1131 | //\r | |
1132 | Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) Buffer);\r | |
1133 | if (EFI_ERROR(Status)) {\r | |
1134 | DEBUG ((EFI_D_ERROR, "Fail to verify FV which address is 0x%11p", Buffer));\r | |
1135 | return EFI_VOLUME_CORRUPTED;\r | |
1136 | }\r | |
1137 | \r | |
3b428ade | 1138 | return EFI_SUCCESS;\r |
1139 | } \r | |
1140 | \r | |
1141 | /**\r | |
1142 | Finds the next file of the specified type.\r | |
1143 | \r | |
1144 | This service enables PEI modules to discover additional firmware files. \r | |
1145 | The FileHandle must be unique within the system.\r | |
1146 | \r | |
1147 | @param This Points to this instance of the\r | |
1148 | EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1149 | @param SearchType A filter to find only files of this type. Type\r | |
1150 | EFI_FV_FILETYPE_ALL causes no filtering to be\r | |
1151 | done.\r | |
1152 | @param FvHandle Handle of firmware volume in which to\r | |
1153 | search.\r | |
1154 | @param FileHandle Points to the current handle from which to\r | |
1155 | begin searching or NULL to start at the\r | |
1156 | beginning of the firmware volume. Updated\r | |
1157 | upon return to reflect the file found.\r | |
1158 | \r | |
1159 | @retval EFI_SUCCESS The file was found.\r | |
1160 | @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.\r | |
1161 | \r | |
1162 | **/\r | |
1163 | EFI_STATUS\r | |
1164 | EFIAPI\r | |
890e5417 | 1165 | PeiFfsFvPpiFindFileByType (\r |
3b428ade | 1166 | IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r |
1167 | IN EFI_FV_FILETYPE SearchType,\r | |
1168 | IN EFI_PEI_FV_HANDLE FvHandle,\r | |
1169 | IN OUT EFI_PEI_FILE_HANDLE *FileHandle\r | |
1170 | )\r | |
1171 | { \r | |
1172 | return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);\r | |
1173 | }\r | |
1174 | \r | |
1175 | /**\r | |
1176 | Find a file within a volume by its name. \r | |
1177 | \r | |
1178 | This service searches for files with a specific name, within\r | |
1179 | either the specified firmware volume or all firmware volumes.\r | |
1180 | \r | |
1181 | @param This Points to this instance of the\r | |
1182 | EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1183 | @param FileName A pointer to the name of the file to find\r | |
1184 | within the firmware volume.\r | |
1185 | @param FvHandle Upon entry, the pointer to the firmware\r | |
1186 | volume to search or NULL if all firmware\r | |
1187 | volumes should be searched. Upon exit, the\r | |
1188 | actual firmware volume in which the file was\r | |
1189 | found.\r | |
1190 | @param FileHandle Upon exit, points to the found file's\r | |
1191 | handle or NULL if it could not be found.\r | |
1192 | \r | |
1193 | @retval EFI_SUCCESS File was found.\r | |
1194 | @retval EFI_NOT_FOUND File was not found.\r | |
1195 | @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or\r | |
1196 | FileName was NULL.\r | |
1197 | \r | |
1198 | \r | |
1199 | **/\r | |
1200 | EFI_STATUS\r | |
1201 | EFIAPI\r | |
890e5417 | 1202 | PeiFfsFvPpiFindFileByName (\r |
3b428ade | 1203 | IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r |
1204 | IN CONST EFI_GUID *FileName,\r | |
1205 | IN EFI_PEI_FV_HANDLE *FvHandle,\r | |
1206 | OUT EFI_PEI_FILE_HANDLE *FileHandle \r | |
1207 | )\r | |
1208 | {\r | |
1209 | EFI_STATUS Status;\r | |
1210 | PEI_CORE_INSTANCE *PrivateData;\r | |
1211 | UINTN Index;\r | |
1212 | \r | |
1213 | if ((FvHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r | |
1214 | return EFI_INVALID_PARAMETER;\r | |
1215 | }\r | |
1216 | \r | |
1217 | if (*FvHandle != NULL) {\r | |
1218 | Status = FindFileEx (*FvHandle, FileName, 0, FileHandle, NULL);\r | |
1219 | if (Status == EFI_NOT_FOUND) {\r | |
1220 | *FileHandle = NULL;\r | |
1221 | }\r | |
1222 | } else { \r | |
1223 | //\r | |
1224 | // If *FvHandle = NULL, so search all FV for given filename\r | |
1225 | //\r | |
1226 | Status = EFI_NOT_FOUND;\r | |
1227 | \r | |
1228 | PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());\r | |
1229 | for (Index = 0; Index < PrivateData->FvCount; Index ++) {\r | |
1230 | //\r | |
1231 | // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.\r | |
1232 | //\r | |
1233 | if (PrivateData->Fv[Index].FvPpi != NULL) {\r | |
1234 | Status = FindFileEx (PrivateData->Fv[Index].FvHandle, FileName, 0, FileHandle, NULL);\r | |
1235 | if (!EFI_ERROR (Status)) {\r | |
1236 | *FvHandle = PrivateData->Fv[Index].FvHandle;\r | |
1c738c8f | 1237 | break;\r |
3b428ade | 1238 | }\r |
1239 | }\r | |
1240 | }\r | |
1241 | }\r | |
1242 | \r | |
1243 | return Status; \r | |
1244 | } \r | |
1245 | \r | |
1246 | /**\r | |
1247 | Returns information about a specific file.\r | |
1248 | \r | |
1249 | This function returns information about a specific\r | |
1250 | file, including its file name, type, attributes, starting\r | |
1251 | address and size. \r | |
1252 | \r | |
1253 | @param This Points to this instance of the\r | |
1254 | EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1255 | @param FileHandle Handle of the file.\r | |
1256 | @param FileInfo Upon exit, points to the file's\r | |
1257 | information.\r | |
1258 | \r | |
1259 | @retval EFI_SUCCESS File information returned.\r | |
1260 | @retval EFI_INVALID_PARAMETER If FileHandle does not\r | |
1261 | represent a valid file.\r | |
1262 | @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r | |
1263 | \r | |
1264 | **/ \r | |
1265 | EFI_STATUS\r | |
1266 | EFIAPI\r | |
890e5417 | 1267 | PeiFfsFvPpiGetFileInfo (\r |
3b428ade | 1268 | IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, \r |
1269 | IN EFI_PEI_FILE_HANDLE FileHandle, \r | |
1270 | OUT EFI_FV_FILE_INFO *FileInfo\r | |
1271 | )\r | |
1272 | {\r | |
1273 | UINT8 FileState;\r | |
1274 | UINT8 ErasePolarity;\r | |
1275 | EFI_FFS_FILE_HEADER *FileHeader;\r | |
1276 | PEI_CORE_FV_HANDLE *CoreFvHandle;\r | |
890e5417 SZ |
1277 | PEI_FW_VOL_INSTANCE *FwVolInstance;\r |
1278 | \r | |
3b428ade | 1279 | if ((FileHandle == NULL) || (FileInfo == NULL)) {\r |
1280 | return EFI_INVALID_PARAMETER;\r | |
1281 | }\r | |
1282 | \r | |
1283 | //\r | |
1284 | // Retrieve the FirmwareVolume which the file resides in.\r | |
1285 | //\r | |
1286 | CoreFvHandle = FileHandleToVolume (FileHandle);\r | |
1287 | if (CoreFvHandle == NULL) {\r | |
1288 | return EFI_INVALID_PARAMETER;\r | |
1289 | }\r | |
1290 | \r | |
890e5417 SZ |
1291 | FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);\r |
1292 | \r | |
4140a663 | 1293 | if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {\r |
3b428ade | 1294 | ErasePolarity = 1;\r |
1295 | } else {\r | |
1296 | ErasePolarity = 0;\r | |
1297 | }\r | |
1298 | \r | |
1299 | //\r | |
1300 | // Get FileState which is the highest bit of the State \r | |
1301 | //\r | |
1302 | FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);\r | |
1303 | \r | |
1304 | switch (FileState) {\r | |
1305 | case EFI_FILE_DATA_VALID:\r | |
1306 | case EFI_FILE_MARKED_FOR_UPDATE:\r | |
1307 | break; \r | |
1308 | default:\r | |
1309 | return EFI_INVALID_PARAMETER;\r | |
1310 | }\r | |
1311 | \r | |
1312 | FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;\r | |
1313 | CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));\r | |
1314 | FileInfo->FileType = FileHeader->Type;\r | |
1315 | FileInfo->FileAttributes = FileHeader->Attributes;\r | |
890e5417 SZ |
1316 | if (IS_FFS_FILE2 (FileHeader)) {\r |
1317 | ASSERT (FFS_FILE2_SIZE (FileHeader) > 0x00FFFFFF);\r | |
1318 | if (!FwVolInstance->IsFfs3Fv) {\r | |
1319 | DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name));\r | |
1320 | return EFI_INVALID_PARAMETER;\r | |
1321 | }\r | |
1322 | FileInfo->BufferSize = FFS_FILE2_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r | |
1323 | FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER2);\r | |
1324 | } else {\r | |
1325 | FileInfo->BufferSize = FFS_FILE_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r | |
1326 | FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);\r | |
1327 | }\r | |
3b428ade | 1328 | return EFI_SUCCESS; \r |
1329 | } \r | |
1330 | \r | |
1331 | /**\r | |
1332 | This function returns information about the firmware volume.\r | |
1333 | \r | |
1334 | @param This Points to this instance of the\r | |
1335 | EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1336 | @param FvHandle Handle to the firmware handle.\r | |
1337 | @param VolumeInfo Points to the returned firmware volume\r | |
1338 | information.\r | |
1339 | \r | |
1340 | @retval EFI_SUCCESS Information returned successfully.\r | |
1341 | @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid\r | |
1342 | firmware volume or VolumeInfo is NULL.\r | |
1343 | \r | |
1344 | **/ \r | |
1345 | EFI_STATUS\r | |
1346 | EFIAPI\r | |
890e5417 | 1347 | PeiFfsFvPpiGetVolumeInfo (\r |
3b428ade | 1348 | IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, \r |
1349 | IN EFI_PEI_FV_HANDLE FvHandle, \r | |
1350 | OUT EFI_FV_INFO *VolumeInfo\r | |
1351 | )\r | |
1352 | {\r | |
1353 | EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;\r | |
1354 | EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;\r | |
1355 | \r | |
8fdcc412 | 1356 | if ((VolumeInfo == NULL) || (FvHandle == NULL)) {\r |
3b428ade | 1357 | return EFI_INVALID_PARAMETER;\r |
1358 | }\r | |
1359 | \r | |
1360 | //\r | |
1361 | // VolumeHandle may not align at 8 byte, \r | |
1362 | // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. \r | |
1363 | // So, Copy FvHeader into the local FvHeader structure.\r | |
1364 | //\r | |
1365 | CopyMem (&FwVolHeader, FvHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r | |
1366 | \r | |
1367 | //\r | |
1368 | // Check Fv Image Signature\r | |
1369 | //\r | |
1370 | if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {\r | |
1371 | return EFI_INVALID_PARAMETER;\r | |
1372 | }\r | |
1373 | \r | |
1374 | ZeroMem (VolumeInfo, sizeof (EFI_FV_INFO));\r | |
1375 | VolumeInfo->FvAttributes = FwVolHeader.Attributes;\r | |
1376 | VolumeInfo->FvStart = (VOID *) FvHandle;\r | |
1377 | VolumeInfo->FvSize = FwVolHeader.FvLength;\r | |
1378 | CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));\r | |
1379 | \r | |
1380 | if (FwVolHeader.ExtHeaderOffset != 0) {\r | |
1381 | FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset);\r | |
1382 | CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r | |
1383 | }\r | |
1384 | \r | |
1385 | return EFI_SUCCESS; \r | |
1386 | } \r | |
1387 | \r | |
1388 | /**\r | |
1389 | Find the next matching section in the firmware file.\r | |
1390 | \r | |
1391 | This service enables PEI modules to discover sections\r | |
1392 | of a given type within a valid file.\r | |
1393 | \r | |
1394 | @param This Points to this instance of the\r | |
1395 | EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1396 | @param SearchType A filter to find only sections of this\r | |
1397 | type.\r | |
1398 | @param FileHandle Handle of firmware file in which to\r | |
1399 | search.\r | |
890e5417 | 1400 | @param SectionData Updated upon return to point to the\r |
3b428ade | 1401 | section found.\r |
1402 | \r | |
1403 | @retval EFI_SUCCESS Section was found.\r | |
1404 | @retval EFI_NOT_FOUND Section of the specified type was not\r | |
1405 | found. SectionData contains NULL.\r | |
1406 | **/\r | |
1407 | EFI_STATUS\r | |
1408 | EFIAPI\r | |
890e5417 | 1409 | PeiFfsFvPpiFindSectionByType (\r |
3b428ade | 1410 | IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r |
1411 | IN EFI_SECTION_TYPE SearchType,\r | |
1412 | IN EFI_PEI_FILE_HANDLE FileHandle,\r | |
1413 | OUT VOID **SectionData\r | |
1414 | )\r | |
1415 | {\r | |
1416 | EFI_FFS_FILE_HEADER *FfsFileHeader;\r | |
1417 | UINT32 FileSize;\r | |
1418 | EFI_COMMON_SECTION_HEADER *Section;\r | |
890e5417 SZ |
1419 | PEI_FW_VOL_INSTANCE *FwVolInstance;\r |
1420 | \r | |
1421 | FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);\r | |
1422 | \r | |
3b428ade | 1423 | FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r |
1424 | \r | |
890e5417 SZ |
1425 | if (IS_FFS_FILE2 (FfsFileHeader)) {\r |
1426 | ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);\r | |
1427 | if (!FwVolInstance->IsFfs3Fv) {\r | |
1428 | DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r | |
1429 | return EFI_NOT_FOUND;\r | |
1430 | }\r | |
1431 | Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r | |
1432 | FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r | |
1433 | } else {\r | |
1434 | Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r | |
1435 | FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r | |
1436 | }\r | |
3b428ade | 1437 | \r |
1438 | return ProcessSection (\r | |
1439 | GetPeiServicesTablePointer (),\r | |
1440 | SearchType, \r | |
1441 | Section, \r | |
1442 | FileSize, \r | |
890e5417 SZ |
1443 | SectionData,\r |
1444 | FwVolInstance->IsFfs3Fv\r | |
3b428ade | 1445 | ); \r |
1446 | } \r | |
1447 | \r | |
1448 | /**\r | |
1449 | Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.\r | |
1450 | \r | |
1451 | @param FvHandle The handle of a FV.\r | |
1452 | \r | |
1453 | @retval NULL if can not find.\r | |
1454 | @return Pointer of corresponding PEI_CORE_FV_HANDLE. \r | |
1455 | **/\r | |
1456 | PEI_CORE_FV_HANDLE *\r | |
1457 | FvHandleToCoreHandle (\r | |
1458 | IN EFI_PEI_FV_HANDLE FvHandle\r | |
1459 | )\r | |
1460 | {\r | |
1461 | UINTN Index;\r | |
1462 | PEI_CORE_INSTANCE *PrivateData;\r | |
1463 | \r | |
1464 | PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer()); \r | |
1465 | for (Index = 0; Index < PrivateData->FvCount; Index ++) {\r | |
1466 | if (FvHandle == PrivateData->Fv[Index].FvHandle) {\r | |
1467 | return &PrivateData->Fv[Index];\r | |
1468 | }\r | |
1469 | }\r | |
1470 | \r | |
1471 | return NULL;\r | |
1472 | } \r | |
1473 | \r | |
1474 | /**\r | |
1475 | Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.\r | |
1476 | \r | |
1477 | This routine also will install FvInfo ppi for FV hob in PI ways.\r | |
1478 | \r | |
1479 | @param Private Pointer of PEI_CORE_INSTANCE\r | |
1480 | @param Instance The index of FV want to be searched.\r | |
1481 | \r | |
1482 | @return Instance of PEI_CORE_FV_HANDLE.\r | |
1483 | **/\r | |
1484 | PEI_CORE_FV_HANDLE *\r | |
1485 | FindNextCoreFvHandle (\r | |
1486 | IN PEI_CORE_INSTANCE *Private,\r | |
1487 | IN UINTN Instance\r | |
1488 | )\r | |
1489 | {\r | |
1490 | UINTN Index;\r | |
1491 | BOOLEAN Match;\r | |
1492 | EFI_HOB_FIRMWARE_VOLUME *FvHob;\r | |
1493 | \r | |
1494 | //\r | |
1495 | // Handle Framework FvHob and Install FvInfo Ppi for it.\r | |
1496 | //\r | |
1497 | if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r | |
1498 | //\r | |
1499 | // Loop to search the wanted FirmwareVolume which supports FFS\r | |
1500 | //\r | |
1501 | FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetFirstHob (EFI_HOB_TYPE_FV);\r | |
1502 | while (FvHob != NULL) {\r | |
20ead725 | 1503 | //\r |
1504 | // Search whether FvHob has been installed into PeiCore's FV database.\r | |
1505 | // If found, no need install new FvInfoPpi for it.\r | |
1506 | //\r | |
3b428ade | 1507 | for (Index = 0, Match = FALSE; Index < Private->FvCount; Index++) {\r |
1508 | if ((EFI_PEI_FV_HANDLE)(UINTN)FvHob->BaseAddress == Private->Fv[Index].FvHeader) {\r | |
1509 | Match = TRUE;\r | |
1510 | break;\r | |
1511 | }\r | |
1512 | }\r | |
20ead725 | 1513 | \r |
3b428ade | 1514 | //\r |
20ead725 | 1515 | // Search whether FvHob has been cached into PeiCore's Unknown FV database.\r |
1516 | // If found, no need install new FvInfoPpi for it.\r | |
1517 | //\r | |
1518 | if (!Match) {\r | |
1519 | for (Index = 0; Index < Private->UnknownFvInfoCount; Index ++) {\r | |
1520 | if ((UINTN)FvHob->BaseAddress == (UINTN)Private->UnknownFvInfo[Index].FvInfo) {\r | |
1521 | Match = TRUE;\r | |
1522 | break;\r | |
1523 | }\r | |
1524 | }\r | |
1525 | }\r | |
1526 | \r | |
1527 | //\r | |
1528 | // If the Fv in FvHob has not been installed into PeiCore's FV database and has\r | |
1529 | // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi\r | |
1530 | // for it then PeiCore will dispatch it in callback of FvInfoPpi.\r | |
3b428ade | 1531 | //\r |
1532 | if (!Match) {\r | |
1533 | PeiServicesInstallFvInfoPpi (\r | |
1534 | &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress)->FileSystemGuid),\r | |
1535 | (VOID *)(UINTN)FvHob->BaseAddress,\r | |
1536 | (UINT32)FvHob->Length,\r | |
1537 | NULL,\r | |
1538 | NULL\r | |
1539 | );\r | |
1540 | }\r | |
20ead725 | 1541 | \r |
3b428ade | 1542 | FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetNextHob (EFI_HOB_TYPE_FV, (VOID *)((UINTN)FvHob + FvHob->Header.HobLength)); \r |
1543 | }\r | |
1544 | }\r | |
1545 | \r | |
60cf9cfc | 1546 | ASSERT (Private->FvCount <= FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r |
3b428ade | 1547 | if (Instance >= Private->FvCount) {\r |
1548 | return NULL;\r | |
1549 | }\r | |
4c6486b9 | 1550 | \r |
3b428ade | 1551 | return &Private->Fv[Instance];\r |
1552 | } \r | |
8e0e40ed | 1553 | \r |
1554 | /**\r | |
1555 | After PeiCore image is shadowed into permanent memory, all build-in FvPpi should\r | |
1556 | be re-installed with the instance in permanent memory and all cached FvPpi pointers in \r | |
1557 | PrivateData->Fv[] array should be fixed up to be pointed to the one in permenant\r | |
1558 | memory.\r | |
1559 | \r | |
1560 | @param PrivateData Pointer to PEI_CORE_INSTANCE.\r | |
1561 | **/ \r | |
1562 | VOID\r | |
1563 | PeiReinitializeFv (\r | |
1564 | IN PEI_CORE_INSTANCE *PrivateData\r | |
1565 | )\r | |
1566 | {\r | |
890e5417 | 1567 | VOID *OldFfsFvPpi;\r |
7ec93917 | 1568 | EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;\r |
1569 | UINTN Index;\r | |
1570 | EFI_STATUS Status;\r | |
1571 | \r | |
1572 | //\r | |
1573 | // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which\r | |
1574 | // in flash.\r | |
1575 | //\r | |
1576 | Status = PeiServicesLocatePpi (\r | |
1577 | &gEfiFirmwareFileSystem2Guid,\r | |
1578 | 0,\r | |
1579 | &OldDescriptor,\r | |
890e5417 | 1580 | &OldFfsFvPpi\r |
7ec93917 | 1581 | );\r |
1582 | ASSERT_EFI_ERROR (Status);\r | |
1583 | \r | |
1584 | //\r | |
1585 | // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2\r | |
1586 | // which is shadowed from flash to permanent memory within PeiCore image.\r | |
1587 | //\r | |
1588 | Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs2FvPpiList);\r | |
1589 | ASSERT_EFI_ERROR (Status);\r | |
890e5417 | 1590 | \r |
7ec93917 | 1591 | //\r |
1592 | // Fixup all FvPpi pointers for the implementation in flash to permanent memory.\r | |
1593 | //\r | |
4140a663 | 1594 | for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r |
890e5417 SZ |
1595 | if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {\r |
1596 | PrivateData->Fv[Index].FvPpi = &mPeiFfs2FwVol.Fv;\r | |
7ec93917 | 1597 | }\r |
1598 | }\r | |
890e5417 SZ |
1599 | \r |
1600 | //\r | |
1601 | // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which\r | |
1602 | // in flash.\r | |
1603 | //\r | |
1604 | Status = PeiServicesLocatePpi (\r | |
1605 | &gEfiFirmwareFileSystem3Guid,\r | |
1606 | 0,\r | |
1607 | &OldDescriptor,\r | |
1608 | &OldFfsFvPpi\r | |
1609 | );\r | |
1610 | ASSERT_EFI_ERROR (Status);\r | |
1611 | \r | |
1612 | //\r | |
1613 | // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3\r | |
1614 | // which is shadowed from flash to permanent memory within PeiCore image.\r | |
1615 | //\r | |
1616 | Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs3FvPpiList);\r | |
1617 | ASSERT_EFI_ERROR (Status);\r | |
1618 | \r | |
1619 | //\r | |
1620 | // Fixup all FvPpi pointers for the implementation in flash to permanent memory.\r | |
1621 | //\r | |
1622 | for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r | |
1623 | if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {\r | |
1624 | PrivateData->Fv[Index].FvPpi = &mPeiFfs3FwVol.Fv;\r | |
1625 | }\r | |
1626 | }\r | |
1627 | }\r | |
8e0e40ed | 1628 | \r |
f3358329 | 1629 | /**\r |
1630 | Report the information for a new discoveried FV in unknown third-party format.\r | |
1631 | \r | |
1632 | If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but\r | |
1633 | the FV in this format has been discoveried, then this FV's information will be cached into \r | |
1634 | PEI_CORE_INSTANCE's UnknownFvInfo array.\r | |
1635 | Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI\r | |
1636 | is installed later by platform's PEIM, the original unknown third-party FV will be processed by\r | |
1637 | using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1638 | \r | |
1639 | @param PrivateData Point to instance of PEI_CORE_INSTANCE\r | |
1640 | @param Format Point to the unknown third-party format guid.\r | |
1641 | @param FvInfo Point to FvInfo buffer.\r | |
1642 | @param FvInfoSize The size of FvInfo buffer.\r | |
1643 | \r | |
1644 | @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.\r | |
1645 | @retval EFI_SUCCESS Success to add the information for unknown FV.\r | |
1646 | **/\r | |
1647 | EFI_STATUS\r | |
1648 | AddUnknownFormatFvInfo (\r | |
1649 | IN PEI_CORE_INSTANCE *PrivateData,\r | |
1650 | IN EFI_GUID *Format,\r | |
1651 | IN VOID *FvInfo,\r | |
1652 | IN UINT32 FvInfoSize\r | |
1653 | )\r | |
1654 | {\r | |
1655 | PEI_CORE_UNKNOW_FORMAT_FV_INFO *NewUnknownFv;\r | |
1656 | \r | |
60cf9cfc | 1657 | if (PrivateData->UnknownFvInfoCount + 1 >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r |
f3358329 | 1658 | return EFI_OUT_OF_RESOURCES;\r |
1659 | }\r | |
1660 | \r | |
1661 | NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount];\r | |
1662 | PrivateData->UnknownFvInfoCount ++;\r | |
1663 | \r | |
1664 | CopyGuid (&NewUnknownFv->FvFormat, Format);\r | |
1665 | NewUnknownFv->FvInfo = FvInfo;\r | |
1666 | NewUnknownFv->FvInfoSize = FvInfoSize;\r | |
1667 | NewUnknownFv->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r | |
1668 | NewUnknownFv->NotifyDescriptor.Guid = &NewUnknownFv->FvFormat;\r | |
1669 | NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback;\r | |
1670 | \r | |
1671 | PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor);\r | |
1672 | return EFI_SUCCESS;\r | |
1673 | }\r | |
1674 | \r | |
1675 | /**\r | |
1676 | Find the FV information according to third-party FV format guid.\r | |
1677 | \r | |
1678 | This routine also will remove the FV information found by given FV format guid from\r | |
1679 | PrivateData->UnknownFvInfo[].\r | |
1680 | \r | |
1681 | @param PrivateData Point to instance of PEI_CORE_INSTANCE\r | |
1682 | @param Format Point to given FV format guid\r | |
1683 | @param FvInfo On return, the pointer of FV information buffer\r | |
1684 | @param FvInfoSize On return, the size of FV information buffer.\r | |
1685 | \r | |
1686 | @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI\r | |
1687 | @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1688 | **/\r | |
1689 | EFI_STATUS\r | |
1690 | FindUnknownFormatFvInfo (\r | |
1691 | IN PEI_CORE_INSTANCE *PrivateData,\r | |
1692 | IN EFI_GUID *Format,\r | |
1693 | OUT VOID **FvInfo,\r | |
1694 | OUT UINT32 *FvInfoSize\r | |
1695 | )\r | |
1696 | {\r | |
1697 | UINTN Index;\r | |
1698 | UINTN Index2;\r | |
1699 | \r | |
1700 | Index = 0;\r | |
1701 | for (; Index < PrivateData->UnknownFvInfoCount; Index ++) {\r | |
1702 | if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) {\r | |
1703 | break;\r | |
1704 | }\r | |
1705 | }\r | |
1706 | \r | |
1707 | if (Index == PrivateData->UnknownFvInfoCount) {\r | |
1708 | return EFI_NOT_FOUND;\r | |
1709 | }\r | |
1710 | \r | |
1711 | *FvInfo = PrivateData->UnknownFvInfo[Index].FvInfo;\r | |
1712 | *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize;\r | |
1713 | \r | |
1714 | //\r | |
1715 | // Remove an entry from UnknownFvInfo array.\r | |
1716 | //\r | |
1717 | Index2 = Index + 1;\r | |
1718 | for (;Index2 < PrivateData->UnknownFvInfoCount; Index2 ++, Index ++) {\r | |
1719 | CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO));\r | |
1720 | }\r | |
1721 | PrivateData->UnknownFvInfoCount --;\r | |
1722 | return EFI_SUCCESS;\r | |
1723 | } \r | |
1724 | \r | |
1725 | /**\r | |
1726 | Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.\r | |
1727 | \r | |
1728 | When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this \r | |
1729 | routine is called to process all discoveried FVs in this format.\r | |
1730 | \r | |
1731 | @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r | |
1732 | @param NotifyDescriptor Address of the notification descriptor data structure.\r | |
1733 | @param Ppi Address of the PPI that was installed.\r | |
1734 | \r | |
1735 | @retval EFI_SUCCESS The notification callback is processed correctly.\r | |
1736 | **/\r | |
1737 | EFI_STATUS\r | |
1738 | EFIAPI\r | |
1739 | ThirdPartyFvPpiNotifyCallback (\r | |
1740 | IN EFI_PEI_SERVICES **PeiServices,\r | |
1741 | IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r | |
1742 | IN VOID *Ppi\r | |
1743 | )\r | |
1744 | {\r | |
1745 | PEI_CORE_INSTANCE *PrivateData;\r | |
1746 | EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r | |
1747 | VOID *FvInfo;\r | |
1748 | UINT32 FvInfoSize;\r | |
1749 | EFI_STATUS Status;\r | |
1750 | EFI_PEI_FV_HANDLE FvHandle;\r | |
1751 | BOOLEAN IsProcessed;\r | |
1752 | UINTN FvIndex;\r | |
1753 | EFI_PEI_FILE_HANDLE FileHandle;\r | |
1754 | VOID *DepexData; \r | |
1755 | \r | |
1756 | PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r | |
1757 | FvPpi = (EFI_PEI_FIRMWARE_VOLUME_PPI*) Ppi;\r | |
1758 | \r | |
1759 | do {\r | |
1760 | Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize);\r | |
1761 | if (EFI_ERROR (Status)) {\r | |
1762 | return EFI_SUCCESS;\r | |
1763 | }\r | |
1764 | \r | |
1765 | //\r | |
1766 | // Process new found FV and get FV handle.\r | |
1767 | //\r | |
1768 | Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle);\r | |
1769 | if (EFI_ERROR (Status)) {\r | |
1770 | DEBUG ((EFI_D_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));\r | |
1771 | continue;\r | |
1772 | }\r | |
1773 | \r | |
1774 | //\r | |
1775 | // Check whether the FV has already been processed.\r | |
1776 | //\r | |
1777 | IsProcessed = FALSE;\r | |
1778 | for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r | |
1779 | if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r | |
1780 | DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo));\r | |
1781 | IsProcessed = TRUE;\r | |
1782 | break;\r | |
1783 | }\r | |
1784 | }\r | |
1785 | \r | |
1786 | if (IsProcessed) {\r | |
1787 | continue;\r | |
1788 | }\r | |
1789 | \r | |
ccf0f68d | 1790 | if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r |
1791 | DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported)));\r | |
1792 | DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));\r | |
1793 | ASSERT (FALSE);\r | |
1794 | }\r | |
1795 | \r | |
f3358329 | 1796 | //\r |
1797 | // Update internal PEI_CORE_FV array.\r | |
1798 | //\r | |
1799 | PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo;\r | |
1800 | PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r | |
1801 | PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r | |
1802 | DEBUG ((\r | |
1803 | EFI_D_INFO, \r | |
1804 | "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r | |
1805 | (UINT32) PrivateData->FvCount, \r | |
1806 | (VOID *) FvInfo, \r | |
1807 | FvInfoSize,\r | |
1808 | FvHandle\r | |
1809 | )); \r | |
1810 | PrivateData->FvCount ++;\r | |
1811 | \r | |
1812 | //\r | |
1813 | // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r | |
1814 | //\r | |
1815 | FileHandle = NULL;\r | |
1816 | do {\r | |
1817 | Status = FvPpi->FindFileByType (\r | |
1818 | FvPpi,\r | |
1819 | EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r | |
1820 | FvHandle,\r | |
1821 | &FileHandle\r | |
1822 | );\r | |
1823 | if (!EFI_ERROR (Status)) {\r | |
1824 | Status = FvPpi->FindSectionByType (\r | |
1825 | FvPpi,\r | |
1826 | EFI_SECTION_PEI_DEPEX,\r | |
1827 | FileHandle,\r | |
1828 | (VOID**)&DepexData\r | |
1829 | );\r | |
1830 | if (!EFI_ERROR (Status)) {\r | |
1831 | if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r | |
1832 | //\r | |
1833 | // Dependency is not satisfied.\r | |
1834 | //\r | |
1835 | continue;\r | |
1836 | }\r | |
1837 | }\r | |
1838 | \r | |
1839 | DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r | |
1840 | ProcessFvFile (&PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r | |
1841 | }\r | |
1842 | } while (FileHandle != NULL);\r | |
1843 | } while (TRUE);\r | |
f3358329 | 1844 | }\r |