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

4.104.114.84.95
Last change on this file since 96b46bf was 96b46bf, checked in by Joel Sherrill <joel.sherrill@…>, on 01/04/99 at 16:23:29

Patch from D. V. Henkel-Wallace <gumby@…> to mark sav as unused.

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