xref: /plan9/sys/src/9/teg2/uarti8250.c (revision 3de6a9c0b3d5cf34fc4090d0bf1930d83799a7fd)
1 /*
2  * 8250-like UART
3  */
4 
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 
11 enum {					/* registers */
12 	Rbr		= 0,		/* Receiver Buffer (RO) */
13 	Thr		= 0,		/* Transmitter Holding (WO) */
14 	Ier		= 1,		/* Interrupt Enable */
15 	Iir		= 2,		/* Interrupt Identification (RO) */
16 	Fcr		= 2,		/* FIFO Control (WO) */
17 	Lcr		= 3,		/* Line Control */
18 	Mcr		= 4,		/* Modem Control */
19 	Lsr		= 5,		/* Line Status */
20 	Msr		= 6,		/* Modem Status */
21 	Scr		= 7,		/* Scratch Pad */
22 	Mdr		= 8,		/* Mode Def'n (omap rw) */
23 //	Usr		= 31,		/* Uart Status Register; missing in omap? */
24 	Dll		= 0,		/* Divisor Latch LSB */
25 	Dlm		= 1,		/* Divisor Latch MSB */
26 };
27 
28 enum {					/* Usr */
29 	Busy		= 0x01,
30 };
31 
32 enum {					/* Ier */
33 	Erda		= 0x01,		/* Enable Received Data Available */
34 	Ethre		= 0x02,		/* Enable Thr Empty */
35 	Erls		= 0x04,		/* Enable Receiver Line Status */
36 	Ems		= 0x08,		/* Enable Modem Status */
37 };
38 
39 enum {					/* Iir */
40 	Ims		= 0x00,		/* Ms interrupt */
41 	Ip		= 0x01,		/* Interrupt Pending (not) */
42 	Ithre		= 0x02,		/* Thr Empty */
43 	Irda		= 0x04,		/* Received Data Available */
44 	Irls		= 0x06,		/* Receiver Line Status */
45 	Ictoi		= 0x0C,		/* Character Time-out Indication */
46 	IirMASK		= 0x3F,
47 	Ifena		= 0xC0,		/* FIFOs enabled */
48 };
49 
50 enum {					/* Fcr */
51 	FIFOena		= 0x01,		/* FIFO enable */
52 	FIFOrclr	= 0x02,		/* clear Rx FIFO */
53 	FIFOtclr	= 0x04,		/* clear Tx FIFO */
54 //	FIFOdma		= 0x08,
55 	FIFO1		= 0x00,		/* Rx FIFO trigger level 1 byte */
56 	FIFO4		= 0x40,		/*	4 bytes */
57 	FIFO8		= 0x80,		/*	8 bytes */
58 	FIFO14		= 0xC0,		/*	14 bytes */
59 };
60 
61 enum {					/* Lcr */
62 	Wls5		= 0x00,		/* Word Length Select 5 bits/byte */
63 	Wls6		= 0x01,		/*	6 bits/byte */
64 	Wls7		= 0x02,		/*	7 bits/byte */
65 	Wls8		= 0x03,		/*	8 bits/byte */
66 	WlsMASK		= 0x03,
67 	Stb		= 0x04,		/* 2 stop bits */
68 	Pen		= 0x08,		/* Parity Enable */
69 	Eps		= 0x10,		/* Even Parity Select */
70 	Stp		= 0x20,		/* Stick Parity */
71 	Brk		= 0x40,		/* Break */
72 	Dlab		= 0x80,		/* Divisor Latch Access Bit */
73 };
74 
75 enum {					/* Mcr */
76 	Dtr		= 0x01,		/* Data Terminal Ready */
77 	Rts		= 0x02,		/* Ready To Send */
78 	Out1		= 0x04,		/* no longer in use */
79 //	Ie		= 0x08,		/* IRQ Enable (cd_sts_ch on omap) */
80 	Dm		= 0x10,		/* Diagnostic Mode loopback */
81 };
82 
83 enum {					/* Lsr */
84 	Dr		= 0x01,		/* Data Ready */
85 	Oe		= 0x02,		/* Overrun Error */
86 	Pe		= 0x04,		/* Parity Error */
87 	Fe		= 0x08,		/* Framing Error */
88 	Bi		= 0x10,		/* Break Interrupt */
89 	Thre		= 0x20,		/* Thr Empty */
90 	Temt		= 0x40,		/* Transmitter Empty */
91 	FIFOerr		= 0x80,		/* error in receiver FIFO */
92 };
93 
94 enum {					/* Msr */
95 	Dcts		= 0x01,		/* Delta Cts */
96 	Ddsr		= 0x02,		/* Delta Dsr */
97 	Teri		= 0x04,		/* Trailing Edge of Ri */
98 	Ddcd		= 0x08,		/* Delta Dcd */
99 	Cts		= 0x10,		/* Clear To Send */
100 	Dsr		= 0x20,		/* Data Set Ready */
101 	Ri		= 0x40,		/* Ring Indicator */
102 	Dcd		= 0x80,		/* Carrier Detect */
103 };
104 
105 enum {					/* Mdr */
106 	Modemask	= 7,
107 	Modeuart	= 0,
108 };
109 
110 
111 typedef struct Ctlr {
112 	u32int*	io;
113 	int	irq;
114 	int	tbdf;
115 	int	iena;
116 	int	poll;
117 
118 	uchar	sticky[Scr+1];
119 
120 	Lock;
121 	int	hasfifo;
122 	int	checkfifo;
123 	int	fena;
124 } Ctlr;
125 
126 extern PhysUart i8250physuart;
127 
128 static Ctlr i8250ctlr[] = {
129 {	.io	= (u32int*)PHYSCONS,
130 	.irq	= Uartirq,
131 	.tbdf	= -1,
132 	.poll	= 0, },
133 };
134 
135 static Uart i8250uart[] = {
136 {	.regs	= &i8250ctlr[0], /* not [2] */
137 	.name	= "COM3",
138 	.freq	= 3686000,	/* Not used, we use the global i8250freq */
139 	.phys	= &i8250physuart,
140 	.console= 1,
141 	.next	= nil, },
142 };
143 
144 #define csr8r(c, r)	((c)->io[r])
145 #define csr8w(c, r, v)	((c)->io[r] = (c)->sticky[r] | (v), coherence())
146 #define csr8o(c, r, v)	((c)->io[r] = (v), coherence())
147 
148 static long
i8250status(Uart * uart,void * buf,long n,long offset)149 i8250status(Uart* uart, void* buf, long n, long offset)
150 {
151 	char *p;
152 	Ctlr *ctlr;
153 	uchar ier, lcr, mcr, msr;
154 
155 	ctlr = uart->regs;
156 	p = malloc(READSTR);
157 	mcr = ctlr->sticky[Mcr];
158 	msr = csr8r(ctlr, Msr);
159 	ier = ctlr->sticky[Ier];
160 	lcr = ctlr->sticky[Lcr];
161 	snprint(p, READSTR,
162 		"b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
163 		"dev(%d) type(%d) framing(%d) overruns(%d) "
164 		"berr(%d) serr(%d)%s%s%s%s\n",
165 
166 		uart->baud,
167 		uart->hup_dcd,
168 		(msr & Dsr) != 0,
169 		uart->hup_dsr,
170 		(lcr & WlsMASK) + 5,
171 		(ier & Ems) != 0,
172 		(lcr & Pen) ? ((lcr & Eps) ? 'e': 'o'): 'n',
173 		(mcr & Rts) != 0,
174 		(lcr & Stb) ? 2: 1,
175 		ctlr->fena,
176 
177 		uart->dev,
178 		uart->type,
179 		uart->ferr,
180 		uart->oerr,
181 		uart->berr,
182 		uart->serr,
183 		(msr & Cts) ? " cts": "",
184 		(msr & Dsr) ? " dsr": "",
185 		(msr & Dcd) ? " dcd": "",
186 		(msr & Ri) ? " ring": ""
187 	);
188 	n = readstr(offset, buf, n, p);
189 	free(p);
190 
191 	return n;
192 }
193 
194 static void
i8250fifo(Uart * uart,int level)195 i8250fifo(Uart* uart, int level)
196 {
197 	Ctlr *ctlr;
198 
199 	ctlr = uart->regs;
200 	if(ctlr->hasfifo == 0)
201 		return;
202 
203 	/*
204 	 * Changing the FIFOena bit in Fcr flushes data
205 	 * from both receive and transmit FIFOs; there's
206 	 * no easy way to guarantee not losing data on
207 	 * the receive side, but it's possible to wait until
208 	 * the transmitter is really empty.
209 	 */
210 	ilock(ctlr);
211 	while(!(csr8r(ctlr, Lsr) & Temt))
212 		;
213 
214 	/*
215 	 * Set the trigger level, default is the max.
216 	 * value.
217 	 * Some UARTs require FIFOena to be set before
218 	 * other bits can take effect, so set it twice.
219 	 */
220 	ctlr->fena = level;
221 	switch(level){
222 	case 0:
223 		break;
224 	case 1:
225 		level = FIFO1|FIFOena;
226 		break;
227 	case 4:
228 		level = FIFO4|FIFOena;
229 		break;
230 	case 8:
231 		level = FIFO8|FIFOena;
232 		break;
233 	default:
234 		level = FIFO14|FIFOena;
235 		break;
236 	}
237 	csr8w(ctlr, Fcr, level);
238 	csr8w(ctlr, Fcr, level);
239 	iunlock(ctlr);
240 }
241 
242 static void
i8250dtr(Uart * uart,int on)243 i8250dtr(Uart* uart, int on)
244 {
245 	Ctlr *ctlr;
246 
247 	/*
248 	 * Toggle DTR.
249 	 */
250 	ctlr = uart->regs;
251 	if(on)
252 		ctlr->sticky[Mcr] |= Dtr;
253 	else
254 		ctlr->sticky[Mcr] &= ~Dtr;
255 	csr8w(ctlr, Mcr, 0);
256 }
257 
258 static void
i8250rts(Uart * uart,int on)259 i8250rts(Uart* uart, int on)
260 {
261 	Ctlr *ctlr;
262 
263 	/*
264 	 * Toggle RTS.
265 	 */
266 	ctlr = uart->regs;
267 	if(on)
268 		ctlr->sticky[Mcr] |= Rts;
269 	else
270 		ctlr->sticky[Mcr] &= ~Rts;
271 	csr8w(ctlr, Mcr, 0);
272 }
273 
274 static void
i8250modemctl(Uart * uart,int on)275 i8250modemctl(Uart* uart, int on)
276 {
277 	Ctlr *ctlr;
278 
279 	ctlr = uart->regs;
280 	ilock(&uart->tlock);
281 	if(on){
282 		ctlr->sticky[Ier] |= Ems;
283 		csr8w(ctlr, Ier, 0);
284 		uart->modem = 1;
285 		uart->cts = csr8r(ctlr, Msr) & Cts;
286 	}
287 	else{
288 		ctlr->sticky[Ier] &= ~Ems;
289 		csr8w(ctlr, Ier, 0);
290 		uart->modem = 0;
291 		uart->cts = 1;
292 	}
293 	iunlock(&uart->tlock);
294 
295 	/* modem needs fifo */
296 	(*uart->phys->fifo)(uart, on);
297 }
298 
299 static int
i8250parity(Uart * uart,int parity)300 i8250parity(Uart* uart, int parity)
301 {
302 	int lcr;
303 	Ctlr *ctlr;
304 
305 	ctlr = uart->regs;
306 	lcr = ctlr->sticky[Lcr] & ~(Eps|Pen);
307 
308 	switch(parity){
309 	case 'e':
310 		lcr |= Eps|Pen;
311 		break;
312 	case 'o':
313 		lcr |= Pen;
314 		break;
315 	case 'n':
316 		break;
317 	default:
318 		return -1;
319 	}
320 	ctlr->sticky[Lcr] = lcr;
321 	csr8w(ctlr, Lcr, 0);
322 
323 	uart->parity = parity;
324 
325 	return 0;
326 }
327 
328 static int
i8250stop(Uart * uart,int stop)329 i8250stop(Uart* uart, int stop)
330 {
331 	int lcr;
332 	Ctlr *ctlr;
333 
334 	ctlr = uart->regs;
335 	lcr = ctlr->sticky[Lcr] & ~Stb;
336 
337 	switch(stop){
338 	case 1:
339 		break;
340 	case 2:
341 		lcr |= Stb;
342 		break;
343 	default:
344 		return -1;
345 	}
346 	ctlr->sticky[Lcr] = lcr;
347 	csr8w(ctlr, Lcr, 0);
348 
349 	uart->stop = stop;
350 
351 	return 0;
352 }
353 
354 static int
i8250bits(Uart * uart,int bits)355 i8250bits(Uart* uart, int bits)
356 {
357 	int lcr;
358 	Ctlr *ctlr;
359 
360 	ctlr = uart->regs;
361 	lcr = ctlr->sticky[Lcr] & ~WlsMASK;
362 
363 	switch(bits){
364 	case 5:
365 		lcr |= Wls5;
366 		break;
367 	case 6:
368 		lcr |= Wls6;
369 		break;
370 	case 7:
371 		lcr |= Wls7;
372 		break;
373 	case 8:
374 		lcr |= Wls8;
375 		break;
376 	default:
377 		return -1;
378 	}
379 	ctlr->sticky[Lcr] = lcr;
380 	csr8w(ctlr, Lcr, 0);
381 
382 	uart->bits = bits;
383 
384 	return 0;
385 }
386 
387 static int
i8250baud(Uart * uart,int baud)388 i8250baud(Uart* uart, int baud)
389 {
390 #ifdef notdef				/* don't change the speed */
391 	ulong bgc;
392 	Ctlr *ctlr;
393 	extern int i8250freq;	/* In the config file */
394 
395 	/*
396 	 * Set the Baud rate by calculating and setting the Baud rate
397 	 * Generator Constant. This will work with fairly non-standard
398 	 * Baud rates.
399 	 */
400 	if(i8250freq == 0 || baud <= 0)
401 		return -1;
402 	bgc = (i8250freq+8*baud-1)/(16*baud);
403 
404 	ctlr = uart->regs;
405 	while(csr8r(ctlr, Usr) & Busy)
406 		delay(1);
407 	csr8w(ctlr, Lcr, Dlab);		/* begin kludge */
408 	csr8o(ctlr, Dlm, bgc>>8);
409 	csr8o(ctlr, Dll, bgc);
410 	csr8w(ctlr, Lcr, 0);
411 #endif
412 	uart->baud = baud;
413 	return 0;
414 }
415 
416 static void
i8250break(Uart * uart,int ms)417 i8250break(Uart* uart, int ms)
418 {
419 	Ctlr *ctlr;
420 
421 	if (up == nil)
422 		panic("i8250break: nil up");
423 	/*
424 	 * Send a break.
425 	 */
426 	if(ms <= 0)
427 		ms = 200;
428 
429 	ctlr = uart->regs;
430 	csr8w(ctlr, Lcr, Brk);
431 	tsleep(&up->sleep, return0, 0, ms);
432 	csr8w(ctlr, Lcr, 0);
433 }
434 
435 static void
emptyoutstage(Uart * uart,int n)436 emptyoutstage(Uart *uart, int n)
437 {
438 	_uartputs((char *)uart->op, n);
439 	uart->op = uart->oe = uart->ostage;
440 }
441 
442 static void
i8250kick(Uart * uart)443 i8250kick(Uart* uart)
444 {
445 	int i;
446 	Ctlr *ctlr;
447 
448 	if(/* uart->cts == 0 || */ uart->blocked)
449 		return;
450 
451 	if(!normalprint) {			/* early */
452 		if (uart->op < uart->oe)
453 			emptyoutstage(uart, uart->oe - uart->op);
454 		while ((i = uartstageoutput(uart)) > 0)
455 			emptyoutstage(uart, i);
456 		return;
457 	}
458 
459 	/* nothing more to send? then disable xmit intr */
460 	ctlr = uart->regs;
461 	if (uart->op >= uart->oe && qlen(uart->oq) == 0 &&
462 	    csr8r(ctlr, Lsr) & Temt) {
463 		ctlr->sticky[Ier] &= ~Ethre;
464 		csr8w(ctlr, Ier, 0);
465 		return;
466 	}
467 
468 	/*
469 	 *  128 here is an arbitrary limit to make sure
470 	 *  we don't stay in this loop too long.  If the
471 	 *  chip's output queue is longer than 128, too
472 	 *  bad -- presotto
473 	 */
474 	for(i = 0; i < 128; i++){
475 		if(!(csr8r(ctlr, Lsr) & Thre))
476 			break;
477 		if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
478 			break;
479 		csr8o(ctlr, Thr, *uart->op++);		/* start tx */
480 		ctlr->sticky[Ier] |= Ethre;
481 		csr8w(ctlr, Ier, 0);			/* intr when done */
482 	}
483 }
484 
485 void
serialkick(void)486 serialkick(void)
487 {
488 	uartkick(&i8250uart[CONSOLE]);
489 }
490 
491 static void
i8250interrupt(Ureg *,void * arg)492 i8250interrupt(Ureg*, void* arg)
493 {
494 	Ctlr *ctlr;
495 	Uart *uart;
496 	int iir, lsr, old, r;
497 
498 	uart = arg;
499 	ctlr = uart->regs;
500 	for(iir = csr8r(ctlr, Iir); !(iir & Ip); iir = csr8r(ctlr, Iir)){
501 		switch(iir & IirMASK){
502 		case Ims:		/* Ms interrupt */
503 			r = csr8r(ctlr, Msr);
504 			if(r & Dcts){
505 				ilock(&uart->tlock);
506 				old = uart->cts;
507 				uart->cts = r & Cts;
508 				if(old == 0 && uart->cts)
509 					uart->ctsbackoff = 2;
510 				iunlock(&uart->tlock);
511 			}
512 		 	if(r & Ddsr){
513 				old = r & Dsr;
514 				if(uart->hup_dsr && uart->dsr && !old)
515 					uart->dohup = 1;
516 				uart->dsr = old;
517 			}
518 		 	if(r & Ddcd){
519 				old = r & Dcd;
520 				if(uart->hup_dcd && uart->dcd && !old)
521 					uart->dohup = 1;
522 				uart->dcd = old;
523 			}
524 			break;
525 		case Ithre:		/* Thr Empty */
526 			uartkick(uart);
527 			break;
528 		case Irda:		/* Received Data Available */
529 		case Irls:		/* Receiver Line Status */
530 		case Ictoi:		/* Character Time-out Indication */
531 			/*
532 			 * Consume any received data.
533 			 * If the received byte came in with a break,
534 			 * parity or framing error, throw it away;
535 			 * overrun is an indication that something has
536 			 * already been tossed.
537 			 */
538 			while((lsr = csr8r(ctlr, Lsr)) & Dr){
539 				if(lsr & (FIFOerr|Oe))
540 					uart->oerr++;
541 				if(lsr & Pe)
542 					uart->perr++;
543 				if(lsr & Fe)
544 					uart->ferr++;
545 				r = csr8r(ctlr, Rbr);
546 				if(!(lsr & (Bi|Fe|Pe)))
547 					uartrecv(uart, r);
548 			}
549 			break;
550 
551 		default:
552 			iprint("weird uart interrupt type %#2.2uX\n", iir);
553 			break;
554 		}
555 	}
556 }
557 
558 static void
i8250disable(Uart * uart)559 i8250disable(Uart* uart)
560 {
561 	Ctlr *ctlr;
562 
563 	/*
564 	 * Turn off DTR and RTS, disable interrupts and fifos.
565 	 */
566 	(*uart->phys->dtr)(uart, 0);
567 	(*uart->phys->rts)(uart, 0);
568 	(*uart->phys->fifo)(uart, 0);
569 
570 	ctlr = uart->regs;
571 	ctlr->sticky[Ier] = 0;
572 	csr8w(ctlr, Ier, 0);
573 
574 	if(ctlr->iena != 0){
575 		if(irqdisable(ctlr->irq, i8250interrupt, uart, uart->name) == 0)
576 			ctlr->iena = 0;
577 	}
578 }
579 
580 static void
i8250enable(Uart * uart,int ie)581 i8250enable(Uart* uart, int ie)
582 {
583 	int mode;
584 	Ctlr *ctlr;
585 
586 	if (up == nil)
587 		return;				/* too soon */
588 
589 	ctlr = uart->regs;
590 
591 	/* omap only: set uart/irda/cir mode to uart */
592 	mode = csr8r(ctlr, Mdr);
593 	csr8o(ctlr, Mdr, (mode & ~Modemask) | Modeuart);
594 
595 	ctlr->sticky[Lcr] = Wls8;		/* no parity */
596 	csr8w(ctlr, Lcr, 0);
597 
598 	/*
599 	 * Check if there is a FIFO.
600 	 * Changing the FIFOena bit in Fcr flushes data
601 	 * from both receive and transmit FIFOs; there's
602 	 * no easy way to guarantee not losing data on
603 	 * the receive side, but it's possible to wait until
604 	 * the transmitter is really empty.
605 	 * Also, reading the Iir outwith i8250interrupt()
606 	 * can be dangerous, but this should only happen
607 	 * once, before interrupts are enabled.
608 	 */
609 	ilock(ctlr);
610 	if(!ctlr->checkfifo){
611 		/*
612 		 * Wait until the transmitter is really empty.
613 		 */
614 		while(!(csr8r(ctlr, Lsr) & Temt))
615 			;
616 		csr8w(ctlr, Fcr, FIFOena);
617 		if(csr8r(ctlr, Iir) & Ifena)
618 			ctlr->hasfifo = 1;
619 		csr8w(ctlr, Fcr, 0);
620 		ctlr->checkfifo = 1;
621 	}
622 	iunlock(ctlr);
623 
624 	/*
625 	 * Enable interrupts and turn on DTR and RTS.
626 	 * Be careful if this is called to set up a polled serial line
627 	 * early on not to try to enable interrupts as interrupt-
628 	 * -enabling mechanisms might not be set up yet.
629 	 */
630 	if(ie){
631 		if(ctlr->iena == 0 && !ctlr->poll){
632 			irqenable(ctlr->irq, i8250interrupt, uart, uart->name);
633 			ctlr->iena = 1;
634 		}
635 		ctlr->sticky[Ier] = Erda;
636 //		ctlr->sticky[Mcr] |= Ie;		/* not on omap */
637 		ctlr->sticky[Mcr] = 0;
638 	}
639 	else{
640 		ctlr->sticky[Ier] = 0;
641 		ctlr->sticky[Mcr] = 0;
642 	}
643 	csr8w(ctlr, Ier, 0);
644 	csr8w(ctlr, Mcr, 0);
645 
646 	(*uart->phys->dtr)(uart, 1);
647 	(*uart->phys->rts)(uart, 1);
648 
649 	/*
650 	 * During startup, the i8259 interrupt controller is reset.
651 	 * This may result in a lost interrupt from the i8250 uart.
652 	 * The i8250 thinks the interrupt is still outstanding and does not
653 	 * generate any further interrupts. The workaround is to call the
654 	 * interrupt handler to clear any pending interrupt events.
655 	 * Note: this must be done after setting Ier.
656 	 */
657 	if(ie)
658 		i8250interrupt(nil, uart);
659 }
660 
661 static Uart*
i8250pnp(void)662 i8250pnp(void)
663 {
664 	return i8250uart;
665 }
666 
667 static int
i8250getc(Uart * uart)668 i8250getc(Uart* uart)
669 {
670 	Ctlr *ctlr;
671 
672 	ctlr = uart->regs;
673 	while(!(csr8r(ctlr, Lsr) & Dr))
674 		delay(1);
675 	return csr8r(ctlr, Rbr);
676 }
677 
678 static void
i8250putc(Uart * uart,int c)679 i8250putc(Uart* uart, int c)
680 {
681 	int i;
682 	Ctlr *ctlr;
683 
684 	if (!normalprint) {		/* too early; use brute force */
685 		int s = splhi();
686 
687 		while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
688 			;
689 		((ulong *)PHYSCONS)[Thr] = c;
690 		coherence();
691 		splx(s);
692 		return;
693 	}
694 
695 	ctlr = uart->regs;
696 	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
697 		delay(1);
698 	csr8o(ctlr, Thr, (uchar)c);
699 	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
700 		delay(1);
701 }
702 
703 void
serialputc(int c)704 serialputc(int c)
705 {
706 	i8250putc(&i8250uart[CONSOLE], c);
707 }
708 
709 void
serialputs(char * s,int n)710 serialputs(char* s, int n)
711 {
712 	_uartputs(s, n);
713 }
714 
715 #ifdef notdef
716 static void
i8250poll(Uart * uart)717 i8250poll(Uart* uart)
718 {
719 	Ctlr *ctlr;
720 
721 	/*
722 	 * If PhysUart has a non-nil .poll member, this
723 	 * routine will be called from the uartclock timer.
724 	 * If the Ctlr .poll member is non-zero, when the
725 	 * Uart is enabled interrupts will not be enabled
726 	 * and the result is polled input and output.
727 	 * Not very useful here, but ports to new hardware
728 	 * or simulators can use this to get serial I/O
729 	 * without setting up the interrupt mechanism.
730 	 */
731 	ctlr = uart->regs;
732 	if(ctlr->iena || !ctlr->poll)
733 		return;
734 	i8250interrupt(nil, uart);
735 }
736 #endif
737 
738 PhysUart i8250physuart = {
739 	.name		= "i8250",
740 	.pnp		= i8250pnp,
741 	.enable		= i8250enable,
742 	.disable	= i8250disable,
743 	.kick		= i8250kick,
744 	.dobreak	= i8250break,
745 	.baud		= i8250baud,
746 	.bits		= i8250bits,
747 	.stop		= i8250stop,
748 	.parity		= i8250parity,
749 	.modemctl	= i8250modemctl,
750 	.rts		= i8250rts,
751 	.dtr		= i8250dtr,
752 	.status		= i8250status,
753 	.fifo		= i8250fifo,
754 	.getc		= i8250getc,
755 	.putc		= i8250putc,
756 //	.poll		= i8250poll,		/* only in 9k, not 9 */
757 };
758 
759 static void
i8250dumpregs(Ctlr * ctlr)760 i8250dumpregs(Ctlr* ctlr)
761 {
762 	int dlm, dll;
763 	int _uartprint(char*, ...);
764 
765 	csr8w(ctlr, Lcr, Dlab);
766 	dlm = csr8r(ctlr, Dlm);
767 	dll = csr8r(ctlr, Dll);
768 	csr8w(ctlr, Lcr, 0);
769 
770 	_uartprint("dlm %#ux dll %#ux\n", dlm, dll);
771 }
772 
773 Uart*	uartenable(Uart *p);
774 
775 /* must call this from a process's context */
776 int
i8250console(void)777 i8250console(void)
778 {
779 	Uart *uart = &i8250uart[CONSOLE];
780 
781 	if (up == nil)
782 		return -1;			/* too early */
783 
784 	if(uartenable(uart) != nil /* && uart->console */){
785 		// iprint("i8250console: enabling console uart\n");
786 		kbdq = uart->iq;
787 		serialoq = uart->oq;
788 		uart->putc = kbdcr2nl;
789 		uart->opens++;
790 		consuart = uart;
791 	}
792 	uartctl(uart, "b115200 l8 pn r1 s1 i1");
793 	return 0;
794 }
795 
796 void
_uartputs(char * s,int n)797 _uartputs(char* s, int n)
798 {
799 	char *e;
800 
801 	for(e = s+n; s < e; s++){
802 		if(*s == '\n')
803 			i8250putc(&i8250uart[CONSOLE], '\r');
804 		i8250putc(&i8250uart[CONSOLE], *s);
805 	}
806 }
807 
808 int
_uartprint(char * fmt,...)809 _uartprint(char* fmt, ...)
810 {
811 	int n;
812 	va_list arg;
813 	char buf[PRINTSIZE];
814 
815 	va_start(arg, fmt);
816 	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
817 	va_end(arg);
818 	_uartputs(buf, n);
819 
820 	return n;
821 }
822