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

4.104.114.84.95
Last change on this file since 3299388d was 27ce642, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 16, 2002 at 10:30:11 PM

2002-07-16 Eric Norum <eric.norum@…>

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