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