return EFI_INVALID_PARAMETER;\r
}\r
\r
+ ZeroMem (&RtPtrTrack, sizeof (RtPtrTrack));\r
+\r
//\r
// The UEFI specification restricts Runtime Services callers from invoking the same or certain other Runtime Service\r
// functions prior to completion and return from a previous Runtime Service call. These restrictions prevent\r
}\r
\r
/**\r
- This code Finds the Next available variable.\r
+ Finds the next available variable in a runtime cache variable store.\r
\r
@param[in, out] VariableNameSize Size of the variable name.\r
@param[in, out] VariableName Pointer to variable name.\r
\r
**/\r
EFI_STATUS\r
-EFIAPI\r
-RuntimeServiceGetNextVariableName (\r
+GetNextVariableNameInRuntimeCache (\r
+ IN OUT UINTN *VariableNameSize,\r
+ IN OUT CHAR16 *VariableName,\r
+ IN OUT EFI_GUID *VendorGuid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN VarNameSize;\r
+ VARIABLE_HEADER *VariablePtr;\r
+ VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];\r
+\r
+ Status = EFI_NOT_FOUND;\r
+\r
+ //\r
+ // The UEFI specification restricts Runtime Services callers from invoking the same or certain other Runtime Service\r
+ // functions prior to completion and return from a previous Runtime Service call. These restrictions prevent\r
+ // a GetVariable () or GetNextVariable () call from being issued until a prior call has returned. The runtime\r
+ // cache read lock should always be free when entering this function.\r
+ //\r
+ ASSERT (!mVariableRuntimeCacheReadLock);\r
+\r
+ CheckForRuntimeCacheSync ();\r
+\r
+ mVariableRuntimeCacheReadLock = TRUE;\r
+ if (!mVariableRuntimeCachePendingUpdate) {\r
+ //\r
+ // 0: Volatile, 1: HOB, 2: Non-Volatile.\r
+ // The index and attributes mapping must be kept in this order as FindVariable\r
+ // makes use of this mapping to implement search algorithm.\r
+ //\r
+ VariableStoreHeader[VariableStoreTypeVolatile] = mVariableRuntimeVolatileCacheBuffer;\r
+ VariableStoreHeader[VariableStoreTypeHob] = mVariableRuntimeHobCacheBuffer;\r
+ VariableStoreHeader[VariableStoreTypeNv] = mVariableRuntimeNvCacheBuffer;\r
+\r
+ Status = VariableServiceGetNextVariableInternal (\r
+ VariableName,\r
+ VendorGuid,\r
+ VariableStoreHeader,\r
+ &VariablePtr,\r
+ mVariableAuthFormat\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ VarNameSize = NameSizeOfVariable (VariablePtr, mVariableAuthFormat);\r
+ ASSERT (VarNameSize != 0);\r
+ if (VarNameSize <= *VariableNameSize) {\r
+ CopyMem (VariableName, GetVariableNamePtr (VariablePtr, mVariableAuthFormat), VarNameSize);\r
+ CopyMem (VendorGuid, GetVendorGuidPtr (VariablePtr, mVariableAuthFormat), sizeof (EFI_GUID));\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *VariableNameSize = VarNameSize;\r
+ }\r
+ }\r
+ mVariableRuntimeCacheReadLock = FALSE;\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Finds the next available variable in a SMM variable store.\r
+\r
+ @param[in, out] VariableNameSize Size of the variable name.\r
+ @param[in, out] VariableName Pointer to variable name.\r
+ @param[in, out] VendorGuid Variable Vendor Guid.\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_SUCCESS Find the specified variable.\r
+ @retval EFI_NOT_FOUND Not found.\r
+ @retval EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
+\r
+**/\r
+EFI_STATUS\r
+GetNextVariableNameInSmm (\r
IN OUT UINTN *VariableNameSize,\r
IN OUT CHAR16 *VariableName,\r
IN OUT EFI_GUID *VendorGuid\r
UINTN OutVariableNameSize;\r
UINTN InVariableNameSize;\r
\r
- if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
OutVariableNameSize = *VariableNameSize;\r
InVariableNameSize = StrSize (VariableName);\r
SmmGetNextVariableName = NULL;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- AcquireLockOnlyAtBootTime(&mVariableServicesLock);\r
-\r
//\r
// Init the communicate buffer. The buffer data size is:\r
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
CopyMem (VariableName, SmmGetNextVariableName->Name, SmmGetNextVariableName->NameSize);\r
\r
Done:\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This code Finds the Next available variable.\r
+\r
+ @param[in, out] VariableNameSize Size of the variable name.\r
+ @param[in, out] VariableName Pointer to variable name.\r
+ @param[in, out] VendorGuid Variable Vendor Guid.\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_SUCCESS Find the specified variable.\r
+ @retval EFI_NOT_FOUND Not found.\r
+ @retval EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceGetNextVariableName (\r
+ IN OUT UINTN *VariableNameSize,\r
+ IN OUT CHAR16 *VariableName,\r
+ IN OUT EFI_GUID *VendorGuid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN MaxLen;\r
+\r
+ Status = EFI_NOT_FOUND;\r
+\r
+ if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Calculate the possible maximum length of name string, including the Null terminator.\r
+ //\r
+ MaxLen = *VariableNameSize / sizeof (CHAR16);\r
+ if ((MaxLen == 0) || (StrnLenS (VariableName, MaxLen) == MaxLen)) {\r
+ //\r
+ // Null-terminator is not found in the first VariableNameSize bytes of the input VariableName buffer,\r
+ // follow spec to return EFI_INVALID_PARAMETER.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ AcquireLockOnlyAtBootTime (&mVariableServicesLock);\r
+ if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) {\r
+ Status = GetNextVariableNameInRuntimeCache (VariableNameSize, VariableName, VendorGuid);\r
+ } else {\r
+ Status = GetNextVariableNameInSmm (VariableNameSize, VariableName, VendorGuid);\r
+ }\r
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);\r
+\r
return Status;\r
}\r
\r