1 /* This is a sample demonstration application that showcases usage of remoteproc
2 and rpmsg APIs on the remote core. This application is meant to run on the remote CPU
3 running baremetal code. This applicationr receives two matrices from the master,
4 multiplies them and returns the result to the master core. */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "openamp/open_amp.h"
10 #include "rsc_table.h"
11 #include "machine.h"
13 #define MAX_SIZE 6
14 #define NUM_MATRIX 2
15 #define SHUTDOWN_MSG 0xEF56A55A
17 typedef struct _matrix {
18 unsigned int size;
19 unsigned int elements[MAX_SIZE][MAX_SIZE];
20 } matrix;
22 /* Internal functions */
23 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
24 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
25 static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
26 unsigned long);
27 static void Matrix_Multiply(const matrix * m, const matrix * n, matrix * r);
28 static void init_system();
30 /* Globals */
31 static struct rpmsg_channel *app_rp_chnl;
32 void *mat_mul_lock;
33 int need_to_cal = 0;
34 static struct rpmsg_endpoint *rp_ept;
35 static matrix matrix_array[NUM_MATRIX];
36 static matrix matrix_result;
37 static struct remote_proc *proc = NULL;
38 static struct rsc_table_info rsc_info;
39 extern const struct remote_resource_table resources;
41 /* Application entry point */
42 int main()
43 {
45 int status = 0;
47 #ifdef ZYNQ_A9
48 SWITCH_TO_SYS_MODE();
49 #endif
51 /* Initialize HW system components */
52 init_system();
54 rsc_info.rsc_tab = (struct resource_table *)&resources;
55 rsc_info.size = sizeof(resources);
57 /* Initialize RPMSG framework */
58 status =
59 remoteproc_resource_init(&rsc_info, rpmsg_channel_created,
60 rpmsg_channel_deleted, rpmsg_read_cb,
61 &proc);
62 if (status < 0) {
63 return -1;
64 }
66 while (1) {
67 __asm__("wfi\n\t");
68 }
70 return 0;
71 }
73 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
74 {
75 app_rp_chnl = rp_chnl;
76 rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
77 RPMSG_ADDR_ANY);
78 }
80 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
81 {
82 rpmsg_destroy_ept(rp_ept);
83 }
85 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
86 void *priv, unsigned long src)
87 {
88 if ((*(int *)data) == SHUTDOWN_MSG) {
89 remoteproc_resource_deinit(proc);
90 } else {
91 env_memcpy(matrix_array, data, len);
92 /* Process received data and multiple matrices. */
93 Matrix_Multiply(&matrix_array[0], &matrix_array[1],
94 &matrix_result);
96 /* Send the result of matrix multiplication back to master. */
97 rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix));
98 }
99 }
101 static void Matrix_Multiply(const matrix * m, const matrix * n, matrix * r)
102 {
103 int i, j, k;
105 env_memset(r, 0x0, sizeof(matrix));
106 r->size = m->size;
108 for (i = 0; i < m->size; ++i) {
109 for (j = 0; j < n->size; ++j) {
110 for (k = 0; k < r->size; ++k) {
111 r->elements[i][j] +=
112 m->elements[i][k] * n->elements[k][j];
113 }
114 }
115 }
116 }
118 static void init_system()
119 {
121 #ifdef ZYNQMP_R5
122 /* Initilaize GIC */
123 zynqMP_r5_gic_initialize();
124 #else
125 #ifdef ZYNQ_A9
126 /* Place the vector table at the image entry point */
127 arm_arch_install_isr_vector_table(RAM_VECTOR_TABLE_ADDR);
129 /* Enable MMU */
130 arm_ar_mem_enable_mmu();
132 /* Initialize ARM stacks */
133 init_arm_stacks();
135 /* Initialize GIC */
136 zc702evk_gic_initialize();
137 #endif
138 #endif
139 }