1 /* This is a sample demonstration application that showcases usage of remoteproc
2 and rpmsg APIs. This application is meant to run on the master CPU running baremetal env
3 and showcases booting of linux remote firmware using remoteproc and
4 IPC with remote firmware using rpmsg; Baremetal env on master core acts as a remoteproc master
5 but as an rpmsg remote;It brings up a remote Linux based
6 firmware which acts as an rpmsg master and transmits data payloads to bametal code.
7 Linux app sends paylaods of incremental sizes to baremetal code which echoes them back to Linux.
8 Once Linux application is complete, it requests a shutdown from baremetal env.
9 Baremetal env acknowledges with a shutdown message which results in Linux starting a system halt.
10 Baremetal env shutsdown the remote core after a reasonable delay which allows
11 Linux to gracefully shutdown. */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "openamp/open_amp.h"
18 #ifdef ZYNQ7_BAREMETAL
19 #include "baremetal.h"
20 #endif
22 #define SHUTDOWN_MSG 0xEF56A55A
24 /* Internal functions */
25 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
26 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
27 static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
28 unsigned long);
29 static void sleep();
31 /* Globals */
32 static struct rpmsg_channel *app_rp_chnl;
33 static struct rpmsg_endpoint *rp_ept;
35 char fw_name[] = "firmware1";
37 static int shutdown_called = 0;
39 /* External functions */
40 extern void init_system();
41 extern void cleanup_system();
43 /* External variables */
44 extern struct hil_proc proc_table[];
46 /* Application entry point */
47 int main()
48 {
50 int status;
51 struct remote_proc *proc;
52 int shutdown_msg = SHUTDOWN_MSG;
53 int i;
55 #ifdef ZYNQ7_BAREMETAL
56 /* Switch to System Mode */
57 SWITCH_TO_SYS_MODE();
58 #endif
60 /* Initialize HW system components */
61 init_system();
63 status =
64 remoteproc_init((void *)fw_name, &proc_table[0], rpmsg_channel_created,
65 rpmsg_channel_deleted, rpmsg_read_cb, &proc);
67 if (!status) {
68 status = remoteproc_boot(proc);
69 }
71 if (status) {
72 return -1;
73 }
75 while (!shutdown_called) {
76 hil_poll(proc->proc, 0);
77 }
79 /* Send shutdown message to remote */
80 rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
82 for (i = 0; i < 100000; i++) {
83 sleep();
84 }
86 remoteproc_shutdown(proc);
88 remoteproc_deinit(proc);
90 cleanup_system();
91 return 0;
92 }
94 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
95 {
96 app_rp_chnl = rp_chnl;
97 rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
98 RPMSG_ADDR_ANY);
99 }
101 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
102 {
103 rpmsg_destroy_ept(rp_ept);
104 }
106 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
107 void *priv, unsigned long src)
108 {
110 if ((*(int *)data) == SHUTDOWN_MSG) {
111 shutdown_called = 1;
112 } else {
113 /* Send data back to master */
114 rpmsg_send(rp_chnl, data, len);
115 }
116 }
118 void sleep()
119 {
120 volatile int i;
121 for (i = 0; i < 100000; i++) ;
122 }