]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Library / VarCheckHiiLib / VarCheckHiiGenFromFv.c
CommitLineData
1241af95
SZ
1/** @file\r
2 Var Check Hii generation from FV.\r
3\r
39cde03c 4Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
1241af95
SZ
6\r
7**/\r
8\r
9#include "VarCheckHiiGen.h"\r
10\r
11// {d0bc7cb4-6a47-495f-aa11-710746da06a2}\r
12#define EFI_VFR_ATTRACT_GUID \\r
13{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }\r
14\r
1436aea4 15EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;\r
1241af95
SZ
16\r
17#define ALL_FF_GUID \\r
18{ 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }\r
19\r
1436aea4 20EFI_GUID mAllFfGuid = ALL_FF_GUID;\r
1241af95 21\r
1436aea4 22#define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I')\r
1241af95
SZ
23\r
24typedef struct {\r
1436aea4
MK
25 UINTN Signature;\r
26 LIST_ENTRY Link;\r
27 EFI_GUID *DriverGuid;\r
1241af95
SZ
28} VAR_CHECK_VFR_DRIVER_INFO;\r
29\r
1436aea4 30LIST_ENTRY mVfrDriverList = INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList);\r
1241af95
SZ
31\r
32#define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE)\r
33\r
1436aea4 34#define MAX_MATCH_GUID_NUM 100\r
1241af95
SZ
35\r
36/**\r
37 Get the address by Guid.\r
38\r
39 Parse the FFS and find the GUID address.\r
40 There may be multiple Guids matching the searched Guid.\r
41\r
42 @param Ffs Pointer to the FFS.\r
43 @param Guid Guid to find.\r
44 @param Length The length of FFS.\r
45 @param Offset Pointer to pointer to the offset.\r
46 @param NumOfMatchingGuid The number of matching Guid.\r
47\r
48 @retval EFI_SUCCESS One or multiple Guids matching the searched Guid.\r
49 @retval EFI_NOT_FOUND No Guid matching the searched Guid.\r
50\r
51**/\r
52EFI_STATUS\r
53GetAddressByGuid (\r
1436aea4
MK
54 IN VOID *Ffs,\r
55 IN EFI_GUID *Guid,\r
56 IN UINTN Length,\r
57 OUT UINTN **Offset,\r
58 OUT UINT8 *NumOfMatchingGuid\r
1241af95
SZ
59 )\r
60{\r
1436aea4
MK
61 UINTN LoopControl;\r
62 BOOLEAN Found;\r
1241af95 63\r
1436aea4 64 if ((Ffs == NULL) || (Guid == NULL) || (Length == 0)) {\r
1241af95
SZ
65 return EFI_NOT_FOUND;\r
66 }\r
67\r
68 if (NumOfMatchingGuid != NULL) {\r
69 *NumOfMatchingGuid = 0;\r
70 }\r
71\r
72 Found = FALSE;\r
73 for (LoopControl = 0; LoopControl < Length; LoopControl++) {\r
1436aea4 74 if (CompareGuid (Guid, (EFI_GUID *)((UINT8 *)Ffs + LoopControl))) {\r
1241af95
SZ
75 Found = TRUE;\r
76 //\r
77 // If NumOfMatchGuid or Offset are NULL, means user only want\r
78 // to check whether current FFS includes this Guid or not.\r
79 //\r
80 if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) {\r
81 if (*NumOfMatchingGuid == 0) {\r
82 *Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM);\r
83 ASSERT (*Offset != NULL);\r
84 }\r
1436aea4 85\r
1241af95
SZ
86 *(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID);\r
87 (*NumOfMatchingGuid)++;\r
88 } else {\r
89 break;\r
90 }\r
91 }\r
92 }\r
93\r
94 return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
95}\r
96\r
97/**\r
98 Search the VfrBin Base address.\r
99\r
100 According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.\r
101\r
102 @param Ffs Pointer to the FFS.\r
103 @param EfiAddr Pointer to the EFI in FFS\r
104 @param Length The length of FFS.\r
105 @param Offset Pointer to pointer to the Addr (Offset).\r
106 @param NumOfMatchingOffset The number of Addr (Offset).\r
107\r
108 @retval EFI_SUCCESS Get the address successfully.\r
109 @retval EFI_NOT_FOUND No VfrBin found.\r
110\r
111**/\r
112EFI_STATUS\r
113SearchVfrBinInFfs (\r
1436aea4
MK
114 IN VOID *Ffs,\r
115 IN VOID *EfiAddr,\r
116 IN UINTN Length,\r
117 OUT UINTN **Offset,\r
118 OUT UINT8 *NumOfMatchingOffset\r
1241af95
SZ
119 )\r
120{\r
1436aea4
MK
121 UINTN Index;\r
122 EFI_STATUS Status;\r
123 UINTN VirOffValue;\r
1241af95
SZ
124\r
125 if ((Ffs == NULL) || (Offset == NULL)) {\r
126 return EFI_NOT_FOUND;\r
127 }\r
1436aea4 128\r
1241af95
SZ
129 Status = GetAddressByGuid (\r
130 Ffs,\r
131 &gVfrArrayAttractGuid,\r
132 Length,\r
133 Offset,\r
134 NumOfMatchingOffset\r
135 );\r
136 if (Status != EFI_SUCCESS) {\r
137 return Status;\r
138 }\r
139\r
140 for (Index = 0; Index < *NumOfMatchingOffset; Index++) {\r
141 //\r
142 // Got the virOffset after the GUID\r
143 //\r
1436aea4 144 VirOffValue = *(UINTN *)((UINTN)Ffs + *(*Offset + Index));\r
1241af95
SZ
145 //\r
146 // Transfer the offset to the VA address. One modules may own multiple VfrBin address.\r
147 //\r
1436aea4 148 *(*Offset + Index) = (UINTN)EfiAddr + VirOffValue;\r
1241af95
SZ
149 }\r
150\r
151 return Status;\r
152}\r
153\r
154/**\r
155 Parse FFS.\r
156\r
157 @param[in] Fv2 Pointer to Fv2 protocol.\r
158 @param[in] DriverGuid Pointer to driver GUID.\r
159\r
160 @return Found the driver in the FV or not.\r
161\r
162**/\r
163BOOLEAN\r
164ParseFfs (\r
165 IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2,\r
166 IN EFI_GUID *DriverGuid\r
167 )\r
168{\r
1436aea4
MK
169 EFI_STATUS Status;\r
170 EFI_FV_FILETYPE FoundType;\r
171 EFI_FV_FILE_ATTRIBUTES FileAttributes;\r
172 UINT32 AuthenticationStatus;\r
173 UINTN Size;\r
174 VOID *Buffer;\r
175 UINTN SectionSize;\r
176 VOID *SectionBuffer;\r
177 UINTN VfrBinIndex;\r
178 UINT8 NumberofMatchingVfrBin;\r
179 UINTN *VfrBinBaseAddress;\r
1241af95
SZ
180\r
181 Status = Fv2->ReadFile (\r
182 Fv2,\r
183 DriverGuid,\r
184 NULL,\r
185 &Size,\r
186 &FoundType,\r
187 &FileAttributes,\r
188 &AuthenticationStatus\r
189 );\r
190 if (EFI_ERROR (Status)) {\r
191 return FALSE;\r
192 }\r
193\r
194 Buffer = NULL;\r
195 Status = Fv2->ReadSection (\r
196 Fv2,\r
197 DriverGuid,\r
198 EFI_SECTION_RAW,\r
199 0, // Instance\r
200 &Buffer,\r
201 &Size,\r
202 &AuthenticationStatus\r
203 );\r
1436aea4
MK
204 if (!EFI_ERROR (Status)) {\r
205 Status = SearchVfrBinInFfs (Buffer, 0, Size, &VfrBinBaseAddress, &NumberofMatchingVfrBin);\r
206 if (!EFI_ERROR (Status)) {\r
207 SectionBuffer = NULL;\r
208 Status = Fv2->ReadSection (\r
209 Fv2,\r
210 DriverGuid,\r
211 EFI_SECTION_PE32,\r
212 0, // Instance\r
213 &SectionBuffer,\r
214 &SectionSize,\r
215 &AuthenticationStatus\r
216 );\r
217 if (!EFI_ERROR (Status)) {\r
218 DEBUG ((DEBUG_INFO, "FfsNameGuid - %g\n", DriverGuid));\r
219 DEBUG ((DEBUG_INFO, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin));\r
220\r
221 for (VfrBinIndex = 0; VfrBinIndex < NumberofMatchingVfrBin; VfrBinIndex++) {\r
222 #ifdef DUMP_HII_DATA\r
223 DEBUG_CODE (\r
224 DumpHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32));\r
225 );\r
226 #endif\r
227 VarCheckParseHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32), TRUE);\r
1241af95
SZ
228 }\r
229\r
1436aea4 230 FreePool (SectionBuffer);\r
1241af95
SZ
231 }\r
232\r
1436aea4 233 InternalVarCheckFreePool (VfrBinBaseAddress);\r
1241af95
SZ
234 }\r
235\r
1436aea4
MK
236 FreePool (Buffer);\r
237 }\r
238\r
239 return TRUE;\r
1241af95
SZ
240}\r
241\r
242/**\r
243 Parse FVs.\r
244\r
245 @param[in] ScanAll Scan all modules in all FVs or not.\r
246\r
247**/\r
248VOID\r
249ParseFv (\r
1436aea4 250 IN BOOLEAN ScanAll\r
1241af95
SZ
251 )\r
252{\r
1436aea4
MK
253 EFI_STATUS Status;\r
254 EFI_HANDLE *HandleBuffer;\r
255 UINTN HandleCount;\r
256 UINTN Index;\r
257 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;\r
258 VOID *Key;\r
259 EFI_FV_FILETYPE FileType;\r
260 EFI_GUID NameGuid;\r
261 EFI_FV_FILE_ATTRIBUTES FileAttributes;\r
262 UINTN Size;\r
263 UINTN FfsIndex;\r
264 VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;\r
265 LIST_ENTRY *VfrDriverLink;\r
1241af95
SZ
266\r
267 HandleBuffer = NULL;\r
1436aea4
MK
268 Status = gBS->LocateHandleBuffer (\r
269 ByProtocol,\r
270 &gEfiFirmwareVolume2ProtocolGuid,\r
271 NULL,\r
272 &HandleCount,\r
273 &HandleBuffer\r
274 );\r
1241af95
SZ
275 if (EFI_ERROR (Status)) {\r
276 return;\r
277 }\r
278\r
279 //\r
280 // Search all FVs\r
281 //\r
282 for (Index = 0; Index < HandleCount; Index++) {\r
1436aea4 283 DEBUG ((DEBUG_INFO, "FvIndex - %x\n", Index));\r
1241af95
SZ
284 Status = gBS->HandleProtocol (\r
285 HandleBuffer[Index],\r
286 &gEfiFirmwareVolume2ProtocolGuid,\r
1436aea4 287 (VOID **)&Fv2\r
1241af95
SZ
288 );\r
289 ASSERT_EFI_ERROR (Status);\r
290\r
db52c7f7 291 DEBUG_CODE_BEGIN ();\r
1436aea4
MK
292 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvb2;\r
293 EFI_PHYSICAL_ADDRESS FvAddress;\r
294 UINT64 FvSize;\r
295\r
296 Status = gBS->HandleProtocol (\r
297 HandleBuffer[Index],\r
298 &gEfiFirmwareVolumeBlock2ProtocolGuid,\r
299 (VOID **)&Fvb2\r
300 );\r
301 ASSERT_EFI_ERROR (Status);\r
302 Status = Fvb2->GetPhysicalAddress (Fvb2, &FvAddress);\r
303 if (!EFI_ERROR (Status)) {\r
304 DEBUG ((DEBUG_INFO, "FvAddress - 0x%08x\n", FvAddress));\r
305 FvSize = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddress)->FvLength;\r
306 DEBUG ((DEBUG_INFO, "FvSize - 0x%08x\n", FvSize));\r
307 }\r
308\r
db52c7f7 309 DEBUG_CODE_END ();\r
1241af95
SZ
310\r
311 if (ScanAll) {\r
312 //\r
313 // Need to parse all modules in all FVs.\r
314 //\r
315 Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize);\r
316 ASSERT (Key != NULL);\r
317\r
318 for (FfsIndex = 0; ; FfsIndex++) {\r
319 FileType = EFI_FV_FILETYPE_ALL;\r
1436aea4
MK
320 Status = Fv2->GetNextFile (\r
321 Fv2,\r
322 Key,\r
323 &FileType,\r
324 &NameGuid,\r
325 &FileAttributes,\r
326 &Size\r
327 );\r
1241af95
SZ
328 if (EFI_ERROR (Status)) {\r
329 break;\r
330 }\r
331\r
332 ParseFfs (Fv2, &NameGuid);\r
333 }\r
334\r
335 InternalVarCheckFreePool (Key);\r
336 } else {\r
337 //\r
338 // Only parse drivers in the VFR drivers list.\r
339 //\r
340 VfrDriverLink = mVfrDriverList.ForwardLink;\r
341 while (VfrDriverLink != &mVfrDriverList) {\r
342 VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);\r
343 VfrDriverLink = VfrDriverLink->ForwardLink;\r
344 if (ParseFfs (Fv2, VfrDriverInfo->DriverGuid)) {\r
345 //\r
346 // Found the driver in the FV.\r
347 //\r
348 RemoveEntryList (&VfrDriverInfo->Link);\r
349 InternalVarCheckFreePool (VfrDriverInfo);\r
350 }\r
351 }\r
352 }\r
353 }\r
354\r
355 FreePool (HandleBuffer);\r
356}\r
357\r
358/**\r
359 Create Vfr Driver List.\r
360\r
361 @param[in] DriverGuidArray Driver Guid Array\r
362\r
363**/\r
364VOID\r
365CreateVfrDriverList (\r
1436aea4 366 IN EFI_GUID *DriverGuidArray\r
1241af95
SZ
367 )\r
368{\r
1436aea4
MK
369 UINTN Index;\r
370 VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;\r
1241af95 371\r
39cde03c 372 for (Index = 0; !IsZeroGuid (&DriverGuidArray[Index]); Index++) {\r
1436aea4
MK
373 DEBUG ((DEBUG_INFO, "CreateVfrDriverList: %g\n", &DriverGuidArray[Index]));\r
374 VfrDriverInfo = InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo));\r
375 ASSERT (VfrDriverInfo != NULL);\r
376 VfrDriverInfo->Signature = VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE;\r
377 VfrDriverInfo->DriverGuid = &DriverGuidArray[Index];\r
378 InsertTailList (&mVfrDriverList, &VfrDriverInfo->Link);\r
1241af95
SZ
379 }\r
380}\r
381\r
382/**\r
383 Destroy Vfr Driver List.\r
384\r
385**/\r
386VOID\r
387DestroyVfrDriverList (\r
388 VOID\r
389 )\r
390{\r
1436aea4
MK
391 VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;\r
392 LIST_ENTRY *VfrDriverLink;\r
1241af95
SZ
393\r
394 while (mVfrDriverList.ForwardLink != &mVfrDriverList) {\r
395 VfrDriverLink = mVfrDriverList.ForwardLink;\r
396 VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);\r
397 RemoveEntryList (&VfrDriverInfo->Link);\r
398 InternalVarCheckFreePool (VfrDriverInfo);\r
399 }\r
400}\r
401\r
402/**\r
403 Generate from FV.\r
404\r
405**/\r
406VOID\r
407VarCheckHiiGenFromFv (\r
408 VOID\r
409 )\r
410{\r
1436aea4
MK
411 EFI_GUID *DriverGuidArray;\r
412 BOOLEAN ScanAll;\r
1241af95 413\r
1436aea4 414 DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromFv\n"));\r
1241af95
SZ
415\r
416 //\r
417 // Get vfr driver guid array from PCD.\r
418 //\r
1436aea4 419 DriverGuidArray = (EFI_GUID *)PcdGetPtr (PcdVarCheckVfrDriverGuidArray);\r
1241af95 420\r
39cde03c 421 if (IsZeroGuid (&DriverGuidArray[0])) {\r
1241af95
SZ
422 //\r
423 // No VFR driver will be parsed from FVs.\r
424 //\r
425 return;\r
426 }\r
427\r
428 if (CompareGuid (&DriverGuidArray[0], &mAllFfGuid)) {\r
429 ScanAll = TRUE;\r
430 } else {\r
431 ScanAll = FALSE;\r
432 CreateVfrDriverList (DriverGuidArray);\r
433 }\r
434\r
435 ParseFv (ScanAll);\r
436\r
437 if (!ScanAll) {\r
438 DestroyVfrDriverList ();\r
439 }\r
440}\r