From owner-p4-projects@FreeBSD.ORG Wed Mar 21 22:00:47 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5C6081065670; Wed, 21 Mar 2012 22:00:47 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 064F5106564A for ; Wed, 21 Mar 2012 22:00:47 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id E20788FC15 for ; Wed, 21 Mar 2012 22:00:46 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q2LM0kvg050065 for ; Wed, 21 Mar 2012 22:00:46 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q2LM0kP5050061 for perforce@freebsd.org; Wed, 21 Mar 2012 22:00:46 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Wed, 21 Mar 2012 22:00:46 GMT Message-Id: <201203212200.q2LM0kP5050061@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 208337 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Mar 2012 22:00:47 -0000 http://p4web.freebsd.org/@@208337?ac=10 Change 208337 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/03/21 21:59:50 Implement a rudimentary FreeBSD tty driver by polling the gxemul debug console; modeled on a similar driver for the Altera JTAG UART, and likely has the same bugs. Not yet well-exercised. Affected files ... .. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/gxemul_cons.c#2 edit Differences ... ==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/gxemul_cons.c#2 (text+ko) ==== @@ -41,6 +41,26 @@ #include +#define GC_LOCK_INIT() mtx_init(&gc_lock, "gc_lock", NULL, MTX_SPIN) + +#define GC_LOCK() do { \ + if (!kdb_active) \ + mtx_lock_spin(&gc_lock); \ +} while (0) + +#define GC_LOCK_ASSERT() do { \ + if (!kdb_active) \ + mtx_assert(&gc_lock, MA_OWNED); \ +} while (0) + +#define GC_UNLOCK() do { \ + if (!kdb_active) \ + mtx_unlock_spin(&gc_lock); \ +} while (0) + + +static struct mtx gc_lock; + /* * Low-level console driver functions. */ @@ -53,6 +73,24 @@ static cn_ungrab_t gxemul_cons_cnungrab; /* + * TTY-level fields. + */ +static tsw_outwakeup_t gxemul_cons_outwakeup; + +static struct ttydevsw gxemul_cons_ttydevsw = { + .tsw_flags = TF_NOPREFIX, + .tsw_outwakeup = gxemul_cons_outwakeup, +}; + +static struct callout gxemul_cons_callout; +static u_int gxemul_cons_polltime = 10; +#ifdef KDB +static int gxemul_cons_alt_break_state; +#endif + +static void gxemul_cons_timeout(void *); + +/* * I/O routines lifted from Deimos. * * XXXRW: Should be using FreeBSD's bus routines here. @@ -138,6 +176,8 @@ { uint32_t v; + GC_LOCK_ASSERT(); + if (buffer_valid) return (1); v = gxemul_cons_data_read(); @@ -153,6 +193,8 @@ gxemul_cons_write(char ch) { + GC_LOCK_ASSERT(); + while (!gxemul_cons_writable()); gxemul_cons_data_write(ch); } @@ -161,6 +203,8 @@ gxemul_cons_read(void) { + GC_LOCK_ASSERT(); + while (!gxemul_cons_readable()); buffer_valid = 0; return (buffer_data); @@ -181,6 +225,7 @@ gxemul_cons_cninit(struct consdev *cp) { + GC_LOCK_INIT(); } static void @@ -194,7 +239,9 @@ { int ret; + GC_LOCK(); ret = gxemul_cons_read(); + GC_UNLOCK(); return (ret); } @@ -202,7 +249,9 @@ gxemul_cons_cnputc(struct consdev *cp, int c) { + GC_LOCK(); gxemul_cons_write(c); + GC_UNLOCK(); } static void @@ -218,3 +267,67 @@ } CONSOLE_DRIVER(gxemul_cons); + +/* + * TTY-level functions for gxemul_cons. + */ +static void +gxemul_cons_ttyinit(void *unused) +{ + struct tty *tp; + + tp = tty_alloc(&gxemul_cons_ttydevsw, NULL); + tty_init_console(tp, 0); + tty_makedev(tp, NULL, "%s", "gcons"); + callout_init(&gxemul_cons_callout, CALLOUT_MPSAFE); + callout_reset(&gxemul_cons_callout, gxemul_cons_polltime, + gxemul_cons_timeout, tp); + +} +SYSINIT(gxemul_cons_ttyinit, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, + gxemul_cons_ttyinit, NULL); + +static void +gxemul_cons_outwakeup(struct tty *tp) +{ + int len; + u_char ch; + + /* + * XXXRW: Would be nice not to do blocking writes to the console here, + * rescheduling on our timer tick if work remains to be done.. + */ + for (;;) { +#ifdef KDB + kdb_alt_break(ch, &gxemul_cons_alt_break_state); +#endif + len = ttydisc_getc(tp, &ch, sizeof(ch)); + if (len == 0) + break; + GC_LOCK(); + gxemul_cons_write(ch); + GC_UNLOCK(); + } +} + +static void +gxemul_cons_timeout(void *v) +{ + struct tty *tp; + int c; + + tp = v; + tty_lock(tp); + GC_LOCK(); + while (gxemul_cons_readable()) { + c = gxemul_cons_read(); + GC_UNLOCK(); + ttydisc_rint(tp, c, 0); + GC_LOCK(); + } + GC_UNLOCK(); + ttydisc_rint_done(tp); + tty_unlock(tp); + callout_reset(&gxemul_cons_callout, gxemul_cons_polltime, + gxemul_cons_timeout, tp); +}