CMake: generic: ZynqMP R5: udpate to use libxil, libmetal
[processor-sdk/open-amp.git] / apps / matrix_multiply / matrix_multiplyd_remoteproc_master.c
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
3 and showcases booting of linux remote firmware using remoteproc and 
4 IPC with remote firmware using rpmsg; Baremetal 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 offloads matrix multiplication to the baremetal context.
7 Linux app generates two random matrices and transmits them to baremetal env which computes 
8 the product and transmits results back to Linux. Once Linux application is complete, it
9 requests a shutdown from baremetal env. Baremetal env acknowledges with a shutdown message which results
10 in Linux starting a system halt. Baremetal env shutsdown the remot core after a reasonable delay which allows
11 Linux to gracefully shutdown. */
13 /* Including required headers */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "openamp/open_amp.h"
19 #define MAX_SIZE        6
20 #define NUM_MATRIX      2
22 #define SHUTDOWN_MSG    0xEF56A55A
24 typedef struct _matrix {
25         unsigned long size;
26         unsigned long elements[MAX_SIZE][MAX_SIZE];
27 } matrix;
29 static matrix matrix_array[NUM_MATRIX];
31 static matrix matrix_result;
33 /* Prototypes */
34 void sleep();
36 /* Application provided callbacks */
37 void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
38 void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
39 void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
40                    void *pric, unsigned long src);
42 /* Globals */
43 struct rpmsg_endpoint *rp_ept;
44 struct rpmsg_channel *app_rp_chnl;
45 char fw_name[] = "firmware1";
47 int int_flag;
49 static int shutdown_called = 0;
51 /* External functions */
52 extern void init_system();
53 extern void cleanup_system();
55 /* External variables */
56 extern struct hil_proc proc_table[];
58 static void Matrix_Multiply(const matrix * m, const matrix * n, matrix * r)
59 {
60         int i, j, k;
62         r->size = m->size;
64         for (i = 0; i < m->size; ++i) {
65                 for (j = 0; j < n->size; ++j) {
66                         r->elements[i][j] = 0;
67                 }
68         }
70         for (i = 0; i < m->size; ++i) {
71                 for (j = 0; j < n->size; ++j) {
72                         for (k = 0; k < r->size; ++k) {
73                                 r->elements[i][j] +=
74                                     m->elements[i][k] * n->elements[k][j];
75                         }
76                 }
77         }
78 }
80 /* Application entry point */
81 int main()
82 {
84         int status;
85         struct remote_proc *proc;
86         int i;
87         int shutdown_msg = SHUTDOWN_MSG;
89         /* Initialize HW system components */
90         init_system();
92         status =
93             remoteproc_init((void *)fw_name, &proc_table[0], rpmsg_channel_created,
94                             rpmsg_channel_deleted, rpmsg_read_cb, &proc);
96         if (!status) {
97                 status = remoteproc_boot(proc);
98         }
100         if (status) {
101                 return -1;
102         }
103         while (1) {
105                 if (int_flag) {
107                         if (shutdown_called == 1) {
108                                 break;
109                         }
111                         /* Process received data and multiple matrices. */
112                         Matrix_Multiply(&matrix_array[0], &matrix_array[1],
113                                         &matrix_result);
115                         /* Send the result of matrix multiplication back to master. */
116                         rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix));
117                         int_flag = 0;
118                 }
120                 hil_poll(proc->proc, 0);
121         }
123         /* Send shutdown message to remote */
124         rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
126         for (i = 0; i < 100000; i++) {
127                 sleep();
128         }
130         remoteproc_shutdown(proc);
132         remoteproc_deinit(proc);
134         cleanup_system();
135         return 0;
138 /* This callback gets invoked when the remote chanl is created */
139 void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
142         app_rp_chnl = rp_chnl;
143         rp_ept =
144             rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
145                              RPMSG_ADDR_ANY);
149 /* This callback gets invoked when the remote channel is deleted */
150 void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
152         rpmsg_destroy_ept(rp_ept);
155 /* This is the read callback, note we are in a task context when this callback
156 is invoked, so kernel primitives can be used freely */
157 void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
158                    void *priv, unsigned long src)
161         if ((*(int *)data) == SHUTDOWN_MSG) {
162                 shutdown_called = 1;
163         } else {
164                 memcpy(matrix_array, data, len);
165         }
167         int_flag = 1;
170 void sleep()
172         volatile int i;
173         for (i = 0; i < 10000000; i++) ;