///\r
BOOLEAN mEnableLocking = TRUE;\r
\r
+//\r
+// It will record the current boot error flag before EndOfDxe.\r
+//\r
+VAR_ERROR_FLAG mCurrentBootVarErrFlag = VAR_ERROR_FLAG_NO_ERROR;\r
+\r
/**\r
\r
SecureBoot Hook for auth variable update.\r
}\r
);\r
\r
+ if (!mEndOfDxe) {\r
+ //\r
+ // Before EndOfDxe, just record the current boot variable error flag to local variable,\r
+ // and leave the variable error flag in NV flash as the last boot variable error flag.\r
+ // After EndOfDxe in InitializeVarErrorFlag (), the variable error flag in NV flash\r
+ // will be initialized to this local current boot variable error flag.\r
+ //\r
+ mCurrentBootVarErrFlag &= Flag;\r
+ return;\r
+ }\r
+\r
//\r
// Record error flag (it should have be initialized).\r
//\r
return;\r
}\r
\r
- Flag = VAR_ERROR_FLAG_NO_ERROR;\r
+ Flag = mCurrentBootVarErrFlag;\r
DEBUG ((EFI_D_INFO, "Initialize variable error flag (%02x)\n", Flag));\r
\r
Status = FindVariable (\r
// Trying to update NV variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL\r
//\r
return EFI_NOT_AVAILABLE_YET;\r
- } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ } else if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
//\r
// Trying to update volatile authenticated variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL\r
// The authenticated variable perhaps is not initialized, just return here.\r
// as a temporary storage.\r
//\r
NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));\r
- ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
+ ScratchSize = mVariableModuleGlobal->ScratchBufferSize;\r
SetMem (NextVariable, ScratchSize, 0xff);\r
DataReady = FALSE;\r
\r
CopyMem (BufferForMerge, (UINT8 *) ((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize);\r
\r
//\r
- // Set Max Common Variable Data Size as default MaxDataSize\r
+ // Set Max Common/Auth Variable Data Size as default MaxDataSize\r
//\r
- MaxDataSize = PcdGet32 (PcdMaxVariableSize) - DataOffset;\r
+ if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
+ MaxDataSize = mVariableModuleGlobal->MaxAuthVariableSize - DataOffset;\r
+ } else {\r
+ MaxDataSize = mVariableModuleGlobal->MaxVariableSize - DataOffset;\r
+ }\r
\r
if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
} else {\r
//\r
// For other Variables, append the new data to the end of existing data.\r
- // Max Harware error record variable data size is different from common variable\r
+ // Max Harware error record variable data size is different from common/auth variable\r
//\r
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - DataOffset;\r
{\r
VARIABLE_ENTRY *Entry;\r
CHAR16 *Name;\r
+ LIST_ENTRY *Link;\r
+ VARIABLE_ENTRY *LockedEntry;\r
\r
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
+ for ( Link = GetFirstNode (&mLockedVariableList)\r
+ ; !IsNull (&mLockedVariableList, Link)\r
+ ; Link = GetNextNode (&mLockedVariableList, Link)\r
+ ) {\r
+ LockedEntry = BASE_CR (Link, VARIABLE_ENTRY, Link);\r
+ Name = (CHAR16 *) ((UINTN) LockedEntry + sizeof (*LockedEntry));\r
+ if (CompareGuid (&LockedEntry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
+ goto Done;\r
+ }\r
+ }\r
+\r
Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
StrnCpy (Name, VariableName, StrLen (VariableName));\r
CopyGuid (&Entry->Guid, VendorGuid);\r
InsertTailList (&mLockedVariableList, &Entry->Link);\r
\r
+Done:\r
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
return EFI_SUCCESS;\r
//\r
// The size of the VariableName, including the Unicode Null in bytes plus\r
// the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize)\r
- // bytes for HwErrRec, and PcdGet32 (PcdMaxVariableSize) bytes for the others.\r
+ // bytes for HwErrRec.\r
//\r
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) {\r
} else {\r
//\r
// The size of the VariableName, including the Unicode Null in bytes plus\r
- // the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes.\r
+ // the DataSize is limited to maximum size of Max(Auth)VariableSize bytes.\r
//\r
- if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) {\r
- return EFI_INVALID_PARAMETER;\r
+ if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
+ if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxAuthVariableSize - sizeof (VARIABLE_HEADER)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } else {\r
+ if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxVariableSize - sizeof (VARIABLE_HEADER)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
}\r
}\r
\r
}\r
\r
//\r
- // Let *MaximumVariableSize be PcdGet32 (PcdMaxVariableSize) with the exception of the variable header size.\r
+ // Let *MaximumVariableSize be Max(Auth)VariableSize with the exception of the variable header size.\r
//\r
- *MaximumVariableSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER);\r
+ if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
+ *MaximumVariableSize = mVariableModuleGlobal->MaxAuthVariableSize - sizeof (VARIABLE_HEADER);\r
+ } else {\r
+ *MaximumVariableSize = mVariableModuleGlobal->MaxVariableSize - sizeof (VARIABLE_HEADER);\r
+ }\r
}\r
\r
//\r
EFI_STATUS Status;\r
UINTN RemainingCommonRuntimeVariableSpace;\r
UINTN RemainingHwErrVariableSpace;\r
+ STATIC BOOLEAN Reclaimed;\r
+\r
+ //\r
+ // This function will be called only once at EndOfDxe or ReadyToBoot event.\r
+ //\r
+ if (Reclaimed) {\r
+ return;\r
+ }\r
+ Reclaimed = TRUE;\r
\r
Status = EFI_SUCCESS;\r
\r
}\r
\r
RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize;\r
+\r
//\r
// Check if the free area is below a threshold.\r
//\r
- if ((RemainingCommonRuntimeVariableSpace < PcdGet32 (PcdMaxVariableSize))\r
- || ((PcdGet32 (PcdHwErrStorageSize) != 0) &&\r
+ if (((RemainingCommonRuntimeVariableSpace < mVariableModuleGlobal->MaxVariableSize) ||\r
+ (RemainingCommonRuntimeVariableSpace < mVariableModuleGlobal->MaxAuthVariableSize)) ||\r
+ ((PcdGet32 (PcdHwErrStorageSize) != 0) &&\r
(RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){\r
Status = Reclaim (\r
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
// Note that in EdkII variable driver implementation, Hardware Error Record type variable\r
// is stored with common variable in the same NV region. So the platform integrator should\r
// ensure that the value of PcdHwErrStorageSize is less than the value of\r
- // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).\r
+ // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).\r
//\r
ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));\r
//\r
// Ensure that the value of PcdMaxUserNvVariableSpaceSize is less than the value of\r
- // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).\r
+ // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).\r
//\r
ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize));\r
//\r
// Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is less than the value of\r
- // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).\r
+ // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).\r
//\r
ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize));\r
\r
DEBUG ((EFI_D_INFO, "Variable driver common space: 0x%x 0x%x 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonRuntimeVariableSpace));\r
\r
//\r
- // The max variable or hardware error variable size should be < variable store size.\r
+ // The max NV variable size should be < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).\r
//\r
- ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) < VariableStoreLength);\r
+ ASSERT (MAX_NV_VARIABLE_SIZE < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));\r
+\r
+ mVariableModuleGlobal->MaxVariableSize = PcdGet32 (PcdMaxVariableSize);\r
+ mVariableModuleGlobal->MaxAuthVariableSize = ((PcdGet32 (PcdMaxAuthVariableSize) != 0) ? PcdGet32 (PcdMaxAuthVariableSize) : mVariableModuleGlobal->MaxVariableSize);\r
\r
//\r
// Parse non-volatile variable data and get last variable offset.\r
//\r
// Authenticated variable initialize.\r
//\r
- Status = AutenticatedVariableServiceInitialize ();\r
+ Status = AutenticatedVariableServiceInitialize (mVariableModuleGlobal->MaxAuthVariableSize - sizeof (VARIABLE_HEADER));\r
\r
return Status;\r
}\r
//\r
// Allocate memory for volatile variable store, note that there is a scratch space to store scratch data.\r
//\r
- ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
+ ScratchSize = MAX_NV_VARIABLE_SIZE;\r
+ mVariableModuleGlobal->ScratchBufferSize = ScratchSize;\r
VolatileVariableStore = AllocateRuntimePool (PcdGet32 (PcdVariableStoreSize) + ScratchSize);\r
if (VolatileVariableStore == NULL) {\r
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {\r