pnor: provide "C" interface to partition table

Change-Id: I35af6c4c43e9a43f6a21992bfb0c13542a2c8f0d
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index cf1f987..8c779f8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,7 +14,7 @@
 mboxd_CFLAGS = $(LIBSYSTEMD_CFLAGS)
 
 if VIRTUAL_PNOR_ENABLED
-mboxd_SOURCES += pnor_partition_table.cpp
+mboxd_SOURCES += pnor_partition_table.cpp mboxd_pnor_partition_table.cpp
 mboxd_LDFLAGS += -lstdc++fs
 endif
 
diff --git a/mbox.h b/mbox.h
index 556994f..b367033 100644
--- a/mbox.h
+++ b/mbox.h
@@ -22,6 +22,7 @@
 #include <systemd/sd-bus.h>
 #include <poll.h>
 #include <stdbool.h>
+#include "mboxd_pnor_partition_table.h"
 
 enum api_version {
 	API_VERSION_INVAL	= 0,
@@ -166,6 +167,10 @@
 	uint32_t block_size_shift;
 	/* Actual Flash Info */
 	struct mtd_info_user mtd_info;
+#ifdef VIRTUAL_PNOR_ENABLED
+	/* Virtual PNOR partition table */
+	struct vpnor_partition_table *vpnor;
+#endif
 };
 
 #endif /* MBOX_H */
diff --git a/mboxd_pnor_partition_table.cpp b/mboxd_pnor_partition_table.cpp
new file mode 100644
index 0000000..72a8953
--- /dev/null
+++ b/mboxd_pnor_partition_table.cpp
@@ -0,0 +1,52 @@
+#include "mboxd_pnor_partition_table.h"
+#include "mbox.h"
+#include "pnor_partition_table.hpp"
+
+struct vpnor_partition_table
+{
+    openpower::virtual_pnor::partition::Table* table = nullptr;
+};
+
+void vpnor_create_partition_table(struct mbox_context *context)
+{
+    if (context)
+    {
+        if (!context->vpnor)
+        {
+            context->vpnor = new vpnor_partition_table;
+            context->vpnor->table =
+                new openpower::virtual_pnor::partition::Table;
+        }
+    }
+}
+
+size_t vpnor_get_partition_table_size(const struct mbox_context *context)
+{
+    return context && context->vpnor ?
+        context->vpnor->table->size() : 0;
+}
+
+const struct pnor_partition_table* vpnor_get_partition_table(
+                                       const struct mbox_context *context)
+{
+    return context && context->vpnor ?
+        &(context->vpnor->table->getHostTable()) : nullptr;
+}
+
+const struct pnor_partition* vpnor_get_partition(
+                                 const struct mbox_context *context,
+                                 const size_t offset)
+{
+    return context && context->vpnor ?
+        &(context->vpnor->table->partition(offset)) : nullptr;
+}
+
+void vpnor_destroy_partition_table(struct mbox_context *context)
+{
+    if(context && context->vpnor)
+    {
+        delete context->vpnor->table;
+        delete context->vpnor;
+        context->vpnor = nullptr;
+    }
+}
diff --git a/mboxd_pnor_partition_table.h b/mboxd_pnor_partition_table.h
new file mode 100644
index 0000000..fea1bef
--- /dev/null
+++ b/mboxd_pnor_partition_table.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#ifdef VIRTUAL_PNOR_ENABLED
+
+#include "pnor_partition_defs.h"
+
+struct mbox_context;
+struct vpnor_partition_table;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Create a virtual PNOR partition table.
+ *
+ *  @param[in] context - mbox context pointer
+ *
+ *  This API should be called before calling any other APIs below. If a table
+ *  already exists, this function will not do anything further. This function
+ *  will not do anything if the context is NULL.
+ */
+void vpnor_create_partition_table(struct mbox_context *context);
+
+
+/** @brief Get partition table size, in blocks (1 block = 4KB)
+ *
+ *  @param[in] context - mbox context pointer
+ *
+ *  @returns partition table size. 0 if no table exists, or if the
+ *           context is NULL.
+ */
+size_t vpnor_get_partition_table_size(const struct mbox_context *context);
+
+
+/** @brief Get virtual PNOR partition table with host-compatible byte-ordering
+ *
+ *  @param[in] context - mbox context pointer
+ *
+ *  @returns pointer to partition table, NULL if partition table doesn't
+ *           exist or if the context is NULL.
+ */
+const struct pnor_partition_table* vpnor_get_partition_table(
+				       const struct mbox_context *context);
+
+
+/** @brief Get a specific partition, by PNOR offset. The returned
+ *         partition is such that the offset lies in that partition's
+ *         boundary.
+ *
+ *  @param[in] context - mbox context pointer
+ *  @param[in] offset - PNOR offset
+ *
+ *  @returns const pointer to pnor_partition, NULL if partition table doesn't
+ *           exist or if the context is NULL
+ */
+const struct pnor_partition* vpnor_get_partition(
+				const struct mbox_context *context,
+				const size_t offset);
+
+
+/** @brief Destroy partition table, if it exists.
+ *
+ *  @param[in] context - mbox context pointer
+ */
+
+void vpnor_destroy_partition_table(struct mbox_context *context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif