summaryrefslogtreecommitdiffstats
path: root/sys/dev/xen/console/console.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-11-22 16:14:52 +0000
committerdfr <dfr@FreeBSD.org>2008-11-22 16:14:52 +0000
commit19b6af98ec71398e77874582eb84ec5310c7156f (patch)
tree61eebb1b357f3edaa339d295e26a47a74534ac23 /sys/dev/xen/console/console.c
parent83299de5870b2dc099c17aec548d3502821bc29b (diff)
downloadFreeBSD-src-19b6af98ec71398e77874582eb84ec5310c7156f.zip
FreeBSD-src-19b6af98ec71398e77874582eb84ec5310c7156f.tar.gz
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
performance in Xen's HVM mode.
Diffstat (limited to 'sys/dev/xen/console/console.c')
-rw-r--r--sys/dev/xen/console/console.c559
1 files changed, 0 insertions, 559 deletions
diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c
deleted file mode 100644
index 64c2dfd..0000000
--- a/sys/dev/xen/console/console.c
+++ /dev/null
@@ -1,559 +0,0 @@
-#include <sys/cdefs.h>
-
-
-#include <sys/param.h>
-#include <sys/module.h>
-#include <sys/systm.h>
-#include <sys/consio.h>
-#include <sys/proc.h>
-#include <sys/uio.h>
-#include <sys/tty.h>
-#include <sys/systm.h>
-#include <sys/taskqueue.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <machine/stdarg.h>
-#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
-#include <sys/cons.h>
-#include <sys/proc.h>
-
-#include <dev/xen/console/xencons_ring.h>
-#include <xen/interface/io/console.h>
-
-
-#include "opt_ddb.h"
-#ifdef DDB
-#include <ddb/ddb.h>
-#endif
-
-static char driver_name[] = "xc";
-devclass_t xc_devclass; /* do not make static */
-static void xcstart (struct tty *);
-static int xcparam (struct tty *, struct termios *);
-static void xcstop (struct tty *, int);
-static void xc_timeout(void *);
-static void __xencons_tx_flush(void);
-static boolean_t xcons_putc(int c);
-
-/* switch console so that shutdown can occur gracefully */
-static void xc_shutdown(void *arg, int howto);
-static int xc_mute;
-
-static void xcons_force_flush(void);
-static void xencons_priv_interrupt(void *);
-
-static cn_probe_t xccnprobe;
-static cn_init_t xccninit;
-static cn_getc_t xccngetc;
-static cn_putc_t xccnputc;
-static cn_putc_t xccnputc_dom0;
-static cn_checkc_t xccncheckc;
-
-#define XC_POLLTIME (hz/10)
-
-CONS_DRIVER(xc, xccnprobe, xccninit, NULL, xccngetc,
- xccncheckc, xccnputc, NULL);
-
-static int xen_console_up;
-static boolean_t xc_start_needed;
-static struct callout xc_callout;
-struct mtx cn_mtx;
-
-#define RBUF_SIZE 1024
-#define RBUF_MASK(_i) ((_i)&(RBUF_SIZE-1))
-#define WBUF_SIZE 4096
-#define WBUF_MASK(_i) ((_i)&(WBUF_SIZE-1))
-static char wbuf[WBUF_SIZE];
-static char rbuf[RBUF_SIZE];
-static int rc, rp;
-static unsigned int cnsl_evt_reg;
-static unsigned int wc, wp; /* write_cons, write_prod */
-
-#define CDEV_MAJOR 12
-#define XCUNIT(x) (minor(x))
-#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN))
-#define CN_LOCK_INIT(x, _name) \
- mtx_init(&x, _name, NULL, MTX_SPIN|MTX_RECURSE)
-
-#define CN_LOCK(l) \
- do { \
- if (panicstr == NULL) \
- mtx_lock_spin(&(l)); \
- } while (0)
-#define CN_UNLOCK(l) \
- do { \
- if (panicstr == NULL) \
- mtx_unlock_spin(&(l)); \
- } while (0)
-#define CN_LOCK_ASSERT(x) mtx_assert(&x, MA_OWNED)
-#define CN_LOCK_DESTROY(x) mtx_destroy(&x)
-
-
-static struct tty *xccons;
-
-struct xc_softc {
- int xc_unit;
- struct cdev *xc_dev;
-};
-
-
-static d_open_t xcopen;
-static d_close_t xcclose;
-static d_ioctl_t xcioctl;
-
-static struct cdevsw xc_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_TTY | D_NEEDGIANT,
- .d_name = driver_name,
- .d_open = xcopen,
- .d_close = xcclose,
- .d_read = ttyread,
- .d_write = ttywrite,
- .d_ioctl = xcioctl,
- .d_poll = ttypoll,
- .d_kqfilter = ttykqfilter,
-};
-
-static void
-xccnprobe(struct consdev *cp)
-{
- cp->cn_pri = CN_REMOTE;
- cp->cn_tp = xccons;
- sprintf(cp->cn_name, "%s0", driver_name);
-}
-
-
-static void
-xccninit(struct consdev *cp)
-{
- CN_LOCK_INIT(cn_mtx,"XCONS LOCK");
-
-}
-int
-xccngetc(struct consdev *dev)
-{
- int c;
- if (xc_mute)
- return 0;
- do {
- if ((c = xccncheckc(dev)) == -1) {
- /* polling without sleeping in Xen doesn't work well.
- * Sleeping gives other things like clock a chance to
- * run
- */
- tsleep(&cn_mtx, PWAIT | PCATCH, "console sleep",
- XC_POLLTIME);
- }
- } while(c == -1);
- return c;
-}
-
-int
-xccncheckc(struct consdev *dev)
-{
- int ret = (xc_mute ? 0 : -1);
- if (xencons_has_input())
- xencons_handle_input(NULL);
-
- CN_LOCK(cn_mtx);
- if ((rp - rc)) {
- /* we need to return only one char */
- ret = (int)rbuf[RBUF_MASK(rc)];
- rc++;
- }
- CN_UNLOCK(cn_mtx);
- return(ret);
-}
-
-static void
-xccnputc(struct consdev *dev, int c)
-{
- xcons_putc(c);
-}
-
-static void
-xccnputc_dom0(struct consdev *dev, int c)
-{
- HYPERVISOR_console_io(CONSOLEIO_write, 1, (char *)&c);
-}
-
-extern int db_active;
-static boolean_t
-xcons_putc(int c)
-{
- int force_flush = xc_mute ||
-#ifdef DDB
- db_active ||
-#endif
- panicstr; /* we're not gonna recover, so force
- * flush
- */
-
- if ((wp-wc) < (WBUF_SIZE-1)) {
- if ((wbuf[WBUF_MASK(wp++)] = c) == '\n') {
- wbuf[WBUF_MASK(wp++)] = '\r';
-#ifdef notyet
- if (force_flush)
- xcons_force_flush();
-#endif
- }
- } else if (force_flush) {
-#ifdef notyet
- xcons_force_flush();
-#endif
- }
- if (cnsl_evt_reg)
- __xencons_tx_flush();
-
- /* inform start path that we're pretty full */
- return ((wp - wc) >= WBUF_SIZE - 100) ? TRUE : FALSE;
-}
-
-static void
-xc_identify(driver_t *driver, device_t parent)
-{
- device_t child;
- child = BUS_ADD_CHILD(parent, 0, driver_name, 0);
- device_set_driver(child, driver);
- device_set_desc(child, "Xen Console");
-}
-
-static int
-xc_probe(device_t dev)
-{
- struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev);
-
- sc->xc_unit = device_get_unit(dev);
- return (0);
-}
-
-static int
-xc_attach(device_t dev)
-{
- struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev);
-
-
- if (xen_start_info->flags & SIF_INITDOMAIN) {
- xc_consdev.cn_putc = xccnputc_dom0;
- }
-
- sc->xc_dev = make_dev(&xc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "xc%r", 0);
- xccons = ttyalloc();
-
- sc->xc_dev->si_drv1 = (void *)sc;
- sc->xc_dev->si_tty = xccons;
-
- xccons->t_oproc = xcstart;
- xccons->t_param = xcparam;
- xccons->t_stop = xcstop;
- xccons->t_dev = sc->xc_dev;
-
- callout_init(&xc_callout, 0);
-
- xencons_ring_init();
-
- cnsl_evt_reg = 1;
- callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, xccons);
-
- if (xen_start_info->flags & SIF_INITDOMAIN) {
- PANIC_IF(bind_virq_to_irqhandler(
- VIRQ_CONSOLE,
- 0,
- "console",
- xencons_priv_interrupt,
- INTR_TYPE_TTY) < 0);
-
- }
-
-
- /* register handler to flush console on shutdown */
- if ((EVENTHANDLER_REGISTER(shutdown_post_sync, xc_shutdown,
- NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
- printf("xencons: shutdown event registration failed!\n");
-
- return (0);
-}
-
-/*
- * return 0 for all console input, force flush all output.
- */
-static void
-xc_shutdown(void *arg, int howto)
-{
- xc_mute = 1;
- xcons_force_flush();
-}
-
-void
-xencons_rx(char *buf, unsigned len)
-{
- int i;
- struct tty *tp = xccons;
-
- for (i = 0; i < len; i++) {
- if (xen_console_up)
- (*linesw[tp->t_line]->l_rint)(buf[i], tp);
- else
- rbuf[RBUF_MASK(rp++)] = buf[i];
- }
-}
-
-static void
-__xencons_tx_flush(void)
-{
- int sz, work_done = 0;
-
- CN_LOCK(cn_mtx);
- while (wc != wp) {
- int sent;
- sz = wp - wc;
- if (sz > (WBUF_SIZE - WBUF_MASK(wc)))
- sz = WBUF_SIZE - WBUF_MASK(wc);
- if (xen_start_info->flags & SIF_INITDOMAIN) {
- HYPERVISOR_console_io(CONSOLEIO_write, sz, &wbuf[WBUF_MASK(wc)]);
- wc += sz;
- } else {
- sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
- if (sent == 0)
- break;
- wc += sent;
- }
- work_done = 1;
- }
- CN_UNLOCK(cn_mtx);
-
- /*
- * ttwakeup calls routines using blocking locks
- *
- */
- if (work_done && xen_console_up && curthread->td_critnest == 0)
- ttwakeup(xccons);
-}
-
-void
-xencons_tx(void)
-{
- __xencons_tx_flush();
-}
-
-static void
-xencons_priv_interrupt(void *arg)
-{
-
- static char rbuf[16];
- int l;
-
- while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0)
- xencons_rx(rbuf, l);
-
- xencons_tx();
-}
-
-int
-xcopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct xc_softc *sc;
- int unit = XCUNIT(dev);
- struct tty *tp;
- int s, error;
-
- sc = (struct xc_softc *)device_get_softc(
- devclass_get_device(xc_devclass, unit));
- if (sc == NULL)
- return (ENXIO);
-
- tp = dev->si_tty;
- s = spltty();
- if (!ISTTYOPEN(tp)) {
- tp->t_state |= TS_CARR_ON;
- ttychars(tp);
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
- tp->t_lflag = TTYDEF_LFLAG;
- tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
- xcparam(tp, &tp->t_termios);
- ttsetwater(tp);
- } else if (tp->t_state & TS_XCLUDE && suser(td)) {
- splx(s);
- return (EBUSY);
- }
- splx(s);
-
- xen_console_up = 1;
-
- error = (*linesw[tp->t_line]->l_open)(dev, tp);
- return error;
-}
-
-int
-xcclose(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct tty *tp = dev->si_tty;
-
- if (tp == NULL)
- return (0);
- xen_console_up = 0;
-
- spltty();
- (*linesw[tp->t_line]->l_close)(tp, flag);
- tty_close(tp);
- spl0();
- return (0);
-}
-
-
-int
-xcioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
-{
- struct tty *tp = dev->si_tty;
- int error;
-
- error = (*linesw[tp->t_line]->l_ioctl)(tp, cmd, data, flag, td);
- if (error != ENOIOCTL)
- return (error);
-
- error = ttioctl(tp, cmd, data, flag);
-
- if (error != ENOIOCTL)
- return (error);
-
- return (ENOTTY);
-}
-
-static inline int
-__xencons_put_char(int ch)
-{
- char _ch = (char)ch;
- if ((wp - wc) == WBUF_SIZE)
- return 0;
- wbuf[WBUF_MASK(wp++)] = _ch;
- return 1;
-}
-
-
-static void
-xcstart(struct tty *tp)
-{
- boolean_t cons_full = FALSE;
-
- CN_LOCK(cn_mtx);
- if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
- CN_UNLOCK(cn_mtx);
-
- ttwwakeup(tp);
- return;
- }
-
- tp->t_state |= TS_BUSY;
- CN_UNLOCK(cn_mtx);
-
- while (tp->t_outq.c_cc != 0 && !cons_full)
- cons_full = xcons_putc(getc(&tp->t_outq));
-
- /* if the console is close to full leave our state as busy */
- if (!cons_full) {
- CN_LOCK(cn_mtx);
- tp->t_state &= ~TS_BUSY;
- CN_UNLOCK(cn_mtx);
- ttwwakeup(tp);
- } else {
- /* let the timeout kick us in a bit */
- xc_start_needed = TRUE;
- }
-
-}
-
-static void
-xcstop(struct tty *tp, int flag)
-{
-
- if (tp->t_state & TS_BUSY) {
- if ((tp->t_state & TS_TTSTOP) == 0) {
- tp->t_state |= TS_FLUSH;
- }
- }
-}
-
-static void
-xc_timeout(void *v)
-{
- struct tty *tp;
- int c;
-
- tp = (struct tty *)v;
-
- while ((c = xccncheckc(NULL)) != -1) {
- if (tp->t_state & TS_ISOPEN) {
- (*linesw[tp->t_line]->l_rint)(c, tp);
- }
- }
-
- if (xc_start_needed) {
- xc_start_needed = FALSE;
- xcstart(tp);
- }
-
- callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, tp);
-}
-
-/*
- * Set line parameters.
- */
-int
-xcparam(struct tty *tp, struct termios *t)
-{
- tp->t_ispeed = t->c_ispeed;
- tp->t_ospeed = t->c_ospeed;
- tp->t_cflag = t->c_cflag;
- return (0);
-}
-
-
-static device_method_t xc_methods[] = {
- DEVMETHOD(device_identify, xc_identify),
- DEVMETHOD(device_probe, xc_probe),
- DEVMETHOD(device_attach, xc_attach),
- {0, 0}
-};
-
-static driver_t xc_driver = {
- driver_name,
- xc_methods,
- sizeof(struct xc_softc),
-};
-
-/*** Forcibly flush console data before dying. ***/
-void
-xcons_force_flush(void)
-{
- int sz;
-
- if (xen_start_info->flags & SIF_INITDOMAIN)
- return;
-
- /* Spin until console data is flushed through to the domain controller. */
- while (wc != wp) {
- int sent = 0;
- if ((sz = wp - wc) == 0)
- continue;
-
- sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
- if (sent > 0)
- wc += sent;
- }
-}
-
-DRIVER_MODULE(xc, nexus, xc_driver, xc_devclass, 0, 0);
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 8
- * tab-width: 4
- * indent-tabs-mode: t
- * End:
- */
OpenPOWER on IntegriCloud