vpnor: add partition version check to the TOC

Change-Id: If5497476f03484334396e483e251b1e9434137f3
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/pnor_partition_defs.h b/pnor_partition_defs.h
index 836dac5..fe2a338 100644
--- a/pnor_partition_defs.h
+++ b/pnor_partition_defs.h
@@ -31,8 +31,10 @@
  * updates, etc. */
 #define PARTITION_USER_WORDS 16
 #define PARTITION_ECC_PROTECTED 0x8000
-#define PARTITION_PRESERVED 0x80000000
-#define PARTITION_READONLY 0x40000000
+#define PARTITION_PRESERVED 0x00800000
+#define PARTITION_READONLY 0x00400000
+#define PARTITION_VERSION_CHECK_SHA512 0x80000000
+#define PARTITION_VERSION_CHECK_SHA512_PER_EC 0x40000000
 
 /* Partition flags */
 enum partition_flags {
diff --git a/pnor_partition_table.cpp b/pnor_partition_table.cpp
index 36f0765..98bba46 100644
--- a/pnor_partition_table.cpp
+++ b/pnor_partition_table.cpp
@@ -90,12 +90,15 @@
     part.data.actual = size;
 }
 
-inline void Table::writeUserdata(pnor_partition& part, const std::string& data)
+inline void Table::writeUserdata(pnor_partition& part,
+                                 uint32_t version,
+                                 const std::string& data)
 {
     if (std::string::npos != data.find("ECC"))
     {
         part.data.user.data[0] = PARTITION_ECC_PROTECTED;
     }
+
     auto perms = 0;
     if (std::string::npos != data.find("READONLY"))
     {
@@ -106,6 +109,8 @@
         perms |= PARTITION_PRESERVED;
     }
     part.data.user.data[1] = perms;
+
+    part.data.user.data[1] |= version;
 }
 
 inline void Table::writeDefaults(pnor_partition& part)
@@ -136,16 +141,19 @@
     static constexpr auto NAME_MATCH = 2;
     static constexpr auto START_ADDR_MATCH = 3;
     static constexpr auto END_ADDR_MATCH = 4;
+    static constexpr auto VERSION_MATCH = 5;
     // Parse PNOR toc (table of contents) file, which has lines like :
-    // partition01=HBB,00010000,000a0000,ECC,PRESERVED, to indicate partitions
+    // partition01=HBB,00010000,000a0000,80,ECC,PRESERVED, to indicate
+    // partition information
     std::regex regex
     {
         "^partition([0-9]+)=([A-Za-z0-9_]+),"
-        "([0-9a-fA-F]+),([0-9a-fA-F]+)",
+        "([0-9a-fA-F]+),([0-9a-fA-F]+),([A-Fa-f0-9]{2})",
         std::regex::extended
     };
     std::smatch match;
     std::string line;
+    constexpr auto versionShift = 24;
 
     decltype(auto) table = getNativeTable();
 
@@ -169,7 +177,11 @@
             writeSizes(table.partitions[numParts],
                        std::stoul(match[START_ADDR_MATCH].str(), nullptr, 16),
                        std::stoul(match[END_ADDR_MATCH].str(), nullptr, 16));
-            writeUserdata(table.partitions[numParts], match.suffix().str());
+            writeUserdata(
+                table.partitions[numParts],
+                std::stoul(match[VERSION_MATCH].str(), nullptr, 16) <<
+                    versionShift, // For eg, convert "80" to 0x80000000
+                match.suffix().str());
             table.partitions[numParts].checksum =
                 details::checksum(table.partitions[numParts].data);
 
diff --git a/pnor_partition_table.hpp b/pnor_partition_table.hpp
index 23cb9f5..662fb76 100644
--- a/pnor_partition_table.hpp
+++ b/pnor_partition_table.hpp
@@ -177,10 +177,13 @@
          *         pnor_partition structure.
          *
          *  @param[in/out] part - pnor_partition structure
+         *  @param[in] version - partition version check algorithm to be used
+         *                       (see pnor_partition_defs.h)
          *  @param[in] data - string having userdata fields in a
          *             comma-separated line.
          */
-        void writeUserdata(pnor_partition& part, const std::string& data);
+        void writeUserdata(pnor_partition& part, uint32_t version,
+                           const std::string& data);
 
         /** @brief Populate the name and id fields for the input
          *         pnor_partition structure.
diff --git a/test/create_pnor_partition_table.cpp b/test/create_pnor_partition_table.cpp
index ec78e70..bfc4471 100644
--- a/test/create_pnor_partition_table.cpp
+++ b/test/create_pnor_partition_table.cpp
@@ -6,7 +6,7 @@
 #include <fstream>
 #include <experimental/filesystem>
 
-constexpr auto line = "partition01=HBB,00000000,00000400,ECC,PRESERVED";
+constexpr auto line = "partition01=HBB,00000000,00000400,80,ECC,PRESERVED";
 constexpr auto partitionName = "HBB";
 char tmplt[] = "/tmp/vpnor_partitions.XXXXXX";
 
@@ -56,6 +56,7 @@
     expectedPartition.data.flags = 0;
     expectedPartition.data.user.data[0] = PARTITION_ECC_PROTECTED;
     expectedPartition.data.user.data[1] |= PARTITION_PRESERVED;
+    expectedPartition.data.user.data[1] |= PARTITION_VERSION_CHECK_SHA512;
     expectedPartition.checksum =
         openpower::virtual_pnor::details::checksum(expectedPartition.data);