+VOID\r
+EFIAPI\r
+FvbNotificationEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN HandleCount;\r
+ UINTN Index;\r
+ EFI_PHYSICAL_ADDRESS FvbBaseAddress;\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
+ EFI_FVB_ATTRIBUTES_2 Attributes;\r
+ EFI_SYSTEM_TABLE *SystemTable;\r
+ EFI_PHYSICAL_ADDRESS NvStorageVariableBase;\r
+\r
+ SystemTable = (EFI_SYSTEM_TABLE *)Context;\r
+ Fvb = NULL;\r
+ \r
+ //\r
+ // Locate all handles of Fvb protocol\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+ \r
+ //\r
+ // Get the FVB to access variable store\r
+ //\r
+ for (Index = 0; Index < HandleCount; Index += 1, Status = EFI_NOT_FOUND, Fvb = NULL) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ (VOID **) &Fvb\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_NOT_FOUND;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Ensure this FVB protocol supported Write operation.\r
+ //\r
+ Status = Fvb->GetAttributes (Fvb, &Attributes);\r
+ if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {\r
+ continue; \r
+ }\r
+ //\r
+ // Compare the address and select the right one\r
+ //\r
+ Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);\r
+ NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
+ if ((NvStorageVariableBase >= FvbBaseAddress) && (NvStorageVariableBase < (FvbBaseAddress + FwVolHeader->FvLength))) {\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (HandleBuffer);\r
+ if (!EFI_ERROR (Status) && Fvb != NULL) {\r
+ //\r
+ // Close the notify event to avoid install gEfiVariableArchProtocolGuid & gEfiVariableWriteArchProtocolGuid again.\r
+ //\r
+ Status = gBS->CloseEvent (Event); \r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = VariableCommonInitialize (Fvb);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ SystemTable->RuntimeServices->GetVariable = RuntimeServiceGetVariable;\r
+ SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName;\r
+ SystemTable->RuntimeServices->SetVariable = RuntimeServiceSetVariable;\r
+ SystemTable->RuntimeServices->QueryVariableInfo = RuntimeServiceQueryVariableInfo;\r
+ \r
+ //\r
+ // Now install the Variable Runtime Architectural Protocol on a new handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mHandle,\r
+ &gEfiVariableArchProtocolGuid, NULL,\r
+ &gEfiVariableWriteArchProtocolGuid, NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ VariableClassAddressChangeEvent,\r
+ NULL,\r
+ &gEfiEventVirtualAddressChangeGuid,\r
+ &mVirtualAddressChangeEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+}\r