diff --git a/platform/linux-keystone2/include/odp_shared_memory_internal.h b/platform/linux-keystone2/include/odp_shared_memory_internal.h
new file mode 100644
index 0000000..833091e
--- /dev/null
+++ b/platform/linux-keystone2/include/odp_shared_memory_internal.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP shared memory internal
+ */
+
+#ifndef ODP_SHARED_MEMORY_INTERNAL_H_
+#define ODP_SHARED_MEMORY_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *_odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
+		       int type);
+uintptr_t _odp_shm_get_paddr(void *vaddr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-keystone2/source/odp_shared_memory.c b/platform/linux-keystone2/source/odp_shared_memory.c
index 8288b46..e595111 100644
--- a/platform/linux-keystone2/source/odp_shared_memory.c
+++ b/platform/linux-keystone2/source/odp_shared_memory.c
@@ -5,6 +5,7 @@
  */
 
 #include <odp_shared_memory.h>
+#include <odp_shared_memory_internal.h>
 #include <odp_internal.h>
 #include <odp_spinlock.h>
 #include <odp_align.h>
@@ -20,6 +21,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <ti_em_rh.h>
 
 #define ODP_SHM_NUM_BLOCKS 32
 
@@ -28,10 +30,9 @@ typedef struct {
 	char name[ODP_SHM_NAME_LEN];
 	uint64_t size;
 	uint64_t align;
-	void *addr_orig;
 	void *addr;
 	int huge;
-
+	ti_em_rh_mem_config_t mem_config;
 } odp_shm_block_t;
 
 
@@ -92,14 +93,19 @@ static int find_block(const char *name)
 	return -1;
 }
 
+enum {
+	ODP_SHM_MMAP,
+	ODP_SHM_CMA
+};
 
-void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align)
+void *_odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
+		       int type)
 {
 	int i;
 	odp_shm_block_t *block;
-	void *addr;
 #ifdef MAP_HUGETLB
 	uint64_t huge_sz, page_sz;
+	ti_em_rh_mem_config_t mem_config = {0};
 
 	huge_sz = odp_sys_huge_page_size();
 	page_sz = odp_sys_page_size();
@@ -128,47 +134,100 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align)
 
 	block = &odp_shm_tbl->block[i];
 
-	addr        = MAP_FAILED;
-	block->huge = 0;
+	/* Allocate memory */
+	mem_config.size = size + align;
+	mem_config.flags = TI_EM_OSAL_MEM_CACHED;
+	/*
+	 * alloc free mapping id.
+	 * FIXME: mapping_id is uint32_t.
+	 */
+	mem_config.mapping_id = -1;
+
+	if (type == ODP_SHM_CMA) {
+		ti_em_rh_alloc_map_cma(&mem_config);
+
+		if (!mem_config.vaddr) {
+			/* Alloc failed */
+			odp_spinlock_unlock(&odp_shm_tbl->lock);
+			ODP_ERR("%s: failed to allocate block: %-24s %4"PRIu64"  %4"PRIu64"\n",
+				__func__,
+				name,
+				size,
+				align);
+			return NULL;
+		}
+
+	} else if (type == ODP_SHM_MMAP) {
+		void *addr = MAP_FAILED;
+		block->huge = 0;
 
 #ifdef MAP_HUGETLB
-	/* Try first huge pages */
-	if (huge_sz && (size + align) > page_sz) {
-		addr = mmap(NULL, size + align, PROT_READ | PROT_WRITE,
-			    SHM_FLAGS | MAP_HUGETLB, -1, 0);
-	}
+		/* Try first huge pages */
+		if (huge_sz && (size + align) > page_sz) {
+			addr = mmap(NULL, size + align, PROT_READ | PROT_WRITE,
+				    SHM_FLAGS | MAP_HUGETLB, -1, 0);
+		}
 #endif
 
-	/* Use normal pages for small or failed huge page allocations */
-	if (addr == MAP_FAILED) {
-		addr = mmap(NULL, size + align, PROT_READ | PROT_WRITE,
-			    SHM_FLAGS, -1, 0);
+		/* Use normal pages for small or failed huge page allocations */
+		if (addr == MAP_FAILED) {
+			addr = mmap(NULL, size + align, PROT_READ | PROT_WRITE,
+				    SHM_FLAGS, -1, 0);
+		} else {
+			block->huge = 1;
+		}
 
+		if (addr == MAP_FAILED) {
+			/* Alloc failed */
+			odp_spinlock_unlock(&odp_shm_tbl->lock);
+			return NULL;
+		}
+		mem_config.vaddr = (uintptr_t)addr;
 	} else {
-		block->huge = 1;
-	}
-
-	if (addr == MAP_FAILED) {
-		/* Alloc failed */
-		odp_spinlock_unlock(&odp_shm_tbl->lock);
-		return NULL;
+		ODP_ERR("Unknown shared memory type: %d\n", type);
 	}
 
-	block->addr_orig = addr;
+	block->mem_config = mem_config;
 
 	/* move to correct alignment */
-	addr = ODP_ALIGN_ROUNDUP_PTR(addr, align);
+	block->addr = ODP_ALIGN_ROUNDUP_PTR(mem_config.vaddr, align);
 
 	strncpy(block->name, name, ODP_SHM_NAME_LEN - 1);
 	block->name[ODP_SHM_NAME_LEN - 1] = 0;
 	block->size   = size;
 	block->align  = align;
-	block->addr   = addr;
 
 	odp_spinlock_unlock(&odp_shm_tbl->lock);
-	return addr;
+	ODP_DBG("%s: reserved block: %-24s %4"PRIu64"  %4"PRIu64" %p\n",
+		__func__,
+		block->name,
+		block->size,
+		block->align,
+		block->addr);
+
+	return block->addr;
+}
+
+void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align)
+{
+	return _odp_shm_reserve(name, size, align, ODP_SHM_CMA);
 }
 
+uintptr_t _odp_shm_get_paddr(void *vaddr)
+{
+	int i;
+	uintptr_t addr = (uintptr_t)vaddr;
+	for (i = 0; i < ODP_SHM_NUM_BLOCKS; i++) {
+		ti_em_rh_mem_config_t *mem = &odp_shm_tbl->block[i].mem_config;
+		if (mem->vaddr == 0)
+			continue;
+		if ((mem->vaddr <= addr) && (addr < mem->vaddr + mem->size)) {
+			addr = (uintptr_t)odp_shm_tbl->block[i].addr;
+			return (addr - mem->vaddr) + mem->paddr;
+		}
+	}
+	return 0;
+}
 
 void *odp_shm_lookup(const char *name)
 {
@@ -202,7 +261,7 @@ void odp_shm_print_all(void)
 	       odp_sys_huge_page_size() / 1024);
 	printf("\n");
 
-	printf("  id name                       kB align huge addr\n");
+	printf("  id name                       kB align huge addr        paddr\n");
 
 	for (i = 0; i < ODP_SHM_NUM_BLOCKS; i++) {
 		odp_shm_block_t *block;
@@ -210,13 +269,14 @@ void odp_shm_print_all(void)
 		block = &odp_shm_tbl->block[i];
 
 		if (block->addr) {
-			printf("  %2i %-24s %4"PRIu64"  %4"PRIu64" %2c   %p\n",
+			printf("  %2i %-24s %4"PRIu64"  %4"PRIu64" %2c   %p  0x%08x\n",
 			       i,
 			       block->name,
 			       block->size/1024,
 			       block->align,
 			       (block->huge ? '*' : ' '),
-			       block->addr);
+			       block->addr,
+			       block->mem_config.paddr);
 		}
 	}
 
