source: rtems/c/src/lib/libbsp/i386/shared/comm/uart.c @ 8ad5399

4.104.114.84.95
Last change on this file since 8ad5399 was 8ad5399, checked in by Joel Sherrill <joel.sherrill@…>, on 10/18/00 at 16:10:50

2000-10-18 Charles-Antoine Gauthier <charles.gauthier@…>

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