1181643Skmacy#include <sys/cdefs.h> 2181643Skmacy__FBSDID("$FreeBSD: releng/10.3/sys/dev/xen/console/xencons_ring.c 255040 2013-08-29 19:52:18Z gibbs $"); 3181643Skmacy 4181643Skmacy#include <sys/param.h> 5181643Skmacy#include <sys/module.h> 6181643Skmacy#include <sys/systm.h> 7181643Skmacy#include <sys/consio.h> 8181643Skmacy#include <sys/proc.h> 9181643Skmacy#include <sys/uio.h> 10181643Skmacy#include <sys/tty.h> 11181643Skmacy#include <sys/systm.h> 12181643Skmacy#include <sys/taskqueue.h> 13181643Skmacy#include <sys/conf.h> 14181643Skmacy#include <sys/kernel.h> 15181643Skmacy#include <sys/bus.h> 16189699Sdfr#include <sys/cons.h> 17189699Sdfr 18181643Skmacy#include <machine/stdarg.h> 19255040Sgibbs 20255040Sgibbs#include <xen/xen-os.h> 21186557Skmacy#include <xen/hypervisor.h> 22186557Skmacy#include <xen/xen_intr.h> 23181643Skmacy#include <sys/cons.h> 24181643Skmacy 25189699Sdfr#include <xen/xen_intr.h> 26189699Sdfr#include <xen/evtchn.h> 27189699Sdfr#include <xen/interface/io/console.h> 28181643Skmacy 29181643Skmacy#include <dev/xen/console/xencons_ring.h> 30186557Skmacy#include <xen/evtchn.h> 31181643Skmacy#include <xen/interface/io/console.h> 32181643Skmacy 33181643Skmacy#define console_evtchn console.domU.evtchn 34255040Sgibbsxen_intr_handle_t console_handle; 35181643Skmacyextern char *console_page; 36186557Skmacyextern struct mtx cn_mtx; 37255040Sgibbsextern device_t xencons_dev; 38186557Skmacy 39181643Skmacystatic inline struct xencons_interface * 40181643Skmacyxencons_interface(void) 41181643Skmacy{ 42181643Skmacy return (struct xencons_interface *)console_page; 43181643Skmacy} 44181643Skmacy 45181643Skmacy 46181643Skmacyint 47181643Skmacyxencons_has_input(void) 48181643Skmacy{ 49181643Skmacy struct xencons_interface *intf; 50181643Skmacy 51181643Skmacy intf = xencons_interface(); 52181643Skmacy 53181643Skmacy return (intf->in_cons != intf->in_prod); 54181643Skmacy} 55181643Skmacy 56181643Skmacy 57181643Skmacyint 58181643Skmacyxencons_ring_send(const char *data, unsigned len) 59181643Skmacy{ 60181643Skmacy struct xencons_interface *intf; 61181643Skmacy XENCONS_RING_IDX cons, prod; 62181643Skmacy int sent; 63181643Skmacy 64181643Skmacy intf = xencons_interface(); 65181643Skmacy cons = intf->out_cons; 66181643Skmacy prod = intf->out_prod; 67181643Skmacy sent = 0; 68181643Skmacy 69181643Skmacy mb(); 70189699Sdfr KASSERT((prod - cons) <= sizeof(intf->out), 71189699Sdfr ("console send ring inconsistent")); 72181643Skmacy 73181643Skmacy while ((sent < len) && ((prod - cons) < sizeof(intf->out))) 74181643Skmacy intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; 75181643Skmacy 76181643Skmacy wmb(); 77181643Skmacy intf->out_prod = prod; 78181643Skmacy 79255040Sgibbs xen_intr_signal(console_handle); 80181643Skmacy 81181643Skmacy return sent; 82181643Skmacy 83181643Skmacy} 84181643Skmacy 85181643Skmacy 86181643Skmacystatic xencons_receiver_func *xencons_receiver; 87181643Skmacy 88181643Skmacyvoid 89181643Skmacyxencons_handle_input(void *unused) 90181643Skmacy{ 91181643Skmacy struct xencons_interface *intf; 92181643Skmacy XENCONS_RING_IDX cons, prod; 93181643Skmacy 94192003Skmacy CN_LOCK(cn_mtx); 95181643Skmacy intf = xencons_interface(); 96181643Skmacy 97181643Skmacy cons = intf->in_cons; 98181643Skmacy prod = intf->in_prod; 99192004Skmacy CN_UNLOCK(cn_mtx); 100192004Skmacy 101181643Skmacy /* XXX needs locking */ 102181643Skmacy while (cons != prod) { 103181643Skmacy xencons_rx(intf->in + MASK_XENCONS_IDX(cons, intf->in), 1); 104181643Skmacy cons++; 105181643Skmacy } 106181643Skmacy 107181643Skmacy mb(); 108181643Skmacy intf->in_cons = cons; 109181643Skmacy 110192004Skmacy CN_LOCK(cn_mtx); 111255040Sgibbs xen_intr_signal(console_handle); 112181643Skmacy 113181643Skmacy xencons_tx(); 114192003Skmacy CN_UNLOCK(cn_mtx); 115181643Skmacy} 116181643Skmacy 117181643Skmacyvoid 118181643Skmacyxencons_ring_register_receiver(xencons_receiver_func *f) 119181643Skmacy{ 120181643Skmacy xencons_receiver = f; 121181643Skmacy} 122181643Skmacy 123181643Skmacyint 124181643Skmacyxencons_ring_init(void) 125181643Skmacy{ 126181643Skmacy int err; 127181643Skmacy 128181643Skmacy if (!xen_start_info->console_evtchn) 129181643Skmacy return 0; 130181643Skmacy 131255040Sgibbs err = xen_intr_bind_local_port(xencons_dev, 132255040Sgibbs xen_start_info->console_evtchn, NULL, xencons_handle_input, NULL, 133255040Sgibbs INTR_TYPE_MISC | INTR_MPSAFE, &console_handle); 134181643Skmacy if (err) { 135181643Skmacy return err; 136181643Skmacy } 137181643Skmacy 138181643Skmacy return 0; 139181643Skmacy} 140189699Sdfr 141189699Sdfrextern void xencons_suspend(void); 142189699Sdfrextern void xencons_resume(void); 143189699Sdfr 144181643Skmacyvoid 145181643Skmacyxencons_suspend(void) 146181643Skmacy{ 147181643Skmacy 148181643Skmacy if (!xen_start_info->console_evtchn) 149181643Skmacy return; 150181643Skmacy 151255040Sgibbs xen_intr_unbind(&console_handle); 152181643Skmacy} 153181643Skmacy 154181643Skmacyvoid 155181643Skmacyxencons_resume(void) 156181643Skmacy{ 157181643Skmacy 158181643Skmacy (void)xencons_ring_init(); 159181643Skmacy} 160189699Sdfr 161181643Skmacy/* 162181643Skmacy * Local variables: 163181643Skmacy * mode: C 164181643Skmacy * c-set-style: "BSD" 165181643Skmacy * c-basic-offset: 8 166181643Skmacy * tab-width: 4 167181643Skmacy * indent-tabs-mode: t 168181643Skmacy * End: 169181643Skmacy */ 170