Use lib/ for source files for OpenAMP library
[processor-sdk/open-amp.git] / lib / proxy / rpmsg_retarget.c
1 #include "openamp/open_amp.h"
2 #include "openamp/rpmsg_retarget.h"
3 #include <stdio.h>
4 #include <string.h>
5 #include <fcntl.h>
7 /*************************************************************************
8  *      Description
9  *      This files contains rpmsg based redefinitions for C RTL system calls
10  *      such as _open, _read, _write, _close.
11  *************************************************************************/
12 static struct _rpc_data *rpc_data;
13 static unsigned int rpc_data_synclock = 0;
14 int get_response = 0;
16 int send_rpc(void *data, int len);
17 static int rpc_count = 0;
19 void rpc_cb(struct rpmsg_channel *rtl_rp_chnl, void *data, int len, void *priv,
20             unsigned long src)
21 {
22         memcpy(rpc_data->rpc_response, data, len);
23         env_release_sync_lock(rpc_data->sync_lock);
24         get_response = 1;
26         if (rpc_data->rpc_response->id == TERM_SYSCALL_ID) {
27                 /* Application terminate signal is received from the proxy app,
28                  * so let the application know of terminate message.
29                  */
30                 rpc_data->shutdown_cb(rtl_rp_chnl);
31         }
32 }
34 int send_rpc(void *data, int len)
35 {
36         int retval;
38         retval = rpmsg_sendto(rpc_data->rpmsg_chnl, data, len, PROXY_ENDPOINT);
39         return retval;
40 }
42 int rpmsg_retarget_init(struct rpmsg_channel *rp_chnl, rpc_shutdown_cb cb)
43 {
44         int status;
46         /* Allocate memory for rpc control block */
47         rpc_data =
48             (struct _rpc_data *)env_allocate_memory(sizeof(struct _rpc_data));
50         /* Create a mutex for synchronization */
51         status = env_create_mutex(&rpc_data->rpc_lock, 1);
53         /* Create a mutex for synchronization */
54         status = env_create_sync_lock(&rpc_data->sync_lock, LOCKED);
56         /* Create a endpoint to handle rpc response from master */
57         rpc_data->rpmsg_chnl = rp_chnl;
58         rpc_data->rp_ept = rpmsg_create_ept(rpc_data->rpmsg_chnl, rpc_cb,
59                                             RPMSG_NULL, PROXY_ENDPOINT);
60         rpc_data->rpc = env_allocate_memory(RPC_BUFF_SIZE);
61         rpc_data->rpc_response = env_allocate_memory(RPC_BUFF_SIZE);
62         rpc_data->shutdown_cb = cb;
64         return status;
65 }
67 int rpmsg_retarget_deinit(struct rpmsg_channel *rp_chnl)
68 {
69         env_free_memory(rpc_data->rpc);
70         env_free_memory(rpc_data->rpc_response);
71         env_delete_mutex(rpc_data->rpc_lock);
72         env_delete_sync_lock(rpc_data->sync_lock);
73         rpmsg_destroy_ept(rpc_data->rp_ept);
74         env_free_memory(rpc_data);
76         return 0;
77 }
79 int rpmsg_retarget_send(void *data, int len)
80 {
81         return send_rpc(data, len);
82 }
84 /*************************************************************************
85  *
86  *   FUNCTION
87  *
88  *       _open
89  *
90  *   DESCRIPTION
91  *
92  *       Open a file.  Minimal implementation
93  *
94  *************************************************************************/
95 int _open(const char *filename, int flags, int mode)
96 {
97         int filename_len = strlen(filename) + 1;
98         int payload_size = sizeof(struct _sys_rpc) + filename_len;
99         int retval = -1;
101         if ((!filename) || (filename_len > FILE_NAME_LEN)) {
102                 return -1;
103         }
105         /* Construct rpc payload */
106         rpc_data->rpc->id = OPEN_SYSCALL_ID;
107         rpc_data->rpc->sys_call_args.int_field1 = flags;
108         rpc_data->rpc->sys_call_args.int_field2 = mode;
109         rpc_data->rpc->sys_call_args.data_len = filename_len;
110         memcpy(&rpc_data->rpc->sys_call_args.data, filename, filename_len);
112         /* Transmit rpc request */
113         env_lock_mutex(rpc_data->rpc_lock);
114         send_rpc((void *)rpc_data->rpc, payload_size);
115         env_unlock_mutex(rpc_data->rpc_lock);
117         /* Wait for response from proxy on master */
118         env_acquire_sync_lock(rpc_data->sync_lock);
120         /* Obtain return args and return to caller */
121         if (rpc_data->rpc_response->id == OPEN_SYSCALL_ID) {
122                 retval = rpc_data->rpc_response->sys_call_args.int_field1;
123         }
125         return retval;
128 /*************************************************************************
129  *
130  *   FUNCTION
131  *
132  *       _read
133  *
134  *   DESCRIPTION
135  *
136  *       Low level function to redirect IO to serial.
137  *
138  *************************************************************************/
139 int _read(int fd, char *buffer, int buflen)
141         int payload_size = sizeof(struct _sys_rpc);
142         int retval = -1;
144         if (!buffer || !buflen)
145                 return retval;
147         /* Construct rpc payload */
148         rpc_data->rpc->id = READ_SYSCALL_ID;
149         rpc_data->rpc->sys_call_args.int_field1 = fd;
150         rpc_data->rpc->sys_call_args.int_field2 = buflen;
151         rpc_data->rpc->sys_call_args.data_len = 0;      /*not used */
153         /* Transmit rpc request */
154         env_lock_mutex(rpc_data->rpc_lock);
155         get_response = 0;
156         send_rpc((void *)rpc_data->rpc, payload_size);
157         env_unlock_mutex(rpc_data->rpc_lock);
159         /* Wait for response from proxy on master */
160         env_acquire_sync_lock(rpc_data->sync_lock);
162         /* Obtain return args and return to caller */
163         if (rpc_data->rpc_response->id == READ_SYSCALL_ID) {
164                 if (rpc_data->rpc_response->sys_call_args.int_field1 > 0) {
165                         memcpy(buffer,
166                                rpc_data->rpc_response->sys_call_args.data,
167                                rpc_data->rpc_response->sys_call_args.data_len);
168                 }
170                 retval = rpc_data->rpc_response->sys_call_args.int_field1;
171         }
173         return retval;
176 /*************************************************************************
177  *
178  *   FUNCTION
179  *
180  *       _write
181  *
182  *   DESCRIPTION
183  *
184  *       Low level function to redirect IO to serial.
185  *
186  *************************************************************************/
187 int _write(int fd, const char *ptr, int len)
189         int retval = -1;
190         int payload_size = sizeof(struct _sys_rpc) + len;
191         int null_term = 0;
193         if (fd == 1) {
194                 null_term = 1;
195         }
197         rpc_data->rpc->id = WRITE_SYSCALL_ID;
198         rpc_data->rpc->sys_call_args.int_field1 = fd;
199         rpc_data->rpc->sys_call_args.int_field2 = len;
200         rpc_data->rpc->sys_call_args.data_len = len + null_term;
201         memcpy(rpc_data->rpc->sys_call_args.data, ptr, len);
202         if (null_term) {
203                 *(char *)(rpc_data->rpc->sys_call_args.data + len + null_term) =
204                     0;
205         }
207         env_lock_mutex(rpc_data->rpc_lock);
208         send_rpc((void *)rpc_data->rpc, payload_size);
209         env_unlock_mutex(rpc_data->rpc_lock);
211         env_acquire_sync_lock(rpc_data->sync_lock);
213         if (rpc_data->rpc_response->id == WRITE_SYSCALL_ID) {
214                 retval = rpc_data->rpc_response->sys_call_args.int_field1;
215         }
217         return retval;
221 /*************************************************************************
222  *
223  *   FUNCTION
224  *
225  *       _close
226  *
227  *   DESCRIPTION
228  *
229  *       Close a file.  Minimal implementation
230  *
231  *************************************************************************/
232 int _close(int fd)
234         int payload_size = sizeof(struct _sys_rpc);
235         int retval = -1;
237         rpc_data->rpc->id = CLOSE_SYSCALL_ID;
238         rpc_data->rpc->sys_call_args.int_field1 = fd;
239         rpc_data->rpc->sys_call_args.int_field2 = 0;    /*not used */
240         rpc_data->rpc->sys_call_args.data_len = 0;      /*not used */
242         env_lock_mutex(rpc_data->rpc_lock);
243         send_rpc((void *)rpc_data->rpc, payload_size);
244         env_unlock_mutex(rpc_data->rpc_lock);
246         /* Wait for response from proxy on master */
247         env_acquire_sync_lock(rpc_data->sync_lock);
249         if (rpc_data->rpc_response->id == CLOSE_SYSCALL_ID) {
250                 retval = rpc_data->rpc_response->sys_call_args.int_field1;
251         }
253         return retval;