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();
42 /* External variables */
43 extern struct hil_proc proc_table[];
45 /* Application entry point */
46 int main()
47 {
49 int status;
50 struct remote_proc *proc;
51 int shutdown_msg = SHUTDOWN_MSG;
52 int i;
54 #ifdef ZYNQ7_BAREMETAL
55 /* Switch to System Mode */
56 SWITCH_TO_SYS_MODE();
57 #endif
59 /* Initialize HW system components */
60 init_system();
62 status =
63 remoteproc_init((void *)fw_name, &proc_table[0], rpmsg_channel_created,
64 rpmsg_channel_deleted, rpmsg_read_cb, &proc);
66 if (!status) {
67 status = remoteproc_boot(proc);
68 }
70 if (status) {
71 return -1;
72 }
74 while (1) {
76 if (shutdown_called == 1) {
77 break;
78 }
79 sleep();
80 }
82 /* Send shutdown message to remote */
83 rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
85 for (i = 0; i < 100000; i++) {
86 sleep();
87 }
89 remoteproc_shutdown(proc);
91 remoteproc_deinit(proc);
93 return 0;
94 }
96 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
97 {
98 app_rp_chnl = rp_chnl;
99 rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
100 RPMSG_ADDR_ANY);
101 }
103 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
104 {
105 rpmsg_destroy_ept(rp_ept);
106 }
108 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
109 void *priv, unsigned long src)
110 {
112 if ((*(int *)data) == SHUTDOWN_MSG) {
113 shutdown_called = 1;
114 } else {
115 /* Send data back to master */
116 rpmsg_send(rp_chnl, data, len);
117 }
118 }
120 void sleep()
121 {
122 volatile int i;
123 for (i = 0; i < 100000; i++) ;
124 }