Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
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
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
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
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
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
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
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
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
486
serialkick(void)
487
{
488
	uartkick(&i8250uart[CONSOLE]);
489
}
490
 
491
static void
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
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
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*
662
i8250pnp(void)
663
{
664
	return i8250uart;
665
}
666
 
667
static int
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
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
704
serialputc(int c)
705
{
706
	i8250putc(&i8250uart[CONSOLE], c);
707
}
708
 
709
void
710
serialputs(char* s, int n)
711
{
712
	_uartputs(s, n);
713
}
714
 
715
#ifdef notdef
716
static void
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
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
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
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
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
}