Introduce NVRAM storage format versioning am: 889c3dda30 am: 06c8e853bb am: 630e2e46ea
am: a8882eec97
Change-Id: I7bfc4a0c5132ad853062391894078ab0e17d16ec
diff --git a/Implementation.h b/Implementation.h
index 2019a8f..92d9ecf 100644
--- a/Implementation.h
+++ b/Implementation.h
@@ -264,6 +264,8 @@
#ifdef EMBEDDED_MODE
// This must be matched by the package using this library!
#define NV_MEMORY_SIZE 16076
+// Versioning NV storage format will allow to smoothly migrate NVRAM contents.
+#define NV_FORMAT_VERSION 1
#else
#define NV_MEMORY_SIZE 16384
#endif
diff --git a/NV.c b/NV.c
index e5a9cae..f714c91 100644
--- a/NV.c
+++ b/NV.c
@@ -780,6 +780,48 @@
pAssert(addr == 0);
return addr;
}
+
+//
+// NvCheckAndMigrateIfNeeded()
+//
+// Supported only in EMBEDDED_MODE.
+//
+// Check if the NVRAM storage format changed, and if so - reinitialize the
+// NVRAM. No content migration yet, hopefully it will come one day.
+//
+// Note that the NV_FIRMWARE_V1 and NV_FIRMWARE_V2 values not used to store
+// TPM versoion when in embedded mode are used for NVRAM format version
+// instead.
+//
+//
+static void
+NvCheckAndMigrateIfNeeded(void)
+{
+#ifdef EMBEDDED_MODE
+ UINT32 nv_vers1;
+ UINT32 nv_vers2;
+
+ NvReadReserved(NV_FIRMWARE_V1, &nv_vers1);
+ NvReadReserved(NV_FIRMWARE_V2, &nv_vers2);
+
+ if ((nv_vers1 == ~nv_vers2) && (nv_vers1 == NV_FORMAT_VERSION))
+ return; // All is well.
+
+ // This will reinitialize NVRAM to empty. Migration code will come here
+ // later.
+ NvInit();
+
+ nv_vers1 = NV_FORMAT_VERSION;
+ nv_vers2 = ~NV_FORMAT_VERSION;
+
+ NvWriteReserved(NV_FIRMWARE_V1, &nv_vers1);
+ NvWriteReserved(NV_FIRMWARE_V2, &nv_vers2);
+
+ NvCommit();
+#endif
+}
+
+
//
//
// NvPowerOn()
@@ -804,7 +846,8 @@
{
if((nvError = _plat__NVEnable(0)) < 0)
FAIL(FATAL_ERROR_NV_UNRECOVERABLE);
- NvInitStatic();
+ NvInitStatic();
+ NvCheckAndMigrateIfNeeded();
}
return nvError == 0;
}