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 #define BAREMETAL_MASTER 1
20 #include "machine.h"
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();
30 static void init_system();
32 /* Globals */
33 static struct rpmsg_channel *app_rp_chnl;
34 static struct rpmsg_endpoint *rp_ept;
36 char fw_name[] = "firmware1";
38 static int shutdown_called = 0;
40 /* Application entry point */
41 int main()
42 {
44 int status;
45 struct remote_proc *proc;
46 int shutdown_msg = SHUTDOWN_MSG;
47 int i;
49 /* Switch to System Mode */
50 SWITCH_TO_SYS_MODE();
52 /* Initialize HW system components */
53 init_system();
55 status =
56 remoteproc_init((void *)fw_name, rpmsg_channel_created,
57 rpmsg_channel_deleted, rpmsg_read_cb, &proc);
59 if (!status) {
60 status = remoteproc_boot(proc);
61 }
63 if (status) {
64 return -1;
65 }
67 while (1) {
69 if (shutdown_called == 1) {
70 break;
71 }
72 sleep();
73 }
75 /* Send shutdown message to remote */
76 rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
78 for (i = 0; i < 100000; i++) {
79 sleep();
80 }
82 remoteproc_shutdown(proc);
84 remoteproc_deinit(proc);
86 return 0;
87 }
89 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
90 {
91 app_rp_chnl = rp_chnl;
92 rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
93 RPMSG_ADDR_ANY);
94 }
96 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
97 {
98 rpmsg_destroy_ept(rp_ept);
99 }
101 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
102 void *priv, unsigned long src)
103 {
105 if ((*(int *)data) == SHUTDOWN_MSG) {
106 shutdown_called = 1;
107 } else {
108 /* Send data back to master */
109 rpmsg_send(rp_chnl, data, len);
110 }
111 }
113 void sleep()
114 {
115 volatile int i;
116 for (i = 0; i < 100000; i++) ;
117 }
119 static void init_system()
120 {
122 /* Place the vector table at the image entry point */
123 arm_arch_install_isr_vector_table(RAM_VECTOR_TABLE_ADDR);
125 /* Enable MMU */
126 arm_ar_mem_enable_mmu();
128 /* Initialize ARM stacks */
129 init_arm_stacks();
131 /* Initialize GIC */
132 zc702evk_gic_initialize();
133 }