index 9aa42e9ae53b5617350ca6ebc189823177b09d30..9c1cec14a62a3b58ad79ef61865b07395b822eb2 100644 (file)
-/* This is a sample demonstration application that showcases usage of rpmsg
-This application is meant to run on the remote CPU running baremetal code.
+/* This is a sample demonstration application that showcases usage of rpmsg
+This application is meant to run on the remote CPU running baremetal code.
This application echoes back data that was sent to it by the master core. */
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "openamp/open_amp.h"
#include "rsc_table.h"
-
-#ifdef ZYNQ7_BAREMETAL
-#include "baremetal.h"
-#endif
+#include "platform_info.h"
#define SHUTDOWN_MSG 0xEF56A55A
-/* Internal functions */
-static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
-static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
-static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
- unsigned long);
+//#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
+#define LPRINTF(format, ...)
+#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
+
+#define REMOTE_ACTIVE 0
+#define REMOTE_RESETTING 1
+#define REMOTE_RESETTED 2
+
+/* External functions */
+extern int init_system(void);
+extern void cleanup_system(void);
+
/* Globals */
-static struct rpmsg_channel *app_rp_chnl;
static struct rpmsg_endpoint *rp_ept;
static struct remote_proc *proc = NULL;
static struct rsc_table_info rsc_info;
-extern const struct remote_resource_table resources;
-
-/* External functions */
-extern void init_system();
+static int evt_chnl_deleted = 0;
+static int remote_proc_state;
-/* Application entry point */
-int main()
+static void virtio_rst_cb(struct hil_proc *hproc, int id)
{
- int status = 0;
+ /* hil_proc only supports single virtio device */
+ (void)id;
-#ifdef ZYNQ7_BAREMETAL
- SWITCH_TO_SYS_MODE();
-#endif
+ if (!proc || proc->proc != hproc || !proc->rdev)
+ return;
+ LPRINTF("Resetting RPMsg\n");
+ atomic_thread_fence(memory_order_seq_cst);
+ remote_proc_state = REMOTE_RESETTING;
- /* Initialize HW system components */
- init_system();
+ rpmsg_deinit(proc->rdev);
+ proc->rdev = NULL;
- rsc_info.rsc_tab = (struct resource_table *)&resources;
- rsc_info.size = sizeof(resources);
+ atomic_thread_fence(memory_order_seq_cst);
+ remote_proc_state = REMOTE_RESETTED;
+ LPRINTF("RPMsg resetted\n");
+}
- /* Initialize RPMSG framework */
- status =
- remoteproc_resource_init(&rsc_info, rpmsg_channel_created,
- rpmsg_channel_deleted, rpmsg_read_cb,
- &proc);
+static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
+ void *priv, unsigned long src)
+{
+ (void)priv;
+ (void)src;
- if (status < 0) {
- return -1;
+ if ((*(unsigned int *)data) == SHUTDOWN_MSG) {
+ evt_chnl_deleted = 1;
+ return;
}
- while (1) {
- __asm__("\
- wfi\n\t");
- };
-
- return 0;
+ /* Send data back to master */
+ rpmsg_send(rp_chnl, data, len);
}
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
{
- app_rp_chnl = rp_chnl;
rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
RPMSG_ADDR_ANY);
}
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
{
+ (void)rp_chnl;
+ rpmsg_destroy_ept(rp_ept);
+ rp_ept = NULL;
+ evt_chnl_deleted = 1;
}
-static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
- void *priv, unsigned long src)
+/* Application entry point */
+int app(struct hil_proc *hproc)
{
- if ((*(int *)data) == SHUTDOWN_MSG) {
- remoteproc_resource_deinit(proc);
+ int status = 0;
+
+ /* Initialize RPMSG framework */
+ LPRINTF("Try to init remoteproc resource\n");
+ status =
+ remoteproc_resource_init(&rsc_info, hproc,
+ rpmsg_channel_created,
+ rpmsg_channel_deleted, rpmsg_read_cb,
+ &proc, 0);
+ LPRINTF("init remoteproc resource done\n");
+
+ if (RPROC_SUCCESS != status) {
+ LPERROR("init remoteproc resource failed\n");
+ return -1;
+ }
+ LPRINTF("init remoteproc resource succeeded\n");
+
+ hil_set_vdev_rst_cb(hproc, 0, virtio_rst_cb);
+
+ do {
+ do {
+ hil_poll(proc->proc, 0);
+ } while (!evt_chnl_deleted);
+
+ while (remote_proc_state == REMOTE_RESETTING);
+
+ if (remote_proc_state == REMOTE_RESETTED) {
+ LPRINTF("Reinitializing RPMsg\n");
+ status = rpmsg_init(hproc, &proc->rdev,
+ rpmsg_channel_created,
+ rpmsg_channel_deleted, rpmsg_read_cb,
+ 1);
+ if (status != RPROC_SUCCESS) {
+ LPERROR("Reinit RPMsg failed\n");
+ goto out;
+ } else {
+ LPRINTF("Reinit RPMsg succeeded\n");
+ evt_chnl_deleted=0;
+ }
+ } else {
+ break;
+ }
+ } while(1);
+
+out:
+ /* disable interrupts and free resources */
+ LPRINTF("De-initializating remoteproc resource\n");
+ remoteproc_resource_deinit(proc);
+
+ cleanup_system();
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ unsigned long proc_id = 0;
+ unsigned long rsc_id = 0;
+ struct hil_proc *hproc;
+ int status = -1;
+
+ LPRINTF("Starting application...\n");
+
+ /* Initialize HW system components */
+ init_system();
+
+ if (argc >= 2) {
+ proc_id = strtoul(argv[1], NULL, 0);
+ }
+
+ if (argc >= 3) {
+ rsc_id = strtoul(argv[2], NULL, 0);
+ }
+
+ hproc = platform_create_proc(proc_id);
+ if (!hproc) {
+ LPERROR("Failed to create proc platform data.\n");
} else {
- /* Send data back to master */
- rpmsg_send(rp_chnl, data, len);
+ rsc_info.rsc_tab = get_resource_table(
+ (int)rsc_id, &rsc_info.size);
+ if (!rsc_info.rsc_tab) {
+ LPERROR("Failed to get resource table data.\n");
+ } else {
+ status = app(hproc);
+ }
}
+
+ return status;
}