+/**\r
+ Return the variable store header and the index table based on the Index.\r
+\r
+ @param Index The index of the variable store.\r
+ @param IndexTable Return the index table.\r
+\r
+ @return Pointer to the variable store header.\r
+**/\r
+VARIABLE_STORE_HEADER *\r
+GetVariableStore (\r
+ IN VARIABLE_STORE_TYPE Type,\r
+ OUT VARIABLE_INDEX_TABLE **IndexTable OPTIONAL\r
+ )\r
+{\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
+ VARIABLE_STORE_HEADER *VariableStoreHeader;\r
+\r
+ if (IndexTable != NULL) {\r
+ *IndexTable = NULL;\r
+ }\r
+ VariableStoreHeader = NULL;\r
+ switch (Type) {\r
+ case VariableStoreTypeHob:\r
+ GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);\r
+ if (GuidHob != NULL) {\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);\r
+ }\r
+ break;\r
+\r
+ case VariableStoreTypeNv:\r
+ if (GetBootModeHob () != BOOT_IN_RECOVERY_MODE) {\r
+ //\r
+ // The content of NV storage for variable is not reliable in recovery boot mode.\r
+ //\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ? \r
+ PcdGet64 (PcdFlashNvStorageVariableBase64) : \r
+ PcdGet32 (PcdFlashNvStorageVariableBase)\r
+ );\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) FvHeader + FvHeader->HeaderLength);\r
+\r
+ if (IndexTable != NULL) {\r
+ GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid);\r
+ if (GuidHob != NULL) {\r
+ *IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
+ } else {\r
+ //\r
+ // If it's the first time to access variable region in flash, create a guid hob to record\r
+ // VAR_ADDED type variable info.\r
+ // Note that as the resource of PEI phase is limited, only store the limited number of \r
+ // VAR_ADDED type variables to reduce access time.\r
+ //\r
+ *IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
+ (*IndexTable)->Length = 0;\r
+ (*IndexTable)->StartPtr = GetStartPointer (VariableStoreHeader);\r
+ (*IndexTable)->EndPtr = GetEndPointer (VariableStoreHeader);\r
+ (*IndexTable)->GoneThrough = 0;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+\r
+ return VariableStoreHeader;\r
+}\r