5 #include <sys/module.h>
7 #include <sys/consio.h>
11 #include <sys/systm.h>
12 #include <sys/taskqueue.h>
14 #include <sys/kernel.h>
18 #include <machine/stdarg.h>
20 #include <xen/xen-os.h>
21 #include <xen/hypervisor.h>
22 #include <xen/xen_intr.h>
25 #include <xen/xen_intr.h>
26 #include <xen/evtchn.h>
27 #include <xen/interface/io/console.h>
29 #include <dev/xen/console/xencons_ring.h>
30 #include <xen/evtchn.h>
31 #include <xen/interface/io/console.h>
33 #define console_evtchn console.domU.evtchn
34 xen_intr_handle_t console_handle;
35 extern struct mtx cn_mtx;
36 extern device_t xencons_dev;
37 extern bool cnsl_evt_reg;
38 #define DOM0_BUFFER_SIZE 16
40 static inline struct xencons_interface *
41 xencons_interface(void)
43 return (struct xencons_interface *)console_page;
48 xencons_has_input(void)
50 struct xencons_interface *intf;
52 if (xen_initial_domain()) {
54 * Since the Dom0 console works with hypercalls
55 * there's no way to know if there's input unless
56 * we actually try to retrieve it, so always return
57 * like there's pending data. Then if the hypercall
58 * returns no input, we can handle it without problems
59 * in xencons_handle_input().
64 intf = xencons_interface();
66 return (intf->in_cons != intf->in_prod);
71 xencons_ring_send(const char *data, unsigned len)
73 struct xencons_interface *intf;
74 XENCONS_RING_IDX cons, prod;
76 struct evtchn_send send = {
77 .port = HYPERVISOR_start_info->console_evtchn
80 intf = xencons_interface();
81 cons = intf->out_cons;
82 prod = intf->out_prod;
86 KASSERT((prod - cons) <= sizeof(intf->out),
87 ("console send ring inconsistent"));
89 while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
90 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
93 intf->out_prod = prod;
96 xen_intr_signal(console_handle);
98 HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
105 static xencons_receiver_func *xencons_receiver;
108 xencons_handle_input(void *unused)
110 struct xencons_interface *intf;
111 XENCONS_RING_IDX cons, prod;
115 if (xen_initial_domain()) {
116 static char rbuf[DOM0_BUFFER_SIZE];
119 while ((l = HYPERVISOR_console_io(CONSOLEIO_read,
120 DOM0_BUFFER_SIZE, rbuf)) > 0)
127 intf = xencons_interface();
129 cons = intf->in_cons;
130 prod = intf->in_prod;
133 /* XXX needs locking */
134 while (cons != prod) {
135 xencons_rx(intf->in + MASK_XENCONS_IDX(cons, intf->in), 1);
140 intf->in_cons = cons;
143 xen_intr_signal(console_handle);
150 xencons_ring_register_receiver(xencons_receiver_func *f)
152 xencons_receiver = f;
156 xencons_ring_init(void)
160 if (HYPERVISOR_start_info->console_evtchn == 0)
163 err = xen_intr_bind_local_port(xencons_dev,
164 HYPERVISOR_start_info->console_evtchn, NULL, xencons_handle_input, NULL,
165 INTR_TYPE_MISC | INTR_MPSAFE, &console_handle);
173 extern void xencons_suspend(void);
174 extern void xencons_resume(void);
177 xencons_suspend(void)
180 if (HYPERVISOR_start_info->console_evtchn == 0)
183 xen_intr_unbind(&console_handle);
190 (void)xencons_ring_init();
199 * indent-tabs-mode: t