incubator-nuttx/openamp/0006-remoteproc_mmap-suppor...

781 lines
24 KiB
Diff

From 27026fc4c781a9dbd328059884b9b94ff39ad6b9 Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Fri, 15 Mar 2019 01:51:03 +0800
Subject: [PATCH 06/10] remoteproc_mmap support va to pa/da conversion
1.change va from output to input/output
2.remoteproc_get_io_xxx fallback to mmap callback
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
.../load_fw/zynqmp_r5_lcm_rproc_example.c | 69 +++++------
apps/machine/zynq7/platform_info.c | 16 +--
apps/machine/zynq7/zynq_a9_rproc.c | 40 ++++---
apps/machine/zynqmp/platform_info.c | 6 +-
apps/machine/zynqmp/zynqmp_linux_r5_proc.c | 40 ++++---
apps/machine/zynqmp_r5/platform_info.c | 16 +--
apps/machine/zynqmp_r5/zynqmp_r5_a53_rproc.c | 38 +++----
.../linux/machine/generic/platform_info.c | 52 +++++----
lib/include/openamp/remoteproc.h | 19 ++--
lib/remoteproc/remoteproc.c | 107 ++++++++++--------
lib/remoteproc/rsc_table_parser.c | 2 +-
11 files changed, 209 insertions(+), 196 deletions(-)
diff --git a/apps/examples/load_fw/zynqmp_r5_lcm_rproc_example.c open-amp/apps/examples/load_fw/zynqmp_r5_lcm_rproc_example.c
index 26a09e5..e224631 100644
--- a/apps/examples/load_fw/zynqmp_r5_lcm_rproc_example.c
+++ open-amp/apps/examples/load_fw/zynqmp_r5_lcm_rproc_example.c
@@ -137,86 +137,79 @@ void r5_rproc_remove(struct remoteproc *rproc)
}
}
-void *r5_rproc_mmap(struct remoteproc *rproc,
- metal_phys_addr_t *pa, metal_phys_addr_t *da,
- size_t size, unsigned int attribute,
- struct metal_io_region **io)
+int r5_rproc_mmap(struct remoteproc *rproc,
+ metal_phys_addr_t *pa, metal_phys_addr_t *da,
+ void **va, size_t size, unsigned int attribute,
+ struct metal_io_region **io)
{
struct remoteproc_mem *mem;
+ struct metal_io_region *tmpio;
struct r5_rproc_priv *priv;
- metal_phys_addr_t lpa, lda;
priv = rproc->priv;
- if (!da || !pa)
- return NULL;
LPRINTF("%s: pa=0x%x, da=0x%x, size=0x%x, atrribute=0x%x\r\n",
__func__, *pa, *da, size, attribute);
- lda = *da;
- lpa = *pa;
if (!attribute)
attribute = NORM_SHARED_NCACHE | PRIV_RW_USER_RW;
- if (lda <= 0x40000) {
+ if (*da <= 0x40000) {
metal_phys_addr_t lda_end;
- lda_end = lda + size;
+ lda_end = *da + size;
if (priv->cpu_id == NODE_RPU_0 || priv->cpu_id == NODE_RPU) {
- lpa = 0xFFE00000 + lda;
- if (lda < 0x10000)
+ *pa = 0xFFE00000 + *da;
+ if (*da < 0x10000)
XPm_RequestNode(NODE_TCM_0_A,
PM_CAP_ACCESS, 0,
REQUEST_ACK_BLOCKING);
- if (lda <= 0x20000 && lda_end >= 0x10000)
+ if (*da <= 0x20000 && lda_end >= 0x10000)
XPm_RequestNode(NODE_TCM_1_A,
PM_CAP_ACCESS, 0,
REQUEST_ACK_BLOCKING);
- if (lda <= 0x30000 && lda_end >= 0x20000)
+ if (*da <= 0x30000 && lda_end >= 0x20000)
XPm_RequestNode(NODE_TCM_0_B,
PM_CAP_ACCESS, 0,
REQUEST_ACK_BLOCKING);
- if (lda <= 0x40000 && lda_end >= 0x30000)
+ if (*da <= 0x40000 && lda_end >= 0x30000)
XPm_RequestNode(NODE_TCM_1_B,
PM_CAP_ACCESS, 0,
REQUEST_ACK_BLOCKING);
} else if (priv->cpu_id == NODE_RPU_1) {
- lpa = 0xFFE90000 + lda;
- if (lda < 0x10000)
+ *pa = 0xFFE90000 + *da;
+ if (*da < 0x10000)
XPm_RequestNode(NODE_TCM_1_A,
PM_CAP_ACCESS, 0,
REQUEST_ACK_BLOCKING);
- if (lda <= 0x30000 && lda_end >= 0x20000)
+ if (*da <= 0x30000 && lda_end >= 0x20000)
XPm_RequestNode(NODE_TCM_1_B,
PM_CAP_ACCESS, 0,
REQUEST_ACK_BLOCKING);
} else {
LPERROR("mmap failed: invalid cpu node: %d\r\n",
priv->cpu_id);
- return NULL;
+ return -RPROC_EINVAL;
}
}
- if (lpa == METAL_BAD_PHYS)
- lpa = lda;
- if (lpa == METAL_BAD_PHYS)
- return NULL;
+ if (*pa == METAL_BAD_PHYS)
+ *pa = *da;
+ if (*pa == METAL_BAD_PHYS)
+ return -RPROC_EINVAL;
mem = metal_allocate_memory(sizeof(*mem));
if (!mem)
- return NULL;
- mem->pa = lpa;
- mem->da = lda;
-
- *io = metal_allocate_memory(sizeof(struct metal_io_region));
- if (!*io) {
+ return -RPROC_ENOMEM;
+ tmpio = metal_allocate_memory(sizeof(struct metal_io_region));
+ if (!tmpio) {
metal_free_memory(mem);
- return NULL;
+ return -RPROC_ENOMEM;
}
- metal_io_init(*io, (void *)mem->pa, &mem->pa, size,
+ remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio);
+ metal_io_init(tmpio, (void *)mem->pa, &mem->pa, size,
sizeof(metal_phys_addr_t)<<3, attribute, NULL);
- mem->io = *io;
- metal_list_add_tail(&rproc->mems, &mem->node);
- *pa = lpa;
- *da = lda;
- mem->size = size;
- return metal_io_phys_to_virt(*io, mem->pa);
+ remoteproc_add_mem(rproc, mem);
+ *va = metal_io_phys_to_virt(tmpio, mem->pa);
+ if (io)
+ *io = tmpio;
+ return 0;
}
int r5_rproc_start(struct remoteproc *rproc)
diff --git a/apps/machine/zynq7/platform_info.c open-amp/apps/machine/zynq7/platform_info.c
index d753e0e..7885b31 100644
--- a/apps/machine/zynq7/platform_info.c
+++ open-amp/apps/machine/zynq7/platform_info.c
@@ -108,16 +108,16 @@ platform_create_proc(int proc_index, int rsc_index)
*/
/* mmap resource table */
pa = (metal_phys_addr_t)rsc_table;
- (void *)remoteproc_mmap(&rproc_inst, &pa,
- NULL, rsc_size,
- NORM_NONCACHE | STRONG_ORDERED,
- &rproc_inst.rsc_io);
+ remoteproc_mmap(&rproc_inst, &pa,
+ NULL, NULL, rsc_size,
+ NORM_NONCACHE | STRONG_ORDERED,
+ &rproc_inst.rsc_io);
/* mmap shared memory */
pa = SHARED_MEM_PA;
- (void *)remoteproc_mmap(&rproc_inst, &pa,
- NULL, SHARED_MEM_SIZE,
- NORM_NONCACHE | STRONG_ORDERED,
- NULL);
+ remoteproc_mmap(&rproc_inst, &pa,
+ NULL, NULL, SHARED_MEM_SIZE,
+ NORM_NONCACHE | STRONG_ORDERED,
+ NULL);
/* parse resource table to remoteproc */
ret = remoteproc_set_rsc_table(&rproc_inst, rsc_table, rsc_size);
diff --git a/apps/machine/zynq7/zynq_a9_rproc.c open-amp/apps/machine/zynq7/zynq_a9_rproc.c
index f830749..ad7cd49 100644
--- a/apps/machine/zynq7/zynq_a9_rproc.c
+++ open-amp/apps/machine/zynq7/zynq_a9_rproc.c
@@ -94,45 +94,43 @@ static void zynq_a9_proc_remove(struct remoteproc *rproc)
metal_device_close(dev);
}
-static void *
+static int
zynq_a9_proc_mmap(struct remoteproc *rproc, metal_phys_addr_t *pa,
- metal_phys_addr_t *da, size_t size,
- unsigned int attribute, struct metal_io_region **io)
+ metal_phys_addr_t *da, void **va, size_t size,
+ unsigned int attribute, struct metal_io_region **io)
{
struct remoteproc_mem *mem;
- metal_phys_addr_t lpa, lda;
struct metal_io_region *tmpio;
- lpa = *pa;
- lda = *da;
-
- if (lpa == METAL_BAD_PHYS && lda == METAL_BAD_PHYS)
- return NULL;
- if (lpa == METAL_BAD_PHYS)
- lpa = lda;
- if (lda == METAL_BAD_PHYS)
- lda = lpa;
+ /* va is the same as pa/da in this platform */
+ if (*pa != METAL_BAD_PHYS) {
+ *da = *pa;
+ *va = (void *)*pa;
+ } else if (*da != METAL_BAD_PHYS) {
+ *pa = *da;
+ *va = (void *)*da;
+ } else if (*va)
+ *pa = *da = (metal_phys_addr_t)*va;
+ else
+ return -RPROC_EINVAL;
if (!attribute)
attribute = NORM_NONCACHE | STRONG_ORDERED;
mem = metal_allocate_memory(sizeof(*mem));
if (!mem)
- return NULL;
+ return -RPROC_ENOMEM;
tmpio = metal_allocate_memory(sizeof(*tmpio));
if (!tmpio) {
metal_free_memory(mem);
- return NULL;
+ return -RPROC_ENOMEM;
}
- remoteproc_init_mem(mem, NULL, lpa, lda, size, tmpio);
- /* va is the same as pa in this platform */
- metal_io_init(tmpio, (void *)lpa, &mem->pa, size,
+ remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio);
+ metal_io_init(tmpio, *va, &mem->pa, size,
sizeof(metal_phys_addr_t)<<3, attribute, NULL);
remoteproc_add_mem(rproc, mem);
- *pa = lpa;
- *da = lda;
if (io)
*io = tmpio;
- return metal_io_phys_to_virt(tmpio, mem->pa);
+ return 0;
}
static int zynq_a9_proc_notify(struct remoteproc *rproc, uint32_t id)
diff --git a/apps/machine/zynqmp/platform_info.c open-amp/apps/machine/zynqmp/platform_info.c
index 3081ec9..17abcc5 100644
--- a/apps/machine/zynqmp/platform_info.c
+++ open-amp/apps/machine/zynqmp/platform_info.c
@@ -84,7 +84,7 @@ static struct rpmsg_virtio_shm_pool shpool;
static struct remoteproc *
platform_create_proc(int proc_index, int rsc_index)
{
- void *rsc_table;
+ void *rsc_table = NULL;
int rsc_size;
int ret;
metal_phys_addr_t pa;
@@ -102,8 +102,8 @@ platform_create_proc(int proc_index, int rsc_index)
/* Mmap resource table */
pa = RSC_MEM_PA;
printf("Calling mmap resource table.\r\n");
- rsc_table = remoteproc_mmap(&rproc_inst, &pa, NULL, rsc_size,
- 0, NULL);
+ remoteproc_mmap(&rproc_inst, &pa, NULL, &rsc_table, rsc_size,
+ 0, NULL);
if (!rsc_table) {
fprintf(stderr, "ERROR: Failed to mmap resource table.\r\n");
return NULL;
diff --git a/apps/machine/zynqmp/zynqmp_linux_r5_proc.c open-amp/apps/machine/zynqmp/zynqmp_linux_r5_proc.c
index 2e4df9d..0950d0b 100644
--- a/apps/machine/zynqmp/zynqmp_linux_r5_proc.c
+++ open-amp/apps/machine/zynqmp/zynqmp_linux_r5_proc.c
@@ -143,38 +143,44 @@ static void zynqmp_linux_r5_proc_remove(struct remoteproc *rproc)
metal_device_close(prproc->shm_dev);
}
-static void *
+static int
zynqmp_linux_r5_proc_mmap(struct remoteproc *rproc, metal_phys_addr_t *pa,
- metal_phys_addr_t *da, size_t size,
- unsigned int attribute, struct metal_io_region **io)
+ metal_phys_addr_t *da, void **va, size_t size,
+ unsigned int attribute, struct metal_io_region **io)
{
struct remoteproc_priv *prproc;
- metal_phys_addr_t lpa, lda;
struct metal_io_region *tmpio;
(void)attribute;
(void)size;
if (!rproc)
- return NULL;
+ return -RPROC_EINVAL;
prproc = rproc->priv;
- lpa = *pa;
- lda = *da;
- if (lpa == METAL_BAD_PHYS && lda == METAL_BAD_PHYS)
- return NULL;
- if (lpa == METAL_BAD_PHYS)
- lpa = lda;
- if (lda == METAL_BAD_PHYS)
- lda = lpa;
tmpio = prproc->shm_io;
if (!tmpio)
- return NULL;
+ return -RPROC_EINVAL;
+
+ if (*pa != METAL_BAD_PHYS) {
+ *da = *pa;
+ *va = metal_io_phys_to_virt(tmpio, *pa);
+ if (!*va)
+ return -RPROC_EINVAL;
+ } else if (*da != METAL_BAD_PHYS) {
+ *pa = *da;
+ *va = metal_io_phys_to_virt(tmpio, *da);
+ if (!*va)
+ return -RPROC_EINVAL;
+ } else if (*va) {
+ *pa = *da = metal_io_virt_to_phys(tmpio, *va);
+ if (*pa == METAL_BAD_PHYS)
+ return -RPROC_EINVAL;
+ } else
+ return -RPROC_EINVAL;
- *pa = lpa;
- *da = lda;
if (io)
*io = tmpio;
- return metal_io_phys_to_virt(tmpio, lpa);
+ return 0;
}
static int zynqmp_linux_r5_proc_notify(struct remoteproc *rproc, uint32_t id)
diff --git a/apps/machine/zynqmp_r5/platform_info.c open-amp/apps/machine/zynqmp_r5/platform_info.c
index 96c03c9..a2f7d9d 100644
--- a/apps/machine/zynqmp_r5/platform_info.c
+++ open-amp/apps/machine/zynqmp_r5/platform_info.c
@@ -114,16 +114,16 @@ platform_create_proc(int proc_index, int rsc_index)
*/
/* mmap resource table */
pa = (metal_phys_addr_t)rsc_table;
- (void *)remoteproc_mmap(&rproc_inst, &pa,
- NULL, rsc_size,
- NORM_NSHARED_NCACHE|PRIV_RW_USER_RW,
- &rproc_inst.rsc_io);
+ remoteproc_mmap(&rproc_inst, &pa,
+ NULL, NULL, rsc_size,
+ NORM_NSHARED_NCACHE|PRIV_RW_USER_RW,
+ &rproc_inst.rsc_io);
/* mmap shared memory */
pa = SHARED_MEM_PA;
- (void *)remoteproc_mmap(&rproc_inst, &pa,
- NULL, SHARED_MEM_SIZE,
- NORM_NSHARED_NCACHE|PRIV_RW_USER_RW,
- NULL);
+ remoteproc_mmap(&rproc_inst, &pa,
+ NULL, NULL, SHARED_MEM_SIZE,
+ NORM_NSHARED_NCACHE|PRIV_RW_USER_RW,
+ NULL);
/* parse resource table to remoteproc */
ret = remoteproc_set_rsc_table(&rproc_inst, rsc_table, rsc_size);
diff --git a/apps/machine/zynqmp_r5/zynqmp_r5_a53_rproc.c open-amp/apps/machine/zynqmp_r5/zynqmp_r5_a53_rproc.c
index ee25368..ef5299c 100644
--- a/apps/machine/zynqmp_r5/zynqmp_r5_a53_rproc.c
+++ open-amp/apps/machine/zynqmp_r5/zynqmp_r5_a53_rproc.c
@@ -109,45 +109,43 @@ static void zynqmp_r5_a53_proc_remove(struct remoteproc *rproc)
}
}
-static void *
+static int
zynqmp_r5_a53_proc_mmap(struct remoteproc *rproc, metal_phys_addr_t *pa,
- metal_phys_addr_t *da, size_t size,
+ metal_phys_addr_t *da, void **va, size_t size,
unsigned int attribute, struct metal_io_region **io)
{
struct remoteproc_mem *mem;
- metal_phys_addr_t lpa, lda;
struct metal_io_region *tmpio;
- lpa = *pa;
- lda = *da;
-
- if (lpa == METAL_BAD_PHYS && lda == METAL_BAD_PHYS)
- return NULL;
- if (lpa == METAL_BAD_PHYS)
- lpa = lda;
- if (lda == METAL_BAD_PHYS)
- lda = lpa;
+ /* va is the same as pa/da in this platform */
+ if (*pa != METAL_BAD_PHYS) {
+ *da = *pa;
+ *va = (void *)*pa;
+ } else if (*da != METAL_BAD_PHYS) {
+ *pa = *da;
+ *va = (void *)*da;
+ } else if (*va)
+ *pa = *da = (metal_phys_addr_t)*va;
+ else
+ return -RPROC_EINVAL;
if (!attribute)
attribute = NORM_SHARED_NCACHE | PRIV_RW_USER_RW;
mem = metal_allocate_memory(sizeof(*mem));
if (!mem)
- return NULL;
+ return -RPROC_ENOMEM;
tmpio = metal_allocate_memory(sizeof(*tmpio));
if (!tmpio) {
metal_free_memory(mem);
- return NULL;
+ return -RPROC_ENOMEM;
}
- remoteproc_init_mem(mem, NULL, lpa, lda, size, tmpio);
- /* va is the same as pa in this platform */
- metal_io_init(tmpio, (void *)lpa, &mem->pa, size,
+ remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio);
+ metal_io_init(tmpio, *va, &mem->pa, size,
sizeof(metal_phys_addr_t)<<3, attribute, NULL);
remoteproc_add_mem(rproc, mem);
- *pa = lpa;
- *da = lda;
if (io)
*io = tmpio;
- return metal_io_phys_to_virt(tmpio, mem->pa);
+ return 0;
}
static int zynqmp_r5_a53_proc_notify(struct remoteproc *rproc, uint32_t id)
diff --git a/apps/system/linux/machine/generic/platform_info.c open-amp/apps/system/linux/machine/generic/platform_info.c
index 0b0f721..748fd83 100644
--- a/apps/system/linux/machine/generic/platform_info.c
+++ open-amp/apps/system/linux/machine/generic/platform_info.c
@@ -300,39 +300,43 @@ static void linux_proc_remove(struct remoteproc *rproc)
}
}
-static void *
+static int
linux_proc_mmap(struct remoteproc *rproc, metal_phys_addr_t *pa,
- metal_phys_addr_t *da, size_t size,
+ metal_phys_addr_t *da, void **va, size_t size,
unsigned int attribute, struct metal_io_region **io)
{
struct remoteproc_mem *mem;
struct remoteproc_priv *prproc;
- metal_phys_addr_t lpa, lda;
- void *va;
(void)attribute;
(void)size;
- lpa = *pa;
- lda = *da;
-
- if (lpa == METAL_BAD_PHYS && lda == METAL_BAD_PHYS)
- return NULL;
- if (lpa == METAL_BAD_PHYS)
- lpa = lda;
- if (lda == METAL_BAD_PHYS)
- lda = lpa;
if (!rproc)
- return NULL;
+ return -RPROC_EINVAL;
prproc = rproc->priv;
mem = &prproc->shm;
- va = metal_io_phys_to_virt(mem->io, lpa);
- if (va) {
- if (io)
- *io = mem->io;
- metal_list_add_tail(&rproc->mems, &mem->node);
- }
- return va;
+
+ if (*pa != METAL_BAD_PHYS) {
+ *da = *pa;
+ *va = metal_io_phys_to_virt(mem->io, *pa);
+ if (!*va)
+ return -RPROC_EINVAL;
+ } else if (*da != METAL_BAD_PHYS) {
+ *pa = *da;
+ *va = metal_io_phys_to_virt(mem->io, *da);
+ if (!*va)
+ return -RPROC_EINVAL;
+ } else if (*va) {
+ *pa = *da = metal_io_virt_to_phys(mem->io, *va);
+ if (*pa == METAL_BAD_PHYS)
+ return -RPROC_EINVAL;
+ } else
+ return -RPROC_EINVAL;
+
+ remoteproc_add_mem(rproc, mem);
+ if (io)
+ *io = mem->io;
+ return 0;
}
static int linux_proc_notify(struct remoteproc *rproc, uint32_t id)
@@ -391,7 +395,7 @@ static struct remoteproc *
platform_create_proc(int proc_index, int rsc_index)
{
struct remoteproc_priv *prproc;
- void *rsc_table, *rsc_table_shm;
+ void *rsc_table, *rsc_table_shm = NULL;
int rsc_size;
int ret;
metal_phys_addr_t pa;
@@ -420,8 +424,8 @@ platform_create_proc(int proc_index, int rsc_index)
/* Mmap resource table */
pa = RSC_MEM_PA;
- rsc_table_shm = remoteproc_mmap(&rproc_inst, &pa, NULL, rsc_size,
- 0, &rproc_inst.rsc_io);
+ remoteproc_mmap(&rproc_inst, &pa, NULL, &rsc_table_shm, rsc_size,
+ 0, &rproc_inst.rsc_io);
/* parse resource table to remoteproc */
ret = remoteproc_set_rsc_table(&rproc_inst, rsc_table_shm, rsc_size);
diff --git a/lib/include/openamp/remoteproc.h open-amp/lib/include/openamp/remoteproc.h
index a83aa12..b34cb1a 100644
--- a/lib/include/openamp/remoteproc.h
+++ open-amp/lib/include/openamp/remoteproc.h
@@ -400,10 +400,10 @@ struct remoteproc_ops {
struct remoteproc *(*init)(struct remoteproc *rproc,
struct remoteproc_ops *ops, void *arg);
void (*remove)(struct remoteproc *rproc);
- void *(*mmap)(struct remoteproc *rproc,
- metal_phys_addr_t *pa, metal_phys_addr_t *da,
- size_t size, unsigned int attribute,
- struct metal_io_region **io);
+ int (*mmap)(struct remoteproc *rproc,
+ metal_phys_addr_t *pa, metal_phys_addr_t *da,
+ void **va, size_t size, unsigned int attribute,
+ struct metal_io_region **io);
int (*handle_rsc)(struct remoteproc *rproc, void *rsc, size_t len);
int (*config)(struct remoteproc *rproc, void *data);
int (*start)(struct remoteproc *rproc);
@@ -606,16 +606,17 @@ remoteproc_get_io_with_va(struct remoteproc *rproc,
* @rproc - pointer to the remote processor
* @pa - physical address pointer
* @da - device address pointer
+ * @va - virtual address pointer
* @size - size of the memory
* @attribute - memory attribute
* @io - pointer to the I/O region
*
- * returns pointer to the memory
+ * returns 0 for success and negative value for errors
*/
-void *remoteproc_mmap(struct remoteproc *rproc,
- metal_phys_addr_t *pa, metal_phys_addr_t *da,
- size_t size, unsigned int attribute,
- struct metal_io_region **io);
+int remoteproc_mmap(struct remoteproc *rproc,
+ metal_phys_addr_t *pa, metal_phys_addr_t *da,
+ void **va, size_t size, unsigned int attribute,
+ struct metal_io_region **io);
/**
* remoteproc_set_rsc_table
diff --git a/lib/remoteproc/remoteproc.c open-amp/lib/remoteproc/remoteproc.c
index 5afb40c..34b8cb8 100644
--- a/lib/remoteproc/remoteproc.c
+++ open-amp/lib/remoteproc/remoteproc.c
@@ -295,13 +295,14 @@ struct metal_io_region *
remoteproc_get_io_with_pa(struct remoteproc *rproc,
metal_phys_addr_t pa)
{
- struct remoteproc_mem *mem;
+ struct metal_io_region *io;
+ int ret;
- mem = remoteproc_get_mem(rproc, NULL, pa, METAL_BAD_PHYS, NULL, 0);
- if (mem)
- return mem->io;
- else
+ ret = remoteproc_mmap(rproc, &pa, NULL, NULL, 0, 0, &io);
+ if (ret < 0)
return NULL;
+
+ return io;
}
struct metal_io_region *
@@ -309,48 +310,44 @@ remoteproc_get_io_with_da(struct remoteproc *rproc,
metal_phys_addr_t da,
unsigned long *offset)
{
- struct remoteproc_mem *mem;
-
- mem = remoteproc_get_mem(rproc, NULL, METAL_BAD_PHYS, da, NULL, 0);
- if (mem) {
- struct metal_io_region *io;
- metal_phys_addr_t pa;
+ struct metal_io_region *io;
+ metal_phys_addr_t pa = METAL_BAD_PHYS;
+ int ret;
- io = mem->io;
- pa = remoteproc_datopa(mem, da);
- *offset = metal_io_phys_to_offset(io, pa);
- return io;
- } else {
+ ret = remoteproc_mmap(rproc, &pa, &da, NULL, 0, 0, &io);
+ if (ret < 0)
return NULL;
- }
+
+ *offset = metal_io_phys_to_offset(io, pa);
+ return io;
}
struct metal_io_region *
remoteproc_get_io_with_va(struct remoteproc *rproc, void *va)
{
- struct remoteproc_mem *mem;
+ struct metal_io_region *io;
+ int ret;
- mem = remoteproc_get_mem(rproc, NULL, METAL_BAD_PHYS, METAL_BAD_PHYS,
- va, 0);
- if (mem)
- return mem->io;
- else
+ ret = remoteproc_mmap(rproc, NULL, NULL, &va, 0, 0, &io);
+ if (ret < 0)
return NULL;
+
+ return io;
}
-void *remoteproc_mmap(struct remoteproc *rproc,
- metal_phys_addr_t *pa, metal_phys_addr_t *da,
- size_t size, unsigned int attribute,
- struct metal_io_region **io)
+int remoteproc_mmap(struct remoteproc *rproc,
+ metal_phys_addr_t *pa, metal_phys_addr_t *da,
+ void **va, size_t size, unsigned int attribute,
+ struct metal_io_region **io)
{
- void *va = NULL;
+ void *lva = NULL;
metal_phys_addr_t lpa, lda;
struct remoteproc_mem *mem;
if (!rproc)
- return NULL;
- else if (!pa && !da)
- return NULL;
+ return -RPROC_EINVAL;
+ else if (!pa && !da && !va)
+ return -RPROC_EINVAL;
if (pa)
lpa = *pa;
else
@@ -359,24 +356,40 @@ void *remoteproc_mmap(struct remoteproc *rproc,
lda = *da;
else
lda = METAL_BAD_PHYS;
- mem = remoteproc_get_mem(rproc, NULL, lpa, lda, NULL, size);
+ if (va)
+ lva = *va;
+ mem = remoteproc_get_mem(rproc, NULL, lpa, lda, lva, size);
if (mem) {
- if (lpa != METAL_BAD_PHYS)
+ if (lpa != METAL_BAD_PHYS) {
lda = remoteproc_patoda(mem, lpa);
- else if (lda != METAL_BAD_PHYS)
+ lva = metal_io_phys_to_virt(mem->io, lpa);
+ } else if (lda != METAL_BAD_PHYS) {
lpa = remoteproc_datopa(mem, lda);
+ lva = metal_io_phys_to_virt(mem->io, lpa);
+ } else if (lva != NULL) {
+ lpa = metal_io_virt_to_phys(mem->io, lva);
+ lda = remoteproc_patoda(mem, lpa);
+ }
if (io)
*io = mem->io;
- va = metal_io_phys_to_virt(mem->io, lpa);
- } else if (rproc->ops->mmap) {
- va = rproc->ops->mmap(rproc, &lpa, &lda, size, attribute, io);
+ } else {
+ int ret = -RPROC_EINVAL;
+
+ if (rproc->ops->mmap)
+ ret = rproc->ops->mmap(rproc, &lpa, &lda, &lva, size, attribute, io);
+
+ if (ret < 0)
+ return ret;
}
if (pa)
*pa = lpa;
if (da)
*da = lda;
- return va;
+ if (va)
+ *va = lva;
+
+ return 0;
}
int remoteproc_load(struct remoteproc *rproc, const char *path,
@@ -529,8 +542,7 @@ int remoteproc_load(struct remoteproc *rproc, const char *path,
img_data = NULL;
/* get the I/O region from remoteproc */
pa = METAL_BAD_PHYS;
- (void)remoteproc_mmap(rproc, &pa, &da, nmemsize, 0,
- &io);
+ remoteproc_mmap(rproc, &pa, &da, NULL, nmemsize, 0, &io);
if (pa == METAL_BAD_PHYS || !io) {
metal_log(METAL_LOG_ERROR,
"load failed, no mapping for 0x%llx.\r\n",
@@ -600,8 +612,9 @@ int remoteproc_load(struct remoteproc *rproc, const char *path,
metal_log(METAL_LOG_DEBUG,
"%s, update resource table\r\n", __func__);
- rsc_table = remoteproc_mmap(rproc, NULL, &rsc_da,
- rsc_size, 0, &io);
+ rsc_table = NULL;
+ remoteproc_mmap(rproc, NULL, &rsc_da,
+ &rsc_table, rsc_size, 0, &io);
if (rsc_table) {
size_t rsc_io_offset;
@@ -760,7 +773,7 @@ int remoteproc_load_noblock(struct remoteproc *rproc,
if (da != RPROC_LOAD_ANYADDR) {
/* get the I/O region from remoteproc */
*pa = METAL_BAD_PHYS;
- (void)remoteproc_mmap(rproc, pa, &da, *nmlen, 0, io);
+ remoteproc_mmap(rproc, pa, &da, NULL, *nmlen, 0, io);
if (*pa == METAL_BAD_PHYS || !io) {
metal_log(METAL_LOG_ERROR,
"load failed, no mapping for 0x%llx.\r\n",
@@ -785,8 +798,8 @@ int remoteproc_load_noblock(struct remoteproc *rproc,
ret = -RPROC_ENOMEM;
goto error1;
}
- rsc_table = remoteproc_mmap(rproc, NULL, &rsc_da,
- rsc_size, 0, io);
+ remoteproc_mmap(rproc, NULL, &rsc_da,
+ &rsc_table, rsc_size, 0, io);
if (!*io) {
metal_log(METAL_LOG_ERROR,
"load failed: failed to mmap rsc\r\n");
@@ -924,7 +937,7 @@ remoteproc_create_virtio(struct remoteproc *rproc,
metal_phys_addr_t da;
unsigned int num_descs, align;
struct metal_io_region *io;
- void *va;
+ void *va = NULL;
size_t size;
int ret;
@@ -934,7 +947,7 @@ remoteproc_create_virtio(struct remoteproc *rproc,
num_descs = vring_rsc->num;
align = vring_rsc->align;
size = vring_size(num_descs, align);
- va = remoteproc_mmap(rproc, NULL, &da, size, 0, &io);
+ remoteproc_mmap(rproc, NULL, &da, &va, size, 0, &io);
if (!va)
goto err1;
ret = rproc_virtio_init_vring(vdev, i, notifyid,
diff --git a/lib/remoteproc/rsc_table_parser.c open-amp/lib/remoteproc/rsc_table_parser.c
index e43fa72..0bfd163 100644
--- a/lib/remoteproc/rsc_table_parser.c
+++ open-amp/lib/remoteproc/rsc_table_parser.c
@@ -109,7 +109,7 @@ int handle_carve_out_rsc(struct remoteproc *rproc, void *rsc)
da = carve_rsc->da;
size = carve_rsc->len;
attribute = carve_rsc->flags;
- if (remoteproc_mmap(rproc, &pa, &da, size, attribute, NULL))
+ if (remoteproc_mmap(rproc, &pa, &da, NULL, size, attribute, NULL))
return 0;
else
return -RPROC_EINVAL;
--
2.17.1