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

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [16450.c] - Blame information for rev 509

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

Line No. Rev Author Line
1 19 jeremybenn
/* 16450.c -- Simulation of 8250/16450 serial UART
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
/* This is functional simulation of 8250/16450/16550 UARTs. Since we RX/TX
27
   data via file streams, we can't simulate modem control lines coming from
28
   the DCE and similar details of communication with the DCE.
29
 
30
   This simulated UART device is intended for basic UART device driver
31
   verification. From device driver perspective this device looks like a
32
   regular UART but never reports any modem control lines changes (the
33
   only DCE responses are incoming characters from the file stream). */
34
 
35
 
36
/* Autoconf and/or portability configuration */
37
#include "config.h"
38
#include "port.h"
39
 
40
/* System includes */
41
#include <stdlib.h>
42
 
43
/* Package includes */
44
#include "sim-config.h"
45
#include "arch.h"
46
#include "pic.h"
47
#include "sched.h"
48
#include "vapi.h"
49
#include "channel.h"
50
#include "abstract.h"
51
#include "toplevel-support.h"
52
#include "sim-cmd.h"
53
 
54
 
55
#define MIN(a,b) ((a) < (b) ? (a) : (b))
56
/* Definitions */
57
#define UART_ADDR_SPACE        8        /*!< UART addr space size in bytes */
58
#define UART_MAX_FIFO_LEN     16        /*!< rx FIFO for uart 16550 */
59
#define MAX_SKEW               1        /*!< max. clock skew in subclocks */
60
#define UART_VAPI_BUF_LEN    128        /*!< Size of VAPI command buffer */
61
#define UART_CLOCK_DIVIDER    16        /*!< UART clock divider */
62
#define UART_FGETC_SLOWDOWN  100        /*!< fgetc() slowdown factor */
63
 
64
/*
65
 * Addresses of visible registers
66
 *
67
 */
68
#define UART_RXBUF  0           /* R: Rx buffer, DLAB=0 */
69
#define UART_TXBUF  0           /* W: Tx buffer, DLAB=0 */
70
#define UART_DLL  0             /* R/W: Divisor Latch Low, DLAB=1 */
71
#define UART_DLH  1             /* R/W: Divisor Latch High, DLAB=1 */
72
#define UART_IER  1             /* R/W: Interrupt Enable Register */
73
#define UART_IIR  2             /* R: Interrupt ID Register */
74
#define UART_FCR  2             /* W: FIFO Control Register */
75
#define UART_LCR  3             /* R/W: Line Control Register */
76
#define UART_MCR  4             /* W: Modem Control Register */
77
#define UART_LSR  5             /* R: Line Status Register */
78
#define UART_MSR  6             /* R: Modem Status Register */
79
#define UART_SCR  7             /* R/W: Scratch Register */
80
 
81
/*
82
 * R/W masks for valid bits in 8250/16450 (mask out 16550 and later bits)
83
 *
84
 */
85
#define UART_VALID_LCR  0xff
86
#define UART_VALID_LSR  0xff
87
#define UART_VALID_IIR  0x0f
88
#define UART_VALID_FCR  0xc0
89
#define UART_VALID_IER  0x0f
90
#define UART_VALID_MCR  0x1f
91
#define UART_VALID_MSR  0xff
92
 
93
/*
94
 * Bit definitions for the Line Control Register
95
 *
96
 */
97
#define UART_LCR_DLAB 0x80      /* Divisor latch access bit */
98
#define UART_LCR_SBC  0x40      /* Set break control */
99
#define UART_LCR_SPAR 0x20      /* Stick parity (?) */
100
#define UART_LCR_EPAR 0x10      /* Even parity select */
101
#define UART_LCR_PARITY 0x08    /* Parity Enable */
102
#define UART_LCR_STOP 0x04      /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
103
#define UART_LCR_WLEN5  0x00    /* Wordlength: 5 bits */
104
#define UART_LCR_WLEN6  0x01    /* Wordlength: 6 bits */
105
#define UART_LCR_WLEN7  0x02    /* Wordlength: 7 bits */
106
#define UART_LCR_WLEN8  0x03    /* Wordlength: 8 bits */
107
#define UART_LCR_RESET  0x03
108
/*
109
 * Bit definitions for the Line Status Register
110
 */
111
#define UART_LSR_RXERR  0x80    /* Error in rx fifo */
112
#define UART_LSR_TXSERE 0x40    /* Transmitter serial register empty */
113
#define UART_LSR_TXBUFE 0x20    /* Transmitter buffer register empty */
114
#define UART_LSR_BREAK  0x10    /* Break interrupt indicator */
115
#define UART_LSR_FRAME  0x08    /* Frame error indicator */
116
#define UART_LSR_PARITY 0x04    /* Parity error indicator */
117
#define UART_LSR_OVRRUN 0x02    /* Overrun error indicator */
118
#define UART_LSR_RDRDY  0x01    /* Receiver data ready */
119
 
120
/*
121
 * Bit definitions for the Interrupt Identification Register
122
 */
123
#define UART_IIR_NO_INT 0x01    /* No interrupts pending */
124
#define UART_IIR_ID 0x06        /* Mask for the interrupt ID */
125
 
126
#define UART_IIR_MSI  0x00      /* Modem status interrupt (Low priority) */
127
#define UART_IIR_THRI 0x02      /* Transmitter holding register empty */
128
#define UART_IIR_RDI  0x04      /* Receiver data interrupt */
129
#define UART_IIR_RLSI 0x06      /* Receiver line status interrupt (High p.) */
130
#define UART_IIR_CTI  0x0c      /* Character timeout */
131
 
132
/*
133
 * Bit Definitions for the FIFO Control Register
134
 */
135
#define UART_FCR_FIE  0x01      /* FIFO enable */
136
#define UART_FCR_RRXFI 0x02     /* Reset rx FIFO */
137
#define UART_FCR_RTXFI 0x04     /* Reset tx FIFO */
138
#define UART_FIFO_TRIGGER(x) /* Trigger values for indexes 0..3 */\
139
  ((x) == 0 ? 1\
140
  :(x) == 1 ? 4\
141
  :(x) == 2 ? 8\
142
  :(x) == 3 ? 14 : 0)
143
 
144
/*
145
 * Bit definitions for the Interrupt Enable Register
146
 */
147
#define UART_IER_MSI  0x08      /* Enable Modem status interrupt */
148
#define UART_IER_RLSI 0x04      /* Enable receiver line status interrupt */
149
#define UART_IER_THRI 0x02      /* Enable Transmitter holding register int. */
150
#define UART_IER_RDI  0x01      /* Enable receiver data interrupt */
151
 
152
/*
153
 * Bit definitions for the Modem Control Register
154
 */
155
#define UART_MCR_LOOP 0x10      /* Enable loopback mode */
156
#define UART_MCR_AUX2 0x08      /* Auxilary 2  */
157
#define UART_MCR_AUX1 0x04      /* Auxilary 1 */
158
#define UART_MCR_RTS  0x02      /* Force RTS */
159
#define UART_MCR_DTR  0x01      /* Force DTR */
160
 
161
/*
162
 * Bit definitions for the Modem Status Register
163
 */
164
#define UART_MSR_DCD  0x80      /* Data Carrier Detect */
165
#define UART_MSR_RI   0x40      /* Ring Indicator */
166
#define UART_MSR_DSR  0x20      /* Data Set Ready */
167
#define UART_MSR_CTS  0x10      /* Clear to Send */
168
#define UART_MSR_DDCD 0x08      /* Delta DCD */
169
#define UART_MSR_TERI 0x04      /* Trailing edge ring indicator */
170
#define UART_MSR_DDSR 0x02      /* Delta DSR */
171
#define UART_MSR_DCTS 0x01      /* Delta CTS */
172
 
173
/*
174
 * Various definitions
175
 */
176
#define UART_BREAK_COUNT   1    /* # of chars to count when doing break */
177
#define UART_CHAR_TIMEOUT  4    /* # of chars to count when doing timeout int */
178
 
179
 
180
/* Registers */
181
 
182
struct dev_16450
183
{
184
  struct
185
  {
186
    uint8_t   txbuf[UART_MAX_FIFO_LEN];
187
    uint16_t  rxbuf[UART_MAX_FIFO_LEN]; /* Upper 8-bits is the LCR modifier */
188
    uint8_t   dll;
189
    uint8_t   dlh;
190
    uint8_t   ier;
191
    uint8_t   iir;
192
    uint8_t   fcr;
193
    uint8_t   lcr;
194
    uint8_t   mcr;
195
    uint8_t   lsr;
196
    uint8_t   msr;
197
    uint8_t   scr;
198
  } regs;                       /* Visible registers */
199
  struct
200
  {
201
    uint8_t   txser;            /* Character just sending */
202
    uint16_t  rxser;            /* Character just receiving */
203
    uint8_t   loopback;
204
  } iregs;                      /* Internal registers */
205
  struct
206
  {
207
    int           txbuf_head;
208
    int           txbuf_tail;
209
    int           rxbuf_head;
210
    int           rxbuf_tail;
211
    unsigned int  txbuf_full;
212
    unsigned int  rxbuf_full;
213
    int           receiveing;   /* Receiving a char */
214
    int           recv_break;   /* Receiving a break */
215
    int           ints;         /* Which interrupts are pending */
216
  } istat;                      /* Internal status */
217
 
218
  /* Clocks per char */
219
  unsigned long  char_clks;
220
 
221
  /* VAPI internal registers */
222
  struct
223
  {
224
    unsigned long  char_clks;
225
    uint8_t        dll;
226
    uint8_t        dlh;
227
    uint8_t        lcr;
228
    int            skew;
229
  } vapi;
230
 
231
  /* Required by VAPI - circular buffer to store incoming chars, since we
232
     cannothandle them so fast - we are serial. */
233
  unsigned long   vapi_buf[UART_VAPI_BUF_LEN];  /* Buffer */
234
  int             vapi_buf_head_ptr;            /* Where we write to */
235
  int             vapi_buf_tail_ptr;            /* Where we read from */
236
 
237
  /* Length of FIFO, 16 for 16550, 1 for 16450 */
238
  int             fifo_len;
239
 
240
  struct channel *channel;
241
 
242
  /* Configuration */
243
  int             enabled;
244
  int             jitter;
245
  oraddr_t        baseaddr;
246
  int             irq;
247
  unsigned long   vapi_id;
248
  int             uart16550;
249
  char           *channel_str;
250
};
251
 
252
/* Forward declarations of static functions */
253
static void uart_recv_break (void *dat);
254
static void uart_recv_char (void *dat);
255
static void uart_check_char (void *dat);
256
static void uart_sched_recv_check (struct dev_16450 *uart);
257
static void uart_vapi_cmd (void *dat);
258
static void uart_clear_int (struct dev_16450 *uart, int intr);
259
static void uart_tx_send (void *dat);
260
 
261
 
262
/* Number of clock cycles (one clock cycle is when UART_CLOCK_DIVIDER simulator
263
 * cycles have elapsed) before a single character is transmitted or received. */
264
static unsigned long
265
char_clks (int dll, int dlh, int lcr)
266
{
267
  unsigned int bauds_per_char = 2;
268
  unsigned long char_clks = ((dlh << 8) + dll);
269
 
270
  if (lcr & UART_LCR_PARITY)
271
    bauds_per_char += 2;
272
 
273
  /* stop bits 1 or two */
274
  if (lcr & UART_LCR_STOP)
275
    bauds_per_char += 4;
276
  else if ((lcr & 0x3) != 0)
277
    bauds_per_char += 2;
278
  else
279
    bauds_per_char += 3;
280
 
281
  bauds_per_char += 10 + ((lcr & 0x3) << 1);
282
 
283
  return (char_clks * bauds_per_char) >> 1;
284
}
285
 
286
/*---------------------------------------------------[ Interrupt handling ]---*/
287
/* Signals the specified interrupt.  If a higher priority interrupt is already
288
 * pending, do nothing */
289
static void
290
uart_int_msi (void *dat)
291
{
292
  struct dev_16450 *uart = dat;
293
 
294
  uart->istat.ints |= 1 << UART_IIR_MSI;
295
 
296
  if (!(uart->regs.ier & UART_IER_MSI))
297
    return;
298
 
299
  if ((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI))
300
    {
301
      uart->regs.iir = UART_IIR_MSI;
302
      report_interrupt (uart->irq);
303
    }
304
}
305
 
306
static void
307
uart_int_thri (void *dat)
308
{
309
  struct dev_16450 *uart = dat;
310
 
311
  uart->istat.ints |= 1 << UART_IIR_THRI;
312
 
313
  if (!(uart->regs.ier & UART_IER_THRI))
314
    return;
315
 
316
  if ((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI)
317
      || (uart->regs.iir == UART_IIR_THRI))
318
    {
319
      uart->regs.iir = UART_IIR_THRI;
320
      report_interrupt (uart->irq);
321
    }
322
}
323
 
324
static void
325
uart_int_cti (void *dat)
326
{
327
  struct dev_16450 *uart = dat;
328
 
329
  uart->istat.ints |= 1 << UART_IIR_CTI;
330
 
331
  if (!(uart->regs.ier & UART_IER_RDI))
332
    return;
333
 
334
  if ((uart->regs.iir != UART_IIR_RLSI) && (uart->regs.iir != UART_IIR_RDI))
335
    {
336
      uart->regs.iir = UART_IIR_CTI;
337
      report_interrupt (uart->irq);
338
    }
339
}
340
 
341
static void
342
uart_int_rdi (void *dat)
343
{
344
  struct dev_16450 *uart = dat;
345
 
346
  uart->istat.ints |= 1 << UART_IIR_RDI;
347
 
348
  if (!(uart->regs.ier & UART_IER_RDI))
349
    return;
350
 
351
  if (uart->regs.iir != UART_IIR_RLSI)
352
    {
353
      uart->regs.iir = UART_IIR_RDI;
354
      report_interrupt (uart->irq);
355
    }
356
}
357
 
358
static void
359
uart_int_rlsi (void *dat)
360
{
361
  struct dev_16450 *uart = dat;
362
 
363
  uart->istat.ints |= 1 << UART_IIR_RLSI;
364
 
365
  if (!(uart->regs.ier & UART_IER_RLSI))
366
    return;
367
 
368
  /* Highest priority interrupt */
369
  uart->regs.iir = UART_IIR_RLSI;
370
  report_interrupt (uart->irq);
371
}
372
 
373
/* Checks to see if an RLSI interrupt is due and schedules one if need be */
374
static void
375
uart_check_rlsi (void *dat)
376
{
377
  struct dev_16450 *uart = dat;
378
 
379
  if (uart->regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY | UART_LSR_FRAME |
380
                        UART_LSR_BREAK))
381
    uart_int_rlsi (uart);
382
}
383
 
384
/* Checks to see if an RDI interrupt is due and schedules one if need be */
385
static void
386
uart_check_rdi (void *dat)
387
{
388
  struct dev_16450 *uart = dat;
389
 
390
  if (uart->istat.rxbuf_full >= UART_FIFO_TRIGGER (uart->regs.fcr >> 6))
391
    {
392
      uart_int_rdi (uart);
393
    }
394
}
395
 
396
/* Raises the next highest priority interrupt */
397
static void
398
uart_next_int (struct dev_16450 *uart)
399
{
400
  /* Interrupt detection in proper priority order. */
401
  if ((uart->istat.ints & (1 << UART_IIR_RLSI)) &&
402
      (uart->regs.ier & UART_IER_RLSI))
403
    uart_int_rlsi (uart);
404
  else if ((uart->istat.ints & (1 << UART_IIR_RDI)) &&
405
           (uart->regs.ier & UART_IER_RDI))
406
    uart_int_rdi (uart);
407
  else if ((uart->istat.ints & (1 << UART_IIR_CTI)) &&
408
           (uart->regs.ier & UART_IER_RDI))
409
    uart_int_cti (uart);
410
  else if ((uart->istat.ints & (1 << UART_IIR_THRI)) &&
411
           (uart->regs.ier & UART_IER_THRI))
412
    uart_int_thri (uart);
413
  else if ((uart->istat.ints & (1 << UART_IIR_MSI)) &&
414
           (uart->regs.ier & UART_IER_MSI))
415
    uart_int_msi (uart);
416
  else
417
    {
418
      clear_interrupt (uart->irq);
419
      uart->regs.iir = UART_IIR_NO_INT;
420
    }
421
}
422
 
423
/* Clears potentially pending interrupts */
424
static void
425
uart_clear_int (struct dev_16450 *uart, int intr)
426
{
427
  uart->istat.ints &= ~(1 << intr);
428
 
429
  /* Some stuff schedule uart_int_cti, therefore remove it here */
430
  if (intr == UART_IIR_CTI)
431
    SCHED_FIND_REMOVE (uart_int_cti, uart);
432
 
433
  if (intr != uart->regs.iir)
434
    return;
435
 
436
  uart_next_int (uart);
437
}
438
 
439
/*----------------------------------------------------[ Loopback handling ]---*/
440
static void
441
uart_loopback (struct dev_16450 *uart)
442
{
443
  if (!(uart->regs.mcr & UART_MCR_LOOP))
444
    return;
445
 
446
  if ((uart->regs.mcr & UART_MCR_AUX2) !=
447
      ((uart->regs.msr & UART_MSR_DCD) >> 4))
448
    uart->regs.msr |= UART_MSR_DDCD;
449
 
450
  if ((uart->regs.mcr & UART_MCR_AUX1) <
451
      ((uart->regs.msr & UART_MSR_RI) >> 4))
452
    uart->regs.msr |= UART_MSR_TERI;
453
 
454
  if ((uart->regs.mcr & UART_MCR_RTS) !=
455
      ((uart->regs.msr & UART_MSR_CTS) >> 3))
456
    uart->regs.msr |= UART_MSR_DCTS;
457
 
458
  if ((uart->regs.mcr & UART_MCR_DTR) !=
459
      ((uart->regs.msr & UART_MSR_DSR) >> 5))
460
    uart->regs.msr |= UART_MSR_DDSR;
461
 
462
  uart->regs.msr &=
463
    ~(UART_MSR_DCD | UART_MSR_RI | UART_MSR_DSR | UART_MSR_CTS);
464
  uart->regs.msr |= ((uart->regs.mcr & UART_MCR_AUX2) << 4);
465
  uart->regs.msr |= ((uart->regs.mcr & UART_MCR_AUX1) << 4);
466
  uart->regs.msr |= ((uart->regs.mcr & UART_MCR_RTS) << 3);
467
  uart->regs.msr |= ((uart->regs.mcr & UART_MCR_DTR) << 5);
468
 
469
  if (uart->regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR | UART_MSR_TERI |
470
                        UART_MSR_DDCD))
471
    uart_int_msi (uart);
472
}
473
 
474
/*----------------------------------------------------[ Transmitter logic ]---*/
475
/* Sends the data in the shift register to the outside world */
476
static void
477
send_char (struct dev_16450 *uart, int bits_send)
478
{
479
  PRINTF ("%c", (char) uart->iregs.txser);
480
  if (uart->regs.mcr & UART_MCR_LOOP)
481
    uart->iregs.loopback = uart->iregs.txser;
482
  else
483
    {
484
      /* Send to either VAPI or to file */
485
      if (uart->vapi_id)
486
        {
487
          int par, pe, fe, nbits;
488
          int j, data;
489
          unsigned long packet = 0;
490
 
491
          nbits = MIN (bits_send, (uart->regs.lcr & UART_LCR_WLEN8) + 5);
492
          /* Encode a packet */
493
          packet = uart->iregs.txser & ((1 << nbits) - 1);
494
 
495
          /* Calculate parity */
496
          for (j = 0, par = 0; j < nbits; j++)
497
            par ^= (packet >> j) & 1;
498
 
499
          if (uart->regs.lcr & UART_LCR_PARITY)
500
            {
501
              if (uart->regs.lcr & UART_LCR_SPAR)
502
                {
503
                  packet |= 1 << nbits;
504
                }
505
              else
506
                {
507
                  if (uart->regs.lcr & UART_LCR_EPAR)
508
                    packet |= par << nbits;
509
                  else
510
                    packet |= (par ^ 1) << nbits;
511
                }
512
              nbits++;
513
            }
514
          packet |= 1 << (nbits++);
515
          if (uart->regs.lcr & UART_LCR_STOP)
516
            packet |= 1 << (nbits++);
517
 
518
          /* Decode a packet */
519
          nbits = (uart->vapi.lcr & UART_LCR_WLEN8) + 5;
520
          data = packet & ((1 << nbits) - 1);
521
 
522
          /* Calculate parity, including parity bit */
523
          for (j = 0, par = 0; j < nbits + 1; j++)
524
            par ^= (packet >> j) & 1;
525
 
526
          if (uart->vapi.lcr & UART_LCR_PARITY)
527
            {
528
              if (uart->vapi.lcr & UART_LCR_SPAR)
529
                {
530
                  pe = !((packet >> nbits) & 1);
531
                }
532
              else
533
                {
534
                  if (uart->vapi.lcr & UART_LCR_EPAR)
535
                    pe = par != 0;
536
                  else
537
                    pe = par != 1;
538
                }
539
              nbits++;
540
            }
541
          else
542
            pe = 0;
543
 
544
          fe = ((packet >> (nbits++)) & 1) ^ 1;
545
          if (uart->vapi.lcr & UART_LCR_STOP)
546
            fe |= ((packet >> (nbits++)) & 1) ^ 1;
547
 
548
          data |=
549
            (uart->vapi.lcr << 8) | (pe << 16) | (fe << 17) | (uart->vapi.
550
                                                               lcr << 8);
551
          vapi_send (uart->vapi_id, data);
552
        }
553
      else
554
        {
555
          char buffer[1] = { uart->iregs.txser & 0xFF };
556
          channel_write (uart->channel, buffer, 1);
557
        }
558
    }
559
}
560
 
561
/* Called when all the bits have been shifted out of the shift register */
562
void
563
uart_char_clock (void *dat)
564
{
565
  struct dev_16450 *uart = dat;
566
 
567
  /* We've sent all bits */
568
  send_char (uart, (uart->regs.lcr & UART_LCR_WLEN8) + 5);
569
 
570
  if (!uart->istat.txbuf_full)
571
    uart->regs.lsr |= UART_LSR_TXSERE;
572
  else
573
    uart_tx_send (uart);
574
}
575
 
576
/* Called when a break has been shifted out of the shift register */
577
void
578
uart_send_break (void *dat)
579
{
580
  struct dev_16450 *uart = dat;
581
 
582
  /* Send one break signal */
583
  vapi_send (uart->vapi_id, UART_LCR_SBC << 8);
584
 
585
  /* Send the next char (if there is one) */
586
  if (!uart->istat.txbuf_full)
587
    uart->regs.lsr |= UART_LSR_TXSERE;
588
  else
589
    uart_tx_send (uart);
590
}
591
 
592
/* Scheduled whenever the TX buffer has characters in it and we aren't sending
593
 * a character. */
594
void
595
uart_tx_send (void *dat)
596
{
597
  struct dev_16450 *uart = dat;
598
 
599
  uart->iregs.txser = uart->regs.txbuf[uart->istat.txbuf_tail];
600
  uart->istat.txbuf_tail = (uart->istat.txbuf_tail + 1) % uart->fifo_len;
601
  uart->istat.txbuf_full--;
602
  uart->regs.lsr &= ~UART_LSR_TXSERE;
603
 
604
  /* Schedules a char_clock to run in the correct amount of time */
605
  if (!(uart->regs.lcr & UART_LCR_SBC))
606
    {
607
      SCHED_ADD (uart_char_clock, uart, uart->char_clks * UART_CLOCK_DIVIDER);
608
    }
609
  else
610
    {
611
      SCHED_ADD (uart_send_break, uart, 0);
612
    }
613
 
614
  /* When UART is in either character mode, i.e. 16450 emulation mode, or FIFO
615
   * mode, the THRE interrupt is raised when THR transitions from full to empty.
616
   */
617
  if (!uart->istat.txbuf_full)
618
    {
619
      uart->regs.lsr |= UART_LSR_TXBUFE;
620
      uart_int_thri (uart);
621
    }
622
}
623
 
624
/*-------------------------------------------------------[ Receiver logic ]---*/
625
/* Adds a character to the RX FIFO */
626
static void
627
uart_add_char (struct dev_16450 *uart, int ch)
628
{
629
  uart->regs.lsr |= UART_LSR_RDRDY;
630
  uart_clear_int (uart, UART_IIR_CTI);
631
  SCHED_ADD (uart_int_cti, uart,
632
             uart->char_clks * UART_CHAR_TIMEOUT * UART_CLOCK_DIVIDER);
633
 
634
  if (uart->istat.rxbuf_full + 1 > uart->fifo_len)
635
    {
636
      uart->regs.lsr |= UART_LSR_OVRRUN | UART_LSR_RXERR;
637
      uart_int_rlsi (uart);
638
    }
639
  else
640
    {
641
      uart->regs.rxbuf[uart->istat.rxbuf_head] = ch;
642
      uart->istat.rxbuf_head = (uart->istat.rxbuf_head + 1) % uart->fifo_len;
643
      if (!uart->istat.rxbuf_full++)
644
        {
645
          uart->regs.lsr |= ch >> 8;
646
          uart_check_rlsi (uart);
647
        }
648
    }
649
  uart_check_rdi (uart);
650
}
651
 
652
/* Called when a break sequence is about to start.  It stops receiveing
653
 * characters and schedules the uart_recv_break to send the break */
654
static void
655
uart_recv_break_start (void *dat)
656
{
657
  struct dev_16450 *uart = dat;
658
 
659
  uart->istat.receiveing = 0;
660
  uart->istat.recv_break = 1;
661
 
662
  SCHED_FIND_REMOVE (uart_recv_char, uart);
663
 
664
  if (uart->vapi_id && (uart->vapi_buf_head_ptr != uart->vapi_buf_tail_ptr))
665
    uart_vapi_cmd (uart);
666
 
667
  SCHED_ADD (uart_recv_break, uart,
668
             UART_BREAK_COUNT * uart->vapi.char_clks * UART_CLOCK_DIVIDER);
669
}
670
 
671
/* Stops sending breaks and starts receiveing characters */
672
static void
673
uart_recv_break_stop (void *dat)
674
{
675
  struct dev_16450 *uart = dat;
676
 
677
  uart->istat.recv_break = 0;
678
  SCHED_FIND_REMOVE (uart_recv_break, dat);
679
}
680
 
681
/* Receives a break */
682
static void
683
uart_recv_break (void *dat)
684
{
685
  struct dev_16450 *uart = dat;
686
  unsigned lsr = UART_LSR_BREAK | UART_LSR_RXERR | UART_LSR_RDRDY;
687
 
688
  uart_add_char (uart, lsr << 8);
689
}
690
 
691
/* Moves a character from the serial register to the RX FIFO */
692
static void
693
uart_recv_char (void *dat)
694
{
695
  struct dev_16450 *uart = dat;
696
  uint16_t char_to_add;
697
 
698
  /* Set unused character bits to zero and allow lsr register in fifo */
699
  char_to_add =
700
    uart->iregs.rxser & (((1 << ((uart->regs.lcr & 3) + 5)) - 1) | 0xff00);
701
 
702
  PRINTF ("%c", (char) char_to_add);
703
 
704
  if (uart->regs.mcr & UART_MCR_LOOP)
705
    {
706
      uart->iregs.rxser = uart->iregs.loopback;
707
      uart->istat.receiveing = 1;
708
      SCHED_ADD (uart_recv_char, uart, uart->char_clks * UART_CLOCK_DIVIDER);
709
    }
710
  else
711
    {
712
      uart->istat.receiveing = 0;
713
      uart_sched_recv_check (uart);
714
      if (uart->vapi_id
715
          && (uart->vapi_buf_head_ptr != uart->vapi_buf_tail_ptr))
716
        SCHED_ADD (uart_vapi_cmd, uart, 0);
717
    }
718
 
719
  uart_add_char (uart, char_to_add);
720
}
721
 
722
/* Checks if there is a character waiting to be received */
723
static void
724
uart_check_char (void *dat)
725
{
726
  struct dev_16450 *uart = dat;
727
  uint8_t buffer;
728
  int retval;
729
 
730
  /* Check if there is something waiting, and put it into rxser */
731
  retval = channel_read (uart->channel, (char *) &buffer, 1);
732
  if (retval > 0)
733
    {
734
      uart->iregs.rxser = buffer;
735
      uart->istat.receiveing = 1;
736
      SCHED_ADD (uart_recv_char, uart, uart->char_clks * UART_CLOCK_DIVIDER);
737
      return;
738
    }
739
 
740
  if (!retval)
741
    {
742
      SCHED_ADD (uart_check_char, uart,
743
                 UART_FGETC_SLOWDOWN * UART_CLOCK_DIVIDER);
744
      return;
745
    }
746
 
747
  if (retval < 0)
748
    perror (uart->channel_str);
749
}
750
 
751
static void
752
uart_sched_recv_check (struct dev_16450 *uart)
753
{
754
  if (!uart->vapi_id)
755
    SCHED_ADD (uart_check_char, uart,
756
               UART_FGETC_SLOWDOWN * UART_CLOCK_DIVIDER);
757
}
758
 
759
/*----------------------------------------------------[ UART I/O handling ]---*/
760
/* Set a specific UART register with value. */
761
static void
762
uart_write_byte (oraddr_t addr, uint8_t value, void *dat)
763
{
764
  struct dev_16450 *uart = dat;
765
 
766
  if (uart->regs.lcr & UART_LCR_DLAB)
767
    {
768
      switch (addr)
769
        {
770
        case UART_DLL:
771
          uart->regs.dll = value;
772
          uart->char_clks =
773
            char_clks (uart->regs.dll, uart->regs.dlh, uart->regs.lcr);
774
          return;
775
        case UART_DLH:
776
          uart->regs.dlh = value;
777
          return;
778
        }
779
    }
780
 
781
  switch (addr)
782
    {
783
    case UART_TXBUF:
784
      uart->regs.lsr &= ~UART_LSR_TXBUFE;
785
      if (uart->istat.txbuf_full < uart->fifo_len)
786
        {
787
          uart->regs.txbuf[uart->istat.txbuf_head] = value;
788
          uart->istat.txbuf_head =
789
            (uart->istat.txbuf_head + 1) % uart->fifo_len;
790
          if (!uart->istat.txbuf_full++ && (uart->regs.lsr & UART_LSR_TXSERE))
791
            SCHED_ADD (uart_tx_send, uart, 0);
792
        }
793
      else
794
        uart->regs.txbuf[uart->istat.txbuf_head] = value;
795
 
796
      uart_clear_int (uart, UART_IIR_THRI);
797
      break;
798
    case UART_FCR:
799
      uart->regs.fcr = value & UART_VALID_FCR;
800
      if ((uart->fifo_len == 1 && (value & UART_FCR_FIE))
801
          || (uart->fifo_len != 1 && !(value & UART_FCR_FIE)))
802
        value |= UART_FCR_RRXFI | UART_FCR_RTXFI;
803
      uart->fifo_len = (value & UART_FCR_FIE) ? 16 : 1;
804
      if (value & UART_FCR_RTXFI)
805
        {
806
          uart->istat.txbuf_head = uart->istat.txbuf_tail = 0;
807
          uart->istat.txbuf_full = 0;
808
          uart->regs.lsr |= UART_LSR_TXBUFE;
809
 
810
          /* For FIFO-mode only, THRE interrupt is set when THR and FIFO are empty
811
           */
812
          if (uart->fifo_len == 16)
813
            uart_int_thri (uart);
814
 
815
          SCHED_FIND_REMOVE (uart_tx_send, uart);
816
        }
817
      if (value & UART_FCR_RRXFI)
818
        {
819
          uart->istat.rxbuf_head = uart->istat.rxbuf_tail = 0;
820
          uart->istat.rxbuf_full = 0;
821
          uart->regs.lsr &= ~UART_LSR_RDRDY;
822
          uart_clear_int (uart, UART_IIR_RDI);
823
          uart_clear_int (uart, UART_IIR_CTI);
824
        }
825
      break;
826
    case UART_IER:
827
      uart->regs.ier = value & UART_VALID_IER;
828
      uart_next_int (uart);
829
      break;
830
    case UART_LCR:
831
      if ((uart->regs.lcr & UART_LCR_SBC) != (value & UART_LCR_SBC))
832
        {
833
          if ((value & UART_LCR_SBC) && !(uart->regs.lsr & UART_LSR_TXSERE))
834
            {
835
              /* Schedule a job to send the break char */
836
              SCHED_FIND_REMOVE (uart_char_clock, uart);
837
              SCHED_ADD (uart_send_break, uart, 0);
838
            }
839
          if (!(value & UART_LCR_SBC) && !(uart->regs.lsr & UART_LSR_TXSERE))
840
            {
841
              /* Schedule a job to start sending characters */
842
              SCHED_ADD (uart_tx_send, uart, 0);
843
              /* Remove the uart_send_break job just in case it has not run yet */
844
              SCHED_FIND_REMOVE (uart_char_clock, uart);
845
            }
846
        }
847
      uart->regs.lcr = value & UART_VALID_LCR;
848
      uart->char_clks =
849
        char_clks (uart->regs.dll, uart->regs.dlh, uart->regs.lcr);
850
      break;
851
    case UART_MCR:
852
      uart->regs.mcr = value & UART_VALID_MCR;
853
      uart_loopback (uart);
854
      break;
855
    case UART_SCR:
856
      uart->regs.scr = value;
857
      break;
858
    }
859
}
860
 
861
/* Read a specific UART register. */
862
static uint8_t
863
uart_read_byte (oraddr_t addr, void *dat)
864
{
865
  struct dev_16450 *uart = dat;
866
  uint8_t value = 0;
867
 
868
  if (uart->regs.lcr & UART_LCR_DLAB)
869
    {
870
      switch (addr)
871
        {
872
        case UART_DLL:
873
          value = uart->regs.dll;
874
          return value;
875
        case UART_DLH:
876
          value = uart->regs.dlh;
877
          return value;
878
        }
879
    }
880
 
881
  switch (addr)
882
    {
883
    case UART_RXBUF:
884
      if (uart->istat.rxbuf_full)
885
        {
886
          value = uart->regs.rxbuf[uart->istat.rxbuf_tail];
887
          uart->istat.rxbuf_tail =
888
            (uart->istat.rxbuf_tail + 1) % uart->fifo_len;
889
          uart->istat.rxbuf_full--;
890
        }
891
 
892
      uart_clear_int (uart, UART_IIR_RDI);
893
      uart_clear_int (uart, UART_IIR_CTI);
894
 
895
      if (uart->istat.rxbuf_full)
896
        {
897
          uart->regs.lsr |=
898
            UART_LSR_RDRDY | uart->regs.rxbuf[uart->istat.rxbuf_tail] >> 8;
899
          SCHED_ADD (uart_int_cti, uart,
900
                     uart->char_clks * UART_CHAR_TIMEOUT *
901
                     UART_CLOCK_DIVIDER);
902
          uart_check_rlsi (uart);
903
          uart_check_rdi (uart);
904
        }
905
      else
906
        {
907
          uart->regs.lsr &= ~UART_LSR_RDRDY;
908
        }
909
      break;
910
    case UART_IER:
911
      value = uart->regs.ier & UART_VALID_IER;
912
      break;
913
    case UART_IIR:
914
      value = (uart->regs.iir & UART_VALID_IIR) | 0xc0;
915
      /* Only clear the thri interrupt if it is the one we are repporting */
916
      if (uart->regs.iir == UART_IIR_THRI)
917
        uart_clear_int (uart, UART_IIR_THRI);
918
      break;
919
    case UART_LCR:
920
      value = uart->regs.lcr & UART_VALID_LCR;
921
      break;
922
    case UART_MCR:
923
      value = 0;
924
      break;
925
    case UART_LSR:
926
      value = uart->regs.lsr & UART_VALID_LSR;
927
      uart->regs.lsr &=
928
        ~(UART_LSR_OVRRUN | UART_LSR_BREAK | UART_LSR_PARITY
929
          | UART_LSR_FRAME | UART_LSR_RXERR);
930
      /* Clear potentially pending RLSI interrupt */
931
      uart_clear_int (uart, UART_IIR_RLSI);
932
      break;
933
    case UART_MSR:
934
      value = uart->regs.msr & UART_VALID_MSR;
935
      uart->regs.msr = 0;
936
      uart_clear_int (uart, UART_IIR_MSI);
937
      uart_loopback (uart);
938
      break;
939
    case UART_SCR:
940
      value = uart->regs.scr;
941
      break;
942
    }
943
  return value;
944
}
945
 
946
/*--------------------------------------------------------[ VAPI handling ]---*/
947
/* Decodes the read vapi command */
948
static void
949
uart_vapi_cmd (void *dat)
950
{
951
  struct dev_16450 *uart = dat;
952
  int received = 0;
953
 
954
  while (!received)
955
    {
956
      if (uart->vapi_buf_head_ptr != uart->vapi_buf_tail_ptr)
957
        {
958
          unsigned long data = uart->vapi_buf[uart->vapi_buf_tail_ptr];
959
          uart->vapi_buf_tail_ptr =
960
            (uart->vapi_buf_tail_ptr + 1) % UART_VAPI_BUF_LEN;
961
          switch (data >> 24)
962
            {
963
            case 0x00:
964
              uart->vapi.lcr = (data >> 8) & 0xff;
965
              /* Put data into rx fifo */
966
              uart->iregs.rxser = data & 0xff;
967
              uart->vapi.char_clks =
968
                char_clks (uart->vapi.dll, uart->vapi.dlh, uart->vapi.lcr);
969
              if ((uart->vapi.lcr & ~UART_LCR_SBC) !=
970
                  (uart->regs.lcr & ~UART_LCR_SBC)
971
                  || uart->vapi.char_clks != uart->char_clks
972
                  || uart->vapi.skew < -MAX_SKEW
973
                  || uart->vapi.skew > MAX_SKEW)
974
                {
975
                  if ((uart->vapi.lcr & ~UART_LCR_SBC) !=
976
                      (uart->regs.lcr & ~UART_LCR_SBC))
977
                    fprintf (stderr, "Warning: Unmatched VAPI (%02" PRIx8
978
                             ") and uart (%02" PRIx8
979
                             ") modes.\n", uart->vapi.lcr & ~UART_LCR_SBC,
980
                             uart->regs.lcr & ~UART_LCR_SBC);
981
                  if (uart->vapi.char_clks != uart->char_clks)
982
                    {
983
                      fprintf (stderr, "Warning: Unmatched VAPI (%li) and "
984
                               "UART (%li) char clocks.\n",
985
                               uart->vapi.char_clks, uart->char_clks);
986
                      fprintf (stderr, "VAPI: lcr: %02" PRIx8 ", dll: %02"
987
                               PRIx8 ", dlh: %02" PRIx8 "\n", uart->vapi.lcr,
988
                               uart->vapi.dll, uart->vapi.dlh);
989
                      fprintf (stderr, "UART: lcr: %02" PRIx8 ", dll: %02"
990
                               PRIx8 ", dlh: %02" PRIx8 "\n", uart->regs.lcr,
991
                               uart->regs.dll, uart->vapi.dlh);
992
                    }
993
                  if (uart->vapi.skew < -MAX_SKEW
994
                      || uart->vapi.skew > MAX_SKEW)
995
                    {
996
                      fprintf(stderr, "VAPI skew is beyond max: %i\n",
997
                              uart->vapi.skew);
998
                    }
999
                  /* Set error bits */
1000
                  uart->iregs.rxser |= (UART_LSR_FRAME | UART_LSR_RXERR) << 8;
1001
                  if (uart->regs.lcr & UART_LCR_PARITY)
1002
                    uart->iregs.rxser |= UART_LSR_PARITY << 8;
1003
                }
1004
              if (!uart->istat.recv_break)
1005
                {
1006
                  uart->istat.receiveing = 1;
1007
                  SCHED_ADD (uart_recv_char, uart,
1008
                             uart->char_clks * UART_CLOCK_DIVIDER);
1009
                }
1010
              received = 1;
1011
              break;
1012
            case 0x01:
1013
              uart->vapi.dll = (data >> 0) & 0xff;
1014
              uart->vapi.dlh = (data >> 8) & 0xff;
1015
              break;
1016
            case 0x02:
1017
              uart->vapi.lcr = (data >> 8) & 0xff;
1018
              break;
1019
            case 0x03:
1020
              uart->vapi.skew = (signed short) (data & 0xffff);
1021
              break;
1022
            case 0x04:
1023
              if ((data >> 16) & 1)
1024
                {
1025
                  /* If data & 0xffff is 0 then set the break imediatly and handle the
1026
                   * following commands as appropriate */
1027
                  if (!(data & 0xffff))
1028
                    uart_recv_break_start (uart);
1029
                  else
1030
                    /* Schedule a job to start sending breaks */
1031
                    SCHED_ADD (uart_recv_break_start, uart,
1032
                               (data & 0xffff) * UART_CLOCK_DIVIDER);
1033
                }
1034
              else
1035
                {
1036
                  /* If data & 0xffff is 0 then release the break imediatly and handle
1037
                   * the following commands as appropriate */
1038
                  if (!(data & 0xffff))
1039
                    uart_recv_break_stop (uart);
1040
                  else
1041
                    /* Schedule a job to stop sending breaks */
1042
                    SCHED_ADD (uart_recv_break_stop, uart,
1043
                               (data & 0xffff) * UART_CLOCK_DIVIDER);
1044
                }
1045
              break;
1046
            default:
1047
              fprintf (stderr, "WARNING: Invalid vapi command %02lx\n",
1048
                       data >> 24);
1049
              break;
1050
            }
1051
        }
1052
      else
1053
        break;
1054
    }
1055
}
1056
 
1057
/* Function that handles incoming VAPI data.  */
1058
static void
1059
uart_vapi_read (unsigned long id, unsigned long data, void *dat)
1060
{
1061
  struct dev_16450 *uart = dat;
1062
  uart->vapi_buf[uart->vapi_buf_head_ptr] = data;
1063
  uart->vapi_buf_head_ptr = (uart->vapi_buf_head_ptr + 1) % UART_VAPI_BUF_LEN;
1064
  if (uart->vapi_buf_tail_ptr == uart->vapi_buf_head_ptr)
1065
    {
1066
      fprintf (stderr, "FATAL: uart VAPI buffer to small.\n");
1067
      exit (1);
1068
    }
1069
  if (!uart->istat.receiveing)
1070
    uart_vapi_cmd (uart);
1071
}
1072
 
1073
/*--------------------------------------------------------[ Sim callbacks ]---*/
1074
/* Reset.  It initializes all registers of all UART devices to zero values,
1075
 * (re)opens all RX/TX file streams and places devices in memory address
1076
 * space.  */
1077
void
1078
uart_reset (void *dat)
1079
{
1080
  struct dev_16450 *uart = dat;
1081
 
1082
  if (uart->vapi_id)
1083
    {
1084
      vapi_install_handler (uart->vapi_id, uart_vapi_read, dat);
1085
    }
1086
  else if (uart->channel_str && uart->channel_str[0])
1087
    {                           /* Try to create stream. */
1088
      if (uart->channel)
1089
        channel_close (uart->channel);
1090
      else
1091
        uart->channel = channel_init (uart->channel_str);
1092
      if (channel_open (uart->channel) < 0)
1093
        {
1094
          fprintf (stderr, "Warning: problem with channel \"%s\" detected.\n",
1095
                   uart->channel_str);
1096
        }
1097
      else if (config.sim.verbose)
1098
        PRINTF ("UART at 0x%" PRIxADDR "\n", uart->baseaddr);
1099
    }
1100
  else
1101
    {
1102
      fprintf (stderr, "Warning: UART at %" PRIxADDR
1103
               " has no vapi nor channel specified\n", uart->baseaddr);
1104
    }
1105
 
1106
  if (uart->uart16550)
1107
    uart->fifo_len = 16;
1108
  else
1109
    uart->fifo_len = 1;
1110
 
1111
  uart->istat.rxbuf_head = uart->istat.rxbuf_tail = 0;
1112
  uart->istat.txbuf_head = uart->istat.txbuf_tail = 0;
1113
 
1114
  uart->istat.txbuf_full = uart->istat.rxbuf_full = 0;
1115
 
1116
  uart->char_clks = 0;
1117
 
1118
  uart->iregs.txser = 0;
1119
  uart->iregs.rxser = 0;
1120
  uart->iregs.loopback = 0;
1121
  uart->istat.receiveing = 0;
1122
  uart->istat.recv_break = 0;
1123
  uart->istat.ints = 0;
1124
 
1125
  memset (uart->regs.txbuf, 0, sizeof (uart->regs.txbuf));
1126
  memset (uart->regs.rxbuf, 0, sizeof (uart->regs.rxbuf));
1127
 
1128
  uart->regs.dll = 0;
1129
  uart->regs.dlh = 0;
1130
  uart->regs.ier = 0;
1131
  uart->regs.iir = UART_IIR_NO_INT;
1132
  uart->regs.fcr = 0;
1133
  uart->regs.lcr = UART_LCR_RESET;
1134
  uart->regs.mcr = 0;
1135
  uart->regs.lsr = UART_LSR_TXBUFE | UART_LSR_TXSERE;
1136
  uart->regs.msr = 0;
1137
  uart->regs.scr = 0;
1138
 
1139
  uart->vapi.skew = 0;
1140
  uart->vapi.lcr = 0;
1141
  uart->vapi.dll = 0;
1142
  uart->vapi.char_clks = 0;
1143
 
1144
  uart->vapi_buf_head_ptr = 0;
1145
  uart->vapi_buf_tail_ptr = 0;
1146
  memset (uart->vapi_buf, 0, sizeof (uart->vapi_buf));
1147
 
1148
  uart_sched_recv_check (uart);
1149
}
1150
 
1151
/* Print register values on stdout. */
1152
void
1153
uart_status (void *dat)
1154
{
1155
  struct dev_16450 *uart = dat;
1156
  int i;
1157
 
1158
  PRINTF ("\nUART visible registers at 0x%" PRIxADDR ":\n", uart->baseaddr);
1159
  PRINTF ("RXBUF: ");
1160
  for (i = uart->istat.rxbuf_head; i != uart->istat.rxbuf_tail;
1161
       i = (i + 1) % uart->fifo_len)
1162
    PRINTF (" %.2x", uart->regs.rxbuf[i]);
1163
  PRINTF ("TXBUF: ");
1164
  for (i = uart->istat.txbuf_head; i != uart->istat.txbuf_tail;
1165
       i = (i + 1) % uart->fifo_len)
1166
    PRINTF (" %.2x", uart->regs.txbuf[i]);
1167
  PRINTF ("\n");
1168
  PRINTF ("DLL  : %.2x  DLH  : %.2x\n", uart->regs.dll, uart->regs.dlh);
1169
  PRINTF ("IER  : %.2x  IIR  : %.2x\n", uart->regs.ier, uart->regs.iir);
1170
  PRINTF ("LCR  : %.2x  MCR  : %.2x\n", uart->regs.lcr, uart->regs.mcr);
1171
  PRINTF ("LSR  : %.2x  MSR  : %.2x\n", uart->regs.lsr, uart->regs.msr);
1172
  PRINTF ("SCR  : %.2x\n", uart->regs.scr);
1173
 
1174
  PRINTF ("\nInternal registers (sim debug):\n");
1175
  PRINTF ("RXSER: %.2" PRIx16 "  TXSER: %.2" PRIx8 "\n", uart->iregs.rxser,
1176
          uart->iregs.txser);
1177
 
1178
  PRINTF ("\nInternal status (sim debug):\n");
1179
  PRINTF ("char_clks: %ld\n", uart->char_clks);
1180
  PRINTF ("rxbuf_full: %d  txbuf_full: %d\n", uart->istat.rxbuf_full,
1181
          uart->istat.txbuf_full);
1182
  PRINTF ("Using IRQ%i\n", uart->irq);
1183
  if (uart->vapi_id)
1184
    PRINTF ("Connected to vapi ID=%lx\n\n", uart->vapi_id);
1185
  /* TODO: replace by a channel_status
1186
     else
1187
     PRINTF("RX fs: %p  TX fs: %p\n\n", uart->rxfs, uart->txfs);
1188
   */
1189
}
1190
 
1191
/*---------------------------------------------------[ UART configuration ]---*/
1192
static void
1193
uart_baseaddr (union param_val val, void *dat)
1194
{
1195
  struct dev_16450 *uart = dat;
1196
  uart->baseaddr = val.addr_val;
1197
}
1198
 
1199
static void
1200
uart_jitter (union param_val val, void *dat)
1201
{
1202
  struct dev_16450 *uart = dat;
1203
  uart->jitter = val.int_val;
1204
}
1205
 
1206
static void
1207
uart_irq (union param_val val, void *dat)
1208
{
1209
  struct dev_16450 *uart = dat;
1210
  uart->irq = val.int_val;
1211
}
1212
 
1213
static void
1214
uart_16550 (union param_val val, void *dat)
1215
{
1216
  struct dev_16450 *uart = dat;
1217
  uart->uart16550 = val.int_val;
1218
}
1219
 
1220
/*---------------------------------------------------------------------------*/
1221
/*!Set the channel description
1222
 
1223
   Free any existing string.
1224
 
1225
   @param[in] val  The value to use
1226
   @param[in] dat  The config data structure                                 */
1227
/*---------------------------------------------------------------------------*/
1228
static void
1229
uart_channel (union param_val  val,
1230
              void            *dat)
1231
{
1232
  struct dev_16450 *uart = dat;
1233
 
1234
  if (NULL != uart->channel_str)
1235
    {
1236
      free (uart->channel_str);
1237
      uart->channel_str = NULL;
1238
    }
1239
 
1240
  if (!(uart->channel_str = strdup (val.str_val)))
1241
    {
1242
      fprintf (stderr, "Peripheral 16450: Run out of memory\n");
1243
      exit (-1);
1244
    }
1245
 
1246
}       /* uart_channel() */
1247
 
1248
 
1249
static void
1250
uart_newway (union param_val val, void *dat)
1251
{
1252
  fprintf (stderr, "Warning: txfile and rxfile now obsolete and ignored. "
1253
           "Use 'channel = \"file:rxfile,txfile\"'.");
1254
}
1255
 
1256
static void
1257
uart_vapi_id (union param_val val, void *dat)
1258
{
1259
  struct dev_16450 *uart = dat;
1260
  uart->vapi_id = val.int_val;
1261
}
1262
 
1263
static void
1264
uart_enabled (union param_val val, void *dat)
1265
{
1266
  struct dev_16450 *uart = dat;
1267
  uart->enabled = val.int_val;
1268
}
1269
 
1270
 
1271
/*---------------------------------------------------------------------------*/
1272
/*!Initialize a new UART configuration
1273
 
1274
   ALL parameters are set explicitly to default values.                      */
1275
/*---------------------------------------------------------------------------*/
1276
static void *
1277
uart_sec_start ()
1278
{
1279
  struct dev_16450 *new = malloc (sizeof (struct dev_16450));
1280
 
1281
  if (!new)
1282
    {
1283
      fprintf (stderr, "Peripheral 16450: Run out of memory\n");
1284
      exit (-1);
1285
    }
1286
 
1287
  new->enabled = 1;
1288
  new->baseaddr = 0;
1289
  new->irq = 0;
1290
  new->uart16550 = 0;
1291
  new->jitter = 0;
1292
  new->channel_str = strdup ("xterm:");
1293
  new->vapi_id = 0;
1294
 
1295
  new->channel = NULL;
1296
 
1297
  return new;
1298
 
1299
}       /* uart_sec_start() */
1300
 
1301
 
1302
static void
1303
uart_sec_end (void *dat)
1304
{
1305
  struct dev_16450 *uart = dat;
1306
  struct mem_ops ops;
1307
 
1308
  if (!uart->enabled)
1309
    {
1310
      free (dat);
1311
      return;
1312
    }
1313
 
1314
  memset (&ops, 0, sizeof (struct mem_ops));
1315
 
1316
  ops.readfunc8 = uart_read_byte;
1317
  ops.writefunc8 = uart_write_byte;
1318
  ops.read_dat8 = dat;
1319
  ops.write_dat8 = dat;
1320
 
1321
  /* FIXME: What should these be? */
1322
  ops.delayr = 2;
1323
  ops.delayw = 2;
1324
 
1325
  reg_mem_area (uart->baseaddr, UART_ADDR_SPACE, 0, &ops);
1326
 
1327
  reg_sim_reset (uart_reset, dat);
1328
  reg_sim_stat (uart_status, dat);
1329
}
1330
 
1331
void
1332
reg_uart_sec (void)
1333
{
1334
  struct config_section *sec = reg_config_sec ("uart", uart_sec_start,
1335
                                               uart_sec_end);
1336
 
1337 224 jeremybenn
  reg_config_param (sec, "enabled",  PARAMT_INT, uart_enabled);
1338
  reg_config_param (sec, "baseaddr", PARAMT_ADDR, uart_baseaddr);
1339
  reg_config_param (sec, "irq",      PARAMT_INT, uart_irq);
1340
  reg_config_param (sec, "16550",    PARAMT_INT, uart_16550);
1341
  reg_config_param (sec, "jitter",   PARAMT_INT, uart_jitter);
1342
  reg_config_param (sec, "channel",  PARAMT_STR, uart_channel);
1343
  reg_config_param (sec, "txfile",   PARAMT_STR, uart_newway);
1344
  reg_config_param (sec, "rxfile",   PARAMT_STR, uart_newway);
1345
  reg_config_param (sec, "vapi_id",  PARAMT_INT, uart_vapi_id);
1346 19 jeremybenn
}

powered by: WebSVN 2.1.0

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