variable.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 667 行 · 第 1/2 页
C
667 行
PtrTrack - Variable Track Pointer structure that contains
Variable Information.
Returns:
EFI_SUCCESS - Variable found successfully
EFI_NOT_FOUND - Variable not found
EFI_INVALID_PARAMETER - Invalid variable name
--*/
{
PEI_FLASH_MAP_PPI *FlashMapPpi;
EFI_FLASH_SUBAREA_ENTRY *VariableStoreEntry;
UINT32 NumEntries;
VARIABLE_STORE_HEADER *VariableStoreHeader;
VARIABLE_HEADER *Variable;
EFI_STATUS Status;
EFI_PEI_HOB_POINTERS Hob;
VARIABLE_HEADER *MaxIndex;
VARIABLE_INDEX_TABLE *IndexTable;
UINT32 Count;
if (VariableName != 0 && VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// First, Let's go through index table in HOB
//
Status = (*PeiServices)->GetHobList (PeiServices, &(Hob.Raw));
ASSERT_PEI_ERROR (PeiServices, Status);
//
// No Variable Address equals zero, so 0 as initial value is safe.
//
MaxIndex = 0;
if (EFI_ERROR (GetFirstGuidHob (&(Hob.Raw), &gEfiVariableIndexTableGuid, &IndexTable, NULL))) {
PeiBuildHobGuid (PeiServices, &gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE), &(Hob.Raw));
IndexTable = (VARIABLE_INDEX_TABLE *) ((UINT8 *) &Hob.Guid->Name + sizeof (EFI_GUID));
IndexTable->Length = 0;
IndexTable->StartPtr = NULL;
IndexTable->EndPtr = NULL;
IndexTable->GoneThrough = 0;
} else {
for (Count = 0; Count < IndexTable->Length; Count++)
{
#if ALIGNMENT <= 1
MaxIndex = (VARIABLE_HEADER *) (IndexTable->Index[Count] + ((UINT32) IndexTable->StartPtr & 0xFFFF0000));
#else
#if ALIGNMENT >= 4
MaxIndex = (VARIABLE_HEADER *) (UINTN) ((((UINT32)IndexTable->Index[Count]) << 2) + ((UINT32)(UINTN)IndexTable->StartPtr & 0xFFFC0000) );
#endif
#endif
if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
PtrTrack->StartPtr = IndexTable->StartPtr;
PtrTrack->EndPtr = IndexTable->EndPtr;
return EFI_SUCCESS;
}
}
if (IndexTable->GoneThrough) {
return EFI_NOT_FOUND;
}
}
//
// If not found in HOB, then let's start from the MaxIndex we've found.
//
if (MaxIndex != NULL) {
Variable = GetNextVariablePtr (MaxIndex);
} else {
if (IndexTable->StartPtr || IndexTable->EndPtr) {
Variable = IndexTable->StartPtr;
} else {
//
// Locate FlashMap PPI
//
Status = (**PeiServices).LocatePpi (
PeiServices,
&gPeiFlashMapPpiGuid,
0,
NULL,
&FlashMapPpi
);
ASSERT_PEI_ERROR (PeiServices, Status);
//
// Get flash area info for variables
//
Status = FlashMapPpi->GetAreaInfo (
PeiServices,
FlashMapPpi,
EFI_FLASH_AREA_EFI_VARIABLES,
NULL,
&NumEntries,
&VariableStoreEntry
);
//
// Currently only one non-volatile variable store is supported
//
if (NumEntries != 1) {
return EFI_UNSUPPORTED;
}
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) (VariableStoreEntry->Base);
if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
return EFI_UNSUPPORTED;
}
if (~VariableStoreHeader->Size == 0) {
return EFI_NOT_FOUND;
}
//
// Find the variable by walk through non-volatile variable store
//
IndexTable->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
IndexTable->EndPtr = (VARIABLE_HEADER *) ((UINTN) VariableStoreHeader + VariableStoreHeader->Size);
//
// Start Pointers for the variable.
// Actual Data Pointer where data can be written.
//
Variable = IndexTable->StartPtr;
}
}
//
// Find the variable by walk through non-volatile variable store
//
PtrTrack->StartPtr = IndexTable->StartPtr;
PtrTrack->EndPtr = IndexTable->EndPtr;
while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {
if (Variable->State == VAR_ADDED) {
//
// Record Variable in VariableIndex HOB
//
if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME)
{
#if ALIGNMENT <= 1
IndexTable->Index[IndexTable->Length++] = (UINT16) (UINT32) Variable;
#else
#if ALIGNMENT >= 4
IndexTable->Index[IndexTable->Length++] = (UINT16) (((UINT32)(UINTN) Variable) >> 2);
#endif
#endif
}
if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
return EFI_SUCCESS;
}
}
Variable = GetNextVariablePtr (Variable);
}
//
// If gone through the VariableStore, that means we never find in Firmware any more.
//
if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {
IndexTable->GoneThrough = 1;
}
PtrTrack->CurrPtr = NULL;
return EFI_NOT_FOUND;
}
EFI_STATUS
EFIAPI
PeiGetVariable (
IN EFI_PEI_SERVICES **PeiServices,
IN CHAR16 *VariableName,
IN EFI_GUID * VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data
)
/*++
Routine Description:
Provide the read variable functionality of the variable services.
Arguments:
PeiServices - General purpose services available to every PEIM.
VariableName - The variable name
VendorGuid - The vendor's GUID
Attributes - Pointer to the attribute
DataSize - Size of data
Data - Pointer to data
Returns:
EFI_SUCCESS - The interface could be successfully installed
EFI_NOT_FOUND - The variable could not be discovered
EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
--*/
{
VARIABLE_POINTER_TRACK Variable;
UINTN VarDataSize;
EFI_STATUS Status;
if (VariableName == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Find existing variable
//
Status = FindVariable (PeiServices, VariableName, VendorGuid, &Variable);
if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
return Status;
}
//
// Get data size
//
VarDataSize = Variable.CurrPtr->DataSize;
if (*DataSize >= VarDataSize) {
(*PeiServices)->CopyMem (Data, GET_VARIABLE_DATA_PTR (Variable.CurrPtr), VarDataSize);
if (Attributes != NULL) {
*Attributes = Variable.CurrPtr->Attributes;
}
*DataSize = VarDataSize;
return EFI_SUCCESS;
} else {
*DataSize = VarDataSize;
return EFI_BUFFER_TOO_SMALL;
}
}
EFI_STATUS
EFIAPI
PeiGetNextVariableName (
IN EFI_PEI_SERVICES **PeiServices,
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
)
/*++
Routine Description:
Provide the get next variable functionality of the variable services.
Arguments:
PeiServices - General purpose services available to every PEIM.
VariabvleNameSize - The variable name's size.
VariableName - A pointer to the variable's name.
VendorGuid - A pointer to the EFI_GUID structure.
VariableNameSize - Size of the variable name
VariableName - The variable name
VendorGuid - The vendor's GUID
Returns:
EFI_SUCCESS - The interface could be successfully installed
EFI_NOT_FOUND - The variable could not be discovered
--*/
{
VARIABLE_POINTER_TRACK Variable;
UINTN VarNameSize;
EFI_STATUS Status;
if (VariableName == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = FindVariable (PeiServices, VariableName, VendorGuid, &Variable);
if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
return Status;
}
if (VariableName[0] != 0) {
//
// If variable name is not NULL, get next variable
//
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
}
while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {
if (IsValidVariableHeader (Variable.CurrPtr)) {
if (Variable.CurrPtr->State == VAR_ADDED) {
VarNameSize = (UINTN) Variable.CurrPtr->NameSize;
if (VarNameSize <= *VariableNameSize) {
(*PeiServices)->CopyMem (VariableName, GET_VARIABLE_NAME_PTR (Variable.CurrPtr), VarNameSize);
(*PeiServices)->CopyMem (VendorGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));
Status = EFI_SUCCESS;
} else {
Status = EFI_BUFFER_TOO_SMALL;
}
*VariableNameSize = VarNameSize;
return Status;
//
// Variable is found
//
} else {
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
}
} else {
break;
}
}
return EFI_NOT_FOUND;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?