1 /* This is a sample demonstration application that showcases usage of rpmsg
2 This application is meant to run on the remote CPU running baremetal code.
3 This application echoes back data that was sent to it by the master core. */
5 #include <stdio.h>
6 #include "openamp/open_amp.h"
7 #include "rsc_table.h"
8 #include "platform_info.h"
10 #define SHUTDOWN_MSG 0xEF56A55A
12 //#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
13 #define LPRINTF(format, ...)
14 #define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
16 #define REMOTE_ACTIVE 0
17 #define REMOTE_RESETTING 1
18 #define REMOTE_RESETTED 2
20 /* External functions */
21 extern int init_system(void);
22 extern void cleanup_system(void);
24 /* Globals */
25 static struct rpmsg_endpoint *rp_ept;
26 static struct remote_proc *proc = NULL;
27 static struct rsc_table_info rsc_info;
28 static int evt_chnl_deleted = 0;
29 static int remote_proc_state;
31 static void virtio_rst_cb(struct hil_proc *hproc, int id)
32 {
33 /* hil_proc only supports single virtio device */
34 (void)id;
36 if (!proc || proc->proc != hproc || !proc->rdev)
37 return;
38 LPRINTF("Resetting RPMsg\n");
39 atomic_thread_fence(memory_order_seq_cst);
40 remote_proc_state = REMOTE_RESETTING;
42 rpmsg_deinit(proc->rdev);
43 proc->rdev = NULL;
45 atomic_thread_fence(memory_order_seq_cst);
46 remote_proc_state = REMOTE_RESETTED;
47 LPRINTF("RPMsg resetted\n");
48 }
50 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
51 void *priv, unsigned long src)
52 {
53 (void)priv;
54 (void)src;
56 if ((*(unsigned int *)data) == SHUTDOWN_MSG) {
57 evt_chnl_deleted = 1;
58 return;
59 }
61 /* Send data back to master */
62 rpmsg_send(rp_chnl, data, len);
63 }
65 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
66 {
67 rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
68 RPMSG_ADDR_ANY);
69 }
71 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
72 {
73 (void)rp_chnl;
75 rpmsg_destroy_ept(rp_ept);
76 rp_ept = NULL;
77 evt_chnl_deleted = 1;
78 }
80 /* Application entry point */
81 int app(struct hil_proc *hproc)
82 {
83 int status = 0;
85 /* Initialize RPMSG framework */
86 LPRINTF("Try to init remoteproc resource\n");
87 status =
88 remoteproc_resource_init(&rsc_info, hproc,
89 rpmsg_channel_created,
90 rpmsg_channel_deleted, rpmsg_read_cb,
91 &proc, 0);
92 LPRINTF("init remoteproc resource done\n");
94 if (RPROC_SUCCESS != status) {
95 LPERROR("init remoteproc resource failed\n");
96 return -1;
97 }
98 LPRINTF("init remoteproc resource succeeded\n");
100 hil_set_vdev_rst_cb(hproc, 0, virtio_rst_cb);
102 do {
103 do {
104 hil_poll(proc->proc, 0);
105 } while (!evt_chnl_deleted);
107 while (remote_proc_state == REMOTE_RESETTING);
109 if (remote_proc_state == REMOTE_RESETTED) {
110 LPRINTF("Reinitializing RPMsg\n");
111 status = rpmsg_init(hproc, &proc->rdev,
112 rpmsg_channel_created,
113 rpmsg_channel_deleted, rpmsg_read_cb,
114 1);
115 if (status != RPROC_SUCCESS) {
116 LPERROR("Reinit RPMsg failed\n");
117 goto out;
118 } else {
119 LPRINTF("Reinit RPMsg succeeded\n");
120 evt_chnl_deleted=0;
121 }
122 } else {
123 break;
124 }
125 } while(1);
127 out:
128 /* disable interrupts and free resources */
129 LPRINTF("De-initializating remoteproc resource\n");
130 remoteproc_resource_deinit(proc);
132 cleanup_system();
134 return 0;
135 }
137 int main(int argc, char *argv[])
138 {
139 unsigned long proc_id = 0;
140 unsigned long rsc_id = 0;
141 struct hil_proc *hproc;
142 int status = -1;
144 LPRINTF("Starting application...\n");
146 /* Initialize HW system components */
147 init_system();
149 if (argc >= 2) {
150 proc_id = strtoul(argv[1], NULL, 0);
151 }
153 if (argc >= 3) {
154 rsc_id = strtoul(argv[2], NULL, 0);
155 }
157 hproc = platform_create_proc(proc_id);
158 if (!hproc) {
159 LPERROR("Failed to create proc platform data.\n");
160 } else {
161 rsc_info.rsc_tab = get_resource_table(
162 (int)rsc_id, &rsc_info.size);
163 if (!rsc_info.rsc_tab) {
164 LPERROR("Failed to get resource table data.\n");
165 } else {
166 status = app(hproc);
167 }
168 }
170 return status;
171 }