vpnor: make PNOR block size configurable

The vpnor code would assume a PNOR FFS block size of 4K. Make it
possible to supply this value, since it needn't always be 4K.

Change-Id: I21463b05f1047e93705ba82d46f746056568dcc5
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/mboxd.c b/mboxd.c
index e1f3251..ffd8c84 100644
--- a/mboxd.c
+++ b/mboxd.c
@@ -312,14 +312,6 @@
 
 	MSG_INFO("Starting Daemon\n");
 
-#ifdef VIRTUAL_PNOR_ENABLED
-	vpnor_create_partition_table(context);
-
-	strcpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC);
-	strcpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC);
-	strcpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC);
-#endif
-
 	rc = init_signals(context, &set);
 	if (rc) {
 		goto finish;
@@ -362,6 +354,14 @@
 		goto finish;
 	}
 
+#ifdef VIRTUAL_PNOR_ENABLED
+	vpnor_create_partition_table(context);
+
+	strcpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC);
+	strcpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC);
+	strcpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC);
+#endif
+
 	MSG_INFO("Entering Polling Loop\n");
 	rc = poll_loop(context);
 
diff --git a/mboxd_pnor_partition_table.cpp b/mboxd_pnor_partition_table.cpp
index 87de2b9..2464e6c 100644
--- a/mboxd_pnor_partition_table.cpp
+++ b/mboxd_pnor_partition_table.cpp
@@ -14,7 +14,9 @@
     {
         context->vpnor = new vpnor_partition_table;
         context->vpnor->table =
-            new openpower::virtual_pnor::partition::Table;
+            new openpower::virtual_pnor::partition::Table(
+                    1 << context->erase_size_shift,
+                    context->flash_size);
     }
 }
 
@@ -27,7 +29,10 @@
     {
         context->vpnor = new vpnor_partition_table;
         context->vpnor->table =
-            new openpower::virtual_pnor::partition::Table(std::move(dir));
+            new openpower::virtual_pnor::partition::Table(
+                    std::move(dir),
+                    1 << context->erase_size_shift,
+                    context->flash_size);
     }
 }
 
diff --git a/pnor_partition_table.cpp b/pnor_partition_table.cpp
index f98dc71..1168d2d 100644
--- a/pnor_partition_table.cpp
+++ b/pnor_partition_table.cpp
@@ -14,24 +14,20 @@
 
 namespace partition
 {
-namespace block
-{
 
-// The PNOR erase-block size is 4 KB
-constexpr size_t size = 4096;
-
-} // namespace block
-
-Table::Table():
-    Table(fs::path(PARTITION_FILES_RO_LOC))
+Table::Table(size_t blockSize, size_t pnorSize):
+    Table(fs::path(PARTITION_FILES_RO_LOC), blockSize, pnorSize)
 {
 }
 
-Table::Table(fs::path&& directory):
+Table::Table(fs::path&& directory,
+             size_t blockSize, size_t pnorSize):
     szBlocks(0),
     imgBlocks(0),
     directory(std::move(directory)),
-    numParts(0)
+    numParts(0),
+    blockSize(blockSize),
+    pnorSize(pnorSize)
 {
     preparePartitions();
     prepareHeader();
@@ -46,8 +42,8 @@
     table.data.size = szBlocks;
     table.data.entry_size = sizeof(pnor_partition);
     table.data.entry_count = numParts;
-    table.data.block_size = block::size;
-    table.data.block_count = imgBlocks;
+    table.data.block_size = blockSize;
+    table.data.block_count = pnorSize / blockSize;
     table.checksum = details::checksum(table.data);
 }
 
@@ -73,8 +69,8 @@
 
     size_t totalSizeBytes = sizeof(pnor_partition_table) +
                             (num * sizeof(pnor_partition));
-    size_t totalSizeAligned = align_up(totalSizeBytes, block::size);
-    szBlocks = totalSizeAligned / block::size;
+    size_t totalSizeAligned = align_up(totalSizeBytes, blockSize);
+    szBlocks = totalSizeAligned / blockSize;
     imgBlocks = szBlocks;
     tbl.resize(totalSizeAligned);
 }
@@ -83,7 +79,7 @@
 {
     size_t size = end - start;
     part.data.base = imgBlocks;
-    size_t sizeInBlocks = align_up(size, block::size) / block::size;
+    size_t sizeInBlocks = align_up(size, blockSize) / blockSize;
     imgBlocks += sizeInBlocks;
     part.data.size = sizeInBlocks;
     part.data.actual = size;
@@ -180,7 +176,7 @@
 const pnor_partition& Table::partition(size_t offset) const
 {
     const decltype(auto) table = getNativeTable();
-    size_t offt = offset / block::size;
+    size_t offt = offset / blockSize;
 
     for (decltype(numParts) i{}; i < numParts; ++i)
     {
diff --git a/pnor_partition_table.hpp b/pnor_partition_table.hpp
index b6c50f4..d933b67 100644
--- a/pnor_partition_table.hpp
+++ b/pnor_partition_table.hpp
@@ -75,10 +75,23 @@
          *         that houses the PNOR partition files.
          *
          *  @param[in] directory - path of the directory housing PNOR partitions
+         *  @param[in] blockSize - PNOR block size, in bytes. See
+         *             open-power/hostboot/blob/master/src/usr/pnor/ffs.h for
+         *             the PNOR FFS structure.
+         *  @param[in] pnorSize - PNOR size, in bytes
          */
-        Table(fs::path&& directory);
+        Table(fs::path&& directory,
+              size_t blockSize,
+              size_t pnorSize);
 
-        Table();
+        /** @brief Constructor - creates partition table
+         *
+         *  @param[in] blockSize - PNOR block size, in bytes
+         *  @param[in] pnorSize - PNOR size, in bytes
+         */
+        Table(size_t blockSize,
+              size_t pnorSize);
+
         Table(const Table&) = delete;
         Table& operator=(const Table&) = delete;
         Table(Table&&) = delete;
@@ -207,6 +220,12 @@
 
         /** @brief Number of partitions */
         size_t numParts;
+
+        /** @brief PNOR block size, in bytes */
+        size_t blockSize;
+
+        /** @brief PNOR size, in bytes */
+        size_t pnorSize;
 };
 
 } // namespace partition
diff --git a/test/create_pnor_partition_table.cpp b/test/create_pnor_partition_table.cpp
index bda443c..ec78e70 100644
--- a/test/create_pnor_partition_table.cpp
+++ b/test/create_pnor_partition_table.cpp
@@ -30,7 +30,8 @@
     partitionFile.write(empty.data(), empty.size());
     partitionFile.close();
 
-    const openpower::virtual_pnor::partition::Table table(fs::path{tmpdir});
+    const openpower::virtual_pnor::partition::Table
+        table(fs::path{tmpdir}, 4 * 1024, 64 * 1024 * 1024);
 
     pnor_partition_table expectedTable{};
     expectedTable.data.magic = PARTITION_HEADER_MAGIC;
@@ -39,7 +40,8 @@
     expectedTable.data.entry_size = sizeof(pnor_partition);
     expectedTable.data.entry_count = 1; // 1 partition
     expectedTable.data.block_size = 4096;
-    expectedTable.data.block_count = 2; // 1 table block and 1 partition block
+    expectedTable.data.block_count =
+        (64 * 1024 * 1024) / expectedTable.data.block_size;
     expectedTable.checksum =
         openpower::virtual_pnor::details::checksum(expectedTable.data);