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
);
85 *(*Offset
+ *NumOfMatchingGuid
) = LoopControl
+ sizeof (EFI_GUID
);
86 (*NumOfMatchingGuid
)++;
93 return (Found
? EFI_SUCCESS
: EFI_NOT_FOUND
);
97 Search the VfrBin Base address.
99 According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.
101 @param Ffs Pointer to the FFS.
102 @param EfiAddr Pointer to the EFI in FFS
103 @param Length The length of FFS.
104 @param Offset Pointer to pointer to the Addr (Offset).
105 @param NumOfMatchingOffset The number of Addr (Offset).
107 @retval EFI_SUCCESS Get the address successfully.
108 @retval EFI_NOT_FOUND No VfrBin found.
117 OUT UINT8
*NumOfMatchingOffset
124 if ((Ffs
== NULL
) || (Offset
== NULL
)) {
125 return EFI_NOT_FOUND
;
127 Status
= GetAddressByGuid (
129 &gVfrArrayAttractGuid
,
134 if (Status
!= EFI_SUCCESS
) {
138 for (Index
= 0; Index
< *NumOfMatchingOffset
; Index
++) {
140 // Got the virOffset after the GUID
142 VirOffValue
= *(UINTN
*) ((UINTN
) Ffs
+ *(*Offset
+ Index
));
144 // Transfer the offset to the VA address. One modules may own multiple VfrBin address.
146 *(*Offset
+ Index
) = (UINTN
) EfiAddr
+ VirOffValue
;
155 @param[in] Fv2 Pointer to Fv2 protocol.
156 @param[in] DriverGuid Pointer to driver GUID.
158 @return Found the driver in the FV or not.
163 IN EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv2
,
164 IN EFI_GUID
*DriverGuid
168 EFI_FV_FILETYPE FoundType
;
169 EFI_FV_FILE_ATTRIBUTES FileAttributes
;
170 UINT32 AuthenticationStatus
;
176 UINT8 NumberofMatchingVfrBin
;
177 UINTN
*VfrBinBaseAddress
;
179 Status
= Fv2
->ReadFile (
186 &AuthenticationStatus
188 if (EFI_ERROR (Status
)) {
193 Status
= Fv2
->ReadSection (
200 &AuthenticationStatus
202 if (!EFI_ERROR (Status
)) {
203 Status
= SearchVfrBinInFfs (Buffer
, 0, Size
, &VfrBinBaseAddress
, &NumberofMatchingVfrBin
);
204 if (!EFI_ERROR (Status
)) {
205 SectionBuffer
= NULL
;
206 Status
= Fv2
->ReadSection (
213 &AuthenticationStatus
215 if (!EFI_ERROR (Status
)) {
216 DEBUG ((DEBUG_INFO
, "FfsNameGuid - %g\n", DriverGuid
));
217 DEBUG ((DEBUG_INFO
, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin
));
219 for (VfrBinIndex
= 0; VfrBinIndex
< NumberofMatchingVfrBin
; VfrBinIndex
++) {
222 DumpHiiPackage ((UINT8
*) (UINTN
) SectionBuffer
+ VfrBinBaseAddress
[VfrBinIndex
] + sizeof (UINT32
));
225 VarCheckParseHiiPackage ((UINT8
*) (UINTN
) SectionBuffer
+ VfrBinBaseAddress
[VfrBinIndex
] + sizeof (UINT32
), TRUE
);
228 FreePool (SectionBuffer
);
231 InternalVarCheckFreePool (VfrBinBaseAddress
);
243 @param[in] ScanAll Scan all modules in all FVs or not.
252 EFI_HANDLE
*HandleBuffer
;
255 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv2
;
257 EFI_FV_FILETYPE FileType
;
259 EFI_FV_FILE_ATTRIBUTES FileAttributes
;
262 VAR_CHECK_VFR_DRIVER_INFO
*VfrDriverInfo
;
263 LIST_ENTRY
*VfrDriverLink
;
266 Status
= gBS
->LocateHandleBuffer (
268 &gEfiFirmwareVolume2ProtocolGuid
,
273 if (EFI_ERROR (Status
)) {
280 for (Index
= 0; Index
< HandleCount
; Index
++) {
281 DEBUG ((DEBUG_INFO
, "FvIndex - %x\n", Index
));
282 Status
= gBS
->HandleProtocol (
284 &gEfiFirmwareVolume2ProtocolGuid
,
287 ASSERT_EFI_ERROR (Status
);
290 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*Fvb2
;
291 EFI_PHYSICAL_ADDRESS FvAddress
;
294 Status
= gBS
->HandleProtocol (
296 &gEfiFirmwareVolumeBlock2ProtocolGuid
,
299 ASSERT_EFI_ERROR (Status
);
300 Status
= Fvb2
->GetPhysicalAddress (Fvb2
, &FvAddress
);
301 if (!EFI_ERROR (Status
)) {
302 DEBUG ((DEBUG_INFO
, "FvAddress - 0x%08x\n", FvAddress
));
303 FvSize
= ((EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) FvAddress
)->FvLength
;
304 DEBUG ((DEBUG_INFO
, "FvSize - 0x%08x\n", FvSize
));
310 // Need to parse all modules in all FVs.
312 Key
= InternalVarCheckAllocateZeroPool (Fv2
->KeySize
);
313 ASSERT (Key
!= NULL
);
315 for (FfsIndex
= 0; ; FfsIndex
++) {
316 FileType
= EFI_FV_FILETYPE_ALL
;
317 Status
= Fv2
->GetNextFile (
325 if (EFI_ERROR (Status
)) {
329 ParseFfs (Fv2
, &NameGuid
);
332 InternalVarCheckFreePool (Key
);
335 // Only parse drivers in the VFR drivers list.
337 VfrDriverLink
= mVfrDriverList
.ForwardLink
;
338 while (VfrDriverLink
!= &mVfrDriverList
) {
339 VfrDriverInfo
= VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink
);
340 VfrDriverLink
= VfrDriverLink
->ForwardLink
;
341 if (ParseFfs (Fv2
, VfrDriverInfo
->DriverGuid
)) {
343 // Found the driver in the FV.
345 RemoveEntryList (&VfrDriverInfo
->Link
);
346 InternalVarCheckFreePool (VfrDriverInfo
);
352 FreePool (HandleBuffer
);
356 Create Vfr Driver List.
358 @param[in] DriverGuidArray Driver Guid Array
362 CreateVfrDriverList (
363 IN EFI_GUID
*DriverGuidArray
367 VAR_CHECK_VFR_DRIVER_INFO
*VfrDriverInfo
;
369 for (Index
= 0; !IsZeroGuid (&DriverGuidArray
[Index
]); Index
++) {
370 DEBUG ((DEBUG_INFO
, "CreateVfrDriverList: %g\n", &DriverGuidArray
[Index
]));
371 VfrDriverInfo
= InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo
));
372 ASSERT (VfrDriverInfo
!= NULL
);
373 VfrDriverInfo
->Signature
= VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE
;
374 VfrDriverInfo
->DriverGuid
= &DriverGuidArray
[Index
];
375 InsertTailList (&mVfrDriverList
, &VfrDriverInfo
->Link
);
380 Destroy Vfr Driver List.
384 DestroyVfrDriverList (
388 VAR_CHECK_VFR_DRIVER_INFO
*VfrDriverInfo
;
389 LIST_ENTRY
*VfrDriverLink
;
391 while (mVfrDriverList
.ForwardLink
!= &mVfrDriverList
) {
392 VfrDriverLink
= mVfrDriverList
.ForwardLink
;
393 VfrDriverInfo
= VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink
);
394 RemoveEntryList (&VfrDriverInfo
->Link
);
395 InternalVarCheckFreePool (VfrDriverInfo
);
404 VarCheckHiiGenFromFv (
408 EFI_GUID
*DriverGuidArray
;
411 DEBUG ((DEBUG_INFO
, "VarCheckHiiGenDxeFromFv\n"));
414 // Get vfr driver guid array from PCD.
416 DriverGuidArray
= (EFI_GUID
*) PcdGetPtr (PcdVarCheckVfrDriverGuidArray
);
418 if (IsZeroGuid (&DriverGuidArray
[0])) {
420 // No VFR driver will be parsed from FVs.
425 if (CompareGuid (&DriverGuidArray
[0], &mAllFfGuid
)) {
429 CreateVfrDriverList (DriverGuidArray
);
435 DestroyVfrDriverList ();