2 Var Check Hii generation from FV.
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "VarCheckHiiGen.h"
11 // {d0bc7cb4-6a47-495f-aa11-710746da06a2}
12 #define EFI_VFR_ATTRACT_GUID \
13 { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }
15 EFI_GUID gVfrArrayAttractGuid
= EFI_VFR_ATTRACT_GUID
;
18 { 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }
20 EFI_GUID mAllFfGuid
= ALL_FF_GUID
;
22 #define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I')
28 } VAR_CHECK_VFR_DRIVER_INFO
;
30 LIST_ENTRY mVfrDriverList
= INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList
);
32 #define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE)
34 #define MAX_MATCH_GUID_NUM 100
37 Get the address by Guid.
39 Parse the FFS and find the GUID address.
40 There may be multiple Guids matching the searched Guid.
42 @param Ffs Pointer to the FFS.
43 @param Guid Guid to find.
44 @param Length The length of FFS.
45 @param Offset Pointer to pointer to the offset.
46 @param NumOfMatchingGuid The number of matching Guid.
48 @retval EFI_SUCCESS One or multiple Guids matching the searched Guid.
49 @retval EFI_NOT_FOUND No Guid matching the searched Guid.
58 OUT UINT8
*NumOfMatchingGuid
64 if ((Ffs
== NULL
) || (Guid
== NULL
) || (Length
== 0)) {
68 if (NumOfMatchingGuid
!= NULL
) {
69 *NumOfMatchingGuid
= 0;
73 for (LoopControl
= 0; LoopControl
< Length
; LoopControl
++) {
74 if (CompareGuid (Guid
, (EFI_GUID
*)((UINT8
*)Ffs
+ LoopControl
))) {
77 // If NumOfMatchGuid or Offset are NULL, means user only want
78 // to check whether current FFS includes this Guid or not.
80 if ((NumOfMatchingGuid
!= NULL
) && (Offset
!= NULL
)) {
81 if (*NumOfMatchingGuid
== 0) {
82 *Offset
= InternalVarCheckAllocateZeroPool (sizeof (UINTN
) * MAX_MATCH_GUID_NUM
);
83 ASSERT (*Offset
!= NULL
);
86 *(*Offset
+ *NumOfMatchingGuid
) = LoopControl
+ sizeof (EFI_GUID
);
87 (*NumOfMatchingGuid
)++;
94 return (Found
? EFI_SUCCESS
: EFI_NOT_FOUND
);
98 Search the VfrBin Base address.
100 According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.
102 @param Ffs Pointer to the FFS.
103 @param EfiAddr Pointer to the EFI in FFS
104 @param Length The length of FFS.
105 @param Offset Pointer to pointer to the Addr (Offset).
106 @param NumOfMatchingOffset The number of Addr (Offset).
108 @retval EFI_SUCCESS Get the address successfully.
109 @retval EFI_NOT_FOUND No VfrBin found.
118 OUT UINT8
*NumOfMatchingOffset
125 if ((Ffs
== NULL
) || (Offset
== NULL
)) {
126 return EFI_NOT_FOUND
;
129 Status
= GetAddressByGuid (
131 &gVfrArrayAttractGuid
,
136 if (Status
!= EFI_SUCCESS
) {
140 for (Index
= 0; Index
< *NumOfMatchingOffset
; Index
++) {
142 // Got the virOffset after the GUID
144 VirOffValue
= *(UINTN
*)((UINTN
)Ffs
+ *(*Offset
+ Index
));
146 // Transfer the offset to the VA address. One modules may own multiple VfrBin address.
148 *(*Offset
+ Index
) = (UINTN
)EfiAddr
+ VirOffValue
;
157 @param[in] Fv2 Pointer to Fv2 protocol.
158 @param[in] DriverGuid Pointer to driver GUID.
160 @return Found the driver in the FV or not.
165 IN EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv2
,
166 IN EFI_GUID
*DriverGuid
170 EFI_FV_FILETYPE FoundType
;
171 EFI_FV_FILE_ATTRIBUTES FileAttributes
;
172 UINT32 AuthenticationStatus
;
178 UINT8 NumberofMatchingVfrBin
;
179 UINTN
*VfrBinBaseAddress
;
181 Status
= Fv2
->ReadFile (
188 &AuthenticationStatus
190 if (EFI_ERROR (Status
)) {
195 Status
= Fv2
->ReadSection (
202 &AuthenticationStatus
204 if (!EFI_ERROR (Status
)) {
205 Status
= SearchVfrBinInFfs (Buffer
, 0, Size
, &VfrBinBaseAddress
, &NumberofMatchingVfrBin
);
206 if (!EFI_ERROR (Status
)) {
207 SectionBuffer
= NULL
;
208 Status
= Fv2
->ReadSection (
215 &AuthenticationStatus
217 if (!EFI_ERROR (Status
)) {
218 DEBUG ((DEBUG_INFO
, "FfsNameGuid - %g\n", DriverGuid
));
219 DEBUG ((DEBUG_INFO
, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin
));
221 for (VfrBinIndex
= 0; VfrBinIndex
< NumberofMatchingVfrBin
; VfrBinIndex
++) {
224 DumpHiiPackage ((UINT8
*)(UINTN
)SectionBuffer
+ VfrBinBaseAddress
[VfrBinIndex
] + sizeof (UINT32
));
227 VarCheckParseHiiPackage ((UINT8
*)(UINTN
)SectionBuffer
+ VfrBinBaseAddress
[VfrBinIndex
] + sizeof (UINT32
), TRUE
);
230 FreePool (SectionBuffer
);
233 InternalVarCheckFreePool (VfrBinBaseAddress
);
245 @param[in] ScanAll Scan all modules in all FVs or not.
254 EFI_HANDLE
*HandleBuffer
;
257 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv2
;
259 EFI_FV_FILETYPE FileType
;
261 EFI_FV_FILE_ATTRIBUTES FileAttributes
;
264 VAR_CHECK_VFR_DRIVER_INFO
*VfrDriverInfo
;
265 LIST_ENTRY
*VfrDriverLink
;
268 Status
= gBS
->LocateHandleBuffer (
270 &gEfiFirmwareVolume2ProtocolGuid
,
275 if (EFI_ERROR (Status
)) {
282 for (Index
= 0; Index
< HandleCount
; Index
++) {
283 DEBUG ((DEBUG_INFO
, "FvIndex - %x\n", Index
));
284 Status
= gBS
->HandleProtocol (
286 &gEfiFirmwareVolume2ProtocolGuid
,
289 ASSERT_EFI_ERROR (Status
);
292 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*Fvb2
;
293 EFI_PHYSICAL_ADDRESS FvAddress
;
296 Status
= gBS
->HandleProtocol (
298 &gEfiFirmwareVolumeBlock2ProtocolGuid
,
301 ASSERT_EFI_ERROR (Status
);
302 Status
= Fvb2
->GetPhysicalAddress (Fvb2
, &FvAddress
);
303 if (!EFI_ERROR (Status
)) {
304 DEBUG ((DEBUG_INFO
, "FvAddress - 0x%08x\n", FvAddress
));
305 FvSize
= ((EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)FvAddress
)->FvLength
;
306 DEBUG ((DEBUG_INFO
, "FvSize - 0x%08x\n", FvSize
));
313 // Need to parse all modules in all FVs.
315 Key
= InternalVarCheckAllocateZeroPool (Fv2
->KeySize
);
316 ASSERT (Key
!= NULL
);
318 for (FfsIndex
= 0; ; FfsIndex
++) {
319 FileType
= EFI_FV_FILETYPE_ALL
;
320 Status
= Fv2
->GetNextFile (
328 if (EFI_ERROR (Status
)) {
332 ParseFfs (Fv2
, &NameGuid
);
335 InternalVarCheckFreePool (Key
);
338 // Only parse drivers in the VFR drivers list.
340 VfrDriverLink
= mVfrDriverList
.ForwardLink
;
341 while (VfrDriverLink
!= &mVfrDriverList
) {
342 VfrDriverInfo
= VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink
);
343 VfrDriverLink
= VfrDriverLink
->ForwardLink
;
344 if (ParseFfs (Fv2
, VfrDriverInfo
->DriverGuid
)) {
346 // Found the driver in the FV.
348 RemoveEntryList (&VfrDriverInfo
->Link
);
349 InternalVarCheckFreePool (VfrDriverInfo
);
355 FreePool (HandleBuffer
);
359 Create Vfr Driver List.
361 @param[in] DriverGuidArray Driver Guid Array
365 CreateVfrDriverList (
366 IN EFI_GUID
*DriverGuidArray
370 VAR_CHECK_VFR_DRIVER_INFO
*VfrDriverInfo
;
372 for (Index
= 0; !IsZeroGuid (&DriverGuidArray
[Index
]); Index
++) {
373 DEBUG ((DEBUG_INFO
, "CreateVfrDriverList: %g\n", &DriverGuidArray
[Index
]));
374 VfrDriverInfo
= InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo
));
375 ASSERT (VfrDriverInfo
!= NULL
);
376 VfrDriverInfo
->Signature
= VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE
;
377 VfrDriverInfo
->DriverGuid
= &DriverGuidArray
[Index
];
378 InsertTailList (&mVfrDriverList
, &VfrDriverInfo
->Link
);
383 Destroy Vfr Driver List.
387 DestroyVfrDriverList (
391 VAR_CHECK_VFR_DRIVER_INFO
*VfrDriverInfo
;
392 LIST_ENTRY
*VfrDriverLink
;
394 while (mVfrDriverList
.ForwardLink
!= &mVfrDriverList
) {
395 VfrDriverLink
= mVfrDriverList
.ForwardLink
;
396 VfrDriverInfo
= VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink
);
397 RemoveEntryList (&VfrDriverInfo
->Link
);
398 InternalVarCheckFreePool (VfrDriverInfo
);
407 VarCheckHiiGenFromFv (
411 EFI_GUID
*DriverGuidArray
;
414 DEBUG ((DEBUG_INFO
, "VarCheckHiiGenDxeFromFv\n"));
417 // Get vfr driver guid array from PCD.
419 DriverGuidArray
= (EFI_GUID
*)PcdGetPtr (PcdVarCheckVfrDriverGuidArray
);
421 if (IsZeroGuid (&DriverGuidArray
[0])) {
423 // No VFR driver will be parsed from FVs.
428 if (CompareGuid (&DriverGuidArray
[0], &mAllFfGuid
)) {
432 CreateVfrDriverList (DriverGuidArray
);
438 DestroyVfrDriverList ();