source: rtems/c/src/lib/libbsp/i386/shared/comm/uart.c @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 23.0 KB
Line 
1/*
2 * This software is Copyright (C) 1998 by T.sqware - all rights limited
3 * It is provided in to the public domain "as is", can be freely modified
4 * as far as this copyight notice is kept unchanged, but does not imply
5 * an endorsement by T.sqware of the product in which it is included.
6 */
7
8#include <stdio.h>
9#include <bsp.h>
10#include <bsp/irq.h>
11#include <uart.h>
12#include <rtems/libio.h>
13#include <rtems/termiostypes.h>
14#include <termios.h>
15#include <assert.h>
16
17/*
18 * Basic 16552 driver
19 */
20
21struct uart_data
22{
23  int ioMode;
24  int hwFlow;
25  unsigned int  ier;
26  unsigned long baud;
27  unsigned long databits;
28  unsigned long parity;
29  unsigned long stopbits;
30};
31
32static struct uart_data uart_data[2];
33
34/*
35 * Macros to read/write register of uart, if configuration is
36 * different just rewrite these macros
37 */
38
39static inline unsigned char
40uread(int uart, unsigned int reg)
41{
42  register unsigned char val;
43
44  if (uart == 0) {
45    inport_byte(COM1_BASE_IO+reg, val);
46  } else {
47    inport_byte(COM2_BASE_IO+reg, val);
48  }
49
50  return val;
51}
52
53static inline void
54uwrite(int uart, int reg, unsigned int val)
55{
56  if (uart == 0) {
57    outport_byte(COM1_BASE_IO+reg, val);
58  } else {
59    outport_byte(COM2_BASE_IO+reg, val);
60  }
61}
62
63#ifdef UARTDEBUG
64    static void
65uartError(int uart)
66{
67  unsigned char uartStatus, dummy;
68
69  uartStatus = uread(uart, LSR);
70  dummy = uread(uart, RBR);
71
72  if (uartStatus & OE)
73    printk("********* Over run Error **********\n");
74  if (uartStatus & PE)
75    printk("********* Parity Error   **********\n");
76  if (uartStatus & FE)
77    printk("********* Framing Error  **********\n");
78  if (uartStatus & BI)
79    printk("********* Parity Error   **********\n");
80  if (uartStatus & ERFIFO)
81    printk("********* Error receive Fifo **********\n");
82
83}
84#else
85inline void uartError(int uart)
86{
87  uread(uart, LSR);
88  uread(uart, RBR);
89}
90#endif
91
92/*
93 * Uart initialization, it is hardcoded to 8 bit, no parity,
94 * one stop bit, FIFO, things to be changed
95 * are baud rate and nad hw flow control,
96 * and longest rx fifo setting
97 */
98void
99BSP_uart_init
100(
101  int uart,
102  unsigned long baud,
103  unsigned long databits,
104  unsigned long parity,
105  unsigned long stopbits,
106  int hwFlow
107)
108{
109  /* Sanity check */
110  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
111
112  switch(baud)
113    {
114    case 50:
115    case 75:
116    case 110:
117    case 134:
118    case 300:
119    case 600:
120    case 1200:
121    case 2400:
122    case 9600:
123    case 19200:
124    case 38400:
125    case 57600:
126    case 115200:
127      break;
128    default:
129      assert(0);
130      return;
131    }
132
133  /* Set DLAB bit to 1 */
134  uwrite(uart, LCR, DLAB);
135
136  /* Set baud rate */
137  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);
138  uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);
139
140  /* 8-bit, no parity , 1 stop */
141  uwrite(uart, LCR, databits | parity | stopbits);
142
143  /* Set DTR, RTS and OUT2 high */
144  uwrite(uart, MCR, DTR | RTS | OUT_2);
145
146  /* Enable FIFO */
147  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
148
149  /* Disable Interrupts */
150  uwrite(uart, IER, 0);
151
152  /* Read status to clear them */
153  uread(uart, LSR);
154  uread(uart, RBR);
155  uread(uart, MSR);
156
157  /* Remember state */
158  uart_data[uart].baud       = baud;
159  uart_data[uart].databits   = databits;
160  uart_data[uart].parity     = parity;
161  uart_data[uart].stopbits   = stopbits;
162  uart_data[uart].hwFlow     = hwFlow;
163  return;
164}
165
166/*
167 * Set baud
168 */
169
170void
171BSP_uart_set_baud(
172  int uart,
173  unsigned long baud
174)
175{
176  /* Sanity check */
177  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
178
179  BSP_uart_set_attributes( uart, baud, uart_data[uart].databits,
180    uart_data[uart].parity, uart_data[uart].stopbits );
181}
182
183/*
184 *  Set all attributes
185 */
186
187void
188BSP_uart_set_attributes
189(
190  int uart,
191  unsigned long baud,
192  unsigned long databits,
193  unsigned long parity,
194  unsigned long stopbits
195)
196{
197  unsigned char mcr, ier;
198
199  /* Sanity check */
200  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
201
202  /*
203   * This function may be called whenever TERMIOS parameters
204   * are changed, so we have to make sure that baud change is
205   * indeed required
206   */
207
208  if( (baud     == uart_data[uart].baud)     &&
209      (databits == uart_data[uart].databits) &&
210      (parity   == uart_data[uart].parity)   &&
211      (stopbits == uart_data[uart].stopbits) )
212    {
213      return;
214    }
215
216  mcr = uread(uart, MCR);
217  ier = uread(uart, IER);
218
219  BSP_uart_init(uart, baud, databits, parity, stopbits, uart_data[uart].hwFlow);
220
221  uwrite(uart, MCR, mcr);
222  uwrite(uart, IER, ier);
223
224  return;
225}
226
227/*
228 * Enable/disable interrupts
229 */
230void
231BSP_uart_intr_ctrl(int uart, int cmd)
232{
233  int iStatus = (int)INTERRUPT_DISABLE;
234
235  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
236
237  switch(cmd)
238    {
239    case BSP_UART_INTR_CTRL_ENABLE:
240      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | TRANSMIT_ENABLE);
241      if ( uart_data[uart].hwFlow ) {
242        iStatus |= MODEM_ENABLE;
243      }
244      break;
245    case BSP_UART_INTR_CTRL_TERMIOS:
246      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
247      if ( uart_data[uart].hwFlow ) {
248        iStatus |= MODEM_ENABLE;
249      }
250      break;
251    case BSP_UART_INTR_CTRL_GDB:
252      iStatus |= RECEIVE_ENABLE;
253      break;
254    }
255
256  uart_data[uart].ier = iStatus;
257  uwrite(uart, IER, iStatus);
258
259  return;
260}
261
262void
263BSP_uart_throttle(int uart)
264{
265  unsigned int mcr;
266
267  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
268
269  if(!uart_data[uart].hwFlow)
270    {
271      /* Should not happen */
272      assert(0);
273      return;
274    }
275  mcr = uread (uart, MCR);
276  /* RTS down */
277  mcr &= ~RTS;
278  uwrite(uart, MCR, mcr);
279
280  return;
281}
282
283void
284BSP_uart_unthrottle(int uart)
285{
286  unsigned int mcr;
287
288  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
289
290  if(!uart_data[uart].hwFlow)
291    {
292      /* Should not happen */
293      assert(0);
294      return;
295    }
296  mcr = uread (uart, MCR);
297  /* RTS up */
298  mcr |= RTS;
299  uwrite(uart, MCR, mcr);
300
301  return;
302}
303
304/*
305 * Status function, -1 if error
306 * detected, 0 if no received chars available,
307 * 1 if received char available, 2 if break
308 * is detected, it will eat break and error
309 * chars. It ignores overruns - we cannot do
310 * anything about - it execpt count statistics
311 * and we are not counting it.
312 */
313int
314BSP_uart_polled_status(int uart)
315{
316  unsigned char val;
317
318  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
319
320  val = uread(uart, LSR);
321
322  if(val & BI)
323    {
324      /* BREAK found, eat character */
325      uread(uart, RBR);
326      return BSP_UART_STATUS_BREAK;
327    }
328
329  if((val & (DR | OE | FE)) ==  1)
330    {
331      /* No error, character present */
332      return BSP_UART_STATUS_CHAR;
333    }
334
335  if((val & (DR | OE | FE)) == 0)
336    {
337      /* Nothing */
338      return BSP_UART_STATUS_NOCHAR;
339    }
340
341  /*
342   * Framing or parity error
343   * eat character
344   */
345  uread(uart, RBR);
346
347  return BSP_UART_STATUS_ERROR;
348}
349
350/*
351 * Polled mode write function
352 */
353void
354BSP_uart_polled_write(int uart, int val)
355{
356  unsigned char val1;
357
358  /* Sanity check */
359  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
360
361  for(;;)
362    {
363      if((val1=uread(uart, LSR)) & THRE)
364        {
365          break;
366        }
367    }
368
369  if(uart_data[uart].hwFlow)
370    {
371      for(;;)
372        {
373          if(uread(uart, MSR) & CTS)
374            {
375              break;
376            }
377        }
378    }
379
380  uwrite(uart, THR, val & 0xff);
381
382  /*
383   * Wait for character to be transmitted.
384   * This ensures that printk and printf play nicely together
385   * when using the same serial port.
386   * Yes, there's a performance hit here, but if we're doing
387   * polled writes to a serial port we're probably not that
388   * interested in efficiency anyway.....
389   */
390  for(;;)
391    {
392      if((val1=uread(uart, LSR)) & THRE)
393      {
394      break;
395      }
396    }
397
398  return;
399}
400
401void
402BSP_output_char_via_serial(char val)
403{
404  BSP_uart_polled_write(BSPConsolePort, val);
405  if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');
406}
407
408/*
409 * Polled mode read function
410 */
411int
412BSP_uart_polled_read(int uart)
413{
414  unsigned char val;
415
416  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
417
418  for(;;)
419    {
420      if(uread(uart, LSR) & DR)
421        {
422          break;
423        }
424    }
425
426  val = uread(uart, RBR);
427
428  return (int)(val & 0xff);
429}
430
431int
432BSP_poll_char_via_serial(void)
433{
434        return BSP_uart_polled_read(BSPConsolePort);
435}
436
437/* ================ Termios support  =================*/
438
439static volatile int  termios_stopped_com1        = 0;
440static volatile int  termios_tx_active_com1      = 0;
441static void*         termios_ttyp_com1           = NULL;
442static char          termios_tx_hold_com1        = 0;
443static volatile char termios_tx_hold_valid_com1  = 0;
444
445static volatile int  termios_stopped_com2        = 0;
446static volatile int  termios_tx_active_com2      = 0;
447static void*         termios_ttyp_com2           = NULL;
448static char          termios_tx_hold_com2        = 0;
449static volatile char termios_tx_hold_valid_com2  = 0;
450
451static void ( *driver_input_handler_com1 )( void *,  char *, int ) = 0;
452static void ( *driver_input_handler_com2 )( void *,  char *, int ) = 0;
453
454/*
455 * This routine sets the handler to handle the characters received
456 * from the serial port.
457 */
458void uart_set_driver_handler( int port, void ( *handler )( void *,  char *, int ) )
459{
460  switch( port )
461  {
462    case BSP_UART_COM1:
463     driver_input_handler_com1 = handler;
464     break;
465
466    case BSP_UART_COM2:
467     driver_input_handler_com2 = handler;
468     break;
469  }
470}
471
472/*
473 * Set channel parameters
474 */
475void
476BSP_uart_termios_set(int uart, void *ttyp)
477{
478  struct rtems_termios_tty *p = (struct rtems_termios_tty *)ttyp;
479  unsigned char val;
480  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
481
482  if(uart == BSP_UART_COM1)
483    {
484      uart_data[uart].ioMode = p->device.outputUsesInterrupts;
485      if(uart_data[uart].hwFlow)
486        {
487          val = uread(uart, MSR);
488
489          termios_stopped_com1   = (val & CTS) ? 0 : 1;
490        }
491      else
492        {
493          termios_stopped_com1 = 0;
494        }
495      termios_tx_active_com1      = 0;
496      termios_ttyp_com1           = ttyp;
497      termios_tx_hold_com1        = 0;
498      termios_tx_hold_valid_com1  = 0;
499    }
500  else
501    {
502      uart_data[uart].ioMode = p->device.outputUsesInterrupts;
503      if(uart_data[uart].hwFlow)
504        {
505          val = uread(uart, MSR);
506
507          termios_stopped_com2   = (val & CTS) ? 0 : 1;
508        }
509      else
510        {
511          termios_stopped_com2 = 0;
512        }
513      termios_tx_active_com2      = 0;
514      termios_ttyp_com2           = ttyp;
515      termios_tx_hold_com2        = 0;
516      termios_tx_hold_valid_com2  = 0;
517    }
518
519  return;
520}
521
522int
523BSP_uart_termios_read_com1(int uart)
524{
525  int     off = (int)0;
526  char    buf[40];
527
528  /* read bytes */
529  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM1, LSR) & DR )) {
530    buf[off++] = uread(BSP_UART_COM1, RBR);
531  }
532
533  /* write out data */
534  if ( off > 0 ) {
535    rtems_termios_enqueue_raw_characters(termios_ttyp_com1, buf, off);
536  }
537
538  /* enable receive interrupts */
539  uart_data[BSP_UART_COM1].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
540  uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
541
542  return ( EOF );
543}
544
545int
546BSP_uart_termios_read_com2(int uart)
547{
548  int     off = (int)0;
549  char    buf[40];
550
551  /* read current byte */
552  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM2, LSR) & DR )) {
553    buf[off++] = uread(BSP_UART_COM2, RBR);
554  }
555
556  /* write out data */
557  if ( off > 0 ) {
558    rtems_termios_enqueue_raw_characters(termios_ttyp_com2, buf, off);
559  }
560
561  /* enable receive interrupts */
562  uart_data[BSP_UART_COM2].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
563  uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
564
565  return ( EOF );
566}
567
568ssize_t
569BSP_uart_termios_write_com1(int minor, const char *buf, size_t len)
570{
571  assert(buf != NULL);
572
573  if(len <= 0)
574    {
575      return 0;
576    }
577
578  /* If there TX buffer is busy - something is royally screwed up */
579  assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);
580
581  if(termios_stopped_com1)
582    {
583      /* CTS low */
584      termios_tx_hold_com1       = *buf;
585      termios_tx_hold_valid_com1 = 1;
586      return 0;
587    }
588
589  /* Write character */
590  uwrite(BSP_UART_COM1, THR, *buf & 0xff);
591
592  /* Enable interrupts if necessary */
593  if ( !termios_tx_active_com1 ) {
594    termios_tx_active_com1 = 1;
595    uart_data[BSP_UART_COM1].ier |= TRANSMIT_ENABLE;
596    uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
597  }
598
599  return 1;
600}
601
602ssize_t
603BSP_uart_termios_write_com2(int minor, const char *buf, size_t len)
604{
605  assert(buf != NULL);
606
607  if(len <= 0)
608    {
609      return 0;
610    }
611
612  /* If there TX buffer is busy - something is royally screwed up */
613  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
614
615  if(termios_stopped_com2)
616    {
617      /* CTS low */
618      termios_tx_hold_com2       = *buf;
619      termios_tx_hold_valid_com2 = 1;
620      return 0;
621    }
622
623  /* Write character */
624  uwrite(BSP_UART_COM2, THR, *buf & 0xff);
625
626  /* Enable interrupts if necessary */
627  if ( !termios_tx_active_com2 ) {
628    termios_tx_active_com2 = 1;
629    uart_data[BSP_UART_COM2].ier |= TRANSMIT_ENABLE;
630    uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
631  }
632
633  return 1;
634}
635
636void
637BSP_uart_termios_isr_com1(void)
638{
639  unsigned char buf[40];
640  unsigned char val;
641  int      off, ret, vect;
642
643  off = 0;
644
645  for(;;)
646    {
647      vect = uread(BSP_UART_COM1, IIR) & 0xf;
648
649      switch(vect)
650        {
651        case MODEM_STATUS :
652          val = uread(BSP_UART_COM1, MSR);
653          if(uart_data[BSP_UART_COM1].hwFlow)
654            {
655              if(val & CTS)
656                {
657                  /* CTS high */
658                  termios_stopped_com1 = 0;
659                  if(termios_tx_hold_valid_com1)
660                    {
661                      termios_tx_hold_valid_com1 = 0;
662                      BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,
663                                                    1);
664                    }
665                }
666              else
667                {
668                  /* CTS low */
669                  termios_stopped_com1 = 1;
670                }
671            }
672          break;
673        case NO_MORE_INTR :
674          /* No more interrupts */
675          if(off != 0)
676            {
677              /* Update rx buffer */
678         if( driver_input_handler_com1 )
679         {
680             driver_input_handler_com1( termios_ttyp_com1, (char *)buf, off );
681         }
682         else
683         {
684            /* Update rx buffer */
685                 rtems_termios_enqueue_raw_characters(termios_ttyp_com1, (char *)buf, off );
686         }
687            }
688          return;
689        case TRANSMITTER_HODING_REGISTER_EMPTY :
690          /*
691           * TX holding empty: we have to disable these interrupts
692           * if there is nothing more to send.
693           */
694
695          /* If nothing else to send disable interrupts */
696          ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
697          if ( ret == 0 ) {
698            termios_tx_active_com1 = 0;
699            uart_data[BSP_UART_COM1].ier &= ~(TRANSMIT_ENABLE);
700            uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
701          }
702          break;
703        case RECEIVER_DATA_AVAIL :
704        case CHARACTER_TIMEOUT_INDICATION:
705          if ( uart_data[BSP_UART_COM1].ioMode == TERMIOS_TASK_DRIVEN ) {
706            /* ensure interrupts are enabled */
707            if ( uart_data[BSP_UART_COM1].ier & RECEIVE_ENABLE ) {
708              /* disable interrupts and notify termios */
709              uart_data[BSP_UART_COM1].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
710              uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
711              rtems_termios_rxirq_occured(termios_ttyp_com1);
712            }
713          }
714          else {
715            /* RX data ready */
716            assert(off < sizeof(buf));
717            buf[off++] = uread(BSP_UART_COM1, RBR);
718          }
719          break;
720        case RECEIVER_ERROR:
721          /* RX error: eat character */
722           uartError(BSP_UART_COM1);
723          break;
724        default:
725          /* Should not happen */
726          assert(0);
727          return;
728        }
729    }
730}
731
732void
733BSP_uart_termios_isr_com2(void)
734{
735  unsigned char buf[40];
736  unsigned char val;
737  int      off, ret, vect;
738
739  off = 0;
740
741  for(;;)
742    {
743      vect = uread(BSP_UART_COM2, IIR) & 0xf;
744
745      switch(vect)
746        {
747        case MODEM_STATUS :
748          val = uread(BSP_UART_COM2, MSR);
749          if(uart_data[BSP_UART_COM2].hwFlow)
750            {
751              if(val & CTS)
752                {
753                  /* CTS high */
754                  termios_stopped_com2 = 0;
755                  if(termios_tx_hold_valid_com2)
756                    {
757                      termios_tx_hold_valid_com2 = 0;
758                      BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,
759                                                    1);
760                    }
761                }
762              else
763                {
764                  /* CTS low */
765                  termios_stopped_com2 = 1;
766                }
767            }
768          break;
769        case NO_MORE_INTR :
770          /* No more interrupts */
771          if(off != 0)
772            {
773              /* Update rx buffer */
774         if( driver_input_handler_com2 )
775         {
776             driver_input_handler_com2( termios_ttyp_com2, (char *)buf, off );
777         }
778         else
779         {
780                rtems_termios_enqueue_raw_characters(termios_ttyp_com2, (char *)buf, off);
781         }
782            }
783          return;
784        case TRANSMITTER_HODING_REGISTER_EMPTY :
785          /*
786           * TX holding empty: we have to disable these interrupts
787           * if there is nothing more to send.
788           */
789
790          /* If nothing else to send disable interrupts */
791          ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
792          if ( ret == 0 ) {
793            termios_tx_active_com2 = 0;
794            uart_data[BSP_UART_COM2].ier &= ~(TRANSMIT_ENABLE);
795            uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
796          }
797          break;
798        case RECEIVER_DATA_AVAIL :
799        case CHARACTER_TIMEOUT_INDICATION:
800          if ( uart_data[BSP_UART_COM2].ioMode == TERMIOS_TASK_DRIVEN ) {
801            /* ensure interrupts are enabled */
802            if ( uart_data[BSP_UART_COM2].ier & RECEIVE_ENABLE ) {
803              /* disable interrupts and notify termios */
804              uart_data[BSP_UART_COM2].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
805              uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
806              rtems_termios_rxirq_occured(termios_ttyp_com2);
807            }
808          }
809          else {
810            /* RX data ready */
811            assert(off < sizeof(buf));
812            buf[off++] = uread(BSP_UART_COM2, RBR);
813          }
814          break;
815        case RECEIVER_ERROR:
816          /* RX error: eat character */
817           uartError(BSP_UART_COM2);
818          break;
819        default:
820          /* Should not happen */
821          assert(0);
822          return;
823        }
824    }
825}
826
827/* ================= GDB support     ===================*/
828int BSP_uart_dbgisr_com_regsav[4] __attribute__ ((unused));
829
830/*
831 * Interrupt service routine for COM1 - all,
832 * it does it check whether ^C is received
833 * if yes it will flip TF bit before returning
834 * Note: it should be installed as raw interrupt
835 * handler
836 */
837
838__asm__ (".p2align 4");
839__asm__ (".text");
840__asm__ (".globl BSP_uart_dbgisr_com1");
841__asm__ ("BSP_uart_dbgisr_com1:");
842__asm__ ("    movl %eax, BSP_uart_dbgisr_com_regsav");          /* Save eax */
843__asm__ ("    movl %ebx, BSP_uart_dbgisr_com_regsav + 4");      /* Save ebx */
844__asm__ ("    movl %edx, BSP_uart_dbgisr_com_regsav + 8");      /* Save edx */
845
846__asm__ ("    movl $0, %ebx");           /* Clear flag */
847
848/*
849 * We know that only receive related interrupts
850 * are available, eat chars
851 */
852__asm__ ("uart_dbgisr_com1_1:");
853__asm__ ("    movw $0x3FD, %dx");
854__asm__ ("    inb  %dx, %al"); /* Read LSR */
855__asm__ ("    andb $1, %al");
856__asm__ ("    cmpb $0, %al");
857__asm__ ("    je   uart_dbgisr_com1_2");
858__asm__ ("    movw $0x3F8, %dx");
859__asm__ ("    inb  %dx, %al");    /* Get input character */
860__asm__ ("    cmpb $3, %al");
861__asm__ ("    jne  uart_dbgisr_com1_1");
862
863/* ^C received, set flag */
864__asm__ ("    movl $1, %ebx");
865__asm__ ("    jmp uart_dbgisr_com1_1");
866
867/* All chars read */
868__asm__ ("uart_dbgisr_com1_2:");
869
870/* If flag is set we have to tweak TF */
871__asm__ ("   cmpl $0, %ebx");
872__asm__ ("   je   uart_dbgisr_com1_3");
873
874/* Flag is set */
875__asm__ ("   movl BSP_uart_dbgisr_com_regsav+4, %ebx");     /* Restore ebx */
876__asm__ ("   movl BSP_uart_dbgisr_com_regsav+8, %edx");     /* Restore edx */
877
878/* Set TF bit */
879__asm__ ("   popl  %eax");                               /* Pop eip */
880__asm__ ("   movl  %eax, BSP_uart_dbgisr_com_regsav + 4");  /* Save it */
881__asm__ ("   popl  %eax");                               /* Pop cs */
882__asm__ ("   movl  %eax, BSP_uart_dbgisr_com_regsav + 8");  /* Save it */
883__asm__ ("   popl  %eax");                               /* Pop flags */
884__asm__ ("   orl   $0x100, %eax");                       /* Modify it */
885__asm__ ("   pushl %eax");                               /* Push it back */
886__asm__ ("   movl  BSP_uart_dbgisr_com_regsav+8, %eax");    /* Put back cs */
887__asm__ ("   pushl %eax");
888__asm__ ("   movl  BSP_uart_dbgisr_com_regsav+4, %eax");    /* Put back eip */
889__asm__ ("   pushl %eax");
890
891/* Acknowledge IRQ */
892__asm__ ("   movb  $0x20, %al");
893__asm__ ("   outb  %al, $0x20");
894__asm__ ("   movl  BSP_uart_dbgisr_com_regsav, %eax");      /* Restore eax */
895__asm__ ("   iret");                                     /* Done */
896
897/* Flag is not set */
898__asm__ ("uart_dbgisr_com1_3:");
899__asm__ ("   movl BSP_uart_dbgisr_com_regsav+4, %ebx");     /* Restore ebx */
900__asm__ ("   movl BSP_uart_dbgisr_com_regsav+8, %edx");     /* Restore edx */
901
902/* Acknowledge irq */
903__asm__ ("   movb  $0x20, %al");
904__asm__ ("   outb  %al, $0x20");
905__asm__ ("   movl  BSP_uart_dbgisr_com_regsav, %eax");      /* Restore eax */
906__asm__ ("   iret");                 /* Done */
907
908/*
909 * Interrupt service routine for COM2 - all,
910 * it does it check whether ^C is received
911 * if yes it will flip TF bit before returning
912 * Note: it has to be installed as raw interrupt
913 * handler
914 */
915__asm__ (".p2align 4");
916__asm__ (".text");
917__asm__ (".globl BSP_uart_dbgisr_com2");
918__asm__ ("BSP_uart_dbgisr_com2:");
919__asm__ ("    movl %eax, BSP_uart_dbgisr_com_regsav");          /* Save eax */
920__asm__ ("    movl %ebx, BSP_uart_dbgisr_com_regsav + 4");      /* Save ebx */
921__asm__ ("    movl %edx, BSP_uart_dbgisr_com_regsav + 8");      /* Save edx */
922
923__asm__ ("    movl $0, %ebx");           /* Clear flag */
924
925/*
926 * We know that only receive related interrupts
927 * are available, eat chars
928 */
929__asm__ ("uart_dbgisr_com2_1:");
930__asm__ ("    movw $0x2FD, %dx");
931__asm__ ("    inb  %dx, %al"); /* Read LSR */
932__asm__ ("    andb $1, %al");
933__asm__ ("    cmpb $0, %al");
934__asm__ ("    je   uart_dbgisr_com2_2");
935__asm__ ("    movw $0x2F8, %dx");
936__asm__ ("    inb  %dx, %al");    /* Get input character */
937__asm__ ("    cmpb $3, %al");
938__asm__ ("    jne  uart_dbgisr_com2_1");
939
940/* ^C received, set flag */
941__asm__ ("    movl $1, %ebx");
942__asm__ ("    jmp uart_dbgisr_com2_1");
943
944/* All chars read */
945__asm__ ("uart_dbgisr_com2_2:");
946
947/* If flag is set we have to tweak TF */
948__asm__ ("   cmpl $0, %ebx");
949__asm__ ("   je   uart_dbgisr_com2_3");
950
951/* Flag is set */
952__asm__ ("   movl BSP_uart_dbgisr_com_regsav+4, %ebx");     /* Restore ebx */
953__asm__ ("   movl BSP_uart_dbgisr_com_regsav+8, %edx");     /* Restore edx */
954
955/* Set TF bit */
956__asm__ ("   popl  %eax");           /* Pop eip */
957__asm__ ("   movl  %eax, BSP_uart_dbgisr_com_regsav + 4");  /* Save it */
958__asm__ ("   popl  %eax");           /* Pop cs */
959__asm__ ("   movl  %eax, BSP_uart_dbgisr_com_regsav + 8");  /* Save it */
960__asm__ ("   popl  %eax");           /* Pop flags */
961__asm__ ("   orl   $0x100, %eax");   /* Modify it */
962__asm__ ("   pushl %eax");           /* Push it back */
963__asm__ ("   movl  BSP_uart_dbgisr_com_regsav+8, %eax");    /* Put back cs */
964__asm__ ("   pushl %eax");
965__asm__ ("   movl  BSP_uart_dbgisr_com_regsav+4, %eax");    /* Put back eip */
966__asm__ ("   pushl %eax");
967
968/* Acknowledge IRQ */
969__asm__ ("   movb  $0x20, %al");
970__asm__ ("   outb  %al, $0x20");
971__asm__ ("   movl  BSP_uart_dbgisr_com_regsav, %eax");      /* Restore eax */
972__asm__ ("   iret");                 /* Done */
973
974/* Flag is not set */
975__asm__ ("uart_dbgisr_com2_3:");
976__asm__ ("   movl BSP_uart_dbgisr_com_regsav+4, %ebx");     /* Restore ebx */
977__asm__ ("   movl BSP_uart_dbgisr_com_regsav+8, %edx");     /* Restore edx */
978
979/* Acknowledge irq */
980__asm__ ("   movb  $0x20, %al");
981__asm__ ("   outb  %al, $0x20");
982__asm__ ("   movl  BSP_uart_dbgisr_com_regsav, %eax");      /* Restore eax */
983__asm__ ("   iret");                 /* Done */
Note: See TracBrowser for help on using the repository browser.