]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/vcon.h
update
[l4.git] / l4 / pkg / l4sys / include / vcon.h
1 /**
2  * \file
3  * \brief Virtual console interface.
4  */
5 /*
6  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
8  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
9  *     economic rights: Technische Universität Dresden (Germany)
10  *
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  *
15  * As a special exception, you may use this file as part of a free software
16  * library without restriction.  Specifically, if other files instantiate
17  * templates or use macros or inline functions from this file, or you compile
18  * this file and link it with other files to produce an executable, this
19  * file does not by itself cause the resulting executable to be covered by
20  * the GNU General Public License.  This exception does not however
21  * invalidate any other reasons why the executable file might be covered by
22  * the GNU General Public License.
23  */
24 #pragma once
25
26 #include <l4/sys/ipc.h>
27
28 /**
29  * \defgroup l4_vcon_api Virtual Console
30  * \ingroup  l4_kernel_object_api
31  * \brief Virtual console for simple character based input and output.
32  *
33  * <c>\#include <l4/sys/vcon.h></c>
34  *
35  * Interrupt for read events are provided by the virtual key interrupt.
36  */
37
38 /**
39  * \brief Send data to virtual console.
40  * \ingroup l4_vcon_api
41  *
42  * \param vcon    Vcon object.
43  * \param buf     Pointer to data buffer.
44  * \param size    Size of buffer in bytes.
45  *
46  * \return Syscall return tag
47  *
48  * \note Size must not exceed L4_VCON_WRITE_SIZE.
49  */
50 L4_INLINE l4_msgtag_t
51 l4_vcon_send(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW;
52
53 /**
54  * \internal
55  */
56 L4_INLINE l4_msgtag_t
57 l4_vcon_send_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW;
58
59
60 /**
61  * \brief Write data to virtual console.
62  * \ingroup l4_vcon_api
63  *
64  * \param vcon    Vcon object.
65  * \param buf     Pointer to data buffer.
66  * \param size    Size of buffer in bytes.
67  *
68  * \return Number of bytes written to the virtual console.
69  */
70 L4_INLINE long
71 l4_vcon_write(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW;
72
73 /**
74  * \internal
75  */
76 L4_INLINE long
77 l4_vcon_write_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW;
78
79 /**
80  * \brief Constants for l4_vcon_write.
81  * \ingroup l4_vcon_api
82  */
83 enum L4_vcon_write_consts
84 {
85   /** Maximum size that can be written with one l4_vcon_write call. */
86   L4_VCON_WRITE_SIZE = (L4_UTCB_GENERIC_DATA_SIZE - 2) * sizeof(l4_umword_t),
87 };
88
89 /**
90  * \brief Read data from virtual console.
91  * \ingroup l4_vcon_api
92  *
93  * \param vcon    Vcon object.
94  * \param buf     Pointer to data buffer.
95  * \param size    Size of buffer in bytes.
96  *
97  * \return Negative error code on error,
98  *         > size if more to read, size bytes are in the buffer,
99  *         <= size bytes read
100  */
101 L4_INLINE int
102 l4_vcon_read(l4_cap_idx_t vcon, char *buf, int size) L4_NOTHROW;
103
104 /**
105  * \internal
106  */
107 L4_INLINE int
108 l4_vcon_read_u(l4_cap_idx_t vcon, char *buf, int size, l4_utcb_t *utcb) L4_NOTHROW;
109
110
111 /**
112  * \brief Vcon attribute structure.
113  * \ingroup l4_vcon_api
114  */
115 typedef struct l4_vcon_attr_t
116 {
117   l4_umword_t i_flags; ///< input flags
118   l4_umword_t o_flags; ///< output flags
119   l4_umword_t l_flags; ///< local flags
120 } l4_vcon_attr_t;
121
122 /**
123  * \brief Input flags.
124  * \ingroup l4_vcon_api
125  */
126 enum L4_vcon_i_flags
127 {
128   L4_VCON_INLCR  = 000100, ///< Translate NL to CR
129   L4_VCON_IGNCR  = 000200, ///< Ignore CR
130   L4_VCON_ICRNL  = 000400, ///< Translate CR to NL if L4_VCON_IGNCR is not set
131 };
132
133 /**
134  * \brief Output flags.
135  * \ingroup l4_vcon_api
136  */
137 enum L4_vcon_o_flags
138 {
139   L4_VCON_ONLCR  = 000004, ///< Translate NL to CR-NL
140   L4_VCON_OCRNL  = 000010, ///< Translate CR to NL
141   L4_VCON_ONLRET = 000040, ///< Do not ouput CR
142 };
143
144 /**
145  * \brief Local flags.
146  * \ingroup l4_vcon_api
147  */
148 enum L4_vcon_l_flags
149 {
150   L4_VCON_ECHO   = 000010,  ///< Echo input
151 };
152
153
154 /**
155  * \brief Set attributes of a Vcon.
156  * \ingroup l4_vcon_api
157  *
158  * \param vcon  Vcon object.
159  * \param attr  Attribute structure.
160  * \return Syscall return tag
161  */
162 L4_INLINE l4_msgtag_t
163 l4_vcon_set_attr(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr) L4_NOTHROW;
164
165 /**
166  * \internal
167  */
168 L4_INLINE l4_msgtag_t
169 l4_vcon_set_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr,
170                    l4_utcb_t *utcb) L4_NOTHROW;
171
172 /**
173  * \brief Get attributes of a Vcon.
174  * \ingroup l4_vcon_api
175  *
176  * \param vcon  Vcon object.
177  * \retval attr  Attribute structure.
178  * \return Syscall return tag
179  */
180 L4_INLINE l4_msgtag_t
181 l4_vcon_get_attr(l4_cap_idx_t vcon, l4_vcon_attr_t *attr) L4_NOTHROW;
182
183 /**
184  * \internal
185  */
186 L4_INLINE l4_msgtag_t
187 l4_vcon_get_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t *attr,
188                    l4_utcb_t *utcb) L4_NOTHROW;
189
190
191 /**
192  * \brief Operations on the vcon objects.
193  * \ingroup l4_vcon_api
194  * \hideinitializer
195  * \internal
196  */
197 enum L4_vcon_ops
198 {
199   L4_VCON_WRITE_OP       = 0UL,    /**< Write */
200   L4_VCON_SET_ATTR_OP    = 2UL,    /**< Get console attributes */
201   L4_VCON_GET_ATTR_OP    = 3UL,    /**< Set console attributes */
202 };
203
204 /******* Implementations ********************/
205
206 L4_INLINE l4_msgtag_t
207 l4_vcon_send_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
208 {
209   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
210   mr->mr[0] = L4_VCON_WRITE_OP;
211   mr->mr[1] = size;
212   __builtin_memcpy(&mr->mr[2], buf, size);
213   return l4_ipc_send(vcon, utcb,
214                      l4_msgtag(L4_PROTO_LOG,
215                                2 + (size + sizeof(l4_umword_t) - 1) / sizeof(l4_umword_t),
216                                0, L4_MSGTAG_SCHEDULE),
217                                L4_IPC_NEVER);
218 }
219
220 L4_INLINE l4_msgtag_t
221 l4_vcon_send(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW
222 {
223   return l4_vcon_send_u(vcon, buf, size, l4_utcb());
224 }
225
226 L4_INLINE long
227 l4_vcon_write_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
228 {
229   l4_msgtag_t t;
230
231   if (size > L4_VCON_WRITE_SIZE)
232     size = L4_VCON_WRITE_SIZE;
233
234   t = l4_vcon_send_u(vcon, buf, size, utcb);
235   if (l4_msgtag_has_error(t))
236     return l4_error(t);
237
238   return size;
239 }
240
241 L4_INLINE long
242 l4_vcon_write(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW
243 {
244   return l4_vcon_write_u(vcon, buf, size, l4_utcb());
245 }
246
247 L4_INLINE int
248 l4_vcon_read_u(l4_cap_idx_t vcon, char *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
249 {
250   int ret, r;
251   l4_msg_regs_t *mr;
252
253   if (size <= 0)
254     return -L4_EINVAL;
255
256   mr = l4_utcb_mr_u(utcb);
257   mr->mr[0] = size << 16;
258
259   ret = l4_error_u(l4_ipc_call(vcon, utcb,
260                                l4_msgtag(L4_PROTO_LOG, 1, 0, 0),
261                                L4_IPC_NEVER), utcb);
262   if (ret < 0)
263     return ret;
264
265   r = mr->mr[0] & ~(1U << 31);
266
267   if (!(mr->mr[0] & (1UL << 31))) // !eof
268     ret = size + 1;
269   else if (r < size)
270     ret = r;
271   else
272     ret = size;
273
274   __builtin_memcpy(buf, &mr->mr[1], r);
275   return ret;
276 }
277
278 L4_INLINE int
279 l4_vcon_read(l4_cap_idx_t vcon, char *buf, int size) L4_NOTHROW
280 {
281   return l4_vcon_read_u(vcon, buf, size, l4_utcb());
282 }
283
284 L4_INLINE l4_msgtag_t
285 l4_vcon_set_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr,
286                    l4_utcb_t *utcb) L4_NOTHROW
287 {
288   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
289
290   mr->mr[0] = L4_VCON_SET_ATTR_OP;
291   __builtin_memcpy(&mr->mr[1], attr, sizeof(*attr));
292
293   return l4_ipc_call(vcon, utcb,
294                      l4_msgtag(L4_PROTO_LOG, 4, 0, 0),
295                      L4_IPC_NEVER);
296 }
297
298 L4_INLINE l4_msgtag_t
299 l4_vcon_set_attr(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr) L4_NOTHROW
300 {
301   return l4_vcon_set_attr_u(vcon, attr, l4_utcb());
302 }
303
304 L4_INLINE l4_msgtag_t
305 l4_vcon_get_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t *attr,
306                    l4_utcb_t *utcb) L4_NOTHROW
307 {
308   l4_msgtag_t res;
309   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
310
311   mr->mr[0] = L4_VCON_GET_ATTR_OP;
312
313   res = l4_ipc_call(vcon, utcb,
314                     l4_msgtag(L4_PROTO_LOG, 1, 0, 0),
315                     L4_IPC_NEVER);
316   if (l4_error_u(res, utcb) >= 0)
317     __builtin_memcpy(attr, &mr->mr[1], sizeof(*attr));
318
319   return res;
320 }
321
322 L4_INLINE l4_msgtag_t
323 l4_vcon_get_attr(l4_cap_idx_t vcon, l4_vcon_attr_t *attr) L4_NOTHROW
324 {
325   return l4_vcon_get_attr_u(vcon, attr, l4_utcb());
326 }