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