]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/vcon.h
f9828651c40657932225c5f2c822a0df03d6919f
[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_ICANON = 000002,  ///< Cannonical mode
151   L4_VCON_ECHO   = 000010,  ///< Echo input
152 };
153
154
155 /**
156  * \brief Set attributes of a Vcon.
157  * \ingroup l4_vcon_api
158  *
159  * \param vcon  Vcon object.
160  * \param attr  Attribute structure.
161  * \return Syscall return tag
162  */
163 L4_INLINE l4_msgtag_t
164 l4_vcon_set_attr(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr) L4_NOTHROW;
165
166 /**
167  * \internal
168  */
169 L4_INLINE l4_msgtag_t
170 l4_vcon_set_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr,
171                    l4_utcb_t *utcb) L4_NOTHROW;
172
173 /**
174  * \brief Get attributes of a Vcon.
175  * \ingroup l4_vcon_api
176  *
177  * \param vcon  Vcon object.
178  * \retval attr  Attribute structure.
179  * \return Syscall return tag
180  */
181 L4_INLINE l4_msgtag_t
182 l4_vcon_get_attr(l4_cap_idx_t vcon, l4_vcon_attr_t *attr) L4_NOTHROW;
183
184 /**
185  * \internal
186  */
187 L4_INLINE l4_msgtag_t
188 l4_vcon_get_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t *attr,
189                    l4_utcb_t *utcb) L4_NOTHROW;
190
191
192 /**
193  * \brief Operations on the vcon objects.
194  * \ingroup l4_vcon_api
195  * \hideinitializer
196  * \internal
197  */
198 enum L4_vcon_ops
199 {
200   L4_VCON_WRITE_OP       = 0UL,    /**< Write */
201   L4_VCON_SET_ATTR_OP    = 2UL,    /**< Get console attributes */
202   L4_VCON_GET_ATTR_OP    = 3UL,    /**< Set console attributes */
203 };
204
205 /******* Implementations ********************/
206
207 L4_INLINE l4_msgtag_t
208 l4_vcon_send_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
209 {
210   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
211   mr->mr[0] = L4_VCON_WRITE_OP;
212   mr->mr[1] = size;
213   __builtin_memcpy(&mr->mr[2], buf, size);
214   return l4_ipc_send(vcon, utcb,
215                      l4_msgtag(L4_PROTO_LOG,
216                                2 + (size + sizeof(l4_umword_t) - 1) / sizeof(l4_umword_t),
217                                0, L4_MSGTAG_SCHEDULE),
218                                L4_IPC_NEVER);
219 }
220
221 L4_INLINE l4_msgtag_t
222 l4_vcon_send(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW
223 {
224   return l4_vcon_send_u(vcon, buf, size, l4_utcb());
225 }
226
227 L4_INLINE long
228 l4_vcon_write_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
229 {
230   l4_msgtag_t t;
231
232   if (size > L4_VCON_WRITE_SIZE)
233     size = L4_VCON_WRITE_SIZE;
234
235   t = l4_vcon_send_u(vcon, buf, size, utcb);
236   if (l4_msgtag_has_error(t))
237     return l4_error(t);
238
239   return size;
240 }
241
242 L4_INLINE long
243 l4_vcon_write(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW
244 {
245   return l4_vcon_write_u(vcon, buf, size, l4_utcb());
246 }
247
248 L4_INLINE int
249 l4_vcon_read_u(l4_cap_idx_t vcon, char *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
250 {
251   int ret, r;
252   l4_msg_regs_t *mr;
253
254   if (size <= 0)
255     return -L4_EINVAL;
256
257   mr = l4_utcb_mr_u(utcb);
258   mr->mr[0] = size << 16;
259
260   ret = l4_error_u(l4_ipc_call(vcon, utcb,
261                                l4_msgtag(L4_PROTO_LOG, 1, 0, 0),
262                                L4_IPC_NEVER), utcb);
263   if (ret < 0)
264     return ret;
265
266   r = mr->mr[0] & ~(1U << 31);
267
268   if (!(mr->mr[0] & (1UL << 31))) // !eof
269     ret = size + 1;
270   else if (r < size)
271     ret = r;
272   else
273     ret = size;
274
275   __builtin_memcpy(buf, &mr->mr[1], r < size ? r : size);
276   return ret;
277 }
278
279 L4_INLINE int
280 l4_vcon_read(l4_cap_idx_t vcon, char *buf, int size) L4_NOTHROW
281 {
282   return l4_vcon_read_u(vcon, buf, size, l4_utcb());
283 }
284
285 L4_INLINE l4_msgtag_t
286 l4_vcon_set_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr,
287                    l4_utcb_t *utcb) L4_NOTHROW
288 {
289   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
290
291   mr->mr[0] = L4_VCON_SET_ATTR_OP;
292   __builtin_memcpy(&mr->mr[1], attr, sizeof(*attr));
293
294   return l4_ipc_call(vcon, utcb,
295                      l4_msgtag(L4_PROTO_LOG, 4, 0, 0),
296                      L4_IPC_NEVER);
297 }
298
299 L4_INLINE l4_msgtag_t
300 l4_vcon_set_attr(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr) L4_NOTHROW
301 {
302   return l4_vcon_set_attr_u(vcon, attr, l4_utcb());
303 }
304
305 L4_INLINE l4_msgtag_t
306 l4_vcon_get_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t *attr,
307                    l4_utcb_t *utcb) L4_NOTHROW
308 {
309   l4_msgtag_t res;
310   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
311
312   mr->mr[0] = L4_VCON_GET_ATTR_OP;
313
314   res = l4_ipc_call(vcon, utcb,
315                     l4_msgtag(L4_PROTO_LOG, 1, 0, 0),
316                     L4_IPC_NEVER);
317   if (l4_error_u(res, utcb) >= 0)
318     __builtin_memcpy(attr, &mr->mr[1], sizeof(*attr));
319
320   return res;
321 }
322
323 L4_INLINE l4_msgtag_t
324 l4_vcon_get_attr(l4_cap_idx_t vcon, l4_vcon_attr_t *attr) L4_NOTHROW
325 {
326   return l4_vcon_get_attr_u(vcon, attr, l4_utcb());
327 }