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