};\r
\r
VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
+EFI_EVENT mFvbRegistration = NULL;\r
+\r
\r
/**\r
Acquires lock only at boot time. Simply returns at runtime.\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 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
&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
CopyGuid (&VolatileVariableStore->Signature, &gEfiVariableGuid);\r
VolatileVariableStore->Size = FixedPcdGet32(PcdVariableStoreSize);\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
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
+ EFI_HANDLE FvbHandle;\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
+ FvbHandle = 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) {\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
+ FvbHandle = HandleBuffer[Index];\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (HandleBuffer);\r
+ if (!EFI_ERROR (Status)) {\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->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- VariableClassAddressChangeEvent,\r
- NULL,\r
- &gEfiEventVirtualAddressChangeGuid,\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