diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index 1f4d705..e5de6cf 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -11,5 +11,7 @@ endif
 
 config_flag_fmt = 'RTE_LIBRTE_@0@_COMMON'
 deps = ['eal', 'pci', 'bus_pci', 'mbuf']
-sources = files('roc_platform.c')
+sources = files('roc_model.c',
+		'roc_platform.c',
+		'roc_utils.c')
 includes += include_directories('../../bus/pci')
diff --git a/drivers/common/cnxk/roc_api.h b/drivers/common/cnxk/roc_api.h
index 83a69ac..7dbeb6a 100644
--- a/drivers/common/cnxk/roc_api.h
+++ b/drivers/common/cnxk/roc_api.h
@@ -29,6 +29,13 @@
 #define ROC_LMT_BASE_PER_CORE_LOG2                                             \
 	(ROC_LMT_LINES_PER_CORE_LOG2 + ROC_LMT_LINE_SIZE_LOG2)
 
+/* IO */
+#if defined(__aarch64__)
+#include "roc_io.h"
+#else
+#include "roc_io_generic.h"
+#endif
+
 /* PCI IDs */
 #define PCI_VENDOR_ID_CAVIUM	      0x177D
 #define PCI_DEVID_CNXK_RVU_PF	      0xA063
@@ -66,4 +73,10 @@
 #include "hw/ssow.h"
 #include "hw/tim.h"
 
+/* Model */
+#include "roc_model.h"
+
+/* Utils */
+#include "roc_utils.h"
+
 #endif /* _ROC_API_H_ */
diff --git a/drivers/common/cnxk/roc_io.h b/drivers/common/cnxk/roc_io.h
new file mode 100644
index 0000000..31849fb
--- /dev/null
+++ b/drivers/common/cnxk/roc_io.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#ifndef _ROC_IO_H_
+#define _ROC_IO_H_
+
+#define ROC_LMT_BASE_ID_GET(lmt_addr, lmt_id)                                  \
+	do {                                                                   \
+		/* 32 Lines per core */                                        \
+		lmt_id = plt_lcore_id() << ROC_LMT_LINES_PER_CORE_LOG2;        \
+		/* Each line is of 128B */                                     \
+		(lmt_addr) += ((uint64_t)lmt_id << ROC_LMT_LINE_SIZE_LOG2);    \
+	} while (0)
+
+#define roc_load_pair(val0, val1, addr)                                        \
+	({                                                                     \
+		asm volatile("ldp %x[x0], %x[x1], [%x[p1]]"                    \
+			     : [x0] "=r"(val0), [x1] "=r"(val1)                \
+			     : [p1] "r"(addr));                                \
+	})
+
+#define roc_store_pair(val0, val1, addr)                                       \
+	({                                                                     \
+		asm volatile(                                                  \
+			"stp %x[x0], %x[x1], [%x[p1], #0]!" ::[x0] "r"(val0),  \
+			[x1] "r"(val1), [p1] "r"(addr));                       \
+	})
+
+#define roc_prefetch_store_keep(ptr)                                           \
+	({ asm volatile("prfm pstl1keep, [%x0]\n" : : "r"(ptr)); })
+
+#if defined(__clang__)
+static __plt_always_inline void
+roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, int64_t *ptr)
+{
+	register uint64_t x0 __asm("x0") = swap0;
+	register uint64_t x1 __asm("x1") = swap1;
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "casp %[x0], %[x1], %[x0], %[x1], [%[ptr]]\n"
+		     : [x0] "+r"(x0), [x1] "+r"(x1)
+		     : [ptr] "r"(ptr)
+		     : "memory");
+}
+#else
+static __plt_always_inline void
+roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, uint64_t ptr)
+{
+	__uint128_t wdata = swap0 | ((__uint128_t)swap1 << 64);
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "casp %[wdata], %H[wdata], %[wdata], %H[wdata], [%[ptr]]\n"
+		     : [wdata] "+r"(wdata)
+		     : [ptr] "r"(ptr)
+		     : "memory");
+}
+#endif
+
+static __plt_always_inline uint64_t
+roc_atomic64_cas(uint64_t compare, uint64_t swap, int64_t *ptr)
+{
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "cas %[compare], %[swap], [%[ptr]]\n"
+		     : [compare] "+r"(compare)
+		     : [swap] "r"(swap), [ptr] "r"(ptr)
+		     : "memory");
+
+	return compare;
+}
+
+static __plt_always_inline uint64_t
+roc_atomic64_add_nosync(int64_t incr, int64_t *ptr)
+{
+	uint64_t result;
+
+	/* Atomic add with no ordering */
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldadd %x[i], %x[r], [%[b]]"
+		     : [r] "=r"(result), "+m"(*ptr)
+		     : [i] "r"(incr), [b] "r"(ptr)
+		     : "memory");
+	return result;
+}
+
+static __plt_always_inline uint64_t
+roc_atomic64_add_sync(int64_t incr, int64_t *ptr)
+{
+	uint64_t result;
+
+	/* Atomic add with ordering */
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldadda %x[i], %x[r], [%[b]]"
+		     : [r] "=r"(result), "+m"(*ptr)
+		     : [i] "r"(incr), [b] "r"(ptr)
+		     : "memory");
+	return result;
+}
+
+static __plt_always_inline uint64_t
+roc_lmt_submit_ldeor(plt_iova_t io_address)
+{
+	uint64_t result;
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldeor xzr, %x[rf], [%[rs]]"
+		     : [rf] "=r"(result)
+		     : [rs] "r"(io_address));
+	return result;
+}
+
+static __plt_always_inline uint64_t
+roc_lmt_submit_ldeorl(plt_iova_t io_address)
+{
+	uint64_t result;
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldeorl xzr,%x[rf],[%[rs]]"
+		     : [rf] "=r"(result)
+		     : [rs] "r"(io_address));
+	return result;
+}
+
+static __plt_always_inline void
+roc_lmt_submit_steor(uint64_t data, plt_iova_t io_address)
+{
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "steor %x[d], [%[rs]]" ::[d] "r"(data),
+		     [rs] "r"(io_address));
+}
+
+static __plt_always_inline void
+roc_lmt_submit_steorl(uint64_t data, plt_iova_t io_address)
+{
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "steorl %x[d], [%[rs]]" ::[d] "r"(data),
+		     [rs] "r"(io_address));
+}
+
+static __plt_always_inline void
+roc_lmt_mov(void *out, const void *in, const uint32_t lmtext)
+{
+	volatile const __uint128_t *src128 = (const __uint128_t *)in;
+	volatile __uint128_t *dst128 = (__uint128_t *)out;
+
+	dst128[0] = src128[0];
+	dst128[1] = src128[1];
+	/* lmtext receives following value:
+	 * 1: NIX_SUBDC_EXT needed i.e. tx vlan case
+	 * 2: NIX_SUBDC_EXT + NIX_SUBDC_MEM i.e. tstamp case
+	 */
+	if (lmtext) {
+		dst128[2] = src128[2];
+		if (lmtext > 1)
+			dst128[3] = src128[3];
+	}
+}
+
+static __plt_always_inline void
+roc_lmt_mov_seg(void *out, const void *in, const uint16_t segdw)
+{
+	volatile const __uint128_t *src128 = (const __uint128_t *)in;
+	volatile __uint128_t *dst128 = (__uint128_t *)out;
+	uint8_t i;
+
+	for (i = 0; i < segdw; i++)
+		dst128[i] = src128[i];
+}
+
+static __plt_always_inline void
+roc_lmt_mov_one(void *out, const void *in)
+{
+	volatile const __uint128_t *src128 = (const __uint128_t *)in;
+	volatile __uint128_t *dst128 = (__uint128_t *)out;
+
+	*dst128 = *src128;
+}
+
+/* Non volatile version of roc_lmt_mov_seg() */
+static __plt_always_inline void
+roc_lmt_mov_seg_nv(void *out, const void *in, const uint16_t segdw)
+{
+	const __uint128_t *src128 = (const __uint128_t *)in;
+	__uint128_t *dst128 = (__uint128_t *)out;
+	uint8_t i;
+
+	for (i = 0; i < segdw; i++)
+		dst128[i] = src128[i];
+}
+
+#endif /* _ROC_IO_H_ */
diff --git a/drivers/common/cnxk/roc_io_generic.h b/drivers/common/cnxk/roc_io_generic.h
new file mode 100644
index 0000000..708c7cd
--- /dev/null
+++ b/drivers/common/cnxk/roc_io_generic.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#ifndef _ROC_IO_GENERIC_H_
+#define _ROC_IO_GENERIC_H_
+
+#define ROC_LMT_BASE_ID_GET(lmt_addr, lmt_id) (lmt_id = 0)
+
+#define roc_load_pair(val0, val1, addr)                                        \
+	do {                                                                   \
+		val0 = plt_read64((void *)(addr));                             \
+		val1 = plt_read64((uint8_t *)(addr) + 8);                      \
+	} while (0)
+
+#define roc_store_pair(val0, val1, addr)                                       \
+	do {                                                                   \
+		plt_write64(val0, (void *)(addr));                             \
+		plt_write64(val1, (((uint8_t *)(addr)) + 8));                  \
+	} while (0)
+
+#define roc_prefetch_store_keep(ptr)                                           \
+	do {                                                                   \
+	} while (0)
+
+static __plt_always_inline void
+roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, uint64_t ptr)
+{
+	PLT_SET_USED(swap0);
+	PLT_SET_USED(swap1);
+	PLT_SET_USED(ptr);
+}
+
+static __plt_always_inline uint64_t
+roc_atomic64_cas(uint64_t compare, uint64_t swap, int64_t *ptr)
+{
+	PLT_SET_USED(swap);
+	PLT_SET_USED(ptr);
+
+	return compare;
+}
+
+static inline uint64_t
+roc_atomic64_add_nosync(int64_t incr, int64_t *ptr)
+{
+	PLT_SET_USED(ptr);
+	PLT_SET_USED(incr);
+
+	return 0;
+}
+
+static inline uint64_t
+roc_atomic64_add_sync(int64_t incr, int64_t *ptr)
+{
+	PLT_SET_USED(ptr);
+	PLT_SET_USED(incr);
+
+	return 0;
+}
+
+static inline uint64_t
+roc_lmt_submit_ldeor(plt_iova_t io_address)
+{
+	PLT_SET_USED(io_address);
+
+	return 0;
+}
+
+static __plt_always_inline uint64_t
+roc_lmt_submit_ldeorl(plt_iova_t io_address)
+{
+	PLT_SET_USED(io_address);
+
+	return 0;
+}
+
+static inline void
+roc_lmt_submit_steor(uint64_t data, plt_iova_t io_address)
+{
+	PLT_SET_USED(data);
+	PLT_SET_USED(io_address);
+}
+
+static inline void
+roc_lmt_submit_steorl(uint64_t data, plt_iova_t io_address)
+{
+	PLT_SET_USED(data);
+	PLT_SET_USED(io_address);
+}
+
+static __plt_always_inline void
+roc_lmt_mov(void *out, const void *in, const uint32_t lmtext)
+{
+	PLT_SET_USED(in);
+	PLT_SET_USED(lmtext);
+	memset(out, 0, sizeof(__uint128_t) * (lmtext ? lmtext > 1 ? 4 : 3 : 2));
+}
+
+static __plt_always_inline void
+roc_lmt_mov_seg(void *out, const void *in, const uint16_t segdw)
+{
+	PLT_SET_USED(out);
+	PLT_SET_USED(in);
+	PLT_SET_USED(segdw);
+}
+
+static __plt_always_inline void
+roc_lmt_mov_one(void *out, const void *in)
+{
+	PLT_SET_USED(out);
+	PLT_SET_USED(in);
+}
+
+static __plt_always_inline void
+roc_lmt_mov_seg_nv(void *out, const void *in, const uint16_t segdw)
+{
+	PLT_SET_USED(out);
+	PLT_SET_USED(in);
+	PLT_SET_USED(segdw);
+}
+
+#endif /* _ROC_IO_GENERIC_H_ */
diff --git a/drivers/common/cnxk/roc_model.c b/drivers/common/cnxk/roc_model.c
new file mode 100644
index 0000000..c00f90d
--- /dev/null
+++ b/drivers/common/cnxk/roc_model.c
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+struct roc_model *roc_model;
+
+/* RoC and CPU IDs and revisions */
+#define VENDOR_ARM    0x41 /* 'A' */
+#define VENDOR_CAVIUM 0x43 /* 'C' */
+
+#define PART_106XX  0xD49
+#define PART_98XX   0xB1
+#define PART_96XX   0xB2
+#define PART_95XX   0xB3
+#define PART_95XXN  0xB4
+#define PART_95XXMM 0xB5
+
+#define MODEL_IMPL_BITS	  8
+#define MODEL_IMPL_SHIFT  24
+#define MODEL_IMPL_MASK	  ((1 << MODEL_IMPL_BITS) - 1)
+#define MODEL_PART_BITS	  12
+#define MODEL_PART_SHIFT  4
+#define MODEL_PART_MASK	  ((1 << MODEL_PART_BITS) - 1)
+#define MODEL_MAJOR_BITS  4
+#define MODEL_MAJOR_SHIFT 20
+#define MODEL_MAJOR_MASK  ((1 << MODEL_MAJOR_BITS) - 1)
+#define MODEL_MINOR_BITS  4
+#define MODEL_MINOR_SHIFT 0
+#define MODEL_MINOR_MASK  ((1 << MODEL_MINOR_BITS) - 1)
+
+static const struct model_db {
+	uint32_t impl;
+	uint32_t part;
+	uint32_t major;
+	uint32_t minor;
+	uint64_t flag;
+	char name[ROC_MODEL_STR_LEN_MAX];
+} model_db[] = {
+	{VENDOR_ARM, PART_106XX, 0, 0, ROC_MODEL_CN10K, "cn10k"},
+	{VENDOR_CAVIUM, PART_98XX, 0, 0, ROC_MODEL_CN98xx_A0, "cn98xx_a0"},
+	{VENDOR_CAVIUM, PART_96XX, 0, 0, ROC_MODEL_CN96xx_A0, "cn96xx_a0"},
+	{VENDOR_CAVIUM, PART_96XX, 0, 1, ROC_MODEL_CN96xx_B0, "cn96xx_b0"},
+	{VENDOR_CAVIUM, PART_96XX, 2, 0, ROC_MODEL_CN96xx_C0, "cn96xx_c0"},
+	{VENDOR_CAVIUM, PART_95XX, 0, 0, ROC_MODEL_CNF95xx_A0, "cnf95xx_a0"},
+	{VENDOR_CAVIUM, PART_95XX, 1, 0, ROC_MODEL_CNF95xx_B0, "cnf95xx_b0"},
+	{VENDOR_CAVIUM, PART_95XXN, 0, 0, ROC_MODEL_CNF95XXN_A0, "cnf95xxn_a0"},
+	{VENDOR_CAVIUM, PART_95XXMM, 0, 0, ROC_MODEL_CNF95XXMM_A0,
+	 "cnf95xxmm_a0"}
+};
+
+static bool
+populate_model(struct roc_model *model, uint32_t midr)
+{
+	uint32_t impl, major, part, minor;
+	bool found = false;
+	size_t i;
+
+	impl = (midr >> MODEL_IMPL_SHIFT) & MODEL_IMPL_MASK;
+	part = (midr >> MODEL_PART_SHIFT) & MODEL_PART_MASK;
+	major = (midr >> MODEL_MAJOR_SHIFT) & MODEL_MAJOR_MASK;
+	minor = (midr >> MODEL_MINOR_SHIFT) & MODEL_MINOR_MASK;
+
+	for (i = 0; i < PLT_DIM(model_db); i++)
+		if (model_db[i].impl == impl && model_db[i].part == part &&
+		    model_db[i].major == major && model_db[i].minor == minor) {
+			model->flag = model_db[i].flag;
+			strncpy(model->name, model_db[i].name,
+				ROC_MODEL_STR_LEN_MAX - 1);
+			found = true;
+			break;
+		}
+	if (!found) {
+		model->flag = 0;
+		strncpy(model->name, "unknown", ROC_MODEL_STR_LEN_MAX - 1);
+		plt_err("Invalid RoC model (impl=0x%x, part=0x%x)", impl, part);
+	}
+
+	return found;
+}
+
+static int
+midr_get(unsigned long *val)
+{
+	const char *file =
+		"/sys/devices/system/cpu/cpu0/regs/identification/midr_el1";
+	int rc = UTIL_ERR_FS;
+	char buf[BUFSIZ];
+	char *end = NULL;
+	FILE *f;
+
+	if (val == NULL)
+		goto err;
+	f = fopen(file, "r");
+	if (f == NULL)
+		goto err;
+
+	if (fgets(buf, sizeof(buf), f) == NULL)
+		goto fclose;
+
+	*val = strtoul(buf, &end, 0);
+	if ((buf[0] == '\0') || (end == NULL) || (*end != '\n'))
+		goto fclose;
+
+	rc = 0;
+fclose:
+	fclose(f);
+err:
+	return rc;
+}
+
+static void
+detect_invalid_config(void)
+{
+#ifdef ROC_PLATFORM_CN9K
+#ifdef ROC_PLATFORM_CN10K
+	PLT_STATIC_ASSERT(0);
+#endif
+#endif
+}
+
+int
+roc_model_init(struct roc_model *model)
+{
+	int rc = UTIL_ERR_PARAM;
+	unsigned long midr;
+
+	detect_invalid_config();
+
+	if (!model)
+		goto err;
+
+	rc = midr_get(&midr);
+	if (rc)
+		goto err;
+
+	rc = UTIL_ERR_INVALID_MODEL;
+	if (!populate_model(model, midr))
+		goto err;
+
+	rc = 0;
+	plt_info("RoC Model: %s", model->name);
+	roc_model = model;
+err:
+	return rc;
+}
diff --git a/drivers/common/cnxk/roc_model.h b/drivers/common/cnxk/roc_model.h
new file mode 100644
index 0000000..5914648
--- /dev/null
+++ b/drivers/common/cnxk/roc_model.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#ifndef _ROC_MODEL_H_
+#define _ROC_MODEL_H_
+
+#include <stdbool.h>
+
+extern struct roc_model *roc_model;
+
+struct roc_model {
+#define ROC_MODEL_CN96xx_A0    BIT_ULL(0)
+#define ROC_MODEL_CN96xx_B0    BIT_ULL(1)
+#define ROC_MODEL_CN96xx_C0    BIT_ULL(2)
+#define ROC_MODEL_CNF95xx_A0   BIT_ULL(4)
+#define ROC_MODEL_CNF95xx_B0   BIT_ULL(6)
+#define ROC_MODEL_CNF95XXMM_A0 BIT_ULL(8)
+#define ROC_MODEL_CNF95XXN_A0  BIT_ULL(12)
+#define ROC_MODEL_CN98xx_A0    BIT_ULL(16)
+#define ROC_MODEL_CN10K	       BIT_ULL(20)
+	uint64_t flag;
+#define ROC_MODEL_STR_LEN_MAX 128
+	char name[ROC_MODEL_STR_LEN_MAX];
+} __plt_cache_aligned;
+
+#define ROC_MODEL_CN96xx_Ax (ROC_MODEL_CN96xx_A0 | ROC_MODEL_CN96xx_B0)
+#define ROC_MODEL_CN9K                                                         \
+	(ROC_MODEL_CN96xx_Ax | ROC_MODEL_CN96xx_C0 | ROC_MODEL_CNF95xx_A0 |    \
+	 ROC_MODEL_CNF95xx_B0 | ROC_MODEL_CNF95XXMM_A0 |                       \
+	 ROC_MODEL_CNF95XXN_A0 | ROC_MODEL_CN98xx_A0)
+
+/* Runtime variants */
+static inline uint64_t
+roc_model_runtime_is_cn9k(void)
+{
+	return (roc_model->flag & (ROC_MODEL_CN9K));
+}
+
+static inline uint64_t
+roc_model_runtime_is_cn10k(void)
+{
+	return (roc_model->flag & (ROC_MODEL_CN10K));
+}
+
+/* Compile time variants */
+#ifdef ROC_PLATFORM_CN9K
+#define roc_model_constant_is_cn9k()  1
+#define roc_model_constant_is_cn10k() 0
+#else
+#define roc_model_constant_is_cn9k()  0
+#define roc_model_constant_is_cn10k() 1
+#endif
+
+/*
+ * Compile time variants to enable optimized version check when the library
+ * configured for specific platform version else to fallback to runtime.
+ */
+static inline uint64_t
+roc_model_is_cn9k(void)
+{
+#ifdef ROC_PLATFORM_CN9K
+	return 1;
+#endif
+#ifdef ROC_PLATFORM_CN10K
+	return 0;
+#endif
+	return roc_model_runtime_is_cn9k();
+}
+
+static inline uint64_t
+roc_model_is_cn10k(void)
+{
+#ifdef ROC_PLATFORM_CN10K
+	return 1;
+#endif
+#ifdef ROC_PLATFORM_CN9K
+	return 0;
+#endif
+	return roc_model_runtime_is_cn10k();
+}
+
+static inline uint64_t
+roc_model_is_cn96_A0(void)
+{
+	return roc_model->flag & ROC_MODEL_CN96xx_A0;
+}
+
+static inline uint64_t
+roc_model_is_cn96_Ax(void)
+{
+	return (roc_model->flag & ROC_MODEL_CN96xx_Ax);
+}
+
+static inline uint64_t
+roc_model_is_cn95_A0(void)
+{
+	return roc_model->flag & ROC_MODEL_CNF95xx_A0;
+}
+
+int roc_model_init(struct roc_model *model);
+
+#endif
diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c
index 2c8b91c..072b3e5 100644
--- a/drivers/common/cnxk/roc_platform.c
+++ b/drivers/common/cnxk/roc_platform.c
@@ -3,3 +3,24 @@
  */
 
 #include "roc_api.h"
+
+int
+plt_init(void)
+{
+	const struct rte_memzone *mz;
+
+	mz = rte_memzone_lookup(PLT_MODEL_MZ_NAME);
+	if (mz == NULL)
+		mz = rte_memzone_reserve(PLT_MODEL_MZ_NAME,
+					 sizeof(struct roc_model),
+					 SOCKET_ID_ANY, 0);
+	else
+		return 0;
+
+	if (mz == NULL) {
+		plt_err("Failed to allocate memory for roc_model");
+		return -ENOMEM;
+	}
+	roc_model_init(mz->addr);
+	return 0;
+}
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 575a6ac..7477613 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -123,6 +123,13 @@
 
 #define plt_strlcpy rte_strlcpy
 
+/* Log */
+#define plt_err(fmt, args...)                                                  \
+	RTE_LOG(ERR, PMD, "%s():%u " fmt "\n", __func__, __LINE__, ##args)
+#define plt_info(fmt, args...) RTE_LOG(INFO, PMD, fmt "\n", ##args)
+#define plt_warn(fmt, args...) RTE_LOG(WARNING, PMD, fmt "\n", ##args)
+#define plt_print(fmt, args...) RTE_LOG(INFO, PMD, fmt "\n", ##args)
+
 #ifdef __cplusplus
 #define CNXK_PCI_ID(subsystem_dev, dev)				\
 	{							\
@@ -143,4 +150,7 @@
 	}
 #endif
 
+__rte_internal
+int plt_init(void);
+
 #endif /* _ROC_PLATFORM_H_ */
diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h
new file mode 100644
index 0000000..be37c6c
--- /dev/null
+++ b/drivers/common/cnxk/roc_priv.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#ifndef _ROC_PRIV_H_
+#define _ROC_PRIV_H_
+
+/* Utils */
+#include "roc_util_priv.h"
+
+#endif /* _ROC_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_util_priv.h b/drivers/common/cnxk/roc_util_priv.h
new file mode 100644
index 0000000..f140967
--- /dev/null
+++ b/drivers/common/cnxk/roc_util_priv.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#ifndef _ROC_UTIL_PRIV_H_
+#define _ROC_UTIL_PRIV_H_
+
+enum util_err_status {
+	UTIL_ERR_PARAM = -6000,
+	UTIL_ERR_FS,
+	UTIL_ERR_INVALID_MODEL,
+};
+
+#endif /* _ROC_UTIL_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_utils.c b/drivers/common/cnxk/roc_utils.c
new file mode 100644
index 0000000..bcba7b2
--- /dev/null
+++ b/drivers/common/cnxk/roc_utils.c
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+const char *
+roc_error_msg_get(int errorcode)
+{
+	const char *err_msg;
+
+	switch (errorcode) {
+	case UTIL_ERR_PARAM:
+		err_msg = "Invalid parameter";
+		break;
+	case UTIL_ERR_FS:
+		err_msg = "file operation failed";
+		break;
+	case UTIL_ERR_INVALID_MODEL:
+		err_msg = "Invalid RoC model";
+		break;
+	default:
+		/**
+		 * Handle general error (as defined in linux errno.h)
+		 */
+		if (abs(errorcode) < 300)
+			err_msg = strerror(abs(errorcode));
+		else
+			err_msg = "Unknown error code";
+		break;
+	}
+
+	return err_msg;
+}
diff --git a/drivers/common/cnxk/roc_utils.h b/drivers/common/cnxk/roc_utils.h
new file mode 100644
index 0000000..7b607a5
--- /dev/null
+++ b/drivers/common/cnxk/roc_utils.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#ifndef _ROC_UTILS_H_
+#define _ROC_UTILS_H_
+
+#include "roc_platform.h"
+
+/* Utils */
+const char *__roc_api roc_error_msg_get(int errorcode);
+
+#endif /* _ROC_UTILS_H_ */
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index dc012a1..227f2ce 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -1,4 +1,9 @@
 INTERNAL {
+	global:
+
+	plt_init;
+	roc_error_msg_get;
+	roc_model;
 
 	local: *;
 };
