VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette