mirror of https://github.com/acidanthera/audk.git
EMU Variable: Add support for pre-reserved NV variable store.
Add PcdEmuVariableNvStoreReserved which allows a platform to declare a memory address for the EMU Variable driver to use for the NV variable store. The EMU Variable driver will look to see if the contents of this memory range appear to be a valid variable store, and if so the EMU driver will use the variables. If a platform can preserve a memory range across system resets, this feature can allow the EMU Variable driver's NV variable store to be preserved across a system reset. In the default case this PCD will be set as a fixed PCD with a value of 0. In this case this new feature should have minimal impact on the EMU Variable driver. (Perhaps a slight increase in code size, but no functional difference is expected.) git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9240 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
2ca6377b5e
commit
02328a57a2
|
@ -321,6 +321,10 @@
|
||||||
# This PCD is a sample to explain String typed PCD usage.
|
# This PCD is a sample to explain String typed PCD usage.
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
|
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
|
||||||
|
|
||||||
|
## This PCD defines a reserved memory range for the EMU Variable driver's NV Variable Store
|
||||||
|
# The range is valid if non-zero. The memory range size must be PcdVariableStoreSize.
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0|UINT64|0x40000008
|
||||||
|
|
||||||
[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]
|
[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]
|
||||||
## This PCD defines the times to print hello world string.
|
## This PCD defines the times to print hello world string.
|
||||||
# This PCD is a sample to explain FixedAtBuild UINT32 PCD usage.
|
# This PCD is a sample to explain FixedAtBuild UINT32 PCD usage.
|
||||||
|
|
|
@ -159,6 +159,38 @@ GetVariableDataPtr (
|
||||||
return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));
|
return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets pointer to header of the next potential variable.
|
||||||
|
|
||||||
|
This function gets the pointer to the next potential variable header
|
||||||
|
according to the input point to the variable header. The return value
|
||||||
|
is not a valid variable if the input variable was the last variable
|
||||||
|
in the variabl store.
|
||||||
|
|
||||||
|
@param Variable Pointer to header of the next variable
|
||||||
|
|
||||||
|
@return Pointer to next variable header.
|
||||||
|
@retval NULL Input was not a valid variable header.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VARIABLE_HEADER *
|
||||||
|
GetNextPotentialVariablePtr (
|
||||||
|
IN VARIABLE_HEADER *Variable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VARIABLE_HEADER *VarHeader;
|
||||||
|
|
||||||
|
if (Variable->StartId != VARIABLE_DATA) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Be careful about pad size for alignment
|
||||||
|
//
|
||||||
|
VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
|
||||||
|
|
||||||
|
return VarHeader;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets pointer to header of the next variable.
|
Gets pointer to header of the next variable.
|
||||||
|
|
||||||
|
@ -177,21 +209,46 @@ GetNextVariablePtr (
|
||||||
{
|
{
|
||||||
VARIABLE_HEADER *VarHeader;
|
VARIABLE_HEADER *VarHeader;
|
||||||
|
|
||||||
if (Variable->StartId != VARIABLE_DATA) {
|
VarHeader = GetNextPotentialVariablePtr (Variable);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Be careful about pad size for alignment
|
|
||||||
//
|
|
||||||
VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
|
|
||||||
|
|
||||||
if (VarHeader->StartId != VARIABLE_DATA) {
|
if ((VarHeader == NULL) || (VarHeader->StartId != VARIABLE_DATA)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VarHeader;
|
return VarHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Updates LastVariableOffset variable for the given variable store.
|
||||||
|
|
||||||
|
LastVariableOffset points to the offset to use for the next variable
|
||||||
|
when updating the variable store.
|
||||||
|
|
||||||
|
@param[in] VariableStore Pointer to the start of the variable store
|
||||||
|
@param[out] LastVariableOffset Offset to put the next new variable in
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
InitializeLocationForLastVariableOffset (
|
||||||
|
IN VARIABLE_STORE_HEADER *VariableStore,
|
||||||
|
OUT UINTN *LastVariableOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VARIABLE_HEADER *VarHeader;
|
||||||
|
|
||||||
|
*LastVariableOffset = sizeof (VARIABLE_STORE_HEADER);
|
||||||
|
VarHeader = (VARIABLE_HEADER*) ((UINT8*)VariableStore + *LastVariableOffset);
|
||||||
|
while (VarHeader->StartId == VARIABLE_DATA) {
|
||||||
|
VarHeader = GetNextPotentialVariablePtr (VarHeader);
|
||||||
|
|
||||||
|
if (VarHeader != NULL) {
|
||||||
|
*LastVariableOffset = (UINTN) VarHeader - (UINTN) VariableStore;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets pointer to the end of the variable storage area.
|
Gets pointer to the end of the variable storage area.
|
||||||
|
|
||||||
|
@ -1307,11 +1364,23 @@ EmuQueryVariableInfo (
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
InitializeVariableStore (
|
InitializeVariableStore (
|
||||||
OUT EFI_PHYSICAL_ADDRESS *VariableBase,
|
IN BOOLEAN VolatileStore
|
||||||
OUT UINTN *LastVariableOffset
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VARIABLE_STORE_HEADER *VariableStore;
|
VARIABLE_STORE_HEADER *VariableStore;
|
||||||
|
BOOLEAN FullyInitializeStore;
|
||||||
|
EFI_PHYSICAL_ADDRESS *VariableBase;
|
||||||
|
UINTN *LastVariableOffset;
|
||||||
|
|
||||||
|
FullyInitializeStore = TRUE;
|
||||||
|
|
||||||
|
if (VolatileStore) {
|
||||||
|
VariableBase = &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase;
|
||||||
|
LastVariableOffset = &mVariableModuleGlobal->VolatileLastVariableOffset;
|
||||||
|
} else {
|
||||||
|
VariableBase = &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase;
|
||||||
|
LastVariableOffset = &mVariableModuleGlobal->NonVolatileLastVariableOffset;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Note that in EdkII variable driver implementation, Hardware Error Record type variable
|
// Note that in EdkII variable driver implementation, Hardware Error Record type variable
|
||||||
|
@ -1322,22 +1391,48 @@ InitializeVariableStore (
|
||||||
ASSERT (FixedPcdGet32(PcdHwErrStorageSize) <= FixedPcdGet32(PcdVariableStoreSize));
|
ASSERT (FixedPcdGet32(PcdHwErrStorageSize) <= FixedPcdGet32(PcdVariableStoreSize));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate memory for volatile variable store
|
// Allocate memory for variable store.
|
||||||
//
|
//
|
||||||
|
if (VolatileStore || (PcdGet64 (PcdEmuVariableNvStoreReserved) == 0)) {
|
||||||
VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (
|
VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (
|
||||||
FixedPcdGet32(PcdVariableStoreSize)
|
FixedPcdGet32(PcdVariableStoreSize)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// A memory location has been reserved for the NV variable store. Certain
|
||||||
|
// platforms may be able to preserve a memory range across system resets,
|
||||||
|
// thereby providing better NV variable emulation.
|
||||||
|
//
|
||||||
|
VariableStore =
|
||||||
|
(VARIABLE_STORE_HEADER *)(VOID*)(UINTN)
|
||||||
|
PcdGet64 (PcdEmuVariableNvStoreReserved);
|
||||||
|
if (
|
||||||
|
(VariableStore->Size == FixedPcdGet32(PcdVariableStoreSize)) &&
|
||||||
|
(VariableStore->Format == VARIABLE_STORE_FORMATTED) &&
|
||||||
|
(VariableStore->State == VARIABLE_STORE_HEALTHY)
|
||||||
|
) {
|
||||||
|
DEBUG((
|
||||||
|
EFI_D_INFO,
|
||||||
|
"Variable Store reserved at %p appears to be valid\n",
|
||||||
|
VariableStore
|
||||||
|
));
|
||||||
|
FullyInitializeStore = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == VariableStore) {
|
if (NULL == VariableStore) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FullyInitializeStore) {
|
||||||
SetMem (VariableStore, FixedPcdGet32(PcdVariableStoreSize), 0xff);
|
SetMem (VariableStore, FixedPcdGet32(PcdVariableStoreSize), 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Variable Specific Data
|
// Variable Specific Data
|
||||||
//
|
//
|
||||||
*VariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;
|
*VariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;
|
||||||
*LastVariableOffset = sizeof (VARIABLE_STORE_HEADER);
|
InitializeLocationForLastVariableOffset (VariableStore, LastVariableOffset);
|
||||||
|
|
||||||
CopyGuid (&VariableStore->Signature, &gEfiVariableGuid);
|
CopyGuid (&VariableStore->Signature, &gEfiVariableGuid);
|
||||||
VariableStore->Size = FixedPcdGet32(PcdVariableStoreSize);
|
VariableStore->Size = FixedPcdGet32(PcdVariableStoreSize);
|
||||||
|
@ -1386,11 +1481,7 @@ VariableCommonInitialize (
|
||||||
//
|
//
|
||||||
// Intialize volatile variable store
|
// Intialize volatile variable store
|
||||||
//
|
//
|
||||||
Status = InitializeVariableStore (
|
Status = InitializeVariableStore (TRUE);
|
||||||
&mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase,
|
|
||||||
&mVariableModuleGlobal->VolatileLastVariableOffset
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
FreePool(mVariableModuleGlobal);
|
FreePool(mVariableModuleGlobal);
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1398,10 +1489,7 @@ VariableCommonInitialize (
|
||||||
//
|
//
|
||||||
// Intialize non volatile variable store
|
// Intialize non volatile variable store
|
||||||
//
|
//
|
||||||
Status = InitializeVariableStore (
|
Status = InitializeVariableStore (FALSE);
|
||||||
&mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase,
|
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset
|
|
||||||
);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
gEfiVariableGuid
|
gEfiVariableGuid
|
||||||
|
|
||||||
[Pcd.common]
|
[Pcd.common]
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
|
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
|
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
|
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
|
||||||
|
|
Loading…
Reference in New Issue