]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/open-amp.git/blob - apps/samples/master/linux/kernelspace/rpmsg_mat_mul_kern_app/rpmsg_mat_mul_kern_app.c
Moving OpenAMP sources to GIT repo.
[processor-sdk/open-amp.git] / apps / samples / master / linux / kernelspace / rpmsg_mat_mul_kern_app / rpmsg_mat_mul_kern_app.c
1 /*
2  * RPMSG Matrix Multiplication Kernel Driver
3  *
4  * Copyright (C) 2014 Mentor Graphics Corporation
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/rpmsg.h>
19 #include <linux/slab.h>
20 #include <linux/random.h>
22 /* Application */
23 #define MAX_SIZE                        6
24 #define NUM_MATRIX                      2
25 /* Shutdown message ID */
26 #define SHUTDOWN_MSG                    0xEF56A55A
28 struct rpmsg_endpoint *ept;
29 static const char init_msg[] = "init_msg";
31 static const char *const shutdown_argv[]
32                 = { "/sbin/shutdown", "-h", "-P", "now", NULL };
34 struct _matrix {
35         unsigned long size;
36         unsigned long elements[MAX_SIZE][MAX_SIZE];
37 };
39 static struct   _matrix *p_matrix;
41 static void matrix_print(struct _matrix *m)
42 {
43         int i, j;
45         /* Generate two random matrices */
46         pr_err(" \r\n Master : Linux : Printing results \r\n");
48         for (i = 0; i < m->size; ++i) {
49                 for (j = 0; j < m->size; ++j)
50                         pr_cont(" %d ", (unsigned int)m->elements[i][j]);
51                 pr_info("\r\n");
52         }
53 }
55 static void generate_matrices(int num_matrices, unsigned int matrix_size,
56                                 void *p_data)
57 {
58         int     i, j, k, val;
59         struct _matrix *p_matrix = p_data;
61         /* Generate two random matrices */
62         pr_err(" \r\n Master : Linux : Generating random matrices \r\n");
64         for (i = 0; i < num_matrices; i++) {
66                 /* Initialize workload */
67                 p_matrix[i].size = matrix_size;
69                 pr_err(" \r\n Master : Linux : Input matrix %d \r\n", i);
70                 for (j = 0; j < matrix_size; j++) {
72                         pr_info("\r\n");
73                         for (k = 0; k < matrix_size; k++) {
74                                 get_random_bytes(&val, sizeof(val));
75                                 p_matrix[i].elements[j][k] =
76                                                 ((val & 0x7F) % 10);
77                                 pr_cont(" %d ",
78                                 (unsigned int)p_matrix[i].elements[j][k]);
79                         }
80                 }
81                 pr_err("\r\n");
82         }
84 }
86 static void rpmsg_mat_mul_kern_app_rx_cb(struct rpmsg_channel *rpdev,
87                         void *data, int len, void *priv, u32 src)
88 {
89         int err;
90         int shutdown_msg = SHUTDOWN_MSG;
92         pr_err(" \r\n Master : Linux : Received %d bytes of data", len);
93         pr_err(" over rpmsg channel from remote \r\n");
95         /* Shutdown Linux if such a message is received. Only applicable
96                 when Linux is a remoteproc remote. */
97         if ((*(int *) data) == SHUTDOWN_MSG) {
98                 call_usermodehelper(shutdown_argv[0], shutdown_argv,
99                                         NULL, UMH_NO_WAIT);
100         } else {
101                 /* print results */
102                 matrix_print((struct _matrix *)data);
104                 /* Send payload to remote. */
105                 err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
106                                         &shutdown_msg, sizeof(int));
108                 if (err)
109                         pr_err(" Shutdown send failed!\r\n");
111                 kzfree(p_matrix);
112         }
115 static int rpmsg_mat_mul_kern_app_probe(struct rpmsg_channel *rpdev)
117         int     err;
119         pr_err("\r\n Demo Start - Demo rpmsg driver got probed \r\n");
120         pr_err("since the rpmsg device associated with driver was found !\r\n");
122         pr_err("\r\n Create endpoint and register rx callback \r\n");
123         /* Create endpoint for remote channel and register rx callabck */
124         ept = rpmsg_create_ept(rpdev, rpmsg_mat_mul_kern_app_rx_cb, 0,
125                                 RPMSG_ADDR_ANY);
127         if (!ept) {
128                 pr_err(" Endpoint creation for failed!\r\n");
129                 return -ENOMEM;
130         }
132         /* Send init message to complete the connection loop */
133         err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
134                                 init_msg, sizeof(init_msg));
136         if (err) {
137                 pr_err(" Init messages send failed!\r\n");
138                 return err;
139         }
141         /* Allocate memory for random matrices */
142         p_matrix = kzalloc(sizeof(struct _matrix)*2, GFP_KERNEL);
144         /* Generate random matrices */
145         generate_matrices(NUM_MATRIX, MAX_SIZE, p_matrix);
147         /* Send matrices to remote for computation */
148         err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
149                                 p_matrix, sizeof(struct _matrix) * 2);
151         pr_err("\r\n Master : Linux : Sent %d bytes of data over rpmsg channel to remote \r\n",
152                 sizeof(struct _matrix) * 2);
154         if (err) {
155                 pr_err(" send failed!\r\n");
156                 return err;
157         }
159         return 0;
162 static void rpmsg_mat_mul_kern_app_remove(struct rpmsg_channel *rpdev)
164         rpmsg_destroy_ept(ept);
167 static void rpmsg_cb(struct rpmsg_channel *rpdev, void *data,
168                                         int len, void *priv, u32 src)
173 static struct rpmsg_device_id rpmsg_mat_mul_kern_app_id_table[] = {
174         { .name = "rpmsg-openamp-demo-channel" },
175         { },
176 };
177 MODULE_DEVICE_TABLE(rpmsg, rpmsg_mat_mul_kern_app_id_table);
179 static struct rpmsg_driver rpmsg_mat_mul_kern_app = {
180         .drv.name       = KBUILD_MODNAME,
181         .drv.owner      = THIS_MODULE,
182         .id_table       = rpmsg_mat_mul_kern_app_id_table,
183         .probe          = rpmsg_mat_mul_kern_app_probe,
184         .callback       = rpmsg_cb,
185         .remove = rpmsg_mat_mul_kern_app_remove,
186 };
188 static int __init init(void)
190         return register_rpmsg_driver(&rpmsg_mat_mul_kern_app);
193 static void __exit fini(void)
195         unregister_rpmsg_driver(&rpmsg_mat_mul_kern_app);
198 module_init(init);
199 module_exit(fini);
201 MODULE_DESCRIPTION("Sample rpmsg matrix multiplication kernel application");
202 MODULE_LICENSE("GPL v2");