3 #include "icu_helper.h"
7 class Vlog : public Icu_h<Vlog>, public Kobject
13 F_ONLCR = 000004, ///< Map NL to CR-NL on output
14 F_OCRNL = 000010, ///< Map CR to NL on output
15 F_ONLRET = 000040, ///< Do not ouput CR
39 #include "entry_frame.h"
41 #include "mem_space.h"
42 #include "l4_buf_iter.h"
46 #include "irq_controller.h"
48 class Vlog_irq_pin : public Sw_irq_pin
52 PUBLIC inline explicit
53 Vlog_irq_pin::Vlog_irq_pin(Vlog *i)
54 { payload()[0] = Mword(i); }
58 Vlog_irq_pin::vlog() const
59 { return (Vlog*)payload()[0]; }
64 Vlog_irq_pin::unbind_irq()
70 replace<Sw_irq_pin>();
74 FIASCO_DEFINE_KOBJ(Vlog);
79 _i_flags(F_ICRNL), _o_flags(F_ONLRET | F_OCRNL), _l_flags(F_ECHO)
81 Vkey::set_echo(Vkey::Echo_crnl);
82 // CAP idx 5 is the initial kernel stream
83 initial_kobjects.register_obj(this, 5);
94 PRIVATE inline NOEXPORT
96 Vlog::log_string(Syscall_frame *f, Utcb const *u)
98 L4_snd_item_iter snd_items(u, f->tag().words());
100 unsigned len = u->values[1];
101 char const *str = (char const *)&u->values[2];
103 if (len > sizeof(u->values) - sizeof(u->values[0]) * 2)
110 if (_o_flags & F_ONLCR && c == '\n')
113 if (_o_flags & F_OCRNL && c == '\r')
116 if (_o_flags & F_ONLRET && c == '\r')
123 PRIVATE inline NOEXPORT
125 Vlog::get_input(Mword rights, Syscall_frame *f, Utcb *u)
129 if (!have_receive(u))
130 return commit_result(0);
132 if (!(rights & L4_fpage::X))
133 return commit_result(-L4_err::EPerm);
135 char *buffer = reinterpret_cast<char *>(&u->values[1]);
136 long cnt_down = u->values[0] >> 16;
138 while (cnt_down && (i = Vkey::get()) != -1)
142 if (_i_flags & F_INLCR && i == '\n')
145 if (_i_flags & F_IGNCR && i == '\r')
148 if (_i_flags & F_ICRNL && i == '\r')
156 u->values[0] = buffer - reinterpret_cast<char *>(&u->values[1]);
158 u->values[0] |= 1UL<<31;
159 return commit_result(0);
164 Vlog::icu_bind_irq(Irq *irq_o, unsigned irqnum)
167 return commit_result(-L4_err::EInval);
170 _irq->pin()->unbind_irq();
172 irq_o->pin()->unbind_irq();
173 irq_o->pin()->replace<Vlog_irq_pin>(this);
176 return commit_result(0);
180 PRIVATE inline NOEXPORT
182 Vlog::set_attr(Mword, Syscall_frame const *, Utcb const *u)
184 _i_flags = u->values[1];
185 _o_flags = u->values[2];
186 _l_flags = u->values[3];
187 Vkey::set_echo((!(_l_flags & F_ECHO))
189 : (_o_flags & F_OCRNL
193 return commit_result(0);
196 PRIVATE inline NOEXPORT
198 Vlog::get_attr(Mword, Syscall_frame *, Utcb *u)
200 if (!have_receive(u))
201 return commit_result(0);
203 u->values[1] = _i_flags;
204 u->values[2] = _o_flags;
205 u->values[3] = _l_flags;
206 return commit_result(0, 4);
211 Vlog::icu_get_irq(unsigned irqnum)
222 Vlog::icu_get_info(Mword *features, Mword *num_irqs, Mword *num_msis)
224 *features = 0; // supported features (only normal irqs)
232 Vlog::kinvoke(L4_obj_ref ref, Mword rights, Syscall_frame *f,
233 Utcb const *r_msg, Utcb *s_msg)
235 L4_msg_tag const t = f->tag();
237 if (t.proto() == L4_msg_tag::Label_irq)
238 return Icu_h<Vlog>::icu_invoke(ref, rights, f, r_msg, s_msg);
239 else if (t.proto() != L4_msg_tag::Label_log)
240 return commit_result(-L4_err::EBadproto);
242 switch (r_msg->values[0])
245 log_string(f, r_msg);
249 return set_attr(rights, f, r_msg);
252 return get_attr(rights, f, s_msg);
255 return get_input(rights, f, s_msg);