openamp: Download libmetal and open-amp from github

and apply the patch which is pending merge to upstream

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2020-04-21 20:37:06 +08:00 committed by patacongo
parent b34d7bf56d
commit daedc1f5e2
15 changed files with 2303 additions and 16 deletions

3
openamp/.gitignore vendored
View File

@ -1,4 +1,7 @@
/.libmetal_headers
/.openamp_headers
/.depend
/Make.dep
/libmetal
/open-amp
/*.zip

View File

@ -0,0 +1,29 @@
From e84d8dd13d31de4942bbf4ec8093932961b9d1b9 Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Tue, 21 Apr 2020 22:02:38 +0800
Subject: [PATCH] nuttx: change sched_kfree to metal_free_memory
since the upstream remove sched_kfree and put the similar logic into kmm_free:
https://github.com/apache/incubator-nuttx/commit/231ad202ee0a3abfd2e14fab1f218b588f61284b
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
lib/system/nuttx/irq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/system/nuttx/irq.c libmetal/lib/system/nuttx/irq.c
index 476eab9..84200d3 100644
--- a/lib/system/nuttx/irq.c
+++ libmetal/lib/system/nuttx/irq.c
@@ -45,7 +45,7 @@ static int metal_cntr_irq_handler(int irq, void *context, void *data)
/* context == NULL mean unregister */
irqchain_detach(irq, metal_cntr_irq_handler, data);
- sched_kfree(data);
+ metal_free_memory(data);
return 0;
}
--
2.17.1

View File

@ -0,0 +1,38 @@
From aca01202ec47984ea90d3904560b973976cab1e5 Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Fri, 24 Apr 2020 01:44:31 +0800
Subject: [PATCH 01/10] rpmsg: remove the address check in
rpmsg_send/rpmsg_trysend
since rpmsg_send_offchannel_raw already do the same validation
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
lib/include/openamp/rpmsg.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index f2a6454..8401c38 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -146,8 +146,6 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data,
int len)
{
- if (ept->dest_addr == RPMSG_ADDR_ANY)
- return RPMSG_ERR_ADDR;
return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
len, true);
}
@@ -216,8 +214,6 @@ static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept,
static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data,
int len)
{
- if (ept->dest_addr == RPMSG_ADDR_ANY)
- return RPMSG_ERR_ADDR;
return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
len, false);
}
--
2.17.1

View File

@ -0,0 +1,128 @@
From c4c3577a3d7a1e957c84f86caa64b7e076b9db89 Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Fri, 24 Apr 2020 03:40:56 +0800
Subject: [PATCH 02/10] rpmsg: merge rpmsg_register_endpoint into
rpmsg_init_ept
so the service which use preserved address could call rpmsg_init_ept
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
lib/include/openamp/rpmsg.h | 19 +++++++------------
lib/rpmsg/rpmsg.c | 17 +++++++++++++----
lib/rpmsg/rpmsg_internal.h | 2 --
lib/rpmsg/rpmsg_virtio.c | 3 +--
4 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index 8401c38..a08f9d3 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -271,6 +271,7 @@ static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
* remoteproc address, endpoint callback, and destroy endpoint callback.
*
* @ept: pointer to rpmsg endpoint
+ * @rdev: pointer to the rpmsg device
* @name: service name associated to the endpoint
* @src: local address of the endpoint
* @dest: target address of the endpoint
@@ -278,18 +279,12 @@ static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
* @ns_unbind_cb: end point service unbind callback, called when remote ept is
* destroyed.
*/
-static inline void rpmsg_init_ept(struct rpmsg_endpoint *ept,
- const char *name,
- uint32_t src, uint32_t dest,
- rpmsg_ept_cb cb,
- rpmsg_ns_unbind_cb ns_unbind_cb)
-{
- strncpy(ept->name, name ? name : "", sizeof(ept->name));
- ept->addr = src;
- ept->dest_addr = dest;
- ept->cb = cb;
- ept->ns_unbind_cb = ns_unbind_cb;
-}
+void rpmsg_init_ept(struct rpmsg_endpoint *ept,
+ struct rpmsg_device *rdev,
+ const char *name,
+ uint32_t src, uint32_t dest,
+ rpmsg_ept_cb cb,
+ rpmsg_ns_unbind_cb ns_unbind_cb);
/**
* rpmsg_create_ept - create rpmsg endpoint and register it to rpmsg device
diff --git a/lib/rpmsg/rpmsg.c open-amp/lib/rpmsg/rpmsg.c
index 5b9c735..eee1c28 100644
--- a/lib/rpmsg/rpmsg.c
+++ open-amp/lib/rpmsg/rpmsg.c
@@ -182,6 +182,7 @@ static void rpmsg_unregister_endpoint(struct rpmsg_endpoint *ept)
return;
rdev = ept->rdev;
+ ept->rdev = NULL;
if (ept->addr != RPMSG_ADDR_ANY)
rpmsg_release_address(rdev->bitmap, RPMSG_ADDR_BMP_SIZE,
@@ -189,9 +190,18 @@ static void rpmsg_unregister_endpoint(struct rpmsg_endpoint *ept)
metal_list_del(&ept->node);
}
-void rpmsg_register_endpoint(struct rpmsg_device *rdev,
- struct rpmsg_endpoint *ept)
+void rpmsg_init_ept(struct rpmsg_endpoint *ept,
+ struct rpmsg_device *rdev,
+ const char *name,
+ uint32_t src, uint32_t dest,
+ rpmsg_ept_cb cb,
+ rpmsg_ns_unbind_cb ns_unbind_cb)
{
+ strncpy(ept->name, name ? name : "", sizeof(ept->name));
+ ept->addr = src;
+ ept->dest_addr = dest;
+ ept->cb = cb;
+ ept->ns_unbind_cb = ns_unbind_cb;
ept->rdev = rdev;
metal_list_add_tail(&rdev->endpoints, &ept->node);
}
@@ -224,8 +234,7 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
addr = rpmsg_get_address(rdev->bitmap, RPMSG_ADDR_BMP_SIZE);
}
- rpmsg_init_ept(ept, name, addr, dest, cb, unbind_cb);
- rpmsg_register_endpoint(rdev, ept);
+ rpmsg_init_ept(ept, rdev, name, addr, dest, cb, unbind_cb);
if (rdev->support_ns && ept->dest_addr == RPMSG_ADDR_ANY) {
/* Send NS announcement to remote processor */
diff --git a/lib/rpmsg/rpmsg_internal.h open-amp/lib/rpmsg/rpmsg_internal.h
index f63c958..9c46970 100644
--- a/lib/rpmsg/rpmsg_internal.h
+++ open-amp/lib/rpmsg/rpmsg_internal.h
@@ -92,8 +92,6 @@ int rpmsg_send_ns_message(struct rpmsg_endpoint *ept, unsigned long flags);
struct rpmsg_endpoint *rpmsg_get_endpoint(struct rpmsg_device *rvdev,
const char *name, uint32_t addr,
uint32_t dest_addr);
-void rpmsg_register_endpoint(struct rpmsg_device *rdev,
- struct rpmsg_endpoint *ept);
static inline struct rpmsg_endpoint *
rpmsg_get_ept_from_addr(struct rpmsg_device *rdev, uint32_t addr)
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
index cf3ec21..ff1226b 100644
--- a/lib/rpmsg/rpmsg_virtio.c
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
@@ -636,10 +636,9 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
* service announcement feature.
*/
if (rdev->support_ns) {
- rpmsg_init_ept(&rdev->ns_ept, "NS",
+ rpmsg_init_ept(&rdev->ns_ept, rdev, "NS",
RPMSG_NS_EPT_ADDR, RPMSG_NS_EPT_ADDR,
rpmsg_virtio_ns_callback, NULL);
- rpmsg_register_endpoint(rdev, &rdev->ns_ept);
}
#ifndef VIRTIO_SLAVE_ONLY
--
2.17.1

View File

@ -0,0 +1,227 @@
From 373d773c188920088af1673867de5cfed12ea4de Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Fri, 24 Apr 2020 01:33:12 +0800
Subject: [PATCH 03/10] rpmsg: shouldn't allocate 0-1023 address in
rpmsg_create_ept
since this region is reserved for predefined services(e.g. NS use 0x35)
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
apps/examples/echo/rpmsg-echo.c | 2 +-
apps/examples/echo/rpmsg-ping.c | 2 +-
.../matrix_multiply/matrix_multiply.c | 2 +-
.../matrix_multiply/matrix_multiplyd.c | 2 +-
apps/examples/rpc_demo/rpc_demod.c | 2 +-
.../rpmsg_sample_echo/rpmsg-sample-ping.c | 2 +-
apps/tests/msg/rpmsg-flood-ping.c | 2 +-
apps/tests/msg/rpmsg-ping.c | 2 +-
apps/tests/msg/rpmsg-update.c | 2 +-
lib/include/openamp/rpmsg.h | 27 ++++++++++---------
lib/rpmsg/rpmsg.c | 11 +++++---
11 files changed, 30 insertions(+), 26 deletions(-)
diff --git a/apps/examples/echo/rpmsg-echo.c open-amp/apps/examples/echo/rpmsg-echo.c
index 0c75203..71a0bbf 100644
--- a/apps/examples/echo/rpmsg-echo.c
+++ open-amp/apps/examples/echo/rpmsg-echo.c
@@ -58,7 +58,7 @@ int app(struct rpmsg_device *rdev, void *priv)
LPRINTF("Try to create rpmsg endpoint.\r\n");
ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME,
- 0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
+ 1024, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
rpmsg_service_unbind);
if (ret) {
LPERROR("Failed to create endpoint.\r\n");
diff --git a/apps/examples/echo/rpmsg-ping.c open-amp/apps/examples/echo/rpmsg-ping.c
index 3b716b0..ff639cd 100644
--- a/apps/examples/echo/rpmsg-ping.c
+++ open-amp/apps/examples/echo/rpmsg-ping.c
@@ -11,7 +11,7 @@ This application echoes back data that was sent to it by the master core. */
#include "platform_info.h"
#include "rpmsg-echo.h"
-#define APP_EPT_ADDR 0
+#define APP_EPT_ADDR 1024
#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
diff --git a/apps/examples/matrix_multiply/matrix_multiply.c open-amp/apps/examples/matrix_multiply/matrix_multiply.c
index b9da29b..3928088 100644
--- a/apps/examples/matrix_multiply/matrix_multiply.c
+++ open-amp/apps/examples/matrix_multiply/matrix_multiply.c
@@ -14,7 +14,7 @@ multiplies them and returns the result to the master core. */
#define MAX_SIZE 6
#define NUM_MATRIX 2
-#define APP_EPT_ADDR 0
+#define APP_EPT_ADDR 1024
#define raw_printf(format, ...) printf(format, ##__VA_ARGS__)
#define LPRINTF(format, ...) raw_printf("CLIENT> " format, ##__VA_ARGS__)
diff --git a/apps/examples/matrix_multiply/matrix_multiplyd.c open-amp/apps/examples/matrix_multiply/matrix_multiplyd.c
index 6b4a118..29c6380 100644
--- a/apps/examples/matrix_multiply/matrix_multiplyd.c
+++ open-amp/apps/examples/matrix_multiply/matrix_multiplyd.c
@@ -92,7 +92,7 @@ int app(struct rpmsg_device *rdev, void *priv)
int ret;
ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME,
- 0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
+ 1024, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
rpmsg_service_unbind);
if (ret) {
LPERROR("Failed to create endpoint.\r\n");
diff --git a/apps/examples/rpc_demo/rpc_demod.c open-amp/apps/examples/rpc_demo/rpc_demod.c
index 44c92a2..a4659f3 100644
--- a/apps/examples/rpc_demo/rpc_demod.c
+++ open-amp/apps/examples/rpc_demo/rpc_demod.c
@@ -312,7 +312,7 @@ int app(struct rpmsg_device *rdev, void *priv)
LPRINTF("Try to create rpmsg endpoint.\r\n");
ret = rpmsg_create_ept(&app_ept, rdev, RPMSG_SERVICE_NAME,
- 0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
+ 1024, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
rpmsg_service_unbind);
if (ret) {
LPERROR("Failed to create endpoint.\r\n");
diff --git a/apps/examples/rpmsg_sample_echo/rpmsg-sample-ping.c open-amp/apps/examples/rpmsg_sample_echo/rpmsg-sample-ping.c
index ee866b4..14456e3 100644
--- a/apps/examples/rpmsg_sample_echo/rpmsg-sample-ping.c
+++ open-amp/apps/examples/rpmsg_sample_echo/rpmsg-sample-ping.c
@@ -20,7 +20,7 @@
#define BYE_MSG "goodbye!"
#define MSG_LIMIT 100
-#define APP_EPT_ADDR 0
+#define APP_EPT_ADDR 1024
#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
diff --git a/apps/tests/msg/rpmsg-flood-ping.c open-amp/apps/tests/msg/rpmsg-flood-ping.c
index 66489f8..28edc66 100644
--- a/apps/tests/msg/rpmsg-flood-ping.c
+++ open-amp/apps/tests/msg/rpmsg-flood-ping.c
@@ -12,7 +12,7 @@
#include "platform_info.h"
#include "rpmsg-ping.h"
-#define APP_EPT_ADDR 0
+#define APP_EPT_ADDR 1024
#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
diff --git a/apps/tests/msg/rpmsg-ping.c open-amp/apps/tests/msg/rpmsg-ping.c
index 0220a27..752b16c 100644
--- a/apps/tests/msg/rpmsg-ping.c
+++ open-amp/apps/tests/msg/rpmsg-ping.c
@@ -11,7 +11,7 @@ This application echoes back data that was sent to it by the master core. */
#include "platform_info.h"
#include "rpmsg-ping.h"
-#define APP_EPT_ADDR 0
+#define APP_EPT_ADDR 1024
#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
diff --git a/apps/tests/msg/rpmsg-update.c open-amp/apps/tests/msg/rpmsg-update.c
index 9b26cac..b8e08db 100644
--- a/apps/tests/msg/rpmsg-update.c
+++ open-amp/apps/tests/msg/rpmsg-update.c
@@ -73,7 +73,7 @@ int app(struct rpmsg_device *rdev, void *priv)
LPRINTF("Try to create rpmsg endpoint.\r\n");
ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME,
- 0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
+ 1024, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
rpmsg_service_unbind);
if (ret) {
LPERROR("Failed to create endpoint.\r\n");
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index a08f9d3..3403240 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -25,22 +25,23 @@ extern "C" {
#endif
/* Configurable parameters */
-#define RPMSG_NAME_SIZE (32)
-#define RPMSG_ADDR_BMP_SIZE (128)
+#define RPMSG_NAME_SIZE (32)
+#define RPMSG_ADDR_BMP_SIZE (128)
-#define RPMSG_NS_EPT_ADDR (0x35)
-#define RPMSG_ADDR_ANY 0xFFFFFFFF
+#define RPMSG_NS_EPT_ADDR (0x35)
+#define RPMSG_RESERVED_ADDRESSES (1024)
+#define RPMSG_ADDR_ANY 0xFFFFFFFF
/* Error macros. */
-#define RPMSG_SUCCESS 0
-#define RPMSG_ERROR_BASE -2000
-#define RPMSG_ERR_NO_MEM (RPMSG_ERROR_BASE - 1)
-#define RPMSG_ERR_NO_BUFF (RPMSG_ERROR_BASE - 2)
-#define RPMSG_ERR_PARAM (RPMSG_ERROR_BASE - 3)
-#define RPMSG_ERR_DEV_STATE (RPMSG_ERROR_BASE - 4)
-#define RPMSG_ERR_BUFF_SIZE (RPMSG_ERROR_BASE - 5)
-#define RPMSG_ERR_INIT (RPMSG_ERROR_BASE - 6)
-#define RPMSG_ERR_ADDR (RPMSG_ERROR_BASE - 7)
+#define RPMSG_SUCCESS 0
+#define RPMSG_ERROR_BASE -2000
+#define RPMSG_ERR_NO_MEM (RPMSG_ERROR_BASE - 1)
+#define RPMSG_ERR_NO_BUFF (RPMSG_ERROR_BASE - 2)
+#define RPMSG_ERR_PARAM (RPMSG_ERROR_BASE - 3)
+#define RPMSG_ERR_DEV_STATE (RPMSG_ERROR_BASE - 4)
+#define RPMSG_ERR_BUFF_SIZE (RPMSG_ERROR_BASE - 5)
+#define RPMSG_ERR_INIT (RPMSG_ERROR_BASE - 6)
+#define RPMSG_ERR_ADDR (RPMSG_ERROR_BASE - 7)
struct rpmsg_endpoint;
struct rpmsg_device;
diff --git a/lib/rpmsg/rpmsg.c open-amp/lib/rpmsg/rpmsg.c
index eee1c28..dcc39c1 100644
--- a/lib/rpmsg/rpmsg.c
+++ open-amp/lib/rpmsg/rpmsg.c
@@ -29,7 +29,7 @@ static uint32_t rpmsg_get_address(unsigned long *bitmap, int size)
nextbit = metal_bitmap_next_clear_bit(bitmap, 0, size);
if (nextbit < (uint32_t)size) {
- addr = nextbit;
+ addr = RPMSG_RESERVED_ADDRESSES + nextbit;
metal_bitmap_set_bit(bitmap, nextbit);
}
@@ -48,7 +48,8 @@ static uint32_t rpmsg_get_address(unsigned long *bitmap, int size)
static void rpmsg_release_address(unsigned long *bitmap, int size,
int addr)
{
- if (addr < size)
+ addr -= RPMSG_RESERVED_ADDRESSES;
+ if (addr >= 0 && addr < size)
metal_bitmap_clear_bit(bitmap, addr);
}
@@ -65,7 +66,8 @@ static void rpmsg_release_address(unsigned long *bitmap, int size,
*/
static int rpmsg_is_address_set(unsigned long *bitmap, int size, int addr)
{
- if (addr < size)
+ addr -= RPMSG_RESERVED_ADDRESSES;
+ if (addr >= 0 && addr < size)
return metal_bitmap_is_bit_set(bitmap, addr);
else
return RPMSG_ERR_PARAM;
@@ -84,7 +86,8 @@ static int rpmsg_is_address_set(unsigned long *bitmap, int size, int addr)
*/
static int rpmsg_set_address(unsigned long *bitmap, int size, int addr)
{
- if (addr < size) {
+ addr -= RPMSG_RESERVED_ADDRESSES;
+ if (addr >= 0 && addr < size) {
metal_bitmap_set_bit(bitmap, addr);
return RPMSG_SUCCESS;
} else {
--
2.17.1

View File

@ -0,0 +1,128 @@
From 2a82b3350bc5eb44d6ffd66da6e3bae6d15ec84c Mon Sep 17 00:00:00 2001
From: ligd <liguiding@pinecone.net>
Date: Wed, 20 Feb 2019 11:36:57 +0800
Subject: [PATCH 04/10] rpmsg: wait ept ready in rpmsg_send
since the destination address need time to return from peer
Signed-off-by: ligd <liguiding@pinecone.net>
---
lib/include/openamp/rpmsg.h | 48 ++++++++++++++++++++++++-------------
lib/rpmsg/rpmsg_virtio.c | 7 ------
2 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index 3403240..7000453 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -15,6 +15,7 @@
#include <metal/compiler.h>
#include <metal/mutex.h>
#include <metal/list.h>
+#include <metal/sleep.h>
#include <metal/utilities.h>
#include <string.h>
#include <stdbool.h>
@@ -32,6 +33,12 @@ extern "C" {
#define RPMSG_RESERVED_ADDRESSES (1024)
#define RPMSG_ADDR_ANY 0xFFFFFFFF
+/* Total tick count for 15secs - 1usec tick. */
+#define RPMSG_TICK_COUNT 15000000
+
+/* Time to wait - In multiple of 1 msecs. */
+#define RPMSG_TICKS_PER_INTERVAL 1000
+
/* Error macros. */
#define RPMSG_SUCCESS 0
#define RPMSG_ERROR_BASE -2000
@@ -129,6 +136,20 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
uint32_t dst, const void *data, int size,
int wait);
+/**
+ * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
+ *
+ * @ept: pointer to rpmsg endpoint
+ *
+ * Returns 1 if the rpmsg endpoint has both local addr and destination
+ * addr set, 0 otherwise
+ */
+static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
+{
+ return (ept->dest_addr != RPMSG_ADDR_ANY) &&
+ (ept->addr != RPMSG_ADDR_ANY);
+}
+
/**
* rpmsg_send() - send a message across to the remote processor
* @ept: the rpmsg endpoint
@@ -147,8 +168,17 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data,
int len)
{
- return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
- len, true);
+ int tc = 0;
+
+ for (; tc < RPMSG_TICK_COUNT; tc += RPMSG_TICKS_PER_INTERVAL) {
+ if (is_rpmsg_ept_ready(ept))
+ return rpmsg_send_offchannel_raw(ept, ept->addr,
+ ept->dest_addr,
+ data, len, true);
+ metal_sleep_usec(RPMSG_TICKS_PER_INTERVAL);
+ }
+
+ return RPMSG_ERR_ADDR;
}
/**
@@ -328,20 +358,6 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
*/
void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
-/**
- * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
- *
- * @ept: pointer to rpmsg endpoint
- *
- * Returns 1 if the rpmsg endpoint has both local addr and destination
- * addr set, 0 otherwise
- */
-static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
-{
- return (ept->dest_addr != RPMSG_ADDR_ANY) &&
- (ept->addr != RPMSG_ADDR_ANY);
-}
-
#if defined __cplusplus
}
#endif
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
index ff1226b..17f2998 100644
--- a/lib/rpmsg/rpmsg_virtio.c
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
@@ -8,7 +8,6 @@
*/
#include <metal/alloc.h>
-#include <metal/sleep.h>
#include <metal/utilities.h>
#include <openamp/rpmsg_virtio.h>
#include <openamp/virtqueue.h>
@@ -17,12 +16,6 @@
#define RPMSG_NUM_VRINGS 2
-/* Total tick count for 15secs - 1usec tick. */
-#define RPMSG_TICK_COUNT 15000000
-
-/* Time to wait - In multiple of 1 msecs. */
-#define RPMSG_TICKS_PER_INTERVAL 1000
-
#ifndef VIRTIO_SLAVE_ONLY
metal_weak void *
rpmsg_virtio_shm_pool_get_buffer(struct rpmsg_virtio_shm_pool *shpool,
--
2.17.1

View File

@ -0,0 +1,45 @@
From 8169c7954d432c6abd8db8f1bde35890bba672ff Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Fri, 24 Apr 2020 02:22:15 +0800
Subject: [PATCH 05/10] rpmsg: return fail if either source or destination
address is zero
to help detect rpmsg_send is called before the endpoint
initialization or after the endpoint uninitialization
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
lib/include/openamp/rpmsg.h | 3 +--
lib/rpmsg/rpmsg.c | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index 7000453..1279ea2 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -146,8 +146,7 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
*/
static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
{
- return (ept->dest_addr != RPMSG_ADDR_ANY) &&
- (ept->addr != RPMSG_ADDR_ANY);
+ return ept && ept->rdev && ept->dest_addr && ept->dest_addr != RPMSG_ADDR_ANY;
}
/**
diff --git a/lib/rpmsg/rpmsg.c open-amp/lib/rpmsg/rpmsg.c
index dcc39c1..9da38a1 100644
--- a/lib/rpmsg/rpmsg.c
+++ open-amp/lib/rpmsg/rpmsg.c
@@ -115,7 +115,7 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
{
struct rpmsg_device *rdev;
- if (!ept || !ept->rdev || !data || dst == RPMSG_ADDR_ANY)
+ if (!ept || !ept->rdev || !data || !dst || dst == RPMSG_ADDR_ANY)
return RPMSG_ERR_PARAM;
rdev = ept->rdev;
--
2.17.1

View File

@ -0,0 +1,785 @@
From bdadd236975ba4b4d9011d3b86d528d305476cb2 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 | 112 ++++++++++--------
lib/remoteproc/rsc_table_parser.c | 2 +-
11 files changed, 212 insertions(+), 198 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 5743c5c..66d15c1 100644
--- a/apps/system/linux/machine/generic/platform_info.c
+++ open-amp/apps/system/linux/machine/generic/platform_info.c
@@ -319,39 +319,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)
@@ -420,7 +424,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;
@@ -449,8 +453,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 057edc6..27fcdb4 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,8 @@ 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);
- if (pa == METAL_BAD_PHYS || io == NULL) {
+ 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",
da);
@@ -599,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;
@@ -759,8 +773,8 @@ 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);
- if (*pa == METAL_BAD_PHYS || io == NULL) {
+ 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",
da);
@@ -784,9 +798,9 @@ int remoteproc_load_noblock(struct remoteproc *rproc,
ret = -RPROC_ENOMEM;
goto error1;
}
- rsc_table = remoteproc_mmap(rproc, NULL, &rsc_da,
- rsc_size, 0, io);
- if (*io == NULL) {
+ 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");
metal_free_memory(lrsc_table);
@@ -923,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;
@@ -933,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 184a463..816a0ee 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

View File

@ -0,0 +1,470 @@
From 4224f5f028aec8ebc13e1e203cbae3127b07605e Mon Sep 17 00:00:00 2001
From: anchao <anchao@pinecone.net>
Date: Mon, 10 Dec 2018 19:39:01 +0800
Subject: [PATCH 07/10] rpmsg: bring back zero copy transfer
Commit-id:
b16ca55 Adding RPMsg Extension layer implementing zero-copy send and receive.
Signed-off-by: anchao <anchao@pinecone.net>
---
lib/include/openamp/rpmsg.h | 178 ++++++++++++++++++++++++++++++++++++
lib/rpmsg/rpmsg.c | 58 ++++++++++++
lib/rpmsg/rpmsg_internal.h | 3 +
lib/rpmsg/rpmsg_virtio.c | 130 +++++++++++++++++++++++++-
4 files changed, 367 insertions(+), 2 deletions(-)
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index 1279ea2..0b46ee1 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -89,9 +89,20 @@ struct rpmsg_endpoint {
/**
* struct rpmsg_device_ops - RPMsg device operations
+ * @hold_rx_buffer: hold RPMsg RX buffer
+ * @release_rx_buffer: release RPMsg RX buffer
+ * @get_tx_payload_buffer: get RPMsg TX buffer
+ * @send_offchannel_nocopy: send RPMsg data without copy
* @send_offchannel_raw: send RPMsg data
*/
struct rpmsg_device_ops {
+ void (*hold_rx_buffer)(struct rpmsg_device *rdev, void *rxbuf);
+ void (*release_rx_buffer)(struct rpmsg_device *rdev, void *rxbuf);
+ void *(*get_tx_payload_buffer)(struct rpmsg_device *rdev,
+ uint32_t *len, int wait);
+ int (*send_offchannel_nocopy)(struct rpmsg_device *rdev,
+ uint32_t src, uint32_t dst,
+ const void *data, int len);
int (*send_offchannel_raw)(struct rpmsg_device *rdev,
uint32_t src, uint32_t dst,
const void *data, int size, int wait);
@@ -294,6 +305,173 @@ static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
return rpmsg_send_offchannel_raw(ept, src, dst, data, len, false);
}
+/**
+ * @brief Holds the rx buffer for usage outside the receive callback.
+ *
+ * Calling this function prevents the RPMsg receive buffer from being released
+ * back to the pool of shmem buffers. This API can only be called at rx
+ * callback context (rpmsg_rx_cb_t). With this API, the application doesn't
+ * need to copy the message in rx callback. Instead, the rx buffer base address
+ * is saved in application context and further processed in application
+ * process. After the message is processed, the application can release the rx
+ * buffer for future reuse in vring by calling the rpmsg_release_rx_buffer()
+ * function.
+ *
+ * @param: ept The rpmsg endpoint
+ * @param: rxbuf RX buffer with message payload
+ *
+ * @see rpmsg_release_rx_buffer
+ */
+void rpmsg_hold_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf);
+
+/**
+ * @brief Releases the rx buffer for future reuse in vring.
+ *
+ * This API can be called at process context when the message in rx buffer is
+ * processed.
+ *
+ * @ept: the rpmsg endpoint
+ * @rxbuf: rx buffer with message payload
+ *
+ * @see rpmsg_hold_rx_buffer
+ */
+void rpmsg_release_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf);
+
+/**
+ * @brief Gets the tx buffer for message payload.
+ *
+ * This API can only be called at process context to get the tx buffer in vring.
+ * By this way, the application can directly put its message into the vring tx
+ * buffer without copy from an application buffer.
+ * It is the application responsibility to correctly fill the allocated tx
+ * buffer by data and passing correct parameters to the rpmsg_send_nocopy() or
+ * rpmsg_sendto_nocopy() function to perform data no-copy-send mechanism.
+ *
+ * @ept: Pointer to rpmsg endpoint
+ * @len: Pointer to store tx buffer size
+ * @wait: Boolean, wait or not for buffer to become available
+ *
+ * @return The tx buffer address on success and NULL on failure
+ *
+ * @see rpmsg_send_offchannel_nocopy
+ * @see rpmsg_sendto_nocopy
+ * @see rpmsg_send_nocopy
+ */
+void *rpmsg_get_tx_payload_buffer(struct rpmsg_endpoint *ept,
+ uint32_t *len, int wait);
+
+/**
+ * rpmsg_send_offchannel_nocopy() - send a message in tx buffer reserved by
+ * rpmsg_get_tx_payload_buffer() across to the remote processor.
+ *
+ * This function sends buf of length len to the remote dst address,
+ * and uses src as the source address.
+ * The message will be sent to the remote processor which the ept
+ * endpoint belongs to.
+ * The application has to take the responsibility for:
+ * 1. tx buffer reserved (rpmsg_get_tx_payload_buffer() )
+ * 2. filling the data to be sent into the pre-allocated tx buffer
+ * 3. not exceeding the buffer size when filling the data
+ * 4. data cache coherency
+ *
+ * After the rpmsg_send_offchannel_nocopy() function is issued the tx buffer is
+ * no more owned by the sending task and must not be touched anymore unless the
+ * rpmsg_send_offchannel_nocopy() function fails and returns an error. In that
+ * case the application should try to re-issue the rpmsg_send_offchannel_nocopy()
+ * again.
+ *
+ * @ept: The rpmsg endpoint
+ * @src: The rpmsg endpoint local address
+ * @dst: The rpmsg endpoint remote address
+ * @data: TX buffer with message filled
+ * @len: Length of payload
+ *
+ * @return number of bytes it has sent or negative error value on failure.
+ *
+ * @see rpmsg_get_tx_payload_buffer
+ * @see rpmsg_sendto_nocopy
+ * @see rpmsg_send_nocopy
+ */
+int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src,
+ uint32_t dst, const void *data, int len);
+
+/**
+ * @brief Sends a message in tx buffer allocated by rpmsg_get_tx_payload_buffer()
+ * across to the remote processor, specify dst.
+ *
+ * This function sends buf of length len to the remote dst address.
+ * The message will be sent to the remote processor which the ept
+ * endpoint belongs to, using ept's source address.
+ * The application has to take the responsibility for:
+ * 1. tx buffer allocation (rpmsg_get_tx_payload_buffer() )
+ * 2. filling the data to be sent into the pre-allocated tx buffer
+ * 3. not exceeding the buffer size when filling the data
+ * 4. data cache coherency
+ *
+ * After the rpmsg_sendto_nocopy() function is issued the tx buffer is no more
+ * owned by the sending task and must not be touched anymore unless the
+ * rpmsg_sendto_nocopy() function fails and returns an error. In that case the
+ * application should try to re-issue the rpmsg_sendto_nocopy() again.
+ *
+ * @ept: The rpmsg endpoint
+ * @data: TX buffer with message filled
+ * @len: Length of payload
+ * @dst: Destination address
+ *
+ * @return number of bytes it has sent or negative error value on failure.
+ *
+ * @see rpmsg_get_tx_payload_buffer
+ * @see rpmsg_send_offchannel_nocopy
+ * @see rpmsg_send_nocopy
+ */
+static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept,
+ const void *data, int len, uint32_t dst)
+{
+ return rpmsg_send_offchannel_nocopy(ept, ept->addr, dst, data, len);
+}
+
+/**
+ * rpmsg_send_nocopy() - send a message in tx buffer reserved by
+ * rpmsg_get_tx_payload_buffer() across to the remote processor.
+ *
+ * This function sends buf of length len on the ept endpoint.
+ * The message will be sent to the remote processor which the ept
+ * endpoint belongs to, using ept's source and destination addresses.
+ * The application has to take the responsibility for:
+ * 1. tx buffer reserved (rpmsg_get_tx_payload_buffer() )
+ * 2. filling the data to be sent into the pre-allocated tx buffer
+ * 3. not exceeding the buffer size when filling the data
+ * 4. data cache coherency
+ *
+ * After the rpmsg_send_nocopy() function is issued the tx buffer is no more
+ * owned by the sending task and must not be touched anymore unless the
+ * rpmsg_send_nocopy() function fails and returns an error. In that case the
+ * application should try to re-issue the rpmsg_send_nocopy() again.
+ *
+ * @ept: The rpmsg endpoint
+ * @data: TX buffer with message filled
+ * @len: Length of payload
+ *
+ * @return number of bytes it has sent or negative error value on failure.
+ *
+ * @see rpmsg_get_tx_payload_buffer
+ * @see rpmsg_send_offchannel_nocopy
+ * @see rpmsg_sendto_nocopy
+ */
+static inline int rpmsg_send_nocopy(struct rpmsg_endpoint *ept, const void *data, int len)
+{
+ int tc = 0;
+
+ for (; tc < RPMSG_TICK_COUNT; tc += RPMSG_TICKS_PER_INTERVAL) {
+ if (is_rpmsg_ept_ready(ept))
+ return rpmsg_send_offchannel_nocopy(ept, ept->addr,
+ ept->dest_addr, data, len);
+ metal_sleep_usec(RPMSG_TICKS_PER_INTERVAL);
+ }
+
+ return RPMSG_ERR_ADDR;
+}
+
/**
* rpmsg_init_ept - initialize rpmsg endpoint
*
diff --git a/lib/rpmsg/rpmsg.c open-amp/lib/rpmsg/rpmsg.c
index 9da38a1..0a8de1b 100644
--- a/lib/rpmsg/rpmsg.c
+++ open-amp/lib/rpmsg/rpmsg.c
@@ -144,6 +144,64 @@ int rpmsg_send_ns_message(struct rpmsg_endpoint *ept, unsigned long flags)
return RPMSG_SUCCESS;
}
+void rpmsg_hold_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf)
+{
+ struct rpmsg_device *rdev;
+
+ if (!ept || !ept->rdev || !rxbuf)
+ return;
+
+ rdev = ept->rdev;
+
+ if (rdev->ops.hold_rx_buffer)
+ rdev->ops.hold_rx_buffer(rdev, rxbuf);
+}
+
+void rpmsg_release_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf)
+{
+ struct rpmsg_device *rdev;
+
+ if (!ept || !ept->rdev || !rxbuf)
+ return;
+
+ rdev = ept->rdev;
+
+ if (rdev->ops.release_rx_buffer)
+ rdev->ops.release_rx_buffer(rdev, rxbuf);
+}
+
+void *rpmsg_get_tx_payload_buffer(struct rpmsg_endpoint *ept,
+ uint32_t *len, int wait)
+{
+ struct rpmsg_device *rdev;
+
+ if (!ept || !ept->rdev || !len)
+ return NULL;
+
+ rdev = ept->rdev;
+
+ if (rdev->ops.get_tx_payload_buffer)
+ return rdev->ops.get_tx_payload_buffer(rdev, len, wait);
+
+ return NULL;
+}
+
+int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src,
+ uint32_t dst, const void *data, int len)
+{
+ struct rpmsg_device *rdev;
+
+ if (!ept || !ept->rdev || !data || !dst || dst == RPMSG_ADDR_ANY)
+ return RPMSG_ERR_PARAM;
+
+ rdev = ept->rdev;
+
+ if (rdev->ops.send_offchannel_nocopy)
+ return rdev->ops.send_offchannel_nocopy(rdev, src, dst, data, len);
+
+ return RPMSG_ERR_PARAM;
+}
+
struct rpmsg_endpoint *rpmsg_get_endpoint(struct rpmsg_device *rdev,
const char *name, uint32_t addr,
uint32_t dest_addr)
diff --git a/lib/rpmsg/rpmsg_internal.h open-amp/lib/rpmsg/rpmsg_internal.h
index 9c46970..3db6b24 100644
--- a/lib/rpmsg/rpmsg_internal.h
+++ open-amp/lib/rpmsg/rpmsg_internal.h
@@ -35,6 +35,9 @@ extern "C" {
} while (0)
#endif
+#define RPMSG_BUF_HELD (1U << 31) /* Flag to suggest to hold the buffer */
+
+#define RPMSG_LOCATE_HDR(p) (struct rpmsg_hdr *)((char *)(p) - sizeof(struct rpmsg_hdr))
#define RPMSG_LOCATE_DATA(p) ((unsigned char *)(p) + sizeof(struct rpmsg_hdr))
/**
* enum rpmsg_ns_flags - dynamic name service announcement flags
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
index 17f2998..a525066 100644
--- a/lib/rpmsg/rpmsg_virtio.c
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
@@ -140,6 +140,7 @@ static void *rpmsg_virtio_get_tx_buffer(struct rpmsg_virtio_device *rvdev,
data = rpmsg_virtio_shm_pool_get_buffer(rvdev->shpool,
RPMSG_BUFFER_SIZE);
*len = RPMSG_BUFFER_SIZE;
+ *idx = 0;
}
}
#endif /*!VIRTIO_SLAVE_ONLY*/
@@ -253,6 +254,118 @@ static int _rpmsg_virtio_get_buffer_size(struct rpmsg_virtio_device *rvdev)
return length;
}
+static void rpmsg_virtio_hold_rx_buffer(struct rpmsg_device *rdev, void *rxbuf)
+{
+ struct rpmsg_hdr *rp_hdr;
+
+ rp_hdr = RPMSG_LOCATE_HDR(rxbuf);
+
+ /* Set held status to keep buffer */
+ rp_hdr->reserved = RPMSG_BUF_HELD;
+}
+
+static void rpmsg_virtio_release_rx_buffer(struct rpmsg_device *rdev, void *rxbuf)
+{
+ struct rpmsg_virtio_device *rvdev;
+ struct rpmsg_hdr *rp_hdr;
+ uint16_t idx;
+ uint32_t len;
+
+ rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev);
+ rp_hdr = RPMSG_LOCATE_HDR(rxbuf);
+ /* The reserved field contains buffer index */
+ idx = rp_hdr->reserved;
+
+ metal_mutex_acquire(&rdev->lock);
+ /* Return buffer on virtqueue. */
+ len = virtqueue_get_buffer_length(rvdev->rvq, idx);
+ rpmsg_virtio_return_buffer(rvdev, rp_hdr, len, idx);
+ metal_mutex_release(&rdev->lock);
+}
+
+static void *rpmsg_virtio_get_tx_payload_buffer(struct rpmsg_device *rdev,
+ uint32_t *len, int wait)
+{
+ struct rpmsg_virtio_device *rvdev;
+ struct rpmsg_hdr *rp_hdr;
+ uint16_t idx;
+ int tick_count;
+
+ /* Get the associated remote device for channel. */
+ rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev);
+
+ if (wait)
+ tick_count = RPMSG_TICK_COUNT / RPMSG_TICKS_PER_INTERVAL;
+ else
+ tick_count = 0;
+
+ while (1) {
+ /* Lock the device to enable exclusive access to virtqueues */
+ metal_mutex_acquire(&rdev->lock);
+ rp_hdr = rpmsg_virtio_get_tx_buffer(rvdev, len, &idx);
+ metal_mutex_release(&rdev->lock);
+ if (rp_hdr || !tick_count)
+ break;
+ metal_sleep_usec(RPMSG_TICKS_PER_INTERVAL);
+ tick_count--;
+ }
+
+ if (!rp_hdr)
+ return NULL;
+
+ /* Store the index into the reserved field to be used when sending */
+ rp_hdr->reserved = idx;
+
+ /* Actual data buffer size is vring buffer size minus rpmsg header length */
+ *len -= sizeof(struct rpmsg_hdr);
+ return RPMSG_LOCATE_DATA(rp_hdr);
+}
+
+static int rpmsg_virtio_send_offchannel_nocopy(struct rpmsg_device *rdev,
+ uint32_t src, uint32_t dst,
+ const void *data, int len)
+{
+ struct rpmsg_virtio_device *rvdev;
+ struct rpmsg_hdr rp_hdr;
+ struct rpmsg_hdr *hdr;
+ uint16_t idx;
+ int status;
+ struct metal_io_region *io;
+
+ /* Get the associated remote device for channel. */
+ rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev);
+
+ hdr = RPMSG_LOCATE_HDR(data);
+ /* The reserved field contains buffer index */
+ idx = hdr->reserved;
+
+ /* Initialize RPMSG header. */
+ rp_hdr.dst = dst;
+ rp_hdr.src = src;
+ rp_hdr.len = len;
+ rp_hdr.reserved = 0;
+ rp_hdr.flags = 0;
+
+ /* Copy data to rpmsg buffer. */
+ io = rvdev->shbuf_io;
+ status = metal_io_block_write(io, metal_io_virt_to_offset(io, hdr),
+ &rp_hdr, sizeof(rp_hdr));
+ RPMSG_ASSERT(status == sizeof(rp_hdr), "failed to write header\r\n");
+
+ metal_mutex_acquire(&rdev->lock);
+
+ /* Enqueue buffer on virtqueue. */
+ len = virtqueue_get_buffer_length(rvdev->svq, idx);
+ status = rpmsg_virtio_enqueue_buffer(rvdev, hdr, len, idx);
+ RPMSG_ASSERT(status == VQUEUE_SUCCESS, "failed to enqueue buffer\r\n");
+ /* Let the other side know that there is a job to process. */
+ virtqueue_kick(rvdev->svq);
+
+ metal_mutex_release(&rdev->lock);
+
+ return len;
+}
+
/**
* This function sends rpmsg "message" to remote device.
*
@@ -389,6 +502,8 @@ static void rpmsg_virtio_rx_callback(struct virtqueue *vq)
metal_mutex_release(&rdev->lock);
while (rp_hdr) {
+ rp_hdr->reserved = 0;
+
/* Get the channel node from the remote device channels list. */
metal_mutex_acquire(&rdev->lock);
ept = rpmsg_get_ept_from_addr(rdev, rp_hdr->dst);
@@ -411,8 +526,15 @@ static void rpmsg_virtio_rx_callback(struct virtqueue *vq)
metal_mutex_acquire(&rdev->lock);
- /* Return used buffers. */
- rpmsg_virtio_return_buffer(rvdev, rp_hdr, len, idx);
+ /* Check whether callback wants to hold buffer */
+ if (rp_hdr->reserved & RPMSG_BUF_HELD) {
+ /* 'rp_hdr->reserved' field is now used as storage for
+ * 'idx' to release buffer later */
+ rp_hdr->reserved = idx;
+ } else {
+ /* Return used buffers. */
+ rpmsg_virtio_return_buffer(rvdev, rp_hdr, len, idx);
+ }
rp_hdr = rpmsg_virtio_get_rx_buffer(rvdev, &len, &idx);
if (rp_hdr == NULL) {
@@ -522,6 +644,10 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
rvdev->vdev = vdev;
rdev->ns_bind_cb = ns_bind_cb;
vdev->priv = rvdev;
+ rdev->ops.hold_rx_buffer = rpmsg_virtio_hold_rx_buffer;
+ rdev->ops.release_rx_buffer = rpmsg_virtio_release_rx_buffer;
+ rdev->ops.get_tx_payload_buffer = rpmsg_virtio_get_tx_payload_buffer;
+ rdev->ops.send_offchannel_nocopy = rpmsg_virtio_send_offchannel_nocopy;
rdev->ops.send_offchannel_raw = rpmsg_virtio_send_offchannel_raw;
role = rpmsg_virtio_get_role(rvdev);
--
2.17.1

View File

@ -0,0 +1,132 @@
From c2d2e03d9a0ddf9e1782c33fd459973c9bc7275a Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Mon, 7 Jan 2019 02:15:42 +0800
Subject: [PATCH 08/10] ns: acknowledge the received creation message
the two phase handsake make the client could initiate the transfer
immediately without the server side send any dummy message first.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
lib/include/openamp/rpmsg.h | 1 +
lib/include/openamp/rpmsg_virtio.h | 1 +
lib/rpmsg/rpmsg.c | 7 +++++--
lib/rpmsg/rpmsg_internal.h | 4 ++--
lib/rpmsg/rpmsg_virtio.c | 12 +++++++++---
5 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h
index 0b46ee1..318acd1 100644
--- a/lib/include/openamp/rpmsg.h
+++ open-amp/lib/include/openamp/rpmsg.h
@@ -127,6 +127,7 @@ struct rpmsg_device {
rpmsg_ns_bind_cb ns_bind_cb;
struct rpmsg_device_ops ops;
bool support_ns;
+ bool support_ack;
};
/**
diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h
index 528b9bf..a2dd504 100644
--- a/lib/include/openamp/rpmsg_virtio.h
+++ open-amp/lib/include/openamp/rpmsg_virtio.h
@@ -28,6 +28,7 @@ extern "C" {
/* The feature bitmap for virtio rpmsg */
#define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */
+#define VIRTIO_RPMSG_F_ACK 1 /* RP supports name service acknowledge */
/**
* struct rpmsg_virtio_shm_pool - shared memory pool used for rpmsg buffers
diff --git a/lib/rpmsg/rpmsg.c open-amp/lib/rpmsg/rpmsg.c
index 0a8de1b..0cc80da 100644
--- a/lib/rpmsg/rpmsg.c
+++ open-amp/lib/rpmsg/rpmsg.c
@@ -297,10 +297,13 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
rpmsg_init_ept(ept, rdev, name, addr, dest, cb, unbind_cb);
- if (rdev->support_ns && ept->dest_addr == RPMSG_ADDR_ANY) {
+ if (ept->name[0]) {
/* Send NS announcement to remote processor */
metal_mutex_release(&rdev->lock);
- status = rpmsg_send_ns_message(ept, RPMSG_NS_CREATE);
+ if (rdev->support_ns && ept->dest_addr == RPMSG_ADDR_ANY)
+ status = rpmsg_send_ns_message(ept, RPMSG_NS_CREATE);
+ else if (rdev->support_ack && ept->dest_addr != RPMSG_ADDR_ANY)
+ status = rpmsg_send_ns_message(ept, RPMSG_NS_CREATE_ACK);
metal_mutex_acquire(&rdev->lock);
if (status)
rpmsg_unregister_endpoint(ept);
diff --git a/lib/rpmsg/rpmsg_internal.h open-amp/lib/rpmsg/rpmsg_internal.h
index 3db6b24..d513a56 100644
--- a/lib/rpmsg/rpmsg_internal.h
+++ open-amp/lib/rpmsg/rpmsg_internal.h
@@ -44,12 +44,12 @@ extern "C" {
*
* @RPMSG_NS_CREATE: a new remote service was just created
* @RPMSG_NS_DESTROY: a known remote service was just destroyed
- * @RPMSG_NS_CREATE_WITH_ACK: a new remote service was just created waiting
- * acknowledgment.
+ * @RPMSG_NS_CREATE_ACK: acknowledge the previous creation message
*/
enum rpmsg_ns_flags {
RPMSG_NS_CREATE = 0,
RPMSG_NS_DESTROY = 1,
+ RPMSG_NS_CREATE_ACK = 2,
};
/**
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
index a525066..e57b1c2 100644
--- a/lib/rpmsg/rpmsg_virtio.c
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
@@ -586,13 +586,13 @@ static int rpmsg_virtio_ns_callback(struct rpmsg_endpoint *ept, void *data,
metal_mutex_acquire(&rdev->lock);
_ept = rpmsg_get_endpoint(rdev, name, RPMSG_ADDR_ANY, dest);
- if (ns_msg->flags & RPMSG_NS_DESTROY) {
+ if (ns_msg->flags == RPMSG_NS_DESTROY) {
if (_ept)
_ept->dest_addr = RPMSG_ADDR_ANY;
metal_mutex_release(&rdev->lock);
if (_ept && _ept->ns_unbind_cb)
_ept->ns_unbind_cb(ept);
- } else {
+ } else if (ns_msg->flags == RPMSG_NS_CREATE) {
if (!_ept) {
/*
* send callback to application, that can
@@ -607,6 +607,11 @@ static int rpmsg_virtio_ns_callback(struct rpmsg_endpoint *ept, void *data,
_ept->dest_addr = dest;
metal_mutex_release(&rdev->lock);
}
+ } else { /* RPMSG_NS_CREATE_ACK */
+ /* save the received destination address */
+ if (_ept)
+ _ept->dest_addr = dest;
+ metal_mutex_release(&rdev->lock);
}
return RPMSG_SUCCESS;
@@ -659,6 +664,7 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
#endif /*!VIRTIO_MASTER_ONLY*/
vdev->features = rpmsg_virtio_get_features(rvdev);
rdev->support_ns = !!(vdev->features & (1 << VIRTIO_RPMSG_F_NS));
+ rdev->support_ack = !!(vdev->features & (1 << VIRTIO_RPMSG_F_ACK));
#ifndef VIRTIO_SLAVE_ONLY
if (role == RPMSG_MASTER) {
@@ -754,7 +760,7 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
* Create name service announcement endpoint if device supports name
* service announcement feature.
*/
- if (rdev->support_ns) {
+ if (rdev->support_ns || rdev->support_ack) {
rpmsg_init_ept(&rdev->ns_ept, rdev, "NS",
RPMSG_NS_EPT_ADDR, RPMSG_NS_EPT_ADDR,
rpmsg_virtio_ns_callback, NULL);
--
2.17.1

View File

@ -0,0 +1,119 @@
From 1d94cd9ae8345543fa93c12cdc11ccbc2ca5b127 Mon Sep 17 00:00:00 2001
From: Xiang Xiao <xiaoxiang@xiaomi.com>
Date: Thu, 3 Jan 2019 14:20:48 +0800
Subject: [PATCH 09/10] implement
rproc_virtio_read_config/rproc_virtio_write_config
so the rpmsg could access the configuration space as needed
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
---
lib/include/openamp/rpmsg_virtio.h | 14 +++++++++++
lib/include/openamp/virtio.h | 1 +
lib/remoteproc/remoteproc_virtio.c | 40 ++++++++++++++++++++++++------
3 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h
index a2dd504..e7c670e 100644
--- a/lib/include/openamp/rpmsg_virtio.h
+++ open-amp/lib/include/openamp/rpmsg_virtio.h
@@ -86,6 +86,20 @@ rpmsg_virtio_get_features(struct rpmsg_virtio_device *rvdev)
return rvdev->vdev->func->get_features(rvdev->vdev);
}
+static inline void
+rpmsg_virtio_read_config(struct rpmsg_virtio_device *rvdev,
+ uint32_t offset, void *dst, int length)
+{
+ rvdev->vdev->func->read_config(rvdev->vdev, offset, dst, length);
+}
+
+static inline void
+rpmsg_virtio_write_config(struct rpmsg_virtio_device *rvdev,
+ uint32_t offset, void *dst, int length)
+{
+ rvdev->vdev->func->write_config(rvdev->vdev, offset, dst, length);
+}
+
static inline int
rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev,
int flags, unsigned int nvqs,
diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h
index 7085554..a93e0d9 100644
--- a/lib/include/openamp/virtio.h
+++ open-amp/lib/include/openamp/virtio.h
@@ -100,6 +100,7 @@ struct virtio_device {
virtio_dev_reset_cb reset_cb; /**< user registered device callback */
const struct virtio_dispatch *func; /**< Virtio dispatch table */
void *priv; /**< TODO: remove pointer to virtio_device private data */
+ unsigned int config_len; /**< config space length */
unsigned int vrings_num; /**< number of vrings */
struct virtio_vring_info *vrings_info;
};
diff --git a/lib/remoteproc/remoteproc_virtio.c open-amp/lib/remoteproc/remoteproc_virtio.c
index e495d81..6a3b28b 100644
--- a/lib/remoteproc/remoteproc_virtio.c
+++ open-amp/lib/remoteproc/remoteproc_virtio.c
@@ -126,20 +126,43 @@ static uint32_t rproc_virtio_negotiate_features(struct virtio_device *vdev,
static void rproc_virtio_read_config(struct virtio_device *vdev,
uint32_t offset, void *dst, int length)
{
- (void)vdev;
- (void)offset;
- (void)dst;
- (void)length;
+ struct remoteproc_virtio *rpvdev;
+ struct fw_rsc_vdev *vdev_rsc;
+ struct metal_io_region *io;
+ char *config;
+
+ if (offset + length > vdev->config_len || offset + length < length)
+ return;
+
+ rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
+ vdev_rsc = rpvdev->vdev_rsc;
+ config = (char *)(&vdev_rsc->vring[vdev->vrings_num]);
+ io = rpvdev->vdev_rsc_io;
+ metal_io_block_read(io,
+ metal_io_virt_to_offset(io, config + offset),
+ dst, length);
}
#ifndef VIRTIO_SLAVE_ONLY
static void rproc_virtio_write_config(struct virtio_device *vdev,
uint32_t offset, void *src, int length)
{
- (void)vdev;
- (void)offset;
- (void)src;
- (void)length;
+ struct remoteproc_virtio *rpvdev;
+ struct fw_rsc_vdev *vdev_rsc;
+ struct metal_io_region *io;
+ char *config;
+
+ if (offset + length > vdev->config_len || offset + length < length)
+ return;
+
+ rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
+ vdev_rsc = rpvdev->vdev_rsc;
+ config = (char *)(&vdev_rsc->vring[vdev->vrings_num]);
+ io = rpvdev->vdev_rsc_io;
+ metal_io_block_write(io,
+ metal_io_virt_to_offset(io, config + offset),
+ src, length);
+ rpvdev->notify(rpvdev->priv, vdev->notifyid);
}
static void rproc_virtio_reset_device(struct virtio_device *vdev)
@@ -220,6 +243,7 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
vdev->notifyid = notifyid;
vdev->role = role;
vdev->reset_cb = rst_cb;
+ vdev->config_len = vdev_rsc->config_len;
vdev->vrings_num = num_vrings;
vdev->func = &remoteproc_virtio_dispatch_funcs;
--
2.17.1

View File

@ -0,0 +1,159 @@
From f5f905a5c7b63e0b90a6b67e45d70305e6dfaa2c Mon Sep 17 00:00:00 2001
From: anchao <anchao@pinecone.net>
Date: Mon, 10 Dec 2018 16:26:39 +0800
Subject: [PATCH 10/10] Negotiate individual buffer size dynamically
If slave support VIRTIO_RPMSG_F_BUFSZ(0x04) feature, master
determine the buffer size from config space(first 8 bytes),
otherwise the default size(512 bytes) will be used.
Signed-off-by: anchao <anchao@pinecone.net>
---
lib/include/openamp/remoteproc.h | 17 +++++++++++++++++
lib/include/openamp/rpmsg_virtio.h | 4 ++++
lib/rpmsg/rpmsg_virtio.c | 22 ++++++++++++++++------
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/lib/include/openamp/remoteproc.h open-amp/lib/include/openamp/remoteproc.h
index b34cb1a..ee9162a 100644
--- a/lib/include/openamp/remoteproc.h
+++ open-amp/lib/include/openamp/remoteproc.h
@@ -303,6 +303,23 @@ struct fw_rsc_vdev {
struct fw_rsc_vdev_vring vring[0];
} METAL_PACKED_END;
+/**
+ * struct fw_rsc_config - configuration space declaration
+ * @txbuf_size: the tx buffer size
+ * @rxbuf_size: the rx buffer size
+ * @reserved: reserved (must be zero)
+ *
+ * This structure immediately follow fw_rsc_vdev to provide the config info.
+ */
+METAL_PACKED_BEGIN
+struct fw_rsc_config {
+ /* The tx/rx individual buffer size(if VIRTIO_RPMSG_F_BUFSZ) */
+ uint32_t txbuf_size;
+ uint32_t rxbuf_size;
+ uint32_t reserved[14]; /* Reserve for the future use */
+ /* Put the customize config here */
+} METAL_PACKED_END;
+
/**
* struct fw_rsc_vendor - remote processor vendor specific resource
* @len: length of the resource
diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h
index e7c670e..e58c84e 100644
--- a/lib/include/openamp/rpmsg_virtio.h
+++ open-amp/lib/include/openamp/rpmsg_virtio.h
@@ -16,6 +16,7 @@
#include <metal/mutex.h>
#include <openamp/rpmsg.h>
#include <openamp/virtio.h>
+#include <openamp/remoteproc.h>
#if defined __cplusplus
extern "C" {
@@ -29,6 +30,7 @@ extern "C" {
/* The feature bitmap for virtio rpmsg */
#define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */
#define VIRTIO_RPMSG_F_ACK 1 /* RP supports name service acknowledge */
+#define VIRTIO_RPMSG_F_BUFSZ 2 /* RP supports get buffer size from config space */
/**
* struct rpmsg_virtio_shm_pool - shared memory pool used for rpmsg buffers
@@ -45,6 +47,7 @@ struct rpmsg_virtio_shm_pool {
/**
* struct rpmsg_virtio_device - representation of a rpmsg device based on virtio
* @rdev: rpmsg device, first property in the struct
+ * @config: rpmsg config information
* @vdev: pointer to the virtio device
* @rvq: pointer to receive virtqueue
* @svq: pointer to send virtqueue
@@ -53,6 +56,7 @@ struct rpmsg_virtio_shm_pool {
*/
struct rpmsg_virtio_device {
struct rpmsg_device rdev;
+ struct fw_rsc_config config;
struct virtio_device *vdev;
struct virtqueue *rvq;
struct virtqueue *svq;
diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
index e57b1c2..792a3b1 100644
--- a/lib/rpmsg/rpmsg_virtio.c
+++ open-amp/lib/rpmsg/rpmsg_virtio.c
@@ -138,8 +138,8 @@ static void *rpmsg_virtio_get_tx_buffer(struct rpmsg_virtio_device *rvdev,
data = virtqueue_get_buffer(rvdev->svq, len, idx);
if (data == NULL) {
data = rpmsg_virtio_shm_pool_get_buffer(rvdev->shpool,
- RPMSG_BUFFER_SIZE);
- *len = RPMSG_BUFFER_SIZE;
+ rvdev->config.rxbuf_size);
+ *len = rvdev->config.rxbuf_size;
*idx = 0;
}
}
@@ -232,7 +232,7 @@ static int _rpmsg_virtio_get_buffer_size(struct rpmsg_virtio_device *rvdev)
* If device role is Master then buffers are provided by us,
* so just provide the macro.
*/
- length = RPMSG_BUFFER_SIZE - sizeof(struct rpmsg_hdr);
+ length = rvdev->config.rxbuf_size - sizeof(struct rpmsg_hdr);
}
#endif /*!VIRTIO_SLAVE_ONLY*/
@@ -649,11 +649,14 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
rvdev->vdev = vdev;
rdev->ns_bind_cb = ns_bind_cb;
vdev->priv = rvdev;
+ rvdev->config.txbuf_size = RPMSG_BUFFER_SIZE;
+ rvdev->config.rxbuf_size = RPMSG_BUFFER_SIZE;
rdev->ops.hold_rx_buffer = rpmsg_virtio_hold_rx_buffer;
rdev->ops.release_rx_buffer = rpmsg_virtio_release_rx_buffer;
rdev->ops.get_tx_payload_buffer = rpmsg_virtio_get_tx_payload_buffer;
rdev->ops.send_offchannel_nocopy = rpmsg_virtio_send_offchannel_nocopy;
rdev->ops.send_offchannel_raw = rpmsg_virtio_send_offchannel_raw;
+
role = rpmsg_virtio_get_role(rvdev);
#ifndef VIRTIO_MASTER_ONLY
@@ -666,6 +669,13 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
rdev->support_ns = !!(vdev->features & (1 << VIRTIO_RPMSG_F_NS));
rdev->support_ack = !!(vdev->features & (1 << VIRTIO_RPMSG_F_ACK));
+ if (vdev->features & (1 << VIRTIO_RPMSG_F_BUFSZ)) {
+ rpmsg_virtio_read_config(rvdev,
+ 0,
+ &rvdev->config,
+ sizeof(rvdev->config));
+ }
+
#ifndef VIRTIO_SLAVE_ONLY
if (role == RPMSG_MASTER) {
/*
@@ -726,11 +736,11 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
unsigned int idx;
void *buffer;
- vqbuf.len = RPMSG_BUFFER_SIZE;
+ vqbuf.len = rvdev->config.txbuf_size;
for (idx = 0; idx < rvdev->rvq->vq_nentries; idx++) {
/* Initialize TX virtqueue buffers for remote device */
buffer = rpmsg_virtio_shm_pool_get_buffer(shpool,
- RPMSG_BUFFER_SIZE);
+ rvdev->config.txbuf_size);
if (!buffer) {
return RPMSG_ERR_NO_BUFF;
@@ -741,7 +751,7 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
metal_io_block_set(shm_io,
metal_io_virt_to_offset(shm_io,
buffer),
- 0x00, RPMSG_BUFFER_SIZE);
+ 0x00, rvdev->config.txbuf_size);
status =
virtqueue_add_buffer(rvdev->rvq, &vqbuf, 0, 1,
buffer);
--
2.17.1

View File

@ -41,6 +41,8 @@ CSRCS =
VPATH := $(SRCDIR)
DEPPATH = --dep-path .
VERSION ?= 2020.01.0
include libmetal.defs
include open-amp.defs
@ -73,7 +75,6 @@ dirlinks::
depend: .depend
clean:
$(foreach obj,$(OBJS),$(call DELFILE, $(obj)))
$(call DELFILE, $(BIN))
$(call CLEAN)

View File

@ -37,15 +37,10 @@ ifeq ($(CONFIG_OPENAMP),y)
ifeq ($(CONFIG_ARCH), sim)
LIBMETAL_ARCH = x86_64
else
LIBMETAL_ARCH = $(subst -,,$(CONFIG_ARCH))
else ifeq ($(CONFIG_ARCH), risc-v)
LIBMETAL_ARCH = riscv
endif
LIBMETAL_HDRS += $(wildcard libmetal/lib/compiler/gcc/*.h)
LIBMETAL_HDRS += $(wildcard libmetal/lib/processor/$(LIBMETAL_ARCH)/*.h)
LIBMETAL_HDRS += $(wildcard libmetal/lib/system/nuttx/*.h)
LIBMETAL_HDRS += $(wildcard libmetal/lib/*.h)
CSRCS += libmetal/lib/system/nuttx/condition.c
CSRCS += libmetal/lib/system/nuttx/device.c
CSRCS += libmetal/lib/system/nuttx/init.c
@ -77,11 +72,21 @@ LIBMETAL_HDRS_SEDEXP := \
s/@PROJECT_MACHINE_UPPER@/$(CONFIG_ARCH_CHIP)/g; \
s/cmakedefine/undef/g"
.libmetal_headers: $(LIBMETAL_HDRS)
$(foreach headers,$(LIBMETAL_HDRS), \
$(eval hobj := $(patsubst libmetal$(DELIM)lib$(DELIM)%,$(TOPDIR)$(DELIM)include$(DELIM)metal$(DELIM)%,$(headers))) \
libmetal.zip:
$(Q) wget https://github.com/OpenAMP/libmetal/archive/v$(VERSION).zip -O libmetal.zip
$(Q) unzip -o libmetal.zip
$(Q) mv libmetal-$(VERSION) libmetal
$(Q) patch -p0 < 0001-nuttx-change-sched_kfree-to-metal_free_memory.patch
.libmetal_headers: libmetal.zip
$(eval headers := $(wildcard libmetal/lib/compiler/gcc/*.h))
$(eval headers += $(wildcard libmetal/lib/processor/$(LIBMETAL_ARCH)/*.h))
$(eval headers += $(wildcard libmetal/lib/system/nuttx/*.h))
$(eval headers += $(wildcard libmetal/lib/*.h))
$(foreach header,$(headers), \
$(eval hobj := $(patsubst libmetal$(DELIM)lib$(DELIM)%,$(TOPDIR)$(DELIM)include$(DELIM)metal$(DELIM)%,$(header))) \
$(shell if [ ! -d $(dir $(hobj)) ];then mkdir -p $(dir $(hobj)); fi) \
$(shell sed $(LIBMETAL_HDRS_SEDEXP) $(headers) > $(hobj)) \
$(shell sed $(LIBMETAL_HDRS_SEDEXP) $(header) > $(hobj)) \
)
touch $@
@ -89,6 +94,8 @@ dirlinks:: .libmetal_headers
distclean::
$(call DELDIR, $(TOPDIR)$(DELIM)include$(DELIM)metal)
$(call DELDIR, libmetal)
$(call DELFILE, libmetal.zip)
$(call DELFILE, .libmetal_headers)
endif

View File

@ -35,8 +35,6 @@
ifeq ($(CONFIG_OPENAMP),y)
OPENAMP_HDRS += $(wildcard open-amp/lib/include/openamp/*.h)
CSRCS += open-amp/lib/remoteproc/elf_loader.c
CSRCS += open-amp/lib/remoteproc/remoteproc.c
CSRCS += open-amp/lib/remoteproc/remoteproc_virtio.c
@ -46,15 +44,33 @@ CSRCS += open-amp/lib/rpmsg/rpmsg_virtio.c
CSRCS += open-amp/lib/virtio/virtio.c
CSRCS += open-amp/lib/virtio/virtqueue.c
.openamp_headers: $(OPENAMP_HDRS)
open-amp.zip:
$(Q) wget https://github.com/OpenAMP/open-amp/archive/v$(VERSION).zip -O open-amp.zip
$(Q) unzip -o open-amp.zip
$(Q) mv open-amp-$(VERSION) open-amp
$(Q) patch -p0 < 0001-rpmsg-remove-the-address-check-in-rpmsg_send-rpmsg_t.patch
$(Q) patch -p0 < 0002-rpmsg-merge-rpmsg_register_endpoint-into-rpmsg_init_.patch
$(Q) patch -p0 < 0003-rpmsg-shouldn-t-allocate-0-1023-address-in-rpmsg_cre.patch
$(Q) patch -p0 < 0004-rpmsg-wait-ept-ready-in-rpmsg_send.patch
$(Q) patch -p0 < 0005-rpmsg-return-fail-if-either-source-or-destination-ad.patch
$(Q) patch -p0 < 0006-remoteproc_mmap-support-va-to-pa-da-conversion.patch
$(Q) patch -p0 < 0007-rpmsg-bring-back-zero-copy-transfer.patch
$(Q) patch -p0 < 0008-ns-acknowledge-the-received-creation-message.patch
$(Q) patch -p0 < 0009-implement-rproc_virtio_read_config-rproc_virtio_writ.patch
$(Q) patch -p0 < 0010-Negotiate-individual-buffer-size-dynamically.patch
.openamp_headers: open-amp.zip
$(eval headers := $(wildcard open-amp/lib/include/openamp/*.h))
$(shell mkdir -p $(TOPDIR)$(DELIM)include$(DELIM)openamp$(DELIM))
$(foreach header,$^,$(shell cp -rf $(header) $(TOPDIR)$(DELIM)include$(DELIM)openamp$(DELIM)))
$(foreach header,$(headers),$(shell cp -rf $(header) $(TOPDIR)$(DELIM)include$(DELIM)openamp$(DELIM)))
touch $@
dirlinks:: .openamp_headers
distclean::
$(call DELDIR, $(TOPDIR)$(DELIM)include$(DELIM)openamp$(DELIM))
$(call DELDIR, open-amp)
$(call DELFILE, open-amp.zip)
$(call DELFILE, .openamp_headers)
endif