]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
ArmPlatformPkg: Change use of EFI_D_* to DEBUG_*
[mirror_edk2.git] / ArmPlatformPkg / Drivers / NorFlashDxe / NorFlashDxe.c
CommitLineData
1e57a462 1/** @file NorFlashDxe.c\r
2\r
8015f3f6 3 Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>\r
1e57a462 4\r
f4dfad05 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1e57a462 6\r
7**/\r
8\r
9#include <Library/UefiLib.h>\r
10#include <Library/BaseMemoryLib.h>\r
11#include <Library/MemoryAllocationLib.h>\r
12#include <Library/UefiBootServicesTableLib.h>\r
13#include <Library/PcdLib.h>\r
c2d1cf1b
MK
14#include <Library/HobLib.h>\r
15#include <Library/DxeServicesTableLib.h>\r
1e57a462 16\r
c2d1cf1b 17#include "NorFlash.h"\r
1e57a462 18\r
1dbbfc17 19STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;\r
1e57a462 20\r
21//\r
22// Global variable declarations\r
23//\r
24NOR_FLASH_INSTANCE **mNorFlashInstances;\r
1dbbfc17 25UINT32 mNorFlashDeviceCount;\r
c2d1cf1b
MK
26UINTN mFlashNvStorageVariableBase;\r
27EFI_EVENT mFvbVirtualAddrChangeEvent;\r
1e57a462 28\r
29NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {\r
30 NOR_FLASH_SIGNATURE, // Signature\r
31 NULL, // Handle ... NEED TO BE FILLED\r
32\r
1e57a462 33 0, // DeviceBaseAddress ... NEED TO BE FILLED\r
34 0, // RegionBaseAddress ... NEED TO BE FILLED\r
35 0, // Size ... NEED TO BE FILLED\r
36 0, // StartLba\r
37\r
1d5d0ae9 38 {\r
39 EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision\r
40 NULL, // Media ... NEED TO BE FILLED\r
41 NorFlashBlockIoReset, // Reset;\r
1e57a462 42 NorFlashBlockIoReadBlocks, // ReadBlocks\r
43 NorFlashBlockIoWriteBlocks, // WriteBlocks\r
1d5d0ae9 44 NorFlashBlockIoFlushBlocks // FlushBlocks\r
1e57a462 45 }, // BlockIoProtocol\r
46\r
1d5d0ae9 47 {\r
48 0, // MediaId ... NEED TO BE FILLED\r
49 FALSE, // RemovableMedia\r
50 TRUE, // MediaPresent\r
51 FALSE, // LogicalPartition\r
52 FALSE, // ReadOnly\r
53 FALSE, // WriteCaching;\r
54 0, // BlockSize ... NEED TO BE FILLED\r
55 4, // IoAlign\r
56 0, // LastBlock ... NEED TO BE FILLED\r
57 0, // LowestAlignedLba\r
58 1, // LogicalBlocksPerPhysicalBlock\r
1e57a462 59 }, //Media;\r
60\r
452a9ee1
BJ
61 {\r
62 EFI_DISK_IO_PROTOCOL_REVISION, // Revision\r
63 NorFlashDiskIoReadDisk, // ReadDisk\r
64 NorFlashDiskIoWriteDisk // WriteDisk\r
65 },\r
66\r
1d5d0ae9 67 {\r
1e57a462 68 FvbGetAttributes, // GetAttributes\r
69 FvbSetAttributes, // SetAttributes\r
70 FvbGetPhysicalAddress, // GetPhysicalAddress\r
71 FvbGetBlockSize, // GetBlockSize\r
72 FvbRead, // Read\r
73 FvbWrite, // Write\r
1d5d0ae9 74 FvbEraseBlocks, // EraseBlocks\r
75 NULL, //ParentHandle\r
1e57a462 76 }, // FvbProtoccol;\r
452a9ee1 77 NULL, // ShadowBuffer\r
1e57a462 78 {\r
79 {\r
80 {\r
81 HARDWARE_DEVICE_PATH,\r
82 HW_VENDOR_DP,\r
4ef11358
AB
83 {\r
84 (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)),\r
85 (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8)\r
86 }\r
1e57a462 87 },\r
b0fdce95 88 { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED\r
1e57a462 89 },\r
8b902534 90 0, // Index\r
1e57a462 91 {\r
92 END_DEVICE_PATH_TYPE,\r
93 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
b0fdce95 94 { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
1e57a462 95 }\r
96 } // DevicePath\r
97};\r
98\r
99EFI_STATUS\r
100NorFlashCreateInstance (\r
101 IN UINTN NorFlashDeviceBase,\r
102 IN UINTN NorFlashRegionBase,\r
103 IN UINTN NorFlashSize,\r
4ef11358 104 IN UINT32 Index,\r
1e57a462 105 IN UINT32 BlockSize,\r
106 IN BOOLEAN SupportFvb,\r
1e57a462 107 OUT NOR_FLASH_INSTANCE** NorFlashInstance\r
108 )\r
109{\r
110 EFI_STATUS Status;\r
111 NOR_FLASH_INSTANCE* Instance;\r
112\r
113 ASSERT(NorFlashInstance != NULL);\r
114\r
2dff0c1a 115 Instance = AllocateRuntimeCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);\r
1e57a462 116 if (Instance == NULL) {\r
117 return EFI_OUT_OF_RESOURCES;\r
118 }\r
119\r
120 Instance->DeviceBaseAddress = NorFlashDeviceBase;\r
121 Instance->RegionBaseAddress = NorFlashRegionBase;\r
122 Instance->Size = NorFlashSize;\r
123\r
124 Instance->BlockIoProtocol.Media = &Instance->Media;\r
4ef11358 125 Instance->Media.MediaId = Index;\r
1e57a462 126 Instance->Media.BlockSize = BlockSize;\r
127 Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;\r
1d5d0ae9 128\r
8b902534
AB
129 CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);\r
130 Instance->DevicePath.Index = (UINT8)Index;\r
1e57a462 131\r
452a9ee1
BJ
132 Instance->ShadowBuffer = AllocateRuntimePool (BlockSize);;\r
133 if (Instance->ShadowBuffer == NULL) {\r
134 return EFI_OUT_OF_RESOURCES;\r
135 }\r
136\r
1e57a462 137 if (SupportFvb) {\r
0f87c53d 138 NorFlashFvbInitialize (Instance);\r
1e57a462 139\r
140 Status = gBS->InstallMultipleProtocolInterfaces (\r
141 &Instance->Handle,\r
142 &gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
143 &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol,\r
144 &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,\r
145 NULL\r
146 );\r
147 if (EFI_ERROR(Status)) {\r
2dff0c1a 148 FreePool (Instance);\r
1e57a462 149 return Status;\r
150 }\r
151 } else {\r
1e57a462 152 Status = gBS->InstallMultipleProtocolInterfaces (\r
153 &Instance->Handle,\r
154 &gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
155 &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol,\r
452a9ee1 156 &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol,\r
1e57a462 157 NULL\r
158 );\r
159 if (EFI_ERROR(Status)) {\r
2dff0c1a 160 FreePool (Instance);\r
1e57a462 161 return Status;\r
162 }\r
163 }\r
1d5d0ae9 164\r
165 *NorFlashInstance = Instance;\r
1e57a462 166 return Status;\r
167}\r
168\r
1e57a462 169/**\r
22044caa 170 * This function unlock and erase an entire NOR Flash block.\r
1e57a462 171 **/\r
172EFI_STATUS\r
173NorFlashUnlockAndEraseSingleBlock (\r
174 IN NOR_FLASH_INSTANCE *Instance,\r
175 IN UINTN BlockAddress\r
176 )\r
177{\r
178 EFI_STATUS Status;\r
179 UINTN Index;\r
180 EFI_TPL OriginalTPL;\r
181\r
2dff0c1a
OM
182 if (!EfiAtRuntime ()) {\r
183 // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
184 OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
185 } else {\r
186 // This initialization is only to prevent the compiler to complain about the\r
187 // use of uninitialized variables\r
188 OriginalTPL = TPL_HIGH_LEVEL;\r
189 }\r
1e57a462 190\r
191 Index = 0;\r
192 // The block erase might fail a first time (SW bug ?). Retry it ...\r
193 do {\r
194 // Unlock the block if we have to\r
195 Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);\r
22044caa
OM
196 if (EFI_ERROR (Status)) {\r
197 break;\r
1e57a462 198 }\r
22044caa 199 Status = NorFlashEraseSingleBlock (Instance, BlockAddress);\r
1e57a462 200 Index++;\r
201 } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));\r
202\r
203 if (Index == NOR_FLASH_ERASE_RETRY) {\r
1d2482e1 204 DEBUG((DEBUG_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));\r
1e57a462 205 }\r
206\r
2dff0c1a
OM
207 if (!EfiAtRuntime ()) {\r
208 // Interruptions can resume.\r
209 gBS->RestoreTPL (OriginalTPL);\r
210 }\r
1e57a462 211\r
212 return Status;\r
213}\r
214\r
1e57a462 215EFI_STATUS\r
452a9ee1 216NorFlashWriteFullBlock (\r
1e57a462 217 IN NOR_FLASH_INSTANCE *Instance,\r
218 IN EFI_LBA Lba,\r
219 IN UINT32 *DataBuffer,\r
220 IN UINT32 BlockSizeInWords\r
221 )\r
222{\r
223 EFI_STATUS Status;\r
224 UINTN WordAddress;\r
225 UINT32 WordIndex;\r
226 UINTN BufferIndex;\r
227 UINTN BlockAddress;\r
228 UINTN BuffersInBlock;\r
229 UINTN RemainingWords;\r
230 EFI_TPL OriginalTPL;\r
518c243d 231 UINTN Cnt;\r
1e57a462 232\r
233 Status = EFI_SUCCESS;\r
234\r
235 // Get the physical address of the block\r
236 BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSizeInWords * 4);\r
237\r
238 // Start writing from the first address at the start of the block\r
239 WordAddress = BlockAddress;\r
240\r
2dff0c1a
OM
241 if (!EfiAtRuntime ()) {\r
242 // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
243 OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
244 } else {\r
245 // This initialization is only to prevent the compiler to complain about the\r
246 // use of uninitialized variables\r
247 OriginalTPL = TPL_HIGH_LEVEL;\r
248 }\r
1e57a462 249\r
250 Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);\r
251 if (EFI_ERROR(Status)) {\r
1d2482e1 252 DEBUG((DEBUG_ERROR, "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single block at 0x%X\n", BlockAddress));\r
1e57a462 253 goto EXIT;\r
254 }\r
255\r
256 // To speed up the programming operation, NOR Flash is programmed using the Buffered Programming method.\r
257\r
258 // Check that the address starts at a 32-word boundary, i.e. last 7 bits must be zero\r
259 if ((WordAddress & BOUNDARY_OF_32_WORDS) == 0x00) {\r
260\r
261 // First, break the entire block into buffer-sized chunks.\r
82745213 262 BuffersInBlock = (UINTN)(BlockSizeInWords * 4) / P30_MAX_BUFFER_SIZE_IN_BYTES;\r
1e57a462 263\r
264 // Then feed each buffer chunk to the NOR Flash\r
518c243d 265 // If a buffer does not contain any data, don't write it.\r
1e57a462 266 for(BufferIndex=0;\r
267 BufferIndex < BuffersInBlock;\r
268 BufferIndex++, WordAddress += P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer += P30_MAX_BUFFER_SIZE_IN_WORDS\r
269 ) {\r
518c243d
HL
270 // Check the buffer to see if it contains any data (not set all 1s).\r
271 for (Cnt = 0; Cnt < P30_MAX_BUFFER_SIZE_IN_WORDS; Cnt++) {\r
272 if (~DataBuffer[Cnt] != 0 ) {\r
273 // Some data found, write the buffer.\r
274 Status = NorFlashWriteBuffer (Instance, WordAddress, P30_MAX_BUFFER_SIZE_IN_BYTES,\r
275 DataBuffer);\r
276 if (EFI_ERROR(Status)) {\r
277 goto EXIT;\r
278 }\r
279 break;\r
280 }\r
1e57a462 281 }\r
282 }\r
283\r
284 // Finally, finish off any remaining words that are less than the maximum size of the buffer\r
285 RemainingWords = BlockSizeInWords % P30_MAX_BUFFER_SIZE_IN_WORDS;\r
286\r
287 if(RemainingWords != 0) {\r
288 Status = NorFlashWriteBuffer (Instance, WordAddress, (RemainingWords * 4), DataBuffer);\r
289 if (EFI_ERROR(Status)) {\r
290 goto EXIT;\r
291 }\r
292 }\r
293\r
294 } else {\r
295 // For now, use the single word programming algorithm\r
296 // It is unlikely that the NOR Flash will exist in an address which falls within a 32 word boundary range,\r
297 // i.e. which ends in the range 0x......01 - 0x......7F.\r
298 for(WordIndex=0; WordIndex<BlockSizeInWords; WordIndex++, DataBuffer++, WordAddress = WordAddress + 4) {\r
299 Status = NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer);\r
300 if (EFI_ERROR(Status)) {\r
301 goto EXIT;\r
302 }\r
303 }\r
304 }\r
305\r
306EXIT:\r
2dff0c1a
OM
307 if (!EfiAtRuntime ()) {\r
308 // Interruptions can resume.\r
309 gBS->RestoreTPL (OriginalTPL);\r
310 }\r
1e57a462 311\r
312 if (EFI_ERROR(Status)) {\r
1d2482e1 313 DEBUG((DEBUG_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));\r
1e57a462 314 }\r
315 return Status;\r
316}\r
317\r
1e57a462 318EFI_STATUS\r
319EFIAPI\r
320NorFlashInitialise (\r
321 IN EFI_HANDLE ImageHandle,\r
322 IN EFI_SYSTEM_TABLE *SystemTable\r
323 )\r
324{\r
325 EFI_STATUS Status;\r
326 UINT32 Index;\r
327 NOR_FLASH_DESCRIPTION* NorFlashDevices;\r
1e57a462 328 BOOLEAN ContainVariableStorage;\r
329\r
330 Status = NorFlashPlatformInitialization ();\r
331 if (EFI_ERROR(Status)) {\r
1d2482e1 332 DEBUG((DEBUG_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n"));\r
1e57a462 333 return Status;\r
334 }\r
335\r
1dbbfc17 336 Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);\r
1e57a462 337 if (EFI_ERROR(Status)) {\r
1d2482e1 338 DEBUG((DEBUG_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));\r
1e57a462 339 return Status;\r
340 }\r
341\r
1dbbfc17 342 mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);\r
1e57a462 343\r
1dbbfc17 344 for (Index = 0; Index < mNorFlashDeviceCount; Index++) {\r
1e57a462 345 // Check if this NOR Flash device contain the variable storage region\r
8015f3f6
VS
346\r
347 if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {\r
348 ContainVariableStorage =\r
349 (NorFlashDevices[Index].RegionBaseAddress <= PcdGet64 (PcdFlashNvStorageVariableBase64)) &&\r
350 (PcdGet64 (PcdFlashNvStorageVariableBase64) + PcdGet32 (PcdFlashNvStorageVariableSize) <=\r
351 NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);\r
352 } else {\r
353 ContainVariableStorage =\r
354 (NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&\r
355 (PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize) <=\r
356 NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);\r
357 }\r
1e57a462 358\r
359 Status = NorFlashCreateInstance (\r
360 NorFlashDevices[Index].DeviceBaseAddress,\r
361 NorFlashDevices[Index].RegionBaseAddress,\r
362 NorFlashDevices[Index].Size,\r
363 Index,\r
364 NorFlashDevices[Index].BlockSize,\r
365 ContainVariableStorage,\r
1e57a462 366 &mNorFlashInstances[Index]\r
367 );\r
368 if (EFI_ERROR(Status)) {\r
1d2482e1 369 DEBUG((DEBUG_ERROR,"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",Index));\r
1e57a462 370 }\r
371 }\r
372\r
1dbbfc17
OM
373 //\r
374 // Register for the virtual address change event\r
375 //\r
376 Status = gBS->CreateEventEx (\r
377 EVT_NOTIFY_SIGNAL,\r
378 TPL_NOTIFY,\r
379 NorFlashVirtualNotifyEvent,\r
380 NULL,\r
381 &gEfiEventVirtualAddressChangeGuid,\r
382 &mNorFlashVirtualAddrChangeEvent\r
383 );\r
384 ASSERT_EFI_ERROR (Status);\r
385\r
1e57a462 386 return Status;\r
387}\r
c2d1cf1b
MK
388\r
389EFI_STATUS\r
390EFIAPI\r
391NorFlashFvbInitialize (\r
392 IN NOR_FLASH_INSTANCE* Instance\r
393 )\r
394{\r
395 EFI_STATUS Status;\r
396 UINT32 FvbNumLba;\r
397 EFI_BOOT_MODE BootMode;\r
398 UINTN RuntimeMmioRegionSize;\r
399\r
400 DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));\r
401 ASSERT((Instance != NULL));\r
402\r
403 //\r
404 // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME\r
405 //\r
406\r
407 // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;\r
408 // even if we only use the small block region at the top of the NOR Flash.\r
409 // The reason is when the NOR Flash memory is set into program mode, the command\r
410 // is written as the base of the flash region (ie: Instance->DeviceBaseAddress)\r
411 RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;\r
412\r
413 Status = gDS->AddMemorySpace (\r
414 EfiGcdMemoryTypeMemoryMappedIo,\r
415 Instance->DeviceBaseAddress, RuntimeMmioRegionSize,\r
416 EFI_MEMORY_UC | EFI_MEMORY_RUNTIME\r
417 );\r
418 ASSERT_EFI_ERROR (Status);\r
419\r
420 Status = gDS->SetMemorySpaceAttributes (\r
421 Instance->DeviceBaseAddress, RuntimeMmioRegionSize,\r
422 EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);\r
423 ASSERT_EFI_ERROR (Status);\r
424\r
4f214830
AB
425 mFlashNvStorageVariableBase = (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) ?\r
426 PcdGet64 (PcdFlashNvStorageVariableBase64) : PcdGet32 (PcdFlashNvStorageVariableBase);\r
c2d1cf1b
MK
427\r
428 // Set the index of the first LBA for the FVB\r
8015f3f6 429 Instance->StartLba = (mFlashNvStorageVariableBase - Instance->RegionBaseAddress) / Instance->Media.BlockSize;\r
c2d1cf1b
MK
430\r
431 BootMode = GetBootModeHob ();\r
432 if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {\r
433 Status = EFI_INVALID_PARAMETER;\r
434 } else {\r
435 // Determine if there is a valid header at the beginning of the NorFlash\r
436 Status = ValidateFvHeader (Instance);\r
437 }\r
438\r
439 // Install the Default FVB header if required\r
440 if (EFI_ERROR(Status)) {\r
441 // There is no valid header, so time to install one.\r
442 DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));\r
443 DEBUG ((DEBUG_INFO, "%a: Installing a correct one for this volume.\n",\r
444 __FUNCTION__));\r
445\r
446 // Erase all the NorFlash that is reserved for variable storage\r
447 FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;\r
448\r
449 Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);\r
450 if (EFI_ERROR(Status)) {\r
451 return Status;\r
452 }\r
453\r
454 // Install all appropriate headers\r
455 Status = InitializeFvAndVariableStoreHeaders (Instance);\r
456 if (EFI_ERROR(Status)) {\r
457 return Status;\r
458 }\r
459 }\r
460\r
461 //\r
462 // The driver implementing the variable read service can now be dispatched;\r
463 // the varstore headers are in place.\r
464 //\r
465 Status = gBS->InstallProtocolInterface (\r
466 &gImageHandle,\r
467 &gEdkiiNvVarStoreFormattedGuid,\r
468 EFI_NATIVE_INTERFACE,\r
469 NULL\r
470 );\r
471 ASSERT_EFI_ERROR (Status);\r
472\r
473 //\r
474 // Register for the virtual address change event\r
475 //\r
476 Status = gBS->CreateEventEx (\r
477 EVT_NOTIFY_SIGNAL,\r
478 TPL_NOTIFY,\r
479 FvbVirtualNotifyEvent,\r
480 NULL,\r
481 &gEfiEventVirtualAddressChangeGuid,\r
482 &mFvbVirtualAddrChangeEvent\r
483 );\r
484 ASSERT_EFI_ERROR (Status);\r
485\r
486 return Status;\r
487}\r