]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
Code Scrub for Dxe Core.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVolBlock / FwVolBlock.c
CommitLineData
162ed594 1/** @file\r
022c6d45 2 Implementations for Firmware Volume Block protocol.\r
3\r
4 It consumes FV HOBs and creates read-lonly Firmare Volume Block protocol\r
e94a9ff7 5 instances for each of them.\r
23c98c94 6\r
7Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
8All rights reserved. This program and the accompanying materials\r
9are licensed and made available under the terms and conditions of the BSD License\r
10which accompanies this distribution. The full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
28a00297 15\r
797a9d67 16**/\r
28a00297 17\r
18#include <DxeMain.h>\r
19\r
20\r
21EFI_FW_VOL_BLOCK_DEVICE mFwVolBlock = {\r
22 FVB_DEVICE_SIGNATURE,\r
23 NULL,\r
24 {\r
25 {\r
26 {\r
27 HARDWARE_DEVICE_PATH,\r
28 HW_MEMMAP_DP,\r
e94a9ff7 29 {\r
30 (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),\r
31 (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)\r
32 }\r
28a00297 33 },\r
34 EfiMemoryMappedIO,\r
e94a9ff7 35 (EFI_PHYSICAL_ADDRESS) 0,\r
36 (EFI_PHYSICAL_ADDRESS) 0,\r
28a00297 37 },\r
38 {\r
39 END_DEVICE_PATH_TYPE,\r
40 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
022c6d45 41 {\r
e94a9ff7 42 END_DEVICE_PATH_LENGTH,\r
43 0\r
022c6d45 44 }\r
28a00297 45 },\r
46 },\r
47 {\r
48 FwVolBlockGetAttributes,\r
49 (EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes,\r
50 FwVolBlockGetPhysicalAddress,\r
51 FwVolBlockGetBlockSize,\r
52 FwVolBlockReadBlock,\r
53 (EFI_FVB_WRITE)FwVolBlockWriteBlock,\r
54 (EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock,\r
022c6d45 55 NULL\r
28a00297 56 },\r
57 0,\r
58 NULL,\r
59 0,\r
60 0\r
61};\r
62\r
63\r
64\r
162ed594 65/**\r
66 Retrieves Volume attributes. No polarity translations are done.\r
67\r
022c6d45 68 @param This Calling context\r
69 @param Attributes output buffer which contains attributes\r
162ed594 70\r
71 @retval EFI_SUCCESS The firmware volume attributes were returned.\r
72\r
73**/\r
28a00297 74EFI_STATUS\r
75EFIAPI\r
76FwVolBlockGetAttributes (\r
77 IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
78 OUT EFI_FVB_ATTRIBUTES *Attributes\r
79 )\r
28a00297 80{\r
81 EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
022c6d45 82\r
28a00297 83 FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
84\r
85 //\r
86 // Since we are read only, it's safe to get attributes data from our in-memory copy.\r
87 //\r
88 *Attributes = FvbDevice->FvbAttributes;\r
89\r
90 return EFI_SUCCESS;\r
91}\r
92\r
93\r
162ed594 94\r
95/**\r
96 Modifies the current settings of the firmware volume according to the input parameter.\r
97\r
022c6d45 98 @param This Calling context\r
99 @param Attributes input buffer which contains attributes\r
162ed594 100\r
022c6d45 101 @retval EFI_SUCCESS The firmware volume attributes were returned.\r
102 @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with\r
103 the capabilities as declared in the firmware\r
104 volume header.\r
162ed594 105 @retval EFI_UNSUPPORTED Not supported.\r
106\r
107**/\r
28a00297 108EFI_STATUS\r
109EFIAPI\r
110FwVolBlockSetAttributes (\r
111 IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
112 IN CONST EFI_FVB_ATTRIBUTES *Attributes\r
113 )\r
28a00297 114{\r
115 return EFI_UNSUPPORTED;\r
116}\r
117\r
118\r
162ed594 119\r
120/**\r
121 The EraseBlock() function erases one or more blocks as denoted by the\r
122 variable argument list. The entire parameter list of blocks must be verified\r
123 prior to erasing any blocks. If a block is requested that does not exist\r
124 within the associated firmware volume (it has a larger index than the last\r
125 block of the firmware volume), the EraseBlock() function must return\r
126 EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.\r
127\r
022c6d45 128 @param This Calling context\r
129 @param ... Starting LBA followed by Number of Lba to erase.\r
130 a -1 to terminate the list.\r
131\r
132 @retval EFI_SUCCESS The erase request was successfully completed.\r
133 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled\r
134 state.\r
135 @retval EFI_DEVICE_ERROR The block device is not functioning correctly\r
136 and could not be written. The firmware device\r
137 may have been partially erased.\r
138 @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable\r
139 argument list do\r
162ed594 140 @retval EFI_UNSUPPORTED Not supported.\r
141\r
142**/\r
28a00297 143EFI_STATUS\r
144EFIAPI\r
145FwVolBlockEraseBlock (\r
146 IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
147 ...\r
148 )\r
28a00297 149{\r
150 return EFI_UNSUPPORTED;\r
151}\r
152\r
153\r
162ed594 154\r
155/**\r
156 Read the specified number of bytes from the block to the input buffer.\r
157\r
022c6d45 158 @param This Indicates the calling context.\r
159 @param Lba The starting logical block index to read.\r
160 @param Offset Offset into the block at which to begin reading.\r
161 @param NumBytes Pointer to a UINT32. At entry, *NumBytes\r
162 contains the total size of the buffer. At exit,\r
163 *NumBytes contains the total number of bytes\r
164 actually read.\r
165 @param Buffer Pinter to a caller-allocated buffer that\r
166 contains the destine for the read.\r
167\r
168 @retval EFI_SUCCESS The firmware volume was read successfully.\r
169 @retval EFI_BAD_BUFFER_SIZE The read was attempted across an LBA boundary.\r
170 @retval EFI_ACCESS_DENIED Access denied.\r
171 @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not\r
162ed594 172 be read.\r
173\r
174**/\r
28a00297 175EFI_STATUS\r
176EFIAPI\r
177FwVolBlockReadBlock (\r
178 IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
179 IN CONST EFI_LBA Lba,\r
180 IN CONST UINTN Offset,\r
181 IN OUT UINTN *NumBytes,\r
182 IN OUT UINT8 *Buffer\r
183 )\r
28a00297 184{\r
185 EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
186 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
187 UINT8 *LbaOffset;\r
188 UINTN LbaStart;\r
189 UINTN NumOfBytesRead;\r
190 UINTN LbaIndex;\r
022c6d45 191\r
28a00297 192 FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
193\r
194 //\r
195 // Check if This FW can be read\r
196 //\r
797a9d67 197 if ((FvbDevice->FvbAttributes & EFI_FVB2_READ_STATUS) == 0) {\r
28a00297 198 return EFI_ACCESS_DENIED;\r
199 }\r
022c6d45 200\r
e94a9ff7 201 LbaIndex = (UINTN) Lba;\r
28a00297 202 if (LbaIndex >= FvbDevice->NumBlocks) {\r
203 //\r
204 // Invalid Lba, read nothing.\r
205 //\r
206 *NumBytes = 0;\r
207 return EFI_BAD_BUFFER_SIZE;\r
208 }\r
022c6d45 209\r
28a00297 210 if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {\r
211 //\r
212 // all exceed boundry, read nothing.\r
213 //\r
214 *NumBytes = 0;\r
215 return EFI_BAD_BUFFER_SIZE;\r
216 }\r
022c6d45 217\r
28a00297 218 NumOfBytesRead = *NumBytes;\r
219 if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {\r
220 //\r
221 // partial exceed boundry, read data from current postion to end.\r
222 //\r
223 NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;\r
224 }\r
022c6d45 225\r
28a00297 226 LbaStart = FvbDevice->LbaCache[LbaIndex].Base;\r
e94a9ff7 227 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN) FvbDevice->BaseAddress);\r
228 LbaOffset = (UINT8 *) FwVolHeader + LbaStart + Offset;\r
28a00297 229\r
230 //\r
231 // Perform read operation\r
232 //\r
233 CopyMem (Buffer, LbaOffset, NumOfBytesRead);\r
022c6d45 234\r
28a00297 235 if (NumOfBytesRead == *NumBytes) {\r
236 return EFI_SUCCESS;\r
237 }\r
022c6d45 238\r
28a00297 239 *NumBytes = NumOfBytesRead;\r
240 return EFI_BAD_BUFFER_SIZE;\r
241}\r
022c6d45 242\r
28a00297 243\r
162ed594 244\r
245/**\r
246 Writes the specified number of bytes from the input buffer to the block.\r
247\r
022c6d45 248 @param This Indicates the calling context.\r
249 @param Lba The starting logical block index to write to.\r
250 @param Offset Offset into the block at which to begin writing.\r
251 @param NumBytes Pointer to a UINT32. At entry, *NumBytes\r
252 contains the total size of the buffer. At exit,\r
253 *NumBytes contains the total number of bytes\r
254 actually written.\r
255 @param Buffer Pinter to a caller-allocated buffer that\r
256 contains the source for the write.\r
257\r
258 @retval EFI_SUCCESS The firmware volume was written successfully.\r
259 @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary.\r
260 On output, NumBytes contains the total number of\r
261 bytes actually written.\r
262 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled\r
263 state.\r
264 @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not\r
265 be written.\r
162ed594 266 @retval EFI_UNSUPPORTED Not supported.\r
267\r
268**/\r
28a00297 269EFI_STATUS\r
270EFIAPI\r
271FwVolBlockWriteBlock (\r
272 IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
273 IN EFI_LBA Lba,\r
274 IN UINTN Offset,\r
275 IN OUT UINTN *NumBytes,\r
276 IN UINT8 *Buffer\r
277 )\r
28a00297 278{\r
279 return EFI_UNSUPPORTED;\r
280}\r
022c6d45 281\r
28a00297 282\r
162ed594 283\r
284/**\r
285 Get Fvb's base address.\r
286\r
022c6d45 287 @param This Indicates the calling context.\r
288 @param Address Fvb device base address.\r
162ed594 289\r
022c6d45 290 @retval EFI_SUCCESS Successfully got Fvb's base address.\r
162ed594 291 @retval EFI_UNSUPPORTED Not supported.\r
292\r
293**/\r
28a00297 294EFI_STATUS\r
295EFIAPI\r
296FwVolBlockGetPhysicalAddress (\r
297 IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
298 OUT EFI_PHYSICAL_ADDRESS *Address\r
299 )\r
28a00297 300{\r
301 EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
022c6d45 302\r
28a00297 303 FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
022c6d45 304\r
797a9d67 305 if (FvbDevice->FvbAttributes & EFI_FVB2_MEMORY_MAPPED) {\r
28a00297 306 *Address = FvbDevice->BaseAddress;\r
307 return EFI_SUCCESS;\r
308 }\r
022c6d45 309\r
28a00297 310 return EFI_UNSUPPORTED;\r
311}\r
312\r
313\r
162ed594 314\r
315/**\r
316 Retrieves the size in bytes of a specific block within a firmware volume.\r
317\r
022c6d45 318 @param This Indicates the calling context.\r
319 @param Lba Indicates the block for which to return the\r
320 size.\r
321 @param BlockSize Pointer to a caller-allocated UINTN in which the\r
322 size of the block is returned.\r
323 @param NumberOfBlocks Pointer to a caller-allocated UINTN in which the\r
324 number of consecutive blocks starting with Lba\r
325 is returned. All blocks in this range have a\r
326 size of BlockSize.\r
327\r
328 @retval EFI_SUCCESS The firmware volume base address is returned.\r
162ed594 329 @retval EFI_INVALID_PARAMETER The requested LBA is out of range.\r
330\r
331**/\r
28a00297 332EFI_STATUS\r
333EFIAPI\r
334FwVolBlockGetBlockSize (\r
335 IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
336 IN CONST EFI_LBA Lba,\r
337 IN OUT UINTN *BlockSize,\r
338 IN OUT UINTN *NumberOfBlocks\r
339 )\r
28a00297 340{\r
341 UINTN TotalBlocks;\r
342 EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
343 EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\r
344 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
022c6d45 345\r
28a00297 346 FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
022c6d45 347\r
28a00297 348 //\r
349 // Do parameter checking\r
350 //\r
351 if (Lba >= FvbDevice->NumBlocks) {\r
352 return EFI_INVALID_PARAMETER;\r
353 }\r
022c6d45 354\r
28a00297 355 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);\r
022c6d45 356\r
28a00297 357 PtrBlockMapEntry = FwVolHeader->BlockMap;\r
022c6d45 358\r
28a00297 359 //\r
360 // Search the block map for the given block\r
361 //\r
362 TotalBlocks = 0;\r
363 while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->Length !=0 )) {\r
364 TotalBlocks += PtrBlockMapEntry->NumBlocks;\r
365 if (Lba < TotalBlocks) {\r
366 //\r
367 // We find the range\r
368 //\r
369 break;\r
370 }\r
022c6d45 371\r
28a00297 372 PtrBlockMapEntry++;\r
373 }\r
022c6d45 374\r
28a00297 375 *BlockSize = PtrBlockMapEntry->Length;\r
376 *NumberOfBlocks = TotalBlocks - (UINTN)Lba;\r
022c6d45 377\r
28a00297 378 return EFI_SUCCESS;\r
379}\r
380\r
381\r
162ed594 382\r
383/**\r
384 This routine produces a firmware volume block protocol on a given\r
385 buffer.\r
386\r
022c6d45 387 @param BaseAddress base address of the firmware volume image\r
388 @param Length length of the firmware volume image\r
389 @param ParentHandle handle of parent firmware volume, if this image\r
390 came from an FV image file in another firmware\r
391 volume (ala capsules)\r
392 @param FvProtocol Firmware volume block protocol produced.\r
162ed594 393\r
022c6d45 394 @retval EFI_VOLUME_CORRUPTED Volume corrupted.\r
395 @retval EFI_OUT_OF_RESOURCES No enough buffer to be allocated.\r
396 @retval EFI_SUCCESS Successfully produced a FVB protocol on given\r
162ed594 397 buffer.\r
398\r
399**/\r
28a00297 400EFI_STATUS\r
401ProduceFVBProtocolOnBuffer (\r
402 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
403 IN UINT64 Length,\r
404 IN EFI_HANDLE ParentHandle,\r
405 OUT EFI_HANDLE *FvProtocol OPTIONAL\r
406 )\r
28a00297 407{\r
408 EFI_STATUS Status;\r
409 EFI_FW_VOL_BLOCK_DEVICE *FvbDev;\r
410 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
411 UINTN BlockIndex;\r
412 UINTN BlockIndex2;\r
413 UINTN LinearOffset;\r
38837959 414 UINT32 FvAlignment;\r
28a00297 415 EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\r
022c6d45 416\r
38837959 417 FvAlignment = 0;\r
e94a9ff7 418 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) BaseAddress;\r
28a00297 419 //\r
420 // Validate FV Header, if not as expected, return\r
421 //\r
422 if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) {\r
423 return EFI_VOLUME_CORRUPTED;\r
424 }\r
425 //\r
38837959
LG
426 // Get FvHeader alignment\r
427 //\r
428 FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
429 if (FvAlignment < 8) {\r
430 FvAlignment = 8;\r
431 }\r
432 if ((UINTN)BaseAddress % FvAlignment != 0) {\r
433 //\r
434 // FvImage buffer is not at its required alignment.\r
435 //\r
436 return EFI_VOLUME_CORRUPTED;\r
437 }\r
438 //\r
022c6d45 439 // Allocate EFI_FW_VOL_BLOCK_DEVICE\r
28a00297 440 //\r
441 FvbDev = CoreAllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);\r
442 if (FvbDev == NULL) {\r
443 return EFI_OUT_OF_RESOURCES;\r
444 }\r
445\r
446 FvbDev->BaseAddress = BaseAddress;\r
447 FvbDev->FvbAttributes = FwVolHeader->Attributes;\r
448 FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle;\r
449\r
450 //\r
451 // Init the block caching fields of the device\r
452 // First, count the number of blocks\r
453 //\r
454 FvbDev->NumBlocks = 0;\r
455 for (PtrBlockMapEntry = FwVolHeader->BlockMap;\r
e94a9ff7 456 PtrBlockMapEntry->NumBlocks != 0;\r
457 PtrBlockMapEntry++) {\r
28a00297 458 FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks;\r
459 }\r
460 //\r
461 // Second, allocate the cache\r
462 //\r
463 FvbDev->LbaCache = CoreAllocateBootServicesPool (FvbDev->NumBlocks * sizeof (LBA_CACHE));\r
464 if (FvbDev->LbaCache == NULL) {\r
465 CoreFreePool (FvbDev);\r
466 return EFI_OUT_OF_RESOURCES;\r
467 }\r
468 //\r
469 // Last, fill in the cache with the linear address of the blocks\r
470 //\r
471 BlockIndex = 0;\r
472 LinearOffset = 0;\r
473 for (PtrBlockMapEntry = FwVolHeader->BlockMap;\r
e94a9ff7 474 PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {\r
28a00297 475 for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {\r
476 FvbDev->LbaCache[BlockIndex].Base = LinearOffset;\r
477 FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->Length;\r
478 LinearOffset += PtrBlockMapEntry->Length;\r
479 BlockIndex++;\r
480 }\r
481 }\r
482\r
483 //\r
484 // Set up the devicepath\r
485 //\r
486 FvbDev->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;\r
487 FvbDev->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1;\r
488\r
489 //\r
490 //\r
491 // Attach FvVolBlock Protocol to new handle\r
492 //\r
493 Status = CoreInstallMultipleProtocolInterfaces (\r
e94a9ff7 494 &FvbDev->Handle,\r
495 &gEfiFirmwareVolumeBlockProtocolGuid, &FvbDev->FwVolBlockInstance,\r
496 &gEfiDevicePathProtocolGuid, &FvbDev->DevicePath,\r
497 &gEfiFirmwareVolumeDispatchProtocolGuid, NULL,\r
498 NULL\r
499 );\r
28a00297 500\r
501 //\r
502 // If they want the handle back, set it.\r
503 //\r
504 if (FvProtocol != NULL) {\r
505 *FvProtocol = FvbDev->Handle;\r
506 }\r
507\r
508 return Status;\r
509}\r
510\r
511\r
162ed594 512\r
513/**\r
514 This routine is the driver initialization entry point. It initializes the\r
515 libraries, consumes FV hobs and NT_NON_MM_FV environment variable and\r
516 produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.\r
517\r
022c6d45 518 @param ImageHandle The image handle.\r
519 @param SystemTable The system table.\r
162ed594 520\r
022c6d45 521 @retval EFI_SUCCESS Successfully initialized firmware volume block\r
162ed594 522 driver.\r
523\r
524**/\r
28a00297 525EFI_STATUS\r
526EFIAPI\r
527FwVolBlockDriverInit (\r
528 IN EFI_HANDLE ImageHandle,\r
529 IN EFI_SYSTEM_TABLE *SystemTable\r
530 )\r
28a00297 531{\r
532 EFI_PEI_HOB_POINTERS FvHob;\r
e94a9ff7 533\r
28a00297 534 //\r
535 // Core Needs Firmware Volumes to function\r
536 //\r
537 FvHob.Raw = GetHobList ();\r
538 while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {\r
539 //\r
540 // Produce an FVB protocol for it\r
541 //\r
022c6d45 542 ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, NULL);\r
28a00297 543 FvHob.Raw = GET_NEXT_HOB (FvHob);\r
544 }\r
e94a9ff7 545\r
28a00297 546 return EFI_SUCCESS;\r
547}\r
548\r
549\r
162ed594 550\r
551/**\r
552 This DXE service routine is used to process a firmware volume. In\r
553 particular, it can be called by BDS to process a single firmware\r
554 volume found in a capsule.\r
555\r
022c6d45 556 @param FvHeader pointer to a firmware volume header\r
557 @param Size the size of the buffer pointed to by FvHeader\r
558 @param FVProtocolHandle the handle on which a firmware volume protocol\r
559 was produced for the firmware volume passed in.\r
162ed594 560\r
022c6d45 561 @retval EFI_OUT_OF_RESOURCES if an FVB could not be produced due to lack of\r
562 system resources\r
563 @retval EFI_VOLUME_CORRUPTED if the volume was corrupted\r
564 @retval EFI_SUCCESS a firmware volume protocol was produced for the\r
162ed594 565 firmware volume\r
566\r
567**/\r
28a00297 568EFI_STATUS\r
569CoreProcessFirmwareVolume (\r
570 IN VOID *FvHeader,\r
022c6d45 571 IN UINTN Size,\r
28a00297 572 OUT EFI_HANDLE *FVProtocolHandle\r
573 )\r
28a00297 574{\r
575 VOID *Ptr;\r
576 EFI_STATUS Status;\r
577\r
578 *FVProtocolHandle = NULL;\r
022c6d45 579 Status = ProduceFVBProtocolOnBuffer (\r
580 (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
581 (UINT64)Size,\r
582 NULL,\r
28a00297 583 FVProtocolHandle\r
584 );\r
585 //\r
586 // Since in our implementation we use register-protocol-notify to put a\r
587 // FV protocol on the FVB protocol handle, we can't directly verify that\r
588 // the FV protocol was produced. Therefore here we will check the handle\r
022c6d45 589 // and make sure an FV protocol is on it. This indicates that all went\r
590 // well. Otherwise we have to assume that the volume was corrupted\r
28a00297 591 // somehow.\r
592 //\r
593 if (!EFI_ERROR(Status)) {\r
594 Ptr = NULL;\r
e94a9ff7 595 Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **) &Ptr);\r
28a00297 596 if (EFI_ERROR(Status) || (Ptr == NULL)) {\r
597 return EFI_VOLUME_CORRUPTED;\r
598 }\r
599 return EFI_SUCCESS;\r
600 }\r
601 return Status;\r
602}\r
603\r
604\r
162ed594 605\r