uarti8250.c 16 KB

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