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

Last change on this file since 930c1c8 was 930c1c8, checked in by Joel Sherrill <joel.sherrill@…>, on 06/12/00 at 15:24:34

Merging main trunk and 4.5 branch. These changes were in the
main trunk.

  • Property mode set to 100644
File size: 18.9 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
427/*
428 * Set channel parameters
429 */
430void
431BSP_uart_termios_set(int uart, void *ttyp)
432{
433  unsigned char val;
434  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
435 
436  if(uart == BSP_UART_COM1)
437    {
438      if(uart_data[uart].hwFlow)
439        {
440          val = uread(uart, MSR);
441
442          termios_stopped_com1   = (val & CTS) ? 0 : 1;
443        }
444      else
445        {
446          termios_stopped_com1 = 0;
447        }
448      termios_tx_active_com1      = 0;
449      termios_ttyp_com1           = ttyp;
450      termios_tx_hold_com1        = 0;
451      termios_tx_hold_valid_com1  = 0;
452    }
453  else
454    {
455      if(uart_data[uart].hwFlow)
456        {
457          val = uread(uart, MSR);
458
459          termios_stopped_com2   = (val & CTS) ? 0 : 1;
460        }
461      else
462        {
463          termios_stopped_com2 = 0;
464        }
465      termios_tx_active_com2      = 0;
466      termios_ttyp_com2           = ttyp;
467      termios_tx_hold_com2        = 0;
468      termios_tx_hold_valid_com2  = 0;
469    }
470
471  return;
472}
473
474int
475BSP_uart_termios_write_com1(int minor, const char *buf, int len)
476{
477  assert(buf != NULL);
478
479  if(len <= 0)
480    {
481      return 0;
482    }
483
484  /* If there TX buffer is busy - something is royally screwed up */
485  assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);
486
487  if(termios_stopped_com1)
488    {
489      /* CTS low */
490      termios_tx_hold_com1       = *buf;
491      termios_tx_hold_valid_com1 = 1;
492      return 0;
493    }
494
495  /* Write character */
496  uwrite(BSP_UART_COM1, THR, *buf & 0xff);
497
498  /* Enable interrupts if necessary */
499  if(!termios_tx_active_com1 && uart_data[BSP_UART_COM1].hwFlow)
500    {
501      termios_tx_active_com1 = 1;
502      uwrite(BSP_UART_COM1, IER,
503             (RECEIVE_ENABLE  |
504              TRANSMIT_ENABLE |
505              RECEIVER_LINE_ST_ENABLE |
506              MODEM_ENABLE
507             )
508            );
509    }
510  else if(!termios_tx_active_com1)
511    {
512      termios_tx_active_com1 = 1;
513      uwrite(BSP_UART_COM1, IER,
514             (RECEIVE_ENABLE  |
515              TRANSMIT_ENABLE |
516              RECEIVER_LINE_ST_ENABLE
517             )
518            );
519    }
520
521  return 0;
522}
523
524int
525BSP_uart_termios_write_com2(int minor, const char *buf, int len)
526{
527  assert(buf != NULL);
528
529  if(len <= 0)
530    {
531      return 0;
532    }
533
534
535  /* If there TX buffer is busy - something is royally screwed up */
536  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
537
538  if(termios_stopped_com2)
539    {
540      /* CTS low */
541      termios_tx_hold_com2       = *buf;
542      termios_tx_hold_valid_com2 = 1;
543      return 0;
544    }
545
546  /* Write character */
547
548  uwrite(BSP_UART_COM2, THR, *buf & 0xff);
549
550  /* Enable interrupts if necessary */
551  if(!termios_tx_active_com2 && uart_data[BSP_UART_COM2].hwFlow)
552    {
553      termios_tx_active_com2 = 1;
554      uwrite(BSP_UART_COM2, IER,
555             (RECEIVE_ENABLE  |
556              TRANSMIT_ENABLE |
557              RECEIVER_LINE_ST_ENABLE |
558              MODEM_ENABLE
559             )
560            );
561    }
562  else if(!termios_tx_active_com2)
563    {
564      termios_tx_active_com2 = 1;
565      uwrite(BSP_UART_COM2, IER,
566             (RECEIVE_ENABLE  |
567              TRANSMIT_ENABLE |
568              RECEIVER_LINE_ST_ENABLE
569             )
570            );
571    }
572
573  return 0;
574}
575
576
577void
578BSP_uart_termios_isr_com1(void)
579{
580  unsigned char buf[40];
581  unsigned char val;
582  int      off, ret, vect;
583
584  off = 0;
585
586  for(;;)
587    {
588      vect = uread(BSP_UART_COM1, IIR) & 0xf;
589     
590      switch(vect)
591        {
592        case MODEM_STATUS :
593          val = uread(BSP_UART_COM1, MSR);
594          if(uart_data[BSP_UART_COM1].hwFlow)
595            {
596              if(val & CTS)
597                {
598                  /* CTS high */
599                  termios_stopped_com1 = 0;
600                  if(termios_tx_hold_valid_com1)
601                    {
602                      termios_tx_hold_valid_com1 = 0;
603                      BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,
604                                                    1);
605                    }
606                }
607              else
608                {
609                  /* CTS low */
610                  termios_stopped_com1 = 1;
611                }
612            }
613          break;
614        case NO_MORE_INTR :
615          /* No more interrupts */
616          if(off != 0)
617            {
618              /* Update rx buffer */
619              rtems_termios_enqueue_raw_characters(termios_ttyp_com1,
620                                                   (char *)buf,
621                                                   off);
622            }
623          return;
624        case TRANSMITTER_HODING_REGISTER_EMPTY :
625          /*
626           * TX holding empty: we have to disable these interrupts
627           * if there is nothing more to send.
628           */
629
630          ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
631
632          /* If nothing else to send disable interrupts */
633          if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow)
634            {
635              uwrite(BSP_UART_COM1, IER,
636                     (RECEIVE_ENABLE  |
637                      RECEIVER_LINE_ST_ENABLE |
638                      MODEM_ENABLE
639                     )
640                    );
641              termios_tx_active_com1 = 0;
642            }
643          else if(ret == 0)
644            {
645              uwrite(BSP_UART_COM1, IER,
646                     (RECEIVE_ENABLE  |
647                      RECEIVER_LINE_ST_ENABLE
648                     )
649                    );
650              termios_tx_active_com1 = 0;
651            }
652          break;
653        case RECEIVER_DATA_AVAIL :
654        case CHARACTER_TIMEOUT_INDICATION:
655          /* RX data ready */
656          assert(off < sizeof(buf));
657          buf[off++] = uread(BSP_UART_COM1, RBR);
658          break;
659        case RECEIVER_ERROR:
660          /* RX error: eat character */
661           uartError(BSP_UART_COM1);
662          break;
663        default:
664          /* Should not happen */
665          assert(0);
666          return;
667        }
668    }
669}
670         
671void
672BSP_uart_termios_isr_com2()
673{
674  unsigned char buf[40];
675  unsigned char val;
676  int      off, ret, vect;
677
678  off = 0;
679
680  for(;;)
681    {
682      vect = uread(BSP_UART_COM2, IIR) & 0xf;
683     
684      switch(vect)
685        {
686        case MODEM_STATUS :
687          val = uread(BSP_UART_COM2, MSR);
688          if(uart_data[BSP_UART_COM2].hwFlow)
689            {
690              if(val & CTS)
691                {
692                  /* CTS high */
693                  termios_stopped_com2 = 0;
694                  if(termios_tx_hold_valid_com2)
695                    {
696                      termios_tx_hold_valid_com2 = 0;
697                      BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,
698                                                    1);
699                    }
700                }
701              else
702                {
703                  /* CTS low */
704                  termios_stopped_com2 = 1;
705                }
706            }
707          break;
708        case NO_MORE_INTR :
709          /* No more interrupts */
710          if(off != 0)
711            {
712              /* Update rx buffer */
713              rtems_termios_enqueue_raw_characters(termios_ttyp_com2,
714                                                   (char *)buf,
715                                                   off);
716            }
717          return;
718        case TRANSMITTER_HODING_REGISTER_EMPTY :
719          /*
720           * TX holding empty: we have to disable these interrupts
721           * if there is nothing more to send.
722           */
723
724          ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
725
726          /* If nothing else to send disable interrupts */
727          if(ret == 0 && uart_data[BSP_UART_COM2].hwFlow)
728            {
729              uwrite(BSP_UART_COM2, IER,
730                     (RECEIVE_ENABLE  |
731                      RECEIVER_LINE_ST_ENABLE |
732                      MODEM_ENABLE
733                     )
734                    );
735              termios_tx_active_com2 = 0;
736            }
737          else if(ret == 0)
738            {
739              uwrite(BSP_UART_COM2, IER,
740                     (RECEIVE_ENABLE  |
741                      RECEIVER_LINE_ST_ENABLE
742                     )
743                    );
744              termios_tx_active_com2 = 0;
745            }
746          break;
747        case RECEIVER_DATA_AVAIL :
748        case CHARACTER_TIMEOUT_INDICATION:
749          /* RX data ready */
750          assert(off < sizeof(buf));
751          buf[off++] = uread(BSP_UART_COM2, RBR);
752          break;
753        case RECEIVER_ERROR:
754          /* RX error: eat character */
755           uartError(BSP_UART_COM2);
756          break;
757        default:
758          /* Should not happen */
759          assert(0);
760          return;
761        }
762    }
763}
764         
765 
766/* ================= GDB support     ===================*/
767static int sav[4] __attribute__ ((unused));
768
769/*
770 * Interrupt service routine for COM1 - all,
771 * it does it check whether ^C is received
772 * if yes it will flip TF bit before returning
773 * Note: it should be installed as raw interrupt
774 * handler
775 */
776
777asm (".p2align 4");
778asm (".text");
779asm (".globl BSP_uart_dbgisr_com1");
780asm ("BSP_uart_dbgisr_com1:");
781asm ("    movl %eax, sav");          /* Save eax */
782asm ("    movl %ebx, sav + 4");      /* Save ebx */
783asm ("    movl %edx, sav + 8");      /* Save edx */
784
785asm ("    movl $0, %ebx");           /* Clear flag */
786
787/*
788 * We know that only receive related interrupts
789 * are available, eat chars
790 */
791asm ("uart_dbgisr_com1_1:");
792asm ("    movw $0x3FD, %dx");
793asm ("    inb  %dx, %al"); /* Read LSR */
794asm ("    andb $1, %al");
795asm ("    cmpb $0, %al");
796asm ("    je   uart_dbgisr_com1_2");
797asm ("    movw $0x3F8, %dx");
798asm ("    inb  %dx, %al");    /* Get input character */
799asm ("    cmpb $3, %al");
800asm ("    jne  uart_dbgisr_com1_1");
801
802/* ^C received, set flag */
803asm ("    movl $1, %ebx");
804asm ("    jmp uart_dbgisr_com1_1");
805
806/* All chars read */
807asm ("uart_dbgisr_com1_2:");
808
809/* If flag is set we have to tweak TF */
810asm ("   cmpl $0, %ebx");
811asm ("   je   uart_dbgisr_com1_3");
812
813/* Flag is set */
814asm ("   movl sav+4, %ebx");     /* Restore ebx */
815asm ("   movl sav+8, %edx");     /* Restore edx */
816
817/* Set TF bit */
818asm ("   popl  %eax");           /* Pop eip */
819asm ("   movl  %eax, sav + 4");  /* Save it */
820asm ("   popl  %eax");           /* Pop cs */
821asm ("   movl  %eax, sav + 8");  /* Save it */
822asm ("   popl  %eax");           /* Pop flags */
823asm ("   orl   $0x100, %eax");   /* Modify it */
824asm ("   pushl %eax");           /* Push it back */
825asm ("   movl  sav+8, %eax");    /* Put back cs */
826asm ("   pushl %eax");
827asm ("   movl  sav+4, %eax");    /* Put back eip */
828asm ("   pushl %eax");
829
830/* Acknowledge IRQ */
831asm ("   movb  $0x20, %al");
832asm ("   outb  %al, $0x20");
833asm ("   movl  sav, %eax");      /* Restore eax */
834asm ("   iret");                 /* Done */
835
836/* Flag is not set */
837asm("uart_dbgisr_com1_3:");
838asm ("   movl sav+4, %ebx");     /* Restore ebx */
839asm ("   movl sav+8, %edx");     /* Restore edx */
840
841/* Acknowledge irq */
842asm ("   movb  $0x20, %al");
843asm ("   outb  %al, $0x20");
844asm ("   movl  sav, %eax");      /* Restore eax */
845asm ("   iret");                 /* Done */
846
847
848/*
849 * Interrupt service routine for COM2 - all,
850 * it does it check whether ^C is received
851 * if yes it will flip TF bit before returning
852 * Note: it has to be installed as raw interrupt
853 * handler
854 */
855asm (".p2align 4");
856asm (".text");
857asm (".globl BSP_uart_dbgisr_com2");
858asm ("BSP_uart_dbgisr_com2:");
859asm ("    movl %eax, sav");          /* Save eax */
860asm ("    movl %ebx, sav + 4");      /* Save ebx */
861asm ("    movl %edx, sav + 8");      /* Save edx */
862
863asm ("    movl $0, %ebx");           /* Clear flag */
864
865/*
866 * We know that only receive related interrupts
867 * are available, eat chars
868 */
869asm ("uart_dbgisr_com2_1:");
870asm ("    movw $0x2FD, %dx");
871asm ("    inb  %dx, %al"); /* Read LSR */
872asm ("    andb $1, %al");
873asm ("    cmpb $0, %al");
874asm ("    je   uart_dbgisr_com2_2");
875asm ("    movw $0x2F8, %dx");
876asm ("    inb  %dx, %al");    /* Get input character */
877asm ("    cmpb $3, %al");
878asm ("    jne  uart_dbgisr_com2_1");
879
880/* ^C received, set flag */
881asm ("    movl $1, %ebx");
882asm ("    jmp uart_dbgisr_com2_1");
883
884/* All chars read */
885asm ("uart_dbgisr_com2_2:");
886
887/* If flag is set we have to tweak TF */
888asm ("   cmpl $0, %ebx");
889asm ("   je   uart_dbgisr_com2_3");
890
891/* Flag is set */
892asm ("   movl sav+4, %ebx");     /* Restore ebx */
893asm ("   movl sav+8, %edx");     /* Restore edx */
894
895/* Set TF bit */
896asm ("   popl  %eax");           /* Pop eip */
897asm ("   movl  %eax, sav + 4");  /* Save it */
898asm ("   popl  %eax");           /* Pop cs */
899asm ("   movl  %eax, sav + 8");  /* Save it */
900asm ("   popl  %eax");           /* Pop flags */
901asm ("   orl   $0x100, %eax");   /* Modify it */
902asm ("   pushl %eax");           /* Push it back */
903asm ("   movl  sav+8, %eax");    /* Put back cs */
904asm ("   pushl %eax");
905asm ("   movl  sav+4, %eax");    /* Put back eip */
906asm ("   pushl %eax");
907
908/* Acknowledge IRQ */
909asm ("   movb  $0x20, %al");
910asm ("   outb  %al, $0x20");
911asm ("   movl  sav, %eax");      /* Restore eax */
912asm ("   iret");                 /* Done */
913
914/* Flag is not set */
915asm("uart_dbgisr_com2_3:");
916asm ("   movl sav+4, %ebx");     /* Restore ebx */
917asm ("   movl sav+8, %edx");     /* Restore edx */
918
919/* Acknowledge irq */
920asm ("   movb  $0x20, %al");
921asm ("   outb  %al, $0x20");
922asm ("   movl  sav, %eax");      /* Restore eax */
923asm ("   iret");                 /* Done */
924
925
926
927
928
929
Note: See TracBrowser for help on using the repository browser.