Implement all four UEFI Runtime Variable services for the nonvolatile\r
and volatile storage space and install variable architecture protocol.\r
\r
-Copyright (c) 2006 - 2008, Intel Corporation \r
+Copyright (c) 2006 - 2009, Intel Corporation \r
All rights reserved. This program and the accompanying materials \r
are licensed and made available under the terms and conditions of the BSD License \r
which accompanies this distribution. The full text of the license may be found at \r
};\r
\r
VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
-\r
-EFI_STATUS\r
-FtwVariableSpace (\r
- IN EFI_PHYSICAL_ADDRESS VariableBaseAddress,\r
- IN UINT8 *Buffer,\r
- IN UINTN BufferSize\r
- );\r
+EFI_EVENT mFvbRegistration = NULL;\r
\r
\r
/**\r
StrCpy (gVariableInfo->Name, VariableName);\r
gVariableInfo->Volatile = Volatile;\r
\r
- gBS->InstallConfigurationTable (&gEfiVariableInfoGuid, gVariableInfo);\r
+ gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);\r
}\r
\r
\r
@param Volatile Point out the Variable is Volatile or Non-Volatile\r
@param SetByIndex TRUE if target pointer is given as index\r
FALSE if target pointer is absolute\r
- @param Instance Instance of FV Block services\r
+ @param Fvb Pointer to the writable FVB protocol\r
@param DataPtrIndex Pointer to the Data from the end of VARIABLE_STORE_HEADER\r
structure\r
@param DataSize Size of data to be written\r
**/\r
EFI_STATUS\r
UpdateVariableStore (\r
- IN VARIABLE_GLOBAL *Global,\r
- IN BOOLEAN Volatile,\r
- IN BOOLEAN SetByIndex,\r
- IN UINTN Instance,\r
- IN UINTN DataPtrIndex,\r
- IN UINT32 DataSize,\r
- IN UINT8 *Buffer\r
+ IN VARIABLE_GLOBAL *Global,\r
+ IN BOOLEAN Volatile,\r
+ IN BOOLEAN SetByIndex,\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,\r
+ IN UINTN DataPtrIndex,\r
+ IN UINT32 DataSize,\r
+ IN UINT8 *Buffer\r
)\r
{\r
EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\r
// Check if the Data is Volatile\r
//\r
if (!Volatile) {\r
- EfiFvbGetPhysicalAddress (Instance, &FvVolHdr);\r
+ Status = Fvb->GetPhysicalAddress(Fvb, &FvVolHdr);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr);\r
//\r
// Data Pointer should point to the actual Address where data is to be\r
//\r
if ((CurrWritePtr >= LinearOffset) && (CurrWritePtr < LinearOffset + PtrBlockMapEntry->Length)) {\r
if ((CurrWritePtr + CurrWriteSize) <= (LinearOffset + PtrBlockMapEntry->Length)) {\r
- Status = EfiFvbWriteBlock (\r
- Instance,\r
+ Status = Fvb->Write (\r
+ Fvb,\r
LbaNumber,\r
(UINTN) (CurrWritePtr - LinearOffset),\r
&CurrWriteSize,\r
CurrBuffer\r
);\r
- return Status;\r
+ return Status;\r
} else {\r
Size = (UINT32) (LinearOffset + PtrBlockMapEntry->Length - CurrWritePtr);\r
- Status = EfiFvbWriteBlock (\r
- Instance,\r
+ Status = Fvb->Write (\r
+ Fvb,\r
LbaNumber,\r
(UINTN) (CurrWritePtr - LinearOffset),\r
&Size,\r
IN VARIABLE_STORE_HEADER *VarStoreHeader\r
)\r
{\r
- if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&\r
+ if (CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid) &&\r
VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&\r
VarStoreHeader->State == VARIABLE_STORE_HEALTHY\r
) {\r
\r
return EfiValid;\r
- } else if (VarStoreHeader->Signature == 0xffffffff &&\r
- VarStoreHeader->Size == 0xffffffff &&\r
- VarStoreHeader->Format == 0xff &&\r
- VarStoreHeader->State == 0xff\r
+ } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&\r
+ ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&\r
+ ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&\r
+ ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&\r
+ VarStoreHeader->Size == 0xffffffff &&\r
+ VarStoreHeader->Format == 0xff &&\r
+ VarStoreHeader->State == 0xff\r
) {\r
\r
return EfiRaw;\r
UINTN Index;\r
\r
if (EfiAtRuntime ()) {\r
+ //\r
// Don't use the cache at runtime\r
+ // \r
return;\r
}\r
\r
if (StrCmp (VariableName, Entry->Name) == 0) { \r
Entry->Attributes = Attributes;\r
if (DataSize == 0) {\r
+ //\r
// Delete Case\r
+ //\r
if (Entry->DataSize != 0) {\r
FreePool (Entry->Data);\r
}\r
CopyMem (Entry->Data, Data, DataSize);\r
} else {\r
Entry->Data = AllocatePool (DataSize);\r
+ ASSERT (Entry->Data != NULL);\r
+\r
Entry->DataSize = DataSize;\r
CopyMem (Entry->Data, Data, DataSize);\r
}\r
if (Variable[Index]->State == VAR_ADDED || \r
Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)\r
) {\r
- if (!EfiAtRuntime () || (Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {\r
+ if (!EfiAtRuntime () || ((Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
if (VariableName[0] == 0) {\r
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
InDeletedVariable = Variable[Index];\r
Point = (VOID *) GetVariableNamePtr (Variable[Index]);\r
\r
ASSERT (NameSizeOfVariable (Variable[Index]) != 0);\r
- if (!CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index]))) {\r
+ if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index])) == 0) {\r
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
InDeletedVariable = Variable[Index];\r
InDeletedStorageIndex = Index;\r
// Variable is found\r
//\r
if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {\r
- if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {\r
+ if ((EfiAtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
VarNameSize = NameSizeOfVariable (Variable.CurrPtr);\r
ASSERT (VarNameSize != 0);\r
\r
IN VOID *Data\r
)\r
{\r
- VARIABLE_POINTER_TRACK Variable;\r
- EFI_STATUS Status;\r
- VARIABLE_HEADER *NextVariable;\r
- UINTN VarNameSize;\r
- UINTN VarNameOffset;\r
- UINTN VarDataOffset;\r
- UINTN VarSize;\r
- UINT8 State;\r
- BOOLEAN Reclaimed;\r
- UINTN *VolatileOffset;\r
- UINTN *NonVolatileOffset;\r
- UINT32 Instance;\r
- BOOLEAN Volatile;\r
- EFI_PHYSICAL_ADDRESS Point;\r
+ VARIABLE_POINTER_TRACK Variable;\r
+ EFI_STATUS Status;\r
+ VARIABLE_HEADER *NextVariable;\r
+ UINTN VarNameSize;\r
+ UINTN VarNameOffset;\r
+ UINTN VarDataOffset;\r
+ UINTN VarSize;\r
+ UINT8 State;\r
+ BOOLEAN Reclaimed;\r
+ UINTN *VolatileOffset;\r
+ UINTN *NonVolatileOffset;\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
+ BOOLEAN Volatile;\r
+ EFI_PHYSICAL_ADDRESS Point;\r
\r
//\r
// Check input parameters\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
Reclaimed = FALSE;\r
- Instance = mVariableModuleGlobal->FvbInstance;\r
+ Fvb = mVariableModuleGlobal->FvbInstance;\r
VolatileOffset = &mVariableModuleGlobal->VolatileLastVariableOffset;\r
\r
//\r
//\r
// Only variable have NV attribute can be updated/deleted in Runtime\r
//\r
- if (!(Variable.CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE)) {\r
+ if ((Variable.CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done; \r
}\r
&mVariableModuleGlobal->VariableGlobal,\r
Variable.Volatile,\r
FALSE,\r
- Instance,\r
+ Fvb,\r
(UINTN) &Variable.CurrPtr->State,\r
sizeof (UINT8),\r
&State\r
&mVariableModuleGlobal->VariableGlobal,\r
Variable.Volatile,\r
FALSE,\r
- Instance,\r
+ Fvb,\r
(UINTN) &Variable.CurrPtr->State,\r
sizeof (UINT8),\r
&State\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
- Instance,\r
+ Fvb,\r
*NonVolatileOffset,\r
sizeof (VARIABLE_HEADER),\r
(UINT8 *) NextVariable\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
- Instance,\r
+ Fvb,\r
*NonVolatileOffset,\r
sizeof (VARIABLE_HEADER),\r
(UINT8 *) NextVariable\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
- Instance,\r
+ Fvb,\r
*NonVolatileOffset + sizeof (VARIABLE_HEADER),\r
(UINT32) VarSize - sizeof (VARIABLE_HEADER),\r
(UINT8 *) NextVariable + sizeof (VARIABLE_HEADER)\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
- Instance,\r
+ Fvb,\r
*NonVolatileOffset,\r
sizeof (VARIABLE_HEADER),\r
(UINT8 *) NextVariable\r
&mVariableModuleGlobal->VariableGlobal,\r
TRUE,\r
TRUE,\r
- Instance,\r
+ Fvb,\r
*VolatileOffset,\r
(UINT32) VarSize,\r
(UINT8 *) NextVariable\r
&mVariableModuleGlobal->VariableGlobal,\r
Variable.Volatile,\r
FALSE,\r
- Instance,\r
+ Fvb,\r
(UINTN) &Variable.CurrPtr->State,\r
sizeof (UINT8),\r
&State\r
/**\r
Initializes variable store area for non-volatile and volatile variable.\r
\r
- @param ImageHandle The Image handle of this driver.\r
@param SystemTable The pointer of EFI_SYSTEM_TABLE.\r
\r
@retval EFI_SUCCESS Function successfully executed.\r
**/\r
EFI_STATUS\r
VariableCommonInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
- CHAR8 *CurrPtr;\r
VARIABLE_STORE_HEADER *VolatileVariableStore;\r
VARIABLE_STORE_HEADER *VariableStoreHeader;\r
VARIABLE_HEADER *NextVariable;\r
- UINT32 Instance;\r
- EFI_PHYSICAL_ADDRESS FvVolHdr;\r
- UINT64 TempVariableStoreHeader;\r
+ EFI_PHYSICAL_ADDRESS TempVariableStoreHeader;\r
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
- UINT64 BaseAddress;\r
+ EFI_PHYSICAL_ADDRESS BaseAddress;\r
UINT64 Length;\r
UINTN Index;\r
UINT8 Data;\r
- UINT64 VariableStoreBase;\r
+ EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
UINT64 VariableStoreLength;\r
EFI_EVENT ReadyToBootEvent;\r
\r
//\r
mVariableModuleGlobal->VariableGlobal.VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;\r
mVariableModuleGlobal->VolatileLastVariableOffset = (UINTN) GetStartPointer (VolatileVariableStore) - (UINTN) VolatileVariableStore;\r
+ mVariableModuleGlobal->FvbInstance = FvbProtocol;\r
\r
- VolatileVariableStore->Signature = VARIABLE_STORE_SIGNATURE;\r
+ CopyGuid (&VolatileVariableStore->Signature, &gEfiVariableGuid);\r
VolatileVariableStore->Size = FixedPcdGet32(PcdVariableStoreSize);\r
VolatileVariableStore->Format = VARIABLE_STORE_FORMATTED;\r
VolatileVariableStore->State = VARIABLE_STORE_HEALTHY;\r
// Get non volatile varaible store\r
//\r
\r
- TempVariableStoreHeader = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase);\r
+ TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
VariableStoreBase = TempVariableStoreHeader + \\r
- (((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength);\r
+ (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader)) -> HeaderLength);\r
VariableStoreLength = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \\r
- (((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength);\r
+ (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader)) -> HeaderLength);\r
//\r
// Mark the variable storage region of the FLASH as RUNTIME\r
//\r
// Get address of non volatile variable store base\r
//\r
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
-\r
- //\r
- // Check Integrity\r
- //\r
- //\r
- // Find the Correct Instance of the FV Block Service.\r
- //\r
- Instance = 0;\r
- CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
- while (EfiFvbGetPhysicalAddress (Instance, &FvVolHdr) == EFI_SUCCESS) {\r
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr);\r
- if (CurrPtr >= (CHAR8 *) FwVolHeader && CurrPtr < (((CHAR8 *) FwVolHeader) + FwVolHeader->FvLength)) {\r
- mVariableModuleGlobal->FvbInstance = Instance;\r
- break;\r
- }\r
-\r
- Instance++;\r
- }\r
-\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) CurrPtr;\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;\r
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {\r
if (~VariableStoreHeader->Size == 0) {\r
Status = UpdateVariableStore (\r
}\r
}\r
\r
- mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr);\r
//\r
// Parse non-volatile variable data and get last variable offset\r
//\r
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) CurrPtr);\r
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);\r
Status = EFI_SUCCESS;\r
\r
while (IsValidVariableHeader (NextVariable)) {\r
NextVariable = GetNextVariablePtr (NextVariable);\r
}\r
\r
- mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) CurrPtr;\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase;\r
\r
//\r
// Check if the free area is really free.\r
NULL, \r
&ReadyToBootEvent\r
);\r
+ } else {\r
+ Status = EFI_VOLUME_CORRUPTED;\r
+ DEBUG((EFI_D_INFO, "Variable Store header is corrupted\n"));\r
}\r
\r
Done:\r
IN VOID *Context\r
)\r
{\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
EfiConvertPointer (\r
0x0,\r
(VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase\r
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
}\r
\r
+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
+ 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
\r
/**\r
Variable Driver main entry point. The Variable driver places the 4 EFI\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
- Status = VariableCommonInitialize (ImageHandle, SystemTable);\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->CreateEvent (\r
- EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
- TPL_NOTIFY,\r
- VariableClassAddressChangeEvent,\r
- NULL,\r
- &mVirtualAddressChangeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ // Register FvbNotificationEvent () notify function.\r
+ // \r
+ EfiCreateProtocolNotifyEvent (\r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ TPL_CALLBACK,\r
+ FvbNotificationEvent,\r
+ (VOID *)SystemTable,\r
+ &mFvbRegistration\r
+ );\r
\r
return EFI_SUCCESS;\r
}\r