3 #include "icu_helper.h"
7 class Vlog : public Icu_h<Vlog>, public Irq_chip_soft
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"
49 FIASCO_DEFINE_KOBJ(Vlog);
54 _i_flags(F_ICRNL), _o_flags(F_ONLCR), _l_flags(F_ECHO)
56 Vkey::set_echo(Vkey::Echo_crnl);
57 // CAP idx 5 is the initial kernel stream
58 initial_kobjects.register_obj(this, 5);
62 Vlog::operator delete (void *)
64 printf("WARNING: tried to delete kernel Vlog object.\n");
68 PRIVATE inline NOEXPORT
70 Vlog::log_string(Syscall_frame *f, Utcb const *u)
72 L4_snd_item_iter snd_items(u, f->tag().words());
74 unsigned len = u->values[1];
75 char const *str = (char const *)&u->values[2];
77 if (len > sizeof(u->values) - sizeof(u->values[0]) * 2)
84 // the kernel does this anyway
86 if (_o_flags & F_ONLCR && c == '\n')
90 if (_o_flags & F_OCRNL && c == '\r')
93 if (_o_flags & F_ONLRET && c == '\r')
100 PRIVATE inline NOEXPORT
102 Vlog::get_input(L4_fpage::Rights rights, Syscall_frame *f, Utcb *u)
106 if (!have_receive(u))
107 return commit_result(0);
109 if (!(rights & L4_fpage::Rights::X()))
110 return commit_result(-L4_err::EPerm);
112 char *buffer = reinterpret_cast<char *>(&u->values[1]);
113 long cnt_down = min<Mword>(u->values[0] >> 16,
114 sizeof(u->values) - sizeof(u->values[0]));
116 while (cnt_down && (i = Vkey::get()) != -1)
120 if (_i_flags & F_INLCR && i == '\n')
123 if (_i_flags & F_IGNCR && i == '\r')
126 if (_i_flags & F_ICRNL && i == '\r')
134 u->values[0] = buffer - reinterpret_cast<char *>(&u->values[1]);
136 u->values[0] |= 1UL<<31;
137 return commit_result(0);
142 Vlog::bind(Irq_base *irq, Mword irqnum)
144 Irq_chip_soft::bind(irq, irqnum);
151 Vlog::icu_bind_irq(Irq *irq_o, unsigned irqnum)
154 return commit_result(-L4_err::EInval);
160 return commit_result(0);
165 Vlog::icu_set_mode(Mword pin, Irq_chip::Mode)
168 return commit_result(-L4_err::EInval);
171 _irq->switch_mode(true);
172 return commit_result(0);
175 PRIVATE inline NOEXPORT
177 Vlog::set_attr(L4_fpage::Rights, Syscall_frame const *, Utcb const *u)
179 _i_flags = u->values[1];
180 _o_flags = u->values[2] | F_ONLCR;
181 _l_flags = u->values[3];
182 Vkey::set_echo((!(_l_flags & F_ECHO))
184 : (_o_flags & F_OCRNL
188 return commit_result(0);
191 PRIVATE inline NOEXPORT
193 Vlog::get_attr(L4_fpage::Rights, Syscall_frame *, Utcb *u)
195 if (!have_receive(u))
196 return commit_result(0);
198 u->values[1] = _i_flags;
199 u->values[2] = _o_flags;
200 u->values[3] = _l_flags;
201 return commit_result(0, 4);
206 Vlog::icu_get_irq(unsigned irqnum)
217 Vlog::icu_get_info(Mword *features, Mword *num_irqs, Mword *num_msis)
219 *features = 0; // supported features (only normal irqs)
227 Vlog::kinvoke(L4_obj_ref ref, L4_fpage::Rights rights, Syscall_frame *f,
228 Utcb const *r_msg, Utcb *s_msg)
230 L4_msg_tag const t = f->tag();
232 if (t.proto() == L4_msg_tag::Label_irq)
233 return Icu_h<Vlog>::icu_invoke(ref, rights, f, r_msg, s_msg);
234 else if (t.proto() != L4_msg_tag::Label_log)
235 return commit_result(-L4_err::EBadproto);
237 switch (r_msg->values[0])
240 log_string(f, r_msg);
244 return set_attr(rights, f, r_msg);
247 return get_attr(rights, f, s_msg);
250 return get_input(rights, f, s_msg);