shithub: riscv

Download patch

ref: 0ff5b74c2555ccc51f4b82de7428443949b6053f
parent: e2ddc61fed70c120ed61540181d1212f2cb05567
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Nov 12 14:32:57 EST 2023

devuart: cleanup uart console code

Some ports used a messy uarti8250 clone that had its
own backdoor unbuffered uart interface (serialputc()...),
which is really not needed at all, as devuart provides
one with uartputc(), once one sets uartcons variable.

There was some ugly interleaving of prints for mpinit,
which was because uartreset() (called from chandevreset)
would set serialoq ealy before the clocks are ticking,
so the coming up processors would use the buffered uart
while cpuidprint uses the unbufferd one...

Instead, we set serialoq in uartini() (called from
chandevinit) which is guaranteed to be done after
mpinit has completed.

--- a/sys/src/9/arm64/main.c
+++ b/sys/src/9/arm64/main.c
@@ -286,12 +286,12 @@
 		schedinit();
 		return;
 	}
+	uartconsinit();
 	quotefmtinstall();
 	bootargsinit();
 	meminit();
 	confinit();
 	xinit();
-	uartconsinit();
 	printinit();
 	print("\nPlan 9\n");
 	trapinit();
--- a/sys/src/9/arm64/uartqemu.c
+++ b/sys/src/9/arm64/uartqemu.c
@@ -342,7 +342,6 @@
 	consuart = &qemuuart;
 	consuart->console = 1;
 	uartctl(consuart, "l8 pn s1");
-	uartputs(kmesg.buf, kmesg.n);
 }
 
 PhysUart qemuphysuart = {
--- a/sys/src/9/cycv/fns.h
+++ b/sys/src/9/cycv/fns.h
@@ -24,7 +24,7 @@
 #define VA(k) ((void*)(k))
 #define PTR2UINT(p) ((uintptr)(p))
 
-void uartinit(void);
+void uartconsinit(void);
 void mmuinit(void);
 uintptr ttbget(void);
 void ttbput(uintptr);
@@ -49,7 +49,6 @@
 void intrenable(int, void (*)(Ureg *, void *), void *, int, char *);
 void intrinit(void);
 void intr(Ureg *);
-int uartconsole(void);
 long fbctlread(Chan*,void*,long,vlong);
 long fbctlwrite(Chan*,void*,long,vlong);
 void fpoff(void);
--- a/sys/src/9/cycv/main.c
+++ b/sys/src/9/cycv/main.c
@@ -212,7 +212,7 @@
 		schedinit();
 		return;
 	}
-	uartinit();
+	uartconsinit();
 	mmuinit();
 	intrinit();
 	options();
--- a/sys/src/9/cycv/uartcycv.c
+++ b/sys/src/9/cycv/uartcycv.c
@@ -32,8 +32,6 @@
 	int irq, iena;
 } Ctlr;
 
-Uart* uartenable(Uart *);
-
 extern PhysUart cycvphysuart;
 
 static Ctlr vctlr[1] = {
@@ -55,7 +53,7 @@
 };
 
 void
-uartinit(void)
+uartconsinit(void)
 {
 	consuart = vuart;
 }
@@ -155,22 +153,6 @@
 		;
 	ct->r[RBR] = c;
 	return;
-}
-
-int
-uartconsole(void)
-{
-	Uart *uart = vuart;
-
-	if(up == nil)
-		return -1;
-
-	if(uartenable(uart) != nil){
-		serialoq = uart->oq;
-		uart->opens++;
-		consuart = uart;
-	}
-	return 0;
 }
 
 int
--- a/sys/src/9/imx8/main.c
+++ b/sys/src/9/imx8/main.c
@@ -337,12 +337,12 @@
 		schedinit();
 		return;
 	}
+	uartconsinit();
 	quotefmtinstall();
 	bootargsinit();
 	meminit();
 	confinit();
 	xinit();
-	uartconsinit();
 	printinit();
 	print("\nPlan 9\n");
 	trapinit();
--- a/sys/src/9/imx8/uartimx.c
+++ b/sys/src/9/imx8/uartimx.c
@@ -379,7 +379,6 @@
 	consuart = &uart1;
 	consuart->console = 1;
 	uartctl(consuart, "l8 pn s1");
-	uartputs(kmesg.buf, kmesg.n);
 }
 
 PhysUart imxphysuart = {
--- a/sys/src/9/kw/archkw.c
+++ b/sys/src/9/kw/archkw.c
@@ -472,13 +472,6 @@
 }
 
 void
-archconsole(void)
-{
-//	uartconsole(0, "b115200");
-//serialputs("uart0 console @ 115200\n", strlen("uart0 console @ 115200\n"));
-}
-
-void
 archflashwp(Flash*, int)
 {
 }
--- a/sys/src/9/kw/clock.c
+++ b/sys/src/9/kw/clock.c
@@ -104,7 +104,7 @@
 	}
 	splx(s);
 	if (ticks == 0) {
-		serialputc('?');
+		uartputc('?');
 		if (tmr->timer0 == 0)
 			panic("clock not interrupting");
 		else if (tmr->timer0 == tmr->reload0)
--- a/sys/src/9/kw/fns.h
+++ b/sys/src/9/kw/fns.h
@@ -6,11 +6,7 @@
 extern int led(int, int);
 extern void ledexit(int);
 extern void delay(int);
-extern void _uartputs(char*, int);
-extern int _uartprint(char*, ...);
-extern void uartkirkwoodconsole(void);
-extern void serialputs(char *, int);
-extern void serialputc(int c);
+extern void uartconsinit(void);
 
 #pragma	varargck argpos	_uartprint 1
 
--- a/sys/src/9/kw/main.c
+++ b/sys/src/9/kw/main.c
@@ -182,8 +182,6 @@
 //	print("spi flash at %#ux: memory reads enabled\n", PHYSSPIFLASH);
 }
 
-void	archconsole(void);
-
 /* dummy for usb */
 int
 isaconfig(char *, int, ISAConf *)
@@ -217,13 +215,13 @@
 	vfy = 0;
 
 wave('9');
+	uartconsinit();
 	machinit();
 	archreset();
 	mmuinit();
+uartputc(' ');
 
 	quotefmtinstall();
-	archconsole();
-wave(' ');
 
 	/* want plan9.ini to be able to affect memory sizing in confinit */
 	plan9iniinit();		/* before we step on plan9.ini in low memory */
@@ -249,7 +247,6 @@
 	clockinit();
 
 	printinit();
-	uartkirkwoodconsole();
 	/* only now can we print */
 	print("from Bell Labs\n\n");
 
--- a/sys/src/9/kw/uartkw.c
+++ b/sys/src/9/kw/uartkw.c
@@ -300,6 +300,13 @@
 	coherence();
 }
 
+void
+uartconsinit(void)
+{
+	consuart = &kirkwooduart[0];
+	uartctl(consuart, "b115200 l8 pn s1 i1");
+}
+
 PhysUart kwphysuart = {
 	.name		= "kirkwood",
 	.pnp		= kw_pnp,
@@ -319,44 +326,3 @@
 	.getc		= kw_getc,
 	.putc		= kw_putc,
 };
-
-void
-uartkirkwoodconsole(void)
-{
-	Uart *uart;
-
-	uart = &kirkwooduart[0];
-	(*uart->phys->enable)(uart, 0);
-	uartctl(uart, "b115200 l8 pn s1 i1");
-	uart->console = 1;
-	consuart = uart;
-//serialputs("uart0 kirkwood\n", strlen("uart0 kirkwood\n"));
-}
-
-void
-serialputc(int c)
-{
-	int cnt, s;
-	UartReg *regs = (UartReg *)soc.uart[0];
-
-	s = splhi();
-	cnt = m->cpuhz;
-	if (cnt <= 0)			/* cpuhz not set yet? */
-		cnt = 1000000;
-	while((regs->lsr & LSRthre) == 0 && --cnt > 0)
-		;
-	regs->thr = c;
-	coherence();
-	delay(1);
-	splx(s);
-}
-
-void
-serialputs(char *p, int len)
-{
-	while(--len >= 0) {
-		if(*p == '\n')
-			serialputc('\r');
-		serialputc(*p++);
-	}
-}
--- a/sys/src/9/mt7688/dat.h
+++ b/sys/src/9/mt7688/dat.h
@@ -221,11 +221,8 @@
 
 extern Mach* machaddr[MAXMACH];
 #define	MACHP(n)	(machaddr[n])
-extern int	normalprint;
 
 extern FPsave initfp;
-
-#define CONSOLE	0
 
 /*
  *  hardware info about a device
--- a/sys/src/9/mt7688/fns.h
+++ b/sys/src/9/mt7688/fns.h
@@ -73,7 +73,7 @@
 
 void	_uartputs(char*, int);
 int		_uartprint(char*, ...);
-void	uartinit(void);
+void	uartconsinit(void);
 void	zoot(void);
 void	idle(void);
 ulong	getstatus(void);
--- a/sys/src/9/mt7688/main.c
+++ b/sys/src/9/mt7688/main.c
@@ -20,8 +20,6 @@
 Conf	conf;
 Mach* machaddr[MAXMACH];
 
-int normalprint;
-
 static void
 checkclock0(void)
 {
@@ -114,7 +112,7 @@
 {
 	savefpregs(&initfp);
 
-	uartinit();
+	uartconsinit();
 	quotefmtinstall();
 
 	confinit();
@@ -121,7 +119,6 @@
 	machinit();			/* calls clockinit */
 	active.exiting = 0;
 	active.machs[0] = 1;
-	normalprint = 1;
 
 	kmapinit();
 	xinit();
@@ -129,7 +126,6 @@
 	plan9iniinit();
 	intrinit();
 
-
 	iprint("\nPlan 9 \n");
 	prcpuid();
 	delay(50);
@@ -214,8 +210,6 @@
 init0(void)
 {
 	char buf[128], **sp;
-
-	i8250console();
 
 	chandevinit();
 
--- a/sys/src/9/mt7688/uarti8250.c
+++ b/sys/src/9/mt7688/uarti8250.c
@@ -439,13 +439,6 @@
 }
 
 static void
-emptyoutstage(Uart *uart, int n)
-{
-	_uartputs((char *)uart->op, n);
-	uart->op = uart->oe = uart->ostage;
-}
-
-static void
 i8250kick(Uart* uart)
 {
 	int i;
@@ -454,14 +447,6 @@
 	if(/* uart->cts == 0 || */ uart->blocked)
 		return;
 
-	if(!normalprint) {			/* early */
-		if (uart->op < uart->oe)
-			emptyoutstage(uart, uart->oe - uart->op);
-		while ((i = uartstageoutput(uart)) > 0)
-			emptyoutstage(uart, i);
-		return;
-	}
-
 	/* nothing more to send? then disable xmit intr */
 	ctlr = uart->regs;
 	if (uart->op >= uart->oe && qlen(uart->oq) == 0 &&
@@ -488,12 +473,6 @@
 	}
 }
 
-void
-serialkick(void)
-{
-	uartkick(&i8250uart[CONSOLE]);
-}
-
 static void
 i8250interrupt(Ureg*, void* arg)
 {
@@ -584,20 +563,11 @@
 }
 
 static void
-i8250clock(void)
-{
-	i8250interrupt(nil, &i8250uart[CONSOLE]);
-}
-
-static void
 i8250enable(Uart* uart, int ie)
 {
 	int mode;
 	Ctlr *ctlr;
 
-	if (up == nil)
-		return;				/* too soon */
-
 	ctlr = uart->regs;
 
 	ctlr->sticky[Lcr] = Wls8;		/* no parity */
@@ -662,14 +632,8 @@
 	 * interrupt handler to clear any pending interrupt events.
 	 * Note: this must be done after setting Ier.
 	 */
-	if(ie){
+	if(ie)
 		i8250interrupt(nil, uart);
-		/*
-		 * force output to resume if stuck.  shouldn't be needed.
-		 */
-//		if (Pollstuckoutput)
-//			addclock0link(i8250clock, 10);
-	}
 }
 
 static Uart*
@@ -695,16 +659,6 @@
 	int i, s;
 	Ctlr *ctlr;
 
-	if (!normalprint) {		/* too early; use brute force */
-		int s = splhi();
-
-		while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
-			;
-		((ulong *)PHYSCONS)[Thr] = c;
-		splx(s);
-		return;
-	}
-
 	ctlr = uart->regs;
 	s = splhi();
 	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
@@ -716,40 +670,12 @@
 }
 
 void
-serialputc(int c)
+uartconsinit(void)
 {
-	i8250putc(&i8250uart[CONSOLE], c);
+	consuart = &i8250uart[0];
+	uartctl(consuart, "b115200 l8 pn s1");
 }
 
-void
-serialputs(char* s, int n)
-{
-	_uartputs(s, n);
-}
-
-#ifdef notdef
-static void
-i8250poll(Uart* uart)
-{
-	Ctlr *ctlr;
-
-	/*
-	 * If PhysUart has a non-nil .poll member, this
-	 * routine will be called from the uartclock timer.
-	 * If the Ctlr .poll member is non-zero, when the
-	 * Uart is enabled interrupts will not be enabled
-	 * and the result is polled input and output.
-	 * Not very useful here, but ports to new hardware
-	 * or simulators can use this to get serial I/O
-	 * without setting up the interrupt mechanism.
-	 */
-	ctlr = uart->regs;
-	if(ctlr->iena || !ctlr->poll)
-		return;
-	i8250interrupt(nil, uart);
-}
-#endif
-
 PhysUart i8250physuart = {
 	.name		= "i8250",
 	.pnp		= i8250pnp,
@@ -768,83 +694,4 @@
 	.fifo		= i8250fifo,
 	.getc		= i8250getc,
 	.putc		= i8250putc,
-//	.poll		= i8250poll,		/* only in 9k, not 9 */
 };
-
-static void
-i8250dumpregs(Ctlr* ctlr)
-{
-	int dlm, dll;
-	int _uartprint(char*, ...);
-
-	csr8w(ctlr, Lcr, Dlab);
-	dlm = csr8r(ctlr, Dlm);
-	dll = csr8r(ctlr, Dll);
-	csr8w(ctlr, Lcr, 0);
-
-	_uartprint("dlm %#ux dll %#ux\n", dlm, dll);
-}
-
-Uart*	uartenable(Uart *p);
-
-/* must call this from a process's context */
-int
-i8250console(void)
-{
-	Uart *uart = &i8250uart[CONSOLE];
-
-	if (up == nil)
-		return -1;			/* too early */
-
-	if(uartenable(uart) != nil /* && uart->console */){
-//		iprint("i8250console: enabling console uart\n");
-//		serialoq = uart->oq;
-/*
- * on mt7688
- * uart->oq seems to fill and block, this bypasses that
- * see port/devcons, putstrn0
- */
-		serialoq = nil;  
-		uart->opens++;
-		consuart = uart;
-//		i8250disable(uart);
-		i8250enable(uart, 1);
-//		screenputs = _uartputs;
-	}
-	uartctl(uart, "b115200 l8 pn s1");
-	return 0;
-}
-
-void
-_uartputs(char* s, int n)
-{
-	char *e;
-
-	for(e = s+n; s < e; s++){
-		if(*s == '\n')
-			i8250putc(&i8250uart[CONSOLE], '\r');
-		i8250putc(&i8250uart[CONSOLE], *s);
-	}
-}
-
-int
-_uartprint(char* fmt, ...)
-{
-	int n;
-	va_list arg;
-	char buf[PRINTSIZE];
-
-	va_start(arg, fmt);
-	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
-	va_end(arg);
-	_uartputs(buf, n);
-
-	return n;
-}
-
-
-void
-uartinit(void)
-{
-	consuart = &i8250uart[CONSOLE];
-}
--- a/sys/src/9/omap/dat.h
+++ b/sys/src/9/omap/dat.h
@@ -18,12 +18,6 @@
 #define MS2TMR(t)	((ulong)(((uvlong)(t) * m->cpuhz)/1000))
 #define US2TMR(t)	((ulong)(((uvlong)(t) * m->cpuhz)/1000000))
 
-/*
- * we ignore the first 2 uarts on the omap3530 (see uarti8250.c) and use the
- * third one but call it 0.
- */
-#define CONSOLE 0
-
 typedef struct Conf	Conf;
 typedef struct Confmem	Confmem;
 typedef struct FPsave	FPsave;
@@ -198,7 +192,6 @@
 extern uintptr kseg0;
 extern Mach* machaddr[MAXMACH];
 extern ulong memsize;
-extern int normalprint;
 
 /*
  *  a parsed plan9.ini line
--- a/sys/src/9/omap/devuart.c
+++ /dev/null
@@ -1,759 +1,0 @@
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"../port/error.h"
-
-#include	"../port/netif.h"
-
-enum
-{
-	/* soft flow control chars */
-	CTLS= 023,
-	CTLQ= 021,
-};
-
-extern Dev uartdevtab;
-extern PhysUart* physuart[];
-
-static Uart* uartlist;
-static Uart** uart;
-static int uartnuart;
-static Dirtab *uartdir;
-static int uartndir;
-static Timer *uarttimer;
-
-struct Uartalloc {
-	Lock;
-	Uart *elist;	/* list of enabled interfaces */
-} uartalloc;
-
-static void	uartclock(void);
-static void	uartflow(void*);
-
-/*
- *  enable/disable uart and add/remove to list of enabled uarts
- */
-//static
-Uart*
-uartenable(Uart *p)
-{
-	Uart **l;
-
-	if (up == nil)
-		return p;		/* too soon; try again later */
-//		return nil;
-
-	if(p->iq == nil){
-		if((p->iq = qopen(8*1024, Qcoalesce, uartflow, p)) == nil)
-			return nil;
-	}
-	else
-		qreopen(p->iq);
-	if(p->oq == nil){
-		if((p->oq = qopen(8*1024, 0, uartkick, p)) == nil){
-			qfree(p->iq);
-			p->iq = nil;
-			return nil;
-		}
-	}
-	else
-		qreopen(p->oq);
-
-	p->ir = p->istage;
-	p->iw = p->istage;
-	p->ie = &p->istage[Stagesize];
-	p->op = p->ostage;
-	p->oe = p->ostage;
-
-	p->hup_dsr = p->hup_dcd = 0;
-	p->dsr = p->dcd = 0;
-
-	/* assume we can send */
-	p->cts = 1;
-	p->ctsbackoff = 0;
-
-if (up) {
-	if(p->bits == 0)
-		uartctl(p, "l8");
-	if(p->stop == 0)
-		uartctl(p, "s1");
-	if(p->parity == 0)
-		uartctl(p, "pn");
-	if(p->baud == 0)
-		uartctl(p, "b9600");
-	(*p->phys->enable)(p, 1);
-}
-
-	/*
-	 * use ilock because uartclock can otherwise interrupt here
-	 * and would hang on an attempt to lock uartalloc.
-	 */
-	ilock(&uartalloc);
-	for(l = &uartalloc.elist; *l; l = &(*l)->elist){
-		if(*l == p)
-			break;
-	}
-	if(*l == 0){
-		p->elist = uartalloc.elist;
-		uartalloc.elist = p;
-	}
-	p->enabled = 1;
-	iunlock(&uartalloc);
-
-	return p;
-}
-
-static void
-uartdisable(Uart *p)
-{
-	Uart **l;
-
-	(*p->phys->disable)(p);
-
-	ilock(&uartalloc);
-	for(l = &uartalloc.elist; *l; l = &(*l)->elist){
-		if(*l == p){
-			*l = p->elist;
-			break;
-		}
-	}
-	p->enabled = 0;
-	iunlock(&uartalloc);
-}
-
-static void
-setlength(int i)
-{
-	Uart *p;
-
-	if(i > 0){
-		p = uart[i];
-		if(p && p->opens && p->iq)
-			uartdir[1+3*i].length = qlen(p->iq);
-	} else for(i = 0; i < uartnuart; i++){
-		p = uart[i];
-		if(p && p->opens && p->iq)
-			uartdir[1+3*i].length = qlen(p->iq);
-	}
-}
-
-/*
- *  set up the '#t' directory
- */
-static void
-uartreset(void)
-{
-	int i;
-	Dirtab *dp;
-	Uart *p, *tail;
-
-	tail = nil;
-	for(i = 0; physuart[i] != nil; i++){
-		if(physuart[i]->pnp == nil)
-			continue;
-		if((p = physuart[i]->pnp()) == nil)
-			continue;
-		if(uartlist != nil)
-			tail->next = p;
-		else
-			uartlist = p;
-		for(tail = p; tail->next != nil; tail = tail->next)
-			uartnuart++;
-		uartnuart++;
-	}
-
-	if(uartnuart)
-		uart = xalloc(uartnuart*sizeof(Uart*));
-
-	uartndir = 1 + 3*uartnuart;
-	uartdir = xalloc(uartndir * sizeof(Dirtab));
-	if (uart == nil || uartdir == nil)
-		panic("uartreset: no memory");
-	dp = uartdir;
-	strcpy(dp->name, ".");
-	mkqid(&dp->qid, 0, 0, QTDIR);
-	dp->length = 0;
-	dp->perm = DMDIR|0555;
-	dp++;
-	p = uartlist;
-	for(i = 0; i < uartnuart; i++){
-		/* 3 directory entries per port */
-		snprint(dp->name, sizeof dp->name, "eia%d", i);
-		dp->qid.path = NETQID(i, Ndataqid);
-		dp->perm = 0660;
-		dp++;
-		snprint(dp->name, sizeof dp->name, "eia%dctl", i);
-		dp->qid.path = NETQID(i, Nctlqid);
-		dp->perm = 0660;
-		dp++;
-		snprint(dp->name, sizeof dp->name, "eia%dstatus", i);
-		dp->qid.path = NETQID(i, Nstatqid);
-		dp->perm = 0444;
-		dp++;
-
-		uart[i] = p;
-		p->dev = i;
-		if(p->console || p->special){
-			if(uartenable(p) != nil){
-				if(p->console && up)
-					serialoq = p->oq;
-				p->opens++;
-			}
-		}
-		p = p->next;
-	}
-
-	if(uartnuart){
-		/*
-		 * at 115200 baud, the 1024 char buffer takes 56 ms to process,
-		 * processing it every 22 ms should be fine.
-		 */
-		uarttimer = addclock0link(uartclock, 22);
-	}
-}
-
-
-static Chan*
-uartattach(char *spec)
-{
-	return devattach('t', spec);
-}
-
-static Walkqid*
-uartwalk(Chan *c, Chan *nc, char **name, int nname)
-{
-	return devwalk(c, nc, name, nname, uartdir, uartndir, devgen);
-}
-
-static int
-uartstat(Chan *c, uchar *dp, int n)
-{
-	if(NETTYPE(c->qid.path) == Ndataqid)
-		setlength(NETID(c->qid.path));
-	return devstat(c, dp, n, uartdir, uartndir, devgen);
-}
-
-static Chan*
-uartopen(Chan *c, int omode)
-{
-	Uart *p;
-
-	c = devopen(c, omode, uartdir, uartndir, devgen);
-
-	switch(NETTYPE(c->qid.path)){
-	case Nctlqid:
-	case Ndataqid:
-		p = uart[NETID(c->qid.path)];
-		qlock(p);
-		if(p->opens++ == 0 && uartenable(p) == nil){
-			qunlock(p);
-			c->flag &= ~COPEN;
-			error(Enodev);
-		}
-		qunlock(p);
-		break;
-	}
-
-	c->iounit = qiomaxatomic;
-	return c;
-}
-
-static int
-uartdrained(void* arg)
-{
-	Uart *p;
-
-	p = arg;
-	return qlen(p->oq) == 0 && p->op == p->oe;
-}
-
-static void
-uartdrainoutput(Uart *p)
-{
-	if(!p->enabled || up == nil)
-		return;
-
-	p->drain = 1;
-	if(waserror()){
-		p->drain = 0;
-		nexterror();
-	}
-	sleep(&p->r, uartdrained, p);
-	poperror();
-}
-
-static void
-uartclose(Chan *c)
-{
-	Uart *p;
-
-	if(c->qid.type & QTDIR)
-		return;
-	if((c->flag & COPEN) == 0)
-		return;
-	switch(NETTYPE(c->qid.path)){
-	case Ndataqid:
-	case Nctlqid:
-		p = uart[NETID(c->qid.path)];
-		qlock(p);
-		if(--(p->opens) == 0){
-			qclose(p->iq);
-			ilock(&p->rlock);
-			p->ir = p->iw = p->istage;
-			iunlock(&p->rlock);
-
-			/*
-			 */
-			qhangup(p->oq, nil);
-			if(!waserror()){
-				uartdrainoutput(p);
-				poperror();
-			}
-			qclose(p->oq);
-			uartdisable(p);
-			p->dcd = p->dsr = p->dohup = 0;
-		}
-		qunlock(p);
-		break;
-	}
-}
-
-static long
-uartread(Chan *c, void *buf, long n, vlong off)
-{
-	Uart *p;
-	ulong offset = off;
-
-	if(c->qid.type & QTDIR){
-		setlength(-1);
-		return devdirread(c, buf, n, uartdir, uartndir, devgen);
-	}
-
-	p = uart[NETID(c->qid.path)];
-	switch(NETTYPE(c->qid.path)){
-	case Ndataqid:
-		return qread(p->iq, buf, n);
-	case Nctlqid:
-		return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
-	case Nstatqid:
-		return (*p->phys->status)(p, buf, n, offset);
-	}
-
-	return 0;
-}
-
-int
-uartctl(Uart *p, char *cmd)
-{
-	char *f[16];
-	int i, n, nf;
-
-	nf = tokenize(cmd, f, nelem(f));
-	for(i = 0; i < nf; i++){
-		if(strncmp(f[i], "break", 5) == 0){
-			(*p->phys->dobreak)(p, 0);
-			continue;
-		}
-
-		n = atoi(f[i]+1);
-		switch(*f[i]){
-		case 'B':
-		case 'b':
-			uartdrainoutput(p);
-			if((*p->phys->baud)(p, n) < 0)
-				return -1;
-			break;
-		case 'C':
-		case 'c':
-			p->hup_dcd = n;
-			break;
-		case 'D':
-		case 'd':
-			uartdrainoutput(p);
-			(*p->phys->dtr)(p, n);
-			break;
-		case 'E':
-		case 'e':
-			p->hup_dsr = n;
-			break;
-		case 'f':
-		case 'F':
-			if(p->oq != nil)
-				qflush(p->oq);
-			break;
-		case 'H':
-		case 'h':
-			if(p->iq != nil)
-				qhangup(p->iq, 0);
-			if(p->oq != nil)
-				qhangup(p->oq, 0);
-			break;
-		case 'i':
-		case 'I':
-			uartdrainoutput(p);
-			(*p->phys->fifo)(p, n);
-			break;
-		case 'K':
-		case 'k':
-			uartdrainoutput(p);
-			(*p->phys->dobreak)(p, n);
-			break;
-		case 'L':
-		case 'l':
-			uartdrainoutput(p);
-			if((*p->phys->bits)(p, n) < 0)
-				return -1;
-			break;
-		case 'm':
-		case 'M':
-			uartdrainoutput(p);
-			(*p->phys->modemctl)(p, n);
-			break;
-		case 'n':
-		case 'N':
-			if(p->oq != nil)
-				qnoblock(p->oq, n);
-			break;
-		case 'P':
-		case 'p':
-			uartdrainoutput(p);
-			if((*p->phys->parity)(p, *(f[i]+1)) < 0)
-				return -1;
-			break;
-		case 'Q':
-		case 'q':
-			if(p->iq != nil)
-				qsetlimit(p->iq, n);
-			if(p->oq != nil)
-				qsetlimit(p->oq, n);
-			break;
-		case 'R':
-		case 'r':
-			uartdrainoutput(p);
-			(*p->phys->rts)(p, n);
-			break;
-		case 'S':
-		case 's':
-			uartdrainoutput(p);
-			if((*p->phys->stop)(p, n) < 0)
-				return -1;
-			break;
-		case 'W':
-		case 'w':
-			if(uarttimer == nil || n < 1)
-				return -1;
-			uarttimer->tns = (vlong)n * 100000LL;
-			break;
-		case 'X':
-		case 'x':
-			if(p->enabled){
-				ilock(&p->tlock);
-				p->xonoff = n;
-				iunlock(&p->tlock);
-			}
-			break;
-		}
-	}
-	return 0;
-}
-
-static long
-uartwrite(Chan *c, void *buf, long n, vlong)
-{
-	Uart *p;
-	char *cmd;
-
-	if(c->qid.type & QTDIR)
-		error(Eperm);
-
-	p = uart[NETID(c->qid.path)];
-
-	switch(NETTYPE(c->qid.path)){
-	case Ndataqid:
-		qlock(p);
-		if(waserror()){
-			qunlock(p);
-			nexterror();
-		}
-
-		n = qwrite(p->oq, buf, n);
-
-		qunlock(p);
-		poperror();
-		break;
-	case Nctlqid:
-		cmd = malloc(n+1);
-		memmove(cmd, buf, n);
-		cmd[n] = 0;
-		qlock(p);
-		if(waserror()){
-			qunlock(p);
-			free(cmd);
-			nexterror();
-		}
-
-		/* let output drain */
-		if(uartctl(p, cmd) < 0)
-			error(Ebadarg);
-
-		qunlock(p);
-		poperror();
-		free(cmd);
-		break;
-	}
-
-	return n;
-}
-
-static int
-uartwstat(Chan *c, uchar *dp, int n)
-{
-	Dir d;
-	Dirtab *dt;
-
-	if(!iseve())
-		error(Eperm);
-	if(QTDIR & c->qid.type)
-		error(Eperm);
-	if(NETTYPE(c->qid.path) == Nstatqid)
-		error(Eperm);
-
-	dt = &uartdir[1 + 3 * NETID(c->qid.path)];
-	n = convM2D(dp, n, &d, nil);
-	if(n == 0)
-		error(Eshortstat);
-	if(d.mode != ~0UL)
-		dt[0].perm = dt[1].perm = d.mode;
-	return n;
-}
-
-void
-uartpower(int on)
-{
-	Uart *p;
-
-	for(p = uartlist; p != nil; p = p->next) {
-		if(p->phys->power)
-			(*p->phys->power)(p, on);
-	}
-}
-
-Dev uartdevtab = {
-	't',
-	"uart",
-
-	uartreset,
-	devinit,
-	devshutdown,
-	uartattach,
-	uartwalk,
-	uartstat,
-	uartopen,
-	devcreate,
-	uartclose,
-	uartread,
-	devbread,
-	uartwrite,
-	devbwrite,
-	devremove,
-	uartwstat,
-	uartpower,
-};
-
-/*
- *  restart input if it's off
- */
-static void
-uartflow(void *v)
-{
-	Uart *p;
-
-	p = v;
-	if(p->modem)
-		(*p->phys->rts)(p, 1);
-}
-
-/*
- *  put some bytes into the local queue to avoid calling
- *  qconsume for every character
- */
-int
-uartstageoutput(Uart *p)
-{
-	int n;
-
-	n = qconsume(p->oq, p->ostage, Stagesize);
-	if(n <= 0)
-//		n = 0;			/* experiment */
-		return 0;
-	p->op = p->ostage;
-	p->oe = p->ostage + n;
-	return n;
-}
-
-/*
- *  restart output
- */
-void
-uartkick(void *v)
-{
-	Uart *p = v;
-
-	if(p->blocked)
-		return;
-
-	ilock(&p->tlock);
-	(*p->phys->kick)(p);
-	iunlock(&p->tlock);
-
-	if(p->drain && uartdrained(p)){
-		p->drain = 0;
-		wakeup(&p->r);
-	}
-}
-
-/*
- * Move data from the interrupt staging area to
- * the input Queue.
- */
-static void
-uartstageinput(Uart *p)
-{
-	int n;
-	uchar *ir, *iw;
-
-	while(p->ir != p->iw){
-		ir = p->ir;
-		if(p->ir > p->iw){
-			iw = p->ie;
-			p->ir = p->istage;
-		}
-		else{
-			iw = p->iw;
-			p->ir = p->iw;
-		}
-		if((n = qproduce(p->iq, ir, iw - ir)) < 0){
-			p->serr++;
-			(*p->phys->rts)(p, 0);
-		}
-		else if(n == 0)
-			p->berr++;
-	}
-}
-
-/*
- *  receive a character at interrupt time
- */
-void
-uartrecv(Uart *p,  char ch)
-{
-	uchar *next;
-
-	/* software flow control */
-	if(p->xonoff){
-		if(ch == CTLS){
-			p->blocked = 1;
-		}else if(ch == CTLQ){
-			p->blocked = 0;
-			p->ctsbackoff = 2; /* clock gets output going again */
-		}
-	}
-
-	/* receive the character */
-	if(p->putc)
-		p->putc(p->iq, ch);
-	else if (p->iw) {		/* maybe the line isn't enabled yet */
-		ilock(&p->rlock);
-		next = p->iw + 1;
-		if(next == p->ie)
-			next = p->istage;
-		if(next == p->ir)
-			uartstageinput(p);
-		if(next != p->ir){
-			*p->iw = ch;
-			p->iw = next;
-		}
-		iunlock(&p->rlock);
-	}
-}
-
-/*
- *  we save up input characters till clock time to reduce
- *  per character interrupt overhead.
- */
-static void
-uartclock(void)
-{
-	Uart *p;
-
-	ilock(&uartalloc);
-	for(p = uartalloc.elist; p; p = p->elist){
-
-		/* this hopefully amortizes cost of qproduce to many chars */
-		if(p->iw != p->ir){
-			ilock(&p->rlock);
-			uartstageinput(p);
-			iunlock(&p->rlock);
-		}
-
-		/* hang up if requested */
-		if(p->dohup){
-			qhangup(p->iq, 0);
-			qhangup(p->oq, 0);
-			p->dohup = 0;
-		}
-
-		/* this adds hysteresis to hardware/software flow control */
-		if(p->ctsbackoff){
-			ilock(&p->tlock);
-			if(p->ctsbackoff){
-				if(--(p->ctsbackoff) == 0)
-					(*p->phys->kick)(p);
-			}
-			iunlock(&p->tlock);
-		}
-		uartkick(p);		/* keep it moving */
-	}
-	iunlock(&uartalloc);
-}
-
-/*
- * polling console input, output
- */
-
-Uart* consuart;
-
-int
-uartgetc(void)
-{
-	if(consuart == nil || consuart->phys->getc == nil)
-		return -1;
-	return consuart->phys->getc(consuart);
-}
-
-void
-uartputc(int c)
-{
-	if(consuart == nil || consuart->phys->putc == nil)
-		return;
-	consuart->phys->putc(consuart, c);
-}
-
-void
-uartputs(char *s, int n)
-{
-	char *e;
-
-	if(consuart == nil || consuart->phys->putc == nil)
-		return;
-
-	e = s+n;
-	for(; s<e; s++){
-		if(*s == '\n')
-			consuart->phys->putc(consuart, '\r');
-		consuart->phys->putc(consuart, *s);
-	}
-}
--- a/sys/src/9/omap/fns.h
+++ b/sys/src/9/omap/fns.h
@@ -6,11 +6,8 @@
 extern int led(int, int);
 extern void ledexit(int);
 extern void delay(int);
-extern void _uartputs(char*, int);
-extern int _uartprint(char*, ...);
+extern void uartconsinit(void);
 
-#pragma	varargck argpos	_uartprint 1
-
 extern void archreboot(void);
 extern void archreset(void);
 extern void cachedinv(void);
@@ -75,7 +72,6 @@
 extern void _reset(void);
 extern void screenclockson(void);
 extern void screeninit(void);
-extern void serialputs(char* s, int n);
 extern void setcachelvl(int);
 extern void setr13(int, u32int*);
 extern int tas(void *);
--- a/sys/src/9/omap/main.c
+++ b/sys/src/9/omap/main.c
@@ -165,6 +165,7 @@
 	vfy = 0;
 
 wave('l');
+	uartconsinit();
 	machinit();
 	mmuinit();
 
@@ -218,8 +219,6 @@
 	screeninit();
 	chandevreset();			/* most devices are discovered here */
 
-//	i8250console();			/* too early; see init0 */
-
 	pageinit();
 	userinit();
 	schedinit();
@@ -349,10 +348,6 @@
 
 	dmatest();		/* needs `up' set, so can't do it earlier */
 	chandevinit();
-	i8250console();		/* might be redundant, but harmless */
-	if(serialoq == nil)
-		panic("init0: nil serialoq");
-	normalprint = 1;
 
 	if(!waserror()){
 		snprint(buf, sizeof(buf), "%s %s", "ARM", conffile);
--- a/sys/src/9/omap/uarti8250.c
+++ b/sys/src/9/omap/uarti8250.c
@@ -462,13 +462,6 @@
 }
 
 static void
-emptyoutstage(Uart *uart, int n)
-{
-	_uartputs((char *)uart->op, n);
-	uart->op = uart->oe = uart->ostage;
-}
-
-static void
 i8250kick(Uart* uart)
 {
 	int i;
@@ -477,14 +470,6 @@
 	if(/* uart->cts == 0 || */ uart->blocked)
 		return;
 
-	if(!normalprint) {			/* early */
-		if (uart->op < uart->oe)
-			emptyoutstage(uart, uart->oe - uart->op);
-		while ((i = uartstageoutput(uart)) > 0)
-			emptyoutstage(uart, i);
-		return;
-	}
-
 	/* nothing more to send? then disable xmit intr */
 	ctlr = uart->regs;
 	if (uart->op >= uart->oe && qlen(uart->oq) == 0 &&
@@ -511,12 +496,6 @@
 	}
 }
 
-void
-serialkick(void)
-{
-	uartkick(&i8250uart[CONSOLE]);
-}
-
 static void
 i8250interrupt(Ureg*, void* arg)
 {
@@ -612,9 +591,6 @@
 	int mode;
 	Ctlr *ctlr;
 
-	if (up == nil)
-		return;				/* too soon */
-
 	ctlr = uart->regs;
 
 	/* omap only: set uart/irda/cir mode to uart */
@@ -710,17 +686,6 @@
 	int i;
 	Ctlr *ctlr;
 
-	if (!normalprint) {		/* too early; use brute force */
-		int s = splhi();
-
-		while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
-			;
-		((ulong *)PHYSCONS)[Thr] = c;
-		coherence();
-		splx(s);
-		return;
-	}
-
 	ctlr = uart->regs;
 	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
 		delay(1);
@@ -730,40 +695,12 @@
 }
 
 void
-serialputc(int c)
+uartconsinit(void)
 {
-	i8250putc(&i8250uart[CONSOLE], c);
+	consuart = &i8250uart[0];
+	uartctl(consuart, "b115200 l8 pn r1 s1 i1");
 }
 
-void
-serialputs(char* s, int n)
-{
-	_uartputs(s, n);
-}
-
-#ifdef notdef
-static void
-i8250poll(Uart* uart)
-{
-	Ctlr *ctlr;
-
-	/*
-	 * If PhysUart has a non-nil .poll member, this
-	 * routine will be called from the uartclock timer.
-	 * If the Ctlr .poll member is non-zero, when the
-	 * Uart is enabled interrupts will not be enabled
-	 * and the result is polled input and output.
-	 * Not very useful here, but ports to new hardware
-	 * or simulators can use this to get serial I/O
-	 * without setting up the interrupt mechanism.
-	 */
-	ctlr = uart->regs;
-	if(ctlr->iena || !ctlr->poll)
-		return;
-	i8250interrupt(nil, uart);
-}
-#endif
-
 PhysUart i8250physuart = {
 	.name		= "i8250",
 	.pnp		= i8250pnp,
@@ -782,67 +719,4 @@
 	.fifo		= i8250fifo,
 	.getc		= i8250getc,
 	.putc		= i8250putc,
-//	.poll		= i8250poll,		/* only in 9k, not 9 */
 };
-
-static void
-i8250dumpregs(Ctlr* ctlr)
-{
-	int dlm, dll;
-	int _uartprint(char*, ...);
-
-	csr8w(ctlr, Lcr, Dlab);
-	dlm = csr8r(ctlr, Dlm);
-	dll = csr8r(ctlr, Dll);
-	csr8w(ctlr, Lcr, 0);
-
-	_uartprint("dlm %#ux dll %#ux\n", dlm, dll);
-}
-
-Uart*	uartenable(Uart *p);
-
-/* must call this from a process's context */
-int
-i8250console(void)
-{
-	Uart *uart = &i8250uart[CONSOLE];
-
-	if (up == nil)
-		return -1;			/* too early */
-
-	if(uartenable(uart) != nil /* && uart->console */){
-		// iprint("i8250console: enabling console uart\n");
-		serialoq = uart->oq;
-		uart->opens++;
-		consuart = uart;
-	}
-	uartctl(uart, "b115200 l8 pn r1 s1 i1");
-	return 0;
-}
-
-void
-_uartputs(char* s, int n)
-{
-	char *e;
-
-	for(e = s+n; s < e; s++){
-		if(*s == '\n')
-			i8250putc(&i8250uart[CONSOLE], '\r');
-		i8250putc(&i8250uart[CONSOLE], *s);
-	}
-}
-
-int
-_uartprint(char* fmt, ...)
-{
-	int n;
-	va_list arg;
-	char buf[PRINTSIZE];
-
-	va_start(arg, fmt);
-	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
-	va_end(arg);
-	_uartputs(buf, n);
-
-	return n;
-}
--- a/sys/src/9/port/devuart.c
+++ b/sys/src/9/port/devuart.c
@@ -25,7 +25,7 @@
 static int uartndir;
 static Timer *uarttimer;
 
-struct Uartalloc {
+static struct Uartalloc {
 	Lock;
 	Uart *elist;	/* list of enabled interfaces */
 } uartalloc;
@@ -36,7 +36,7 @@
 /*
  *  enable/disable uart and add/remove to list of enabled uarts
  */
-Uart*
+static Uart*
 uartenable(Uart *p)
 {
 	Uart **l;
@@ -264,7 +264,6 @@
 						consuart = p;
 						uartputs(kmesg.buf, kmesg.n);
 					}
-					serialoq = p->oq;
 				}
 				p->opens++;
 			}
@@ -281,6 +280,13 @@
 	}
 }
 
+static void
+uartinit(void)
+{
+	/* now that the timers are ticking, enable buffered uart */
+	if(serialoq == nil && consuart != nil)
+		serialoq = consuart->oq;
+}
 
 static Chan*
 uartattach(char *spec)
@@ -594,7 +600,7 @@
 	return n;
 }
 
-void
+static void
 uartpower(int on)
 {
 	Uart *p;
@@ -610,7 +616,7 @@
 	"uart",
 
 	uartreset,
-	devinit,
+	uartinit,
 	devshutdown,
 	uartattach,
 	uartwalk,
--- a/sys/src/9/teg2/archtegra.c
+++ b/sys/src/9/teg2/archtegra.c
@@ -675,8 +675,8 @@
 
 	up = nil;
 	if (active.machs[m->machno]) {
-		serialputc('?');
-		serialputc('r');
+		uartputc('?');
+		uartputc('r');
 		panic("cpu%d: resetting after start", m->machno);
 	}
 	assert(m->machno != 0);
--- a/sys/src/9/teg2/dat.h
+++ b/sys/src/9/teg2/dat.h
@@ -19,8 +19,6 @@
 #define MS2TMR(t)	((ulong)(((uvlong)(t) * m->cpuhz)/1000))
 #define US2TMR(t)	((ulong)(((uvlong)(t) * m->cpuhz)/1000000))
 
-#define CONSOLE 0
-
 typedef struct Conf	Conf;
 typedef struct Confmem	Confmem;
 typedef struct FPsave	FPsave;
@@ -244,7 +242,6 @@
 extern Mach* machaddr[MAXMACH];
 extern ulong memsize;
 extern int navailcpus;
-extern int normalprint;
 
 /*
  *  a parsed plan9.ini line
--- a/sys/src/9/teg2/fns.h
+++ b/sys/src/9/teg2/fns.h
@@ -9,8 +9,7 @@
 extern int led(int, int);
 extern void ledexit(int);
 extern void delay(int);
-extern void _uartputs(char*, int);
-extern int _uartprint(char*, ...);
+extern void uartconsinit(void);
 
 #pragma	varargck argpos	_uartprint 1
 
@@ -104,8 +103,6 @@
 extern void _reset(void);
 extern void screenclockson(void);
 extern void screeninit(void);
-extern void serialputc(int c);
-extern void serialputs(char* s, int n);
 extern void setcachelvl(int);
 extern void setsp(uintptr);
 extern void setr13(int, u32int*);
@@ -137,7 +134,6 @@
  */
 extern void archconfinit(void);
 extern void clockinit(void);
-extern int i8250console(void);
 extern void links(void);
 extern void mmuinit(void);
 extern void touser(uintptr);
--- a/sys/src/9/teg2/main.c
+++ b/sys/src/9/teg2/main.c
@@ -42,7 +42,6 @@
 Lowmemcache *cacheconf;
 
 int vflag;
-int normalprint;
 char debug[256];
 
 static Lock testlock;
@@ -181,19 +180,19 @@
 	Mach *m0;
 
 	if (m == 0) {
-		serialputc('?');
-		serialputc('m');
-		serialputc('0');
+		uartputc('?');
+		uartputc('m');
+		uartputc('0');
 	}
 	if(machaddr[m->machno] != m) {
-		serialputc('?');
-		serialputc('m');
-		serialputc('m');
+		uartputc('?');
+		uartputc('m');
+		uartputc('m');
 	}
 
 	if (canlock(&testlock)) {
-		serialputc('?');
-		serialputc('l');
+		uartputc('?');
+		uartputc('l');
 		panic("cpu%d: locks don't work", m->machno);
 	}
 
@@ -220,8 +219,8 @@
 mach0init(void)
 {
 	if (m == 0) {
-		serialputc('?');
-		serialputc('m');
+		uartputc('?');
+		uartputc('m');
 	}
 	conf.nmach = 0;
 
@@ -306,15 +305,8 @@
 main(void)
 {
 	int cpu;
-	static ulong vfy = 0xcafebabe;
 
 	up = nil;
-	if (vfy != 0xcafebabe) {
-		serialputc('?');
-		serialputc('d');
-		panic("data segment misaligned");
-	}
-
 	memset(edata, 0, end - edata);
 
 	/*
@@ -322,6 +314,7 @@
 	 * until l1 & l2 are on.  too bad.  l1 is on, l2 will soon be.
 	 */
 	smpon();
+	uartconsinit();
 	iprint("ll Labs ");
 	cacheinit();
 
@@ -398,7 +391,6 @@
 	iprint("ok\n");
 
 	chandevreset();			/* most devices are discovered here */
-//	i8250console();			/* too early; see init0 */
 
 	pageinit();			/* prints "1020M memory: ⋯ */
 	userinit();
@@ -545,10 +537,6 @@
 	int i;
 
 	chandevinit();
-	i8250console();		/* might be redundant, but harmless */
-	if(serialoq == nil)
-		panic("init0: nil serialoq");
-	normalprint = 1;
 
 	if(!waserror()){
 		snprint(buf, sizeof(buf), "%s %s", "ARM", conffile);
--- a/sys/src/9/teg2/uarti8250.c
+++ b/sys/src/9/teg2/uarti8250.c
@@ -433,13 +433,6 @@
 }
 
 static void
-emptyoutstage(Uart *uart, int n)
-{
-	_uartputs((char *)uart->op, n);
-	uart->op = uart->oe = uart->ostage;
-}
-
-static void
 i8250kick(Uart* uart)
 {
 	int i;
@@ -448,14 +441,6 @@
 	if(/* uart->cts == 0 || */ uart->blocked)
 		return;
 
-	if(!normalprint) {			/* early */
-		if (uart->op < uart->oe)
-			emptyoutstage(uart, uart->oe - uart->op);
-		while ((i = uartstageoutput(uart)) > 0)
-			emptyoutstage(uart, i);
-		return;
-	}
-
 	/* nothing more to send? then disable xmit intr */
 	ctlr = uart->regs;
 	if (uart->op >= uart->oe && qlen(uart->oq) == 0 &&
@@ -482,12 +467,6 @@
 	}
 }
 
-void
-serialkick(void)
-{
-	uartkick(&i8250uart[CONSOLE]);
-}
-
 static void
 i8250interrupt(Ureg*, void* arg)
 {
@@ -583,9 +562,6 @@
 	int mode;
 	Ctlr *ctlr;
 
-	if (up == nil)
-		return;				/* too soon */
-
 	ctlr = uart->regs;
 
 	/* omap only: set uart/irda/cir mode to uart */
@@ -681,17 +657,6 @@
 	int i;
 	Ctlr *ctlr;
 
-	if (!normalprint) {		/* too early; use brute force */
-		int s = splhi();
-
-		while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
-			;
-		((ulong *)PHYSCONS)[Thr] = c;
-		coherence();
-		splx(s);
-		return;
-	}
-
 	ctlr = uart->regs;
 	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
 		delay(1);
@@ -701,40 +666,11 @@
 }
 
 void
-serialputc(int c)
+uartconsinit(void)
 {
-	i8250putc(&i8250uart[CONSOLE], c);
+	consuart = &i8250uart[0];
 }
 
-void
-serialputs(char* s, int n)
-{
-	_uartputs(s, n);
-}
-
-#ifdef notdef
-static void
-i8250poll(Uart* uart)
-{
-	Ctlr *ctlr;
-
-	/*
-	 * If PhysUart has a non-nil .poll member, this
-	 * routine will be called from the uartclock timer.
-	 * If the Ctlr .poll member is non-zero, when the
-	 * Uart is enabled interrupts will not be enabled
-	 * and the result is polled input and output.
-	 * Not very useful here, but ports to new hardware
-	 * or simulators can use this to get serial I/O
-	 * without setting up the interrupt mechanism.
-	 */
-	ctlr = uart->regs;
-	if(ctlr->iena || !ctlr->poll)
-		return;
-	i8250interrupt(nil, uart);
-}
-#endif
-
 PhysUart i8250physuart = {
 	.name		= "i8250",
 	.pnp		= i8250pnp,
@@ -753,67 +689,4 @@
 	.fifo		= i8250fifo,
 	.getc		= i8250getc,
 	.putc		= i8250putc,
-//	.poll		= i8250poll,		/* only in 9k, not 9 */
 };
-
-static void
-i8250dumpregs(Ctlr* ctlr)
-{
-	int dlm, dll;
-	int _uartprint(char*, ...);
-
-	csr8w(ctlr, Lcr, Dlab);
-	dlm = csr8r(ctlr, Dlm);
-	dll = csr8r(ctlr, Dll);
-	csr8w(ctlr, Lcr, 0);
-
-	_uartprint("dlm %#ux dll %#ux\n", dlm, dll);
-}
-
-Uart*	uartenable(Uart *p);
-
-/* must call this from a process's context */
-int
-i8250console(void)
-{
-	Uart *uart = &i8250uart[CONSOLE];
-
-	if (up == nil)
-		return -1;			/* too early */
-
-	if(uartenable(uart) != nil /* && uart->console */){
-		// iprint("i8250console: enabling console uart\n");
-		serialoq = uart->oq;
-		uart->opens++;
-		consuart = uart;
-	}
-	uartctl(uart, "b115200 l8 pn r1 s1 i1");
-	return 0;
-}
-
-void
-_uartputs(char* s, int n)
-{
-	char *e;
-
-	for(e = s+n; s < e; s++){
-		if(*s == '\n')
-			i8250putc(&i8250uart[CONSOLE], '\r');
-		i8250putc(&i8250uart[CONSOLE], *s);
-	}
-}
-
-int
-_uartprint(char* fmt, ...)
-{
-	int n;
-	va_list arg;
-	char buf[PRINTSIZE];
-
-	va_start(arg, fmt);
-	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
-	va_end(arg);
-	_uartputs(buf, n);
-
-	return n;
-}
--- a/sys/src/9/zynq/uartzynq.c
+++ b/sys/src/9/zynq/uartzynq.c
@@ -55,7 +55,6 @@
 {
 	consuart = zuart;
 	uartctl(consuart, "l8 pn s1");
-	uartputs(kmesg.buf, kmesg.n);
 }
 
 static Uart *