1/*
2 * Copyright 2016, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(D61_BSD)
11 */
12
13#include "dspace.h"
14#include "stdio_dspace.h"
15#include "screen_dspace.h"
16
17 /*! @file
18     @brief Common dataspace interface functions.
19
20     This module implements the actual functions defined in <refos-rpc/data_server.h>, and then
21     analyses the parameters to decide which dataspace to delegate the message to. If the parameters
22     indicate the message should be handed off to the serial / screen dataspace, this module then
23     calls the corresponding dataspace interface function of the correct serial / screen dataspace.
24*/
25
26seL4_CPtr
27data_open_handler(void *rpc_userptr , char* rpc_name , int rpc_flags , int rpc_mode , int rpc_size ,
28                  int* rpc_errno)
29{
30    if (!rpc_name) {
31        SET_ERRNO_PTR(rpc_errno, EFILENOTFOUND);
32        return 0;
33    }
34
35    /* Handle stdio / serial dataspace open requests. */
36    if (strcmp(rpc_name, "serial") == 0 || strcmp(rpc_name, "stdio") == 0) {
37        return serial_open_handler(rpc_userptr, rpc_name, rpc_flags, rpc_mode, rpc_size, rpc_errno);
38    }
39
40    /* Handle screen dataspace open requests. */
41    if (strcmp(rpc_name, "screen") == 0 || strcmp(rpc_name, "keyboard") == 0) {
42        return screen_open_handler(rpc_userptr, rpc_name, rpc_flags, rpc_mode, rpc_size, rpc_errno);
43    }
44
45    SET_ERRNO_PTR(rpc_errno, EFILENOTFOUND);
46    return 0;
47}
48
49refos_err_t
50data_close_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd)
51{
52    struct srv_client *c = (struct srv_client *) rpc_userptr;
53    srv_msg_t *m = (srv_msg_t *) c->rpcClient.userptr;
54    assert(c && (c->magic == CONSERV_DISPATCH_ANON_CLIENT_MAGIC ||
55           c->magic == CONSERV_CLIENT_MAGIC));
56
57    if (!srv_check_dispatch_caps(m, 0x00000001, 1)) {
58        return EINVALIDPARAM;
59    }
60
61    /* No need to close stdio / serial dataspaces. */
62    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_STDIO) {
63        return ESUCCESS;
64    }
65
66    /* No need to close screen dataspaces. */
67    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_SCREEN) {
68        return ESUCCESS;
69    }
70
71    return EFILENOTFOUND;
72}
73
74int
75data_read_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , uint32_t rpc_offset ,
76                  rpc_buffer_t rpc_buf , uint32_t rpc_count)
77{
78    struct srv_client *c = (struct srv_client *) rpc_userptr;
79    srv_msg_t *m = (srv_msg_t *) c->rpcClient.userptr;
80    assert(c && (c->magic == CONSERV_DISPATCH_ANON_CLIENT_MAGIC || c->magic == CONSERV_CLIENT_MAGIC));
81
82    if (!srv_check_dispatch_caps(m, 0x00000001, 1)) {
83        return -EINVALIDPARAM;
84    }
85
86    /* Handle read from stdio / serial dataspaces. */
87    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_STDIO) {
88        return -EACCESSDENIED;
89    }
90
91    /* Handle read from screen dataspaces. */
92    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_SCREEN) {
93        return -EACCESSDENIED;
94    }
95
96    return -EFILENOTFOUND;
97}
98
99int
100data_write_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , uint32_t rpc_offset ,
101                   rpc_buffer_t rpc_buf , uint32_t rpc_count)
102{
103    struct srv_client *c = (struct srv_client *) rpc_userptr;
104    srv_msg_t *m = (srv_msg_t *) c->rpcClient.userptr;
105    assert(c && (c->magic == CONSERV_DISPATCH_ANON_CLIENT_MAGIC || c->magic == CONSERV_CLIENT_MAGIC));
106
107    if (!srv_check_dispatch_caps(m, 0x00000001, 1)) {
108        return -EINVALIDPARAM;
109    }
110
111    /* Handle write to stdio / serial dataspaces. */
112    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_STDIO) {
113        return serial_write_handler(rpc_userptr, rpc_dspace_fd, rpc_offset, rpc_buf, rpc_count);
114    }
115
116    /* Handle write to screen dataspaces. */
117    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_SCREEN) {
118        return screen_write_handler(rpc_userptr, rpc_dspace_fd, rpc_offset, rpc_buf, rpc_count);
119    }
120
121    return -EFILENOTFOUND;
122}
123
124int
125data_getc_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , int rpc_block)
126{
127    struct srv_client *c = (struct srv_client *) rpc_userptr;
128    srv_msg_t *m = (srv_msg_t *) c->rpcClient.userptr;
129
130    if (c->magic == CONSERV_DISPATCH_ANON_CLIENT_MAGIC) {
131        return -1;
132    }
133    if (!srv_check_dispatch_caps(m, 0x00000001, 1)) {
134        return -1;
135    }
136
137    /* Handle getc stdio / serial dataspaces. */
138    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_STDIO) {
139        return serial_getc_handler(rpc_userptr, rpc_dspace_fd, rpc_block);
140    }
141
142    /* Handle getc screen dataspaces. */
143    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_SCREEN) {
144        return screen_getc_handler(rpc_userptr, rpc_dspace_fd, rpc_block);
145    }
146
147    return -1;
148}
149
150refos_err_t
151data_expand_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , uint32_t rpc_size)
152{
153    return EUNIMPLEMENTED;
154}
155
156refos_err_t
157data_putc_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , int rpc_c)
158{
159    struct srv_client *c = (struct srv_client *) rpc_userptr;
160    srv_msg_t *m = (srv_msg_t *) c->rpcClient.userptr;
161    assert(c && (c->magic == CONSERV_DISPATCH_ANON_CLIENT_MAGIC || c->magic == CONSERV_CLIENT_MAGIC));
162
163    if (!srv_check_dispatch_caps(m, 0x00000001, 1)) {
164        return EINVALIDPARAM;
165    }
166
167    /* Handle close stdio / serial dataspaces. */
168    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_STDIO) {
169        return serial_putc_handler(rpc_userptr, rpc_dspace_fd, rpc_c);
170    }
171
172    /* Handle close screen dataspaces. */
173    if (rpc_dspace_fd == CONSERV_DSPACE_BADGE_SCREEN) {
174        return screen_putc_handler(rpc_userptr, rpc_dspace_fd, rpc_c);
175    }
176
177    return EFILENOTFOUND;
178}
179
180off_t
181data_lseek_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , off_t rpc_offset , int rpc_whence)
182{
183    assert(!"data_lseek_handler unimplemented.");
184    return 0;
185}
186
187uint32_t
188data_get_size_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd)
189{
190    return 0;
191}
192
193refos_err_t
194data_datamap_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , seL4_CPtr rpc_memoryWindow ,
195                     uint32_t rpc_offset)
196{
197    assert(!"data_datamap_handler unimplemented.");
198    return EUNIMPLEMENTED;
199}
200
201refos_err_t
202data_dataunmap_handler(void *rpc_userptr , seL4_CPtr rpc_memoryWindow)
203{
204    assert(!"data_dataunmap_handler unimplemented.");
205    return EUNIMPLEMENTED;
206}
207
208refos_err_t
209data_init_data_handler(void *rpc_userptr , seL4_CPtr rpc_destDataspace , seL4_CPtr rpc_srcDataspace,
210                       uint32_t rpc_srcDataspaceOffset)
211{
212    assert(!"data_init_data_handler unimplemented.");
213    return EUNIMPLEMENTED;
214}
215
216refos_err_t
217data_have_data_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , seL4_CPtr rpc_faultNotifyEP ,
218                       uint32_t* rpc_dataID)
219{
220    assert(!"data_have_data_handler unimplemented.");
221    return EUNIMPLEMENTED;
222}
223
224refos_err_t
225data_unhave_data_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd)
226{
227    assert(!"data_unhave_data_handler unimplemented.");
228    return EUNIMPLEMENTED;
229}
230
231refos_err_t
232data_provide_data_from_parambuffer_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd ,
233                                           uint32_t rpc_offset , uint32_t rpc_contentSize)
234{
235    assert(!"data_provide_data_from_parambuffer_handler unimplemented.");
236    return EUNIMPLEMENTED;
237}
238
239int
240check_dispatch_data(srv_msg_t *m, void **userptr)
241{
242    return check_dispatch_interface(m, userptr, RPC_DATA_LABEL_MIN, RPC_DATA_LABEL_MAX);
243}