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