OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [shared/] [comm/] [uart.c] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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: uart.c,v 1.2 2001-09-27 11:59:49 chris Exp $
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
 
20
struct uart_data
21
{
22
  int hwFlow;
23
  int baud;
24
};
25
 
26
static 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
 
33
static inline unsigned char
34
uread(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
 
47
static inline void
48
uwrite(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
59
uartError(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
79
inline 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
 */
94
void
95
BSP_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
 */
157
void
158
BSP_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
 */
190
void
191
BSP_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
 
252
void
253
BSP_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
 
273
void
274
BSP_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
 */
303
int
304
BSP_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
 */
344
void
345
BSP_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
 
376
void
377
BSP_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
 */
386
int
387
BSP_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
 
406
unsigned
407
BSP_poll_char_via_serial()
408
{
409
        return BSP_uart_polled_read(BSPConsolePort);
410
}
411
 
412
 
413
/* ================ Termios support  =================*/
414
 
415
static volatile int  termios_stopped_com1        = 0;
416
static volatile int  termios_tx_active_com1      = 0;
417
static void*         termios_ttyp_com1           = NULL;
418
static char          termios_tx_hold_com1        = 0;
419
static volatile char termios_tx_hold_valid_com1  = 0;
420
 
421
static volatile int  termios_stopped_com2        = 0;
422
static volatile int  termios_tx_active_com2      = 0;
423
static void*         termios_ttyp_com2           = NULL;
424
static char          termios_tx_hold_com2        = 0;
425
static volatile char termios_tx_hold_valid_com2  = 0;
426
 
427
/*
428
 * Set channel parameters
429
 */
430
void
431
BSP_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
 
474
int
475
BSP_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
 
524
int
525
BSP_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
 
577
void
578
BSP_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
 
671
void
672
BSP_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     ===================*/
767
static 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
 
777
asm (".p2align 4");
778
asm (".text");
779
asm (".globl BSP_uart_dbgisr_com1");
780
asm ("BSP_uart_dbgisr_com1:");
781
asm ("    movl %eax, sav");          /* Save eax */
782
asm ("    movl %ebx, sav + 4");      /* Save ebx */
783
asm ("    movl %edx, sav + 8");      /* Save edx */
784
 
785
asm ("    movl $0, %ebx");           /* Clear flag */
786
 
787
/*
788
 * We know that only receive related interrupts
789
 * are available, eat chars
790
 */
791
asm ("uart_dbgisr_com1_1:");
792
asm ("    movw $0x3FD, %dx");
793
asm ("    inb  %dx, %al"); /* Read LSR */
794
asm ("    andb $1, %al");
795
asm ("    cmpb $0, %al");
796
asm ("    je   uart_dbgisr_com1_2");
797
asm ("    movw $0x3F8, %dx");
798
asm ("    inb  %dx, %al");    /* Get input character */
799
asm ("    cmpb $3, %al");
800
asm ("    jne  uart_dbgisr_com1_1");
801
 
802
/* ^C received, set flag */
803
asm ("    movl $1, %ebx");
804
asm ("    jmp uart_dbgisr_com1_1");
805
 
806
/* All chars read */
807
asm ("uart_dbgisr_com1_2:");
808
 
809
/* If flag is set we have to tweak TF */
810
asm ("   cmpl $0, %ebx");
811
asm ("   je   uart_dbgisr_com1_3");
812
 
813
/* Flag is set */
814
asm ("   movl sav+4, %ebx");     /* Restore ebx */
815
asm ("   movl sav+8, %edx");     /* Restore edx */
816
 
817
/* Set TF bit */
818
asm ("   popl  %eax");           /* Pop eip */
819
asm ("   movl  %eax, sav + 4");  /* Save it */
820
asm ("   popl  %eax");           /* Pop cs */
821
asm ("   movl  %eax, sav + 8");  /* Save it */
822
asm ("   popl  %eax");           /* Pop flags */
823
asm ("   orl   $0x100, %eax");   /* Modify it */
824
asm ("   pushl %eax");           /* Push it back */
825
asm ("   movl  sav+8, %eax");    /* Put back cs */
826
asm ("   pushl %eax");
827
asm ("   movl  sav+4, %eax");    /* Put back eip */
828
asm ("   pushl %eax");
829
 
830
/* Acknowledge IRQ */
831
asm ("   movb  $0x20, %al");
832
asm ("   outb  %al, $0x20");
833
asm ("   movl  sav, %eax");      /* Restore eax */
834
asm ("   iret");                 /* Done */
835
 
836
/* Flag is not set */
837
asm("uart_dbgisr_com1_3:");
838
asm ("   movl sav+4, %ebx");     /* Restore ebx */
839
asm ("   movl sav+8, %edx");     /* Restore edx */
840
 
841
/* Acknowledge irq */
842
asm ("   movb  $0x20, %al");
843
asm ("   outb  %al, $0x20");
844
asm ("   movl  sav, %eax");      /* Restore eax */
845
asm ("   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
 */
855
asm (".p2align 4");
856
asm (".text");
857
asm (".globl BSP_uart_dbgisr_com2");
858
asm ("BSP_uart_dbgisr_com2:");
859
asm ("    movl %eax, sav");          /* Save eax */
860
asm ("    movl %ebx, sav + 4");      /* Save ebx */
861
asm ("    movl %edx, sav + 8");      /* Save edx */
862
 
863
asm ("    movl $0, %ebx");           /* Clear flag */
864
 
865
/*
866
 * We know that only receive related interrupts
867
 * are available, eat chars
868
 */
869
asm ("uart_dbgisr_com2_1:");
870
asm ("    movw $0x2FD, %dx");
871
asm ("    inb  %dx, %al"); /* Read LSR */
872
asm ("    andb $1, %al");
873
asm ("    cmpb $0, %al");
874
asm ("    je   uart_dbgisr_com2_2");
875
asm ("    movw $0x2F8, %dx");
876
asm ("    inb  %dx, %al");    /* Get input character */
877
asm ("    cmpb $3, %al");
878
asm ("    jne  uart_dbgisr_com2_1");
879
 
880
/* ^C received, set flag */
881
asm ("    movl $1, %ebx");
882
asm ("    jmp uart_dbgisr_com2_1");
883
 
884
/* All chars read */
885
asm ("uart_dbgisr_com2_2:");
886
 
887
/* If flag is set we have to tweak TF */
888
asm ("   cmpl $0, %ebx");
889
asm ("   je   uart_dbgisr_com2_3");
890
 
891
/* Flag is set */
892
asm ("   movl sav+4, %ebx");     /* Restore ebx */
893
asm ("   movl sav+8, %edx");     /* Restore edx */
894
 
895
/* Set TF bit */
896
asm ("   popl  %eax");           /* Pop eip */
897
asm ("   movl  %eax, sav + 4");  /* Save it */
898
asm ("   popl  %eax");           /* Pop cs */
899
asm ("   movl  %eax, sav + 8");  /* Save it */
900
asm ("   popl  %eax");           /* Pop flags */
901
asm ("   orl   $0x100, %eax");   /* Modify it */
902
asm ("   pushl %eax");           /* Push it back */
903
asm ("   movl  sav+8, %eax");    /* Put back cs */
904
asm ("   pushl %eax");
905
asm ("   movl  sav+4, %eax");    /* Put back eip */
906
asm ("   pushl %eax");
907
 
908
/* Acknowledge IRQ */
909
asm ("   movb  $0x20, %al");
910
asm ("   outb  %al, $0x20");
911
asm ("   movl  sav, %eax");      /* Restore eax */
912
asm ("   iret");                 /* Done */
913
 
914
/* Flag is not set */
915
asm("uart_dbgisr_com2_3:");
916
asm ("   movl sav+4, %ebx");     /* Restore ebx */
917
asm ("   movl sav+8, %edx");     /* Restore edx */
918
 
919
/* Acknowledge irq */
920
asm ("   movb  $0x20, %al");
921
asm ("   outb  %al, $0x20");
922
asm ("   movl  sav, %eax");      /* Restore eax */
923
asm ("   iret");                 /* Done */
924
 
925
 
926
 
927
 
928
 
929
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.