]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/vcon.h
6bd01fbc7d2fffeacc08a66db6eea847d18479ab
[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 Write 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_write(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_write_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW;
58
59 /**
60  * \brief Constants for l4_vcon_write.
61  * \ingroup l4_vcon_api
62  */
63 enum L4_vcon_write_consts
64 {
65   /** Maximum size that can be written with one l4_vcon_write call. */
66   L4_VCON_WRITE_SIZE = (L4_UTCB_GENERIC_DATA_SIZE - 2) * sizeof(l4_umword_t),
67 };
68
69 /**
70  * \brief Read data from virtual console.
71  * \ingroup l4_vcon_api
72  *
73  * \param vcon    Vcon object.
74  * \param buf     Pointer to data buffer.
75  * \param size    Size of buffer in bytes.
76  *
77  * \return Negative error code on error,
78  *         > size if more to read, size bytes are in the buffer,
79  *         <= size bytes read
80  */
81 L4_INLINE int
82 l4_vcon_read(l4_cap_idx_t vcon, char *buf, int size) L4_NOTHROW;
83
84 /**
85  * \internal
86  */
87 L4_INLINE int
88 l4_vcon_read_u(l4_cap_idx_t vcon, char *buf, int size, l4_utcb_t *utcb) L4_NOTHROW;
89
90
91 /**
92  * \brief Vcon attribute structure.
93  * \ingroup l4_vcon_api
94  */
95 typedef struct l4_vcon_attr_t
96 {
97   l4_umword_t i_flags; ///< input flags
98   l4_umword_t o_flags; ///< output flags
99   l4_umword_t l_flags; ///< local flags
100 } l4_vcon_attr_t;
101
102 /**
103  * \brief Input flags.
104  * \ingroup l4_vcon_api
105  */
106 enum L4_vcon_i_flags
107 {
108   L4_VCON_INLCR  = 000100, ///< Translate NL to CR
109   L4_VCON_IGNCR  = 000200, ///< Ignore CR
110   L4_VCON_ICRNL  = 000400, ///< Translate CR to NL if L4_VCON_IGNCR is not set
111 };
112
113 /**
114  * \brief Output flags.
115  * \ingroup l4_vcon_api
116  */
117 enum L4_vcon_o_flags
118 {
119   L4_VCON_ONLCR  = 000004, ///< Translate NL to CR-NL
120   L4_VCON_OCRNL  = 000010, ///< Translate CR to NL
121   L4_VCON_ONLRET = 000040, ///< Do not ouput CR
122 };
123
124 /**
125  * \brief Local flags.
126  * \ingroup l4_vcon_api
127  */
128 enum L4_vcon_l_flags
129 {
130   L4_VCON_ECHO   = 000010,  ///< Echo input
131 };
132
133
134 /**
135  * \brief Set attributes of a Vcon.
136  * \ingroup l4_vcon_api
137  *
138  * \param vcon  Vcon object.
139  * \param attr  Attribute structure.
140  * \return Syscall return tag
141  */
142 L4_INLINE l4_msgtag_t
143 l4_vcon_set_attr(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr) L4_NOTHROW;
144
145 /**
146  * \internal
147  */
148 L4_INLINE l4_msgtag_t
149 l4_vcon_set_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr,
150                    l4_utcb_t *utcb) L4_NOTHROW;
151
152 /**
153  * \brief Get attributes of a Vcon.
154  * \ingroup l4_vcon_api
155  *
156  * \param vcon  Vcon object.
157  * \retval attr  Attribute structure.
158  * \return Syscall return tag
159  */
160 L4_INLINE l4_msgtag_t
161 l4_vcon_get_attr(l4_cap_idx_t vcon, l4_vcon_attr_t *attr) L4_NOTHROW;
162
163 /**
164  * \internal
165  */
166 L4_INLINE l4_msgtag_t
167 l4_vcon_get_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t *attr,
168                    l4_utcb_t *utcb) L4_NOTHROW;
169
170
171 /**
172  * \brief Operations on the vcon objects.
173  * \ingroup l4_vcon_api
174  * \hideinitializer
175  * \internal
176  */
177 enum L4_vcon_ops
178 {
179   L4_VCON_WRITE_OP       = 0UL,    /**< Write */
180   L4_VCON_SET_ATTR_OP    = 2UL,    /**< Get console attributes */
181   L4_VCON_GET_ATTR_OP    = 3UL,    /**< Set console attributes */
182 };
183
184 /******* Implementations ********************/
185
186 L4_INLINE l4_msgtag_t
187 l4_vcon_write_u(l4_cap_idx_t vcon, char const *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
188 {
189   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
190   mr->mr[0] = L4_VCON_WRITE_OP;
191   mr->mr[1] = size;
192   __builtin_memcpy(&mr->mr[2], buf, size);
193   return l4_ipc_send(vcon, utcb,
194                      l4_msgtag(L4_PROTO_LOG,
195                                2 + (size + sizeof(l4_umword_t) - 1) / sizeof(l4_umword_t),
196                                0, L4_MSGTAG_SCHEDULE),
197                                L4_IPC_NEVER);
198 }
199
200 L4_INLINE int
201 l4_vcon_read_u(l4_cap_idx_t vcon, char *buf, int size, l4_utcb_t *utcb) L4_NOTHROW
202 {
203   int ret, r;
204   l4_msg_regs_t *mr;
205
206   if (size <= 0)
207     return -L4_EINVAL;
208
209   mr = l4_utcb_mr_u(utcb);
210   mr->mr[0] = size << 16;
211
212   ret = l4_error_u(l4_ipc_call(vcon, utcb,
213                                l4_msgtag(L4_PROTO_LOG, 1, 0, 0),
214                                L4_IPC_NEVER), utcb);
215   if (ret < 0)
216     return ret;
217
218   r = mr->mr[0] & ~(1U << 31);
219
220   if (!(mr->mr[0] & (1UL << 31))) // !eof
221     ret = size + 1;
222   else if (r < size)
223     ret = r;
224   else
225     ret = size;
226
227   __builtin_memcpy(buf, &mr->mr[1], r);
228   return ret;
229 }
230
231 L4_INLINE l4_msgtag_t
232 l4_vcon_write(l4_cap_idx_t vcon, char const *buf, int size) L4_NOTHROW
233 {
234   return l4_vcon_write_u(vcon, buf, size, l4_utcb());
235 }
236
237 L4_INLINE int
238 l4_vcon_read(l4_cap_idx_t vcon, char *buf, int size) L4_NOTHROW
239 {
240   return l4_vcon_read_u(vcon, buf, size, l4_utcb());
241 }
242
243 L4_INLINE l4_msgtag_t
244 l4_vcon_set_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr,
245                    l4_utcb_t *utcb) L4_NOTHROW
246 {
247   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
248
249   mr->mr[0] = L4_VCON_SET_ATTR_OP;
250   __builtin_memcpy(&mr->mr[1], attr, sizeof(*attr));
251
252   return l4_ipc_call(vcon, utcb,
253                      l4_msgtag(L4_PROTO_LOG, 4, 0, 0),
254                      L4_IPC_NEVER);
255 }
256
257 L4_INLINE l4_msgtag_t
258 l4_vcon_set_attr(l4_cap_idx_t vcon, l4_vcon_attr_t const *attr) L4_NOTHROW
259 {
260   return l4_vcon_set_attr_u(vcon, attr, l4_utcb());
261 }
262
263 L4_INLINE l4_msgtag_t
264 l4_vcon_get_attr_u(l4_cap_idx_t vcon, l4_vcon_attr_t *attr,
265                    l4_utcb_t *utcb) L4_NOTHROW
266 {
267   l4_msgtag_t res;
268   l4_msg_regs_t *mr = l4_utcb_mr_u(utcb);
269
270   mr->mr[0] = L4_VCON_GET_ATTR_OP;
271
272   res = l4_ipc_call(vcon, utcb,
273                     l4_msgtag(L4_PROTO_LOG, 1, 0, 0),
274                     L4_IPC_NEVER);
275   if (l4_error_u(res, utcb) >= 0)
276     __builtin_memcpy(attr, &mr->mr[1], sizeof(*attr));
277
278   return res;
279 }
280
281 L4_INLINE l4_msgtag_t
282 l4_vcon_get_attr(l4_cap_idx_t vcon, l4_vcon_attr_t *attr) L4_NOTHROW
283 {
284   return l4_vcon_get_attr_u(vcon, attr, l4_utcb());
285 }