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

4.104.114.84.95
Last change on this file since b459526 was b459526, checked in by Joel Sherrill <joel.sherrill@…>, on 08/30/00 at 08:18:56

2000-08-26 Rosimildo da Silva <rdasilva@…>

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