Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
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
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
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
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
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
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
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
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
489
serialkick(void)
490
{
491
	uartkick(&i8250uart[CONSOLE]);
492
}
493
 
494
static void
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
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
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*
665
i8250pnp(void)
666
{
667
	return i8250uart;
668
}
669
 
670
static int
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
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
707
serialputc(int c)
708
{
709
	i8250putc(&i8250uart[CONSOLE], c);
710
}
711
 
712
void
713
serialputs(char* s, int n)
714
{
715
	_uartputs(s, n);
716
}
717
 
718
#ifdef notdef
719
static void
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
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
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
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
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
}