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