+/**\r
+ Init emulated non-volatile variable store.\r
+\r
+ @param[out] VariableStoreBase Output pointer to emulated non-volatile variable store base.\r
+\r
+ @retval EFI_SUCCESS Function successfully executed.\r
+ @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.\r
+\r
+**/\r
+EFI_STATUS\r
+InitEmuNonVolatileVariableStore (\r
+ EFI_PHYSICAL_ADDRESS *VariableStoreBase\r
+ )\r
+{\r
+ VARIABLE_STORE_HEADER *VariableStore;\r
+ UINT32 VariableStoreLength;\r
+ BOOLEAN FullyInitializeStore;\r
+ UINT32 HwErrStorageSize;\r
+\r
+ FullyInitializeStore = TRUE;\r
+\r
+ VariableStoreLength = PcdGet32 (PcdVariableStoreSize);\r
+ ASSERT (sizeof (VARIABLE_STORE_HEADER) <= VariableStoreLength);\r
+\r
+ //\r
+ // Allocate memory for variable store.\r
+ //\r
+ if (PcdGet64 (PcdEmuVariableNvStoreReserved) == 0) {\r
+ VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (VariableStoreLength);\r
+ if (VariableStore == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ } else {\r
+ //\r
+ // A memory location has been reserved for the NV variable store. Certain\r
+ // platforms may be able to preserve a memory range across system resets,\r
+ // thereby providing better NV variable emulation.\r
+ //\r
+ VariableStore =\r
+ (VARIABLE_STORE_HEADER *)(VOID*)(UINTN)\r
+ PcdGet64 (PcdEmuVariableNvStoreReserved);\r
+ if ((VariableStore->Size == VariableStoreLength) &&\r
+ (CompareGuid (&VariableStore->Signature, &gEfiAuthenticatedVariableGuid) ||\r
+ CompareGuid (&VariableStore->Signature, &gEfiVariableGuid)) &&\r
+ (VariableStore->Format == VARIABLE_STORE_FORMATTED) &&\r
+ (VariableStore->State == VARIABLE_STORE_HEALTHY)) {\r
+ DEBUG((\r
+ DEBUG_INFO,\r
+ "Variable Store reserved at %p appears to be valid\n",\r
+ VariableStore\r
+ ));\r
+ FullyInitializeStore = FALSE;\r
+ }\r
+ }\r
+\r
+ if (FullyInitializeStore) {\r
+ SetMem (VariableStore, VariableStoreLength, 0xff);\r
+ //\r
+ // Use gEfiAuthenticatedVariableGuid for potential auth variable support.\r
+ //\r
+ CopyGuid (&VariableStore->Signature, &gEfiAuthenticatedVariableGuid);\r
+ VariableStore->Size = VariableStoreLength;\r
+ VariableStore->Format = VARIABLE_STORE_FORMATTED;\r
+ VariableStore->State = VARIABLE_STORE_HEALTHY;\r
+ VariableStore->Reserved = 0;\r
+ VariableStore->Reserved1 = 0;\r
+ }\r
+\r
+ *VariableStoreBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;\r
+\r
+ HwErrStorageSize = PcdGet32 (PcdHwErrStorageSize);\r
+\r
+ //\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
+ //\r
+ ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));\r
+\r
+ mVariableModuleGlobal->CommonVariableSpace = ((UINTN) VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize);\r
+ mVariableModuleGlobal->CommonMaxUserVariableSpace = mVariableModuleGlobal->CommonVariableSpace;\r
+ mVariableModuleGlobal->CommonRuntimeVariableSpace = mVariableModuleGlobal->CommonVariableSpace;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r