uarti8250.c 15 KB

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