OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_68/] [or1ksim/] [peripheral/] [16450.c] - Blame information for rev 385

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

Line No. Rev Author Line
1 31 lampret
/* 16450.c -- Simulation of 8250/16450 serial UART
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* This is functional simulation of 8250/16450 UARTs. Since we RX/TX data
21
   via file streams, we can't simulate modem control lines coming from the
22
   DCE and similar details of communication with the DCE.
23
 
24
   This simulated UART device is intended for basic UART device driver
25
   verification. From device driver perspective this device looks like a
26
   regular UART but never reports and modem control lines changes (the
27
   only DCE responses are incoming characters from the file stream).
28
*/
29
 
30
#include <stdlib.h>
31
#include <stdio.h>
32
#include <string.h>
33
 
34 235 erez
#include "abstract.h"
35 31 lampret
#include "16450.h"
36
#include "sim-config.h"
37 102 lampret
#include "pic.h"
38 336 markom
#include "vapi.h"
39 31 lampret
 
40
static struct dev_16450 uarts[NR_UARTS];
41 221 markom
static int thre_int;
42 31 lampret
 
43
/* Number of clock cycles (one clock cycle is one call to the uart_clock())
44
   before a single character is transmitted or received. */
45 355 markom
static unsigned long char_clks(int dll, int dlh, int lcr)
46 31 lampret
{
47 355 markom
  float bauds_per_char = 0;
48
  unsigned long char_clks = (dlh << 8) + dll;
49
 
50
  if (lcr & UART_LCR_PARITY)
51
    bauds_per_char = bauds_per_char + 1.;
52 31 lampret
 
53 355 markom
  /* stop bits 1 or two */
54
  if (lcr & UART_LCR_STOP)
55
    bauds_per_char = bauds_per_char + 2.;
56
  else
57
    if ((lcr & 0x3) != 0)
58
      bauds_per_char = bauds_per_char + 1.;
59
    else
60
      bauds_per_char = bauds_per_char + 1.5;
61
 
62
  bauds_per_char = bauds_per_char + (5. + (lcr & 0x3));
63
 
64
  return char_clks * bauds_per_char;
65 31 lampret
}
66
 
67
/* Set a specific UART register with value. */
68 238 erez
void uart_write_byte(unsigned long addr, unsigned long value)
69 31 lampret
{
70 355 markom
  int chipsel;
71
 
72
  debug(4, "uart_write_byte(%x,%02x)\n", addr, (unsigned)value);
73 341 markom
 
74 355 markom
  for(chipsel = 0; chipsel < NR_UARTS; chipsel++)
75
    if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr)
76
      break;
77
  if (chipsel >= NR_UARTS) return;
78 31 lampret
 
79 355 markom
  if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
80
    switch (addr % UART_ADDR_SPACE) {
81
      case UART_DLL:
82
        uarts[chipsel].regs.dll = value;
83
        uarts[chipsel].char_clks = char_clks(uarts[chipsel].regs.dll, uarts[chipsel].regs.dlh, uarts[chipsel].regs.lcr);
84
        return;
85
      case UART_DLH:
86
        uarts[chipsel].regs.dlh = value;
87
        return;
88
    }
89
  }
90
 
91
  switch (addr % UART_ADDR_SPACE) {
92
    case UART_TXBUF:
93
      if (uarts[chipsel].istat.txbuf_full < uarts[chipsel].fifo_len) {
94
        uarts[chipsel].istat.txbuf_full++;
95
        uarts[chipsel].regs.txbuf[uarts[chipsel].istat.txbuf_head] = value;
96
        uarts[chipsel].istat.txbuf_head = (uarts[chipsel].istat.txbuf_head + 1) % uarts[chipsel].fifo_len;
97
      } else
98
        uarts[chipsel].regs.txbuf[uarts[chipsel].istat.txbuf_head] = value;
99 341 markom
 
100 355 markom
      if (uarts[chipsel].istat.txbuf_full < uarts[chipsel].fifo_len)
101
        uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
102
      else
103
        uarts[chipsel].regs.lsr |= UART_LSR_TXBUFE;
104
      uarts[chipsel].regs.lsr &= ~UART_LSR_TXSERE;
105 341 markom
 
106 355 markom
      uarts[chipsel].istat.thre_int = 0;
107
      break;
108
    case UART_IER:
109
      uarts[chipsel].regs.ier = value & UART_VALID_IER;
110
      break;
111
    case UART_LCR:
112
      uarts[chipsel].regs.lcr = value & UART_VALID_LCR;
113
      break;
114
    case UART_MCR:
115
      uarts[chipsel].regs.mcr = value & UART_VALID_MCR;
116
      break;
117
    case UART_SCR:
118
      uarts[chipsel].regs.scr = value;
119
      break;
120
    default:
121
      debug(1, "write out of range (addr %x)\n", addr);
122
  }
123 31 lampret
}
124
 
125
/* Read a specific UART register. */
126 238 erez
unsigned long uart_read_byte(unsigned long addr)
127 31 lampret
{
128 355 markom
  unsigned char value = 0;
129
  int chipsel;
130
 
131
  debug(4, "uart_read_byte(%x)", addr);
132
 
133
  for(chipsel = 0; chipsel < NR_UARTS; chipsel++)
134
    if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr)
135
      break;
136 31 lampret
 
137 355 markom
  if (chipsel >= NR_UARTS)
138
    return 0;
139 344 markom
 
140 355 markom
  if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
141
    switch (addr % UART_ADDR_SPACE) {
142
      case UART_DLL:
143
        value = uarts[chipsel].regs.dll;
144
        debug(4, "= %x\n", value);
145
        return value;
146
      case UART_DLH:
147
        value = uarts[chipsel].regs.dlh;
148
        debug(4, "= %x\n", value);
149
        return value;
150
    }
151
  }
152
 
153
  switch (addr % UART_ADDR_SPACE) {
154
    case UART_RXBUF:
155
      if (uarts[chipsel].istat.rxbuf_full) {
156
        value = uarts[chipsel].regs.rxbuf[uarts[chipsel].istat.rxbuf_tail];
157
        uarts[chipsel].istat.rxbuf_tail = (uarts[chipsel].istat.rxbuf_tail + 1) % uarts[chipsel].fifo_len;
158
        uarts[chipsel].istat.rxbuf_full--;
159
      }
160
 
161
      if (uarts[chipsel].istat.rxbuf_full)
162
        uarts[chipsel].regs.lsr |= UART_LSR_RDRDY;
163
      else
164
        uarts[chipsel].regs.lsr &= ~UART_LSR_RDRDY;
165
      break;
166
    case UART_IER:
167
      value = uarts[chipsel].regs.ier & UART_VALID_IER;
168
      break;
169
    case UART_IIR:
170
      value = (uarts[chipsel].regs.iir & UART_VALID_IIR) | 0xc0;
171
      uarts[chipsel].istat.thre_int = 0;
172
      break;
173
    case UART_LCR:
174
      value = uarts[chipsel].regs.lcr & UART_VALID_LCR;
175
      break;
176
    case UART_MCR:
177
      value = 0;
178
      break;
179
    case UART_LSR:
180
      value = uarts[chipsel].regs.lsr & UART_VALID_LSR;
181
      uarts[chipsel].regs.lsr &=
182
        ~(UART_LSR_OVRRUN | UART_LSR_PARITY
183
         | UART_LSR_FRAME | UART_LSR_BREAK);
184
      break;
185
    case UART_MSR:
186
      value = uarts[chipsel].regs.msr & UART_VALID_MSR;
187
      uarts[chipsel].regs.msr = 0;
188
      break;
189
    case UART_SCR:
190
      value = uarts[chipsel].regs.scr;
191
      break;
192
    default:
193
      debug(1, "read out of range (addr %x)\n", addr);
194
  }
195
  debug(4, " = %x\n", value);
196
  return value;
197 31 lampret
}
198
 
199 336 markom
/* Function that handles incoming VAPI data.  */
200
void uart_vapi_read (unsigned long id, unsigned long data)
201
{
202 341 markom
  int uart;
203 344 markom
  debug(4, "UART: id %08x, data %08x\n", id, data);
204 341 markom
  uart = id & VAPI_DEVICE_ID;
205
  uarts[uart].vapi_buf[uarts[uart].vapi_buf_head_ptr] = data;
206
  uarts[uart].vapi_buf_head_ptr = (uarts[uart].vapi_buf_head_ptr + 1) % UART_RX_BUF;
207
  if (uarts[uart].vapi_buf_tail_ptr == uarts[uart].vapi_buf_head_ptr) {
208
    fprintf (stderr, "FATAL: uart VAPI buffer to small.\n");
209
    exit (1);
210
  }
211
}
212 336 markom
 
213 341 markom
/* Reset.  It initializes all registers of all UART devices to zero values,
214 31 lampret
   (re)opens all RX/TX file streams and places devices in memory address
215 341 markom
   space.  */
216 31 lampret
void uart_reset()
217
{
218 355 markom
  int i;
219
 
220 261 markom
  if (!config.uarts_enabled)
221
    config.nuarts = 0;
222 341 markom
 
223
  if (config.sim.verbose && config.nuarts)
224
    printf("Resetting %u UART(s).\n", config.nuarts);
225
 
226 355 markom
  memset(uarts, 0, sizeof(uarts));
227 261 markom
 
228 355 markom
  for(i = 0; i < config.nuarts; i++) {
229 341 markom
    if (config.uarts[i].vapi_id) {
230
      if ((config.uarts[i].vapi_id & VAPI_DEVICE_ID) != i) {
231
        fprintf (stderr, "ERROR: Wrong vapi_id (0x%x) for uart %i, last byte is required to be %02x; ignoring.\n", config.uarts[i].vapi_id, i, i);
232
        config.uarts[i].vapi_id = 0;
233
        uarts[i].txfs = 0;
234
      } else {
235 355 markom
        vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read);
236
        register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
237
      }
238
    } else if (config.uarts[i].txfile) { /* MM: Try to create stream.  */
239
      if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
240
        && !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
241 361 markom
        debug (0, "WARNING: UART%d has problems with RX file stream.\n", i);
242 355 markom
        continue;
243
      }
244
      uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
245
      if (uarts[i].rxfs && uarts[i].txfs && config.sim.verbose) {
246
        printf("UART%d at 0x%.8x uses ", i, config.uarts[i].baseaddr);
247
        printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile);
248
      } else
249 361 markom
        debug (1, "WARNING: UART%d has problems with TX file stream.\n", i);
250 355 markom
      register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
251 341 markom
    }
252
 
253
    if (config.uarts[i].uart16550)
254
      uarts[i].fifo_len = 16;
255
    else
256
      uarts[i].fifo_len = 1;
257 344 markom
 
258 341 markom
    uarts[i].istat.rxbuf_head = uarts[i].istat.rxbuf_tail = 0;
259
    uarts[i].istat.txbuf_head = uarts[i].istat.txbuf_tail = 0;
260 344 markom
 
261
    uarts[i].regs.lcr = UART_LCR_RESET;
262 385 markom
    uarts[i].vapi.cur_break = uarts[i].vapi.cur_break_cnt = uarts[i].vapi.next_break = 0;
263
    uarts[i].vapi.next_break_cnt = -1;
264 336 markom
  }
265 31 lampret
}
266 261 markom
 
267 31 lampret
/* Simulation hook. Must be called every clock cycle to simulate all UART
268
   devices. It does internal functional UART simulation. */
269
void uart_clock()
270
{
271 355 markom
  int i, retval;
272 341 markom
 
273 355 markom
  for(i = 0; i < config.nuarts; i++) {
274 341 markom
    /* If VAPI is not selected, UART communicates with two file streams;
275
       if VAPI is selected, we use VAPI streams.  */
276
 
277
    /* if txfs is corrupted, skip this uart. */
278 355 markom
    if (!config.uarts[i].vapi_id && !uarts[i].txfs) continue;
279 385 markom
 
280
    if (uarts[i].vapi.next_break_cnt >= 0)
281
      if (--uarts[i].vapi.next_break_cnt < 0)
282
        uarts[i].vapi.cur_break = uarts[i].vapi.next_break;
283
 
284
    /***************** Transmit *****************/
285 355 markom
    if (!uarts[i].istat.txser_full) {
286
      uarts[i].regs.lsr |= UART_LSR_TXBUFE;
287
      if (uarts[i].istat.txbuf_full) {
288
        uarts[i].iregs.txser = uarts[i].regs.txbuf[uarts[i].istat.txbuf_tail];
289
        uarts[i].istat.txbuf_tail = (uarts[i].istat.txbuf_tail + 1) % uarts[i].fifo_len;
290
        uarts[i].istat.txser_full = 1;
291
        uarts[i].istat.txbuf_full--;
292
        uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
293
        uarts[i].istat.thre_int = 1;
294
      } else
295
        uarts[i].regs.lsr |= UART_LSR_TXSERE;
296
    } else if (uarts[i].char_clks >= uarts[i].istat.txser_clks++) {
297
      debug(4, "TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
298
      if (uarts[i].regs.mcr & UART_MCR_LOOP)
299
        uarts[i].iregs.loopback = uarts[i].iregs.txser;
300
      else {
301
        /* Send to either VAPI or to file */
302
        if (config.uarts[i].vapi_id) {
303
          int par, pe, fe, nbits = (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5;
304 361 markom
          int j, data;
305 355 markom
          unsigned long packet = 0;
306 361 markom
 
307 355 markom
          /* Encode a packet */
308 361 markom
          packet = uarts[i].iregs.txser & ((1 << nbits) - 1);
309 31 lampret
 
310 355 markom
          /* Calculate parity */
311 361 markom
          for (j = 0, par = 0; j < nbits; j++)
312
            par ^= (packet >> j) & 1;
313 355 markom
 
314
          if (uarts[i].regs.lcr & UART_LCR_PARITY) {
315
            if (uarts[i].regs.lcr & UART_LCR_SPAR) {
316
              packet |= 1 << nbits;
317
            } else {
318
              if (uarts[i].regs.lcr & UART_LCR_EPAR)
319
                packet |= par << nbits;
320
              else
321
                packet |= (par ^ 1) << nbits;
322
            }
323
            nbits++;
324
          }
325
          packet |= 1 << (nbits++);
326
          if (uarts[i].regs.lcr & UART_LCR_STOP)
327
            packet |= 1 << (nbits++);
328
 
329
          /* Decode a packet */
330
          nbits = (uarts[i].vapi.lcr & UART_LCR_WLEN8) + 5;
331
          data = packet & ((1 << nbits) - 1);
332
 
333
          /* Calculate parity, including parity bit */
334 361 markom
          for (j = 0, par = 0; j < nbits + 1; j++)
335
            par ^= (packet >> j) & 1;
336 355 markom
 
337
          if (uarts[i].vapi.lcr & UART_LCR_PARITY) {
338
            if (uarts[i].vapi.lcr & UART_LCR_SPAR) {
339
              pe = !((packet >> nbits) & 1);
340
            } else {
341
              if (uarts[i].vapi.lcr & UART_LCR_EPAR)
342
                pe = par != 0;
343
              else
344
                pe = par != 1;
345
            }
346
            nbits++;
347
          } else
348
            pe = 0;
349
 
350 361 markom
          fe = ((packet >> (nbits++)) & 1) ^ 1;
351 355 markom
          if (uarts[i].vapi.lcr & UART_LCR_STOP)
352
            fe |= ((packet >> (nbits++)) & 1) ^ 1;
353
 
354 361 markom
          debug (4, "vapi_send (%08x, %08x)\n", config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
355 355 markom
          vapi_send (config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
356
        } else {
357
          fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs);
358
          fflush(uarts[i].txfs);
359
        }
360 341 markom
      }
361 355 markom
      uarts[i].istat.txser_full = 0;
362
      uarts[i].istat.txser_clks = 0;
363
    }
364 341 markom
 
365 385 markom
    /***************** Receive *****************/
366
 
367
    /* Is there a break? */
368
    if (uarts[i].vapi.cur_break)
369
      uarts[i].vapi.cur_break_cnt++;
370
    if (uarts[i].vapi.cur_break_cnt > MAX_BREAK_COUNT * uarts[i].istat.rxser_clks) {
371
      if (uarts[i].vapi.cur_break)
372
        uarts[i].regs.lsr |= UART_LSR_BREAK;
373
      else
374
        uarts[i].vapi.cur_break_cnt = 0;
375
    } else {
376
      if (uarts[i].istat.rxser_full) {
377
        if (uarts[i].char_clks >= uarts[i].istat.rxser_clks++) {
378
          debug(4, "Receiving via UART%d...\n", i);
379
          uarts[i].istat.rxser_full = 0;
380
          uarts[i].istat.rxser_clks = 0;
381 355 markom
 
382 385 markom
          if (++uarts[i].istat.rxbuf_full > uarts[i].fifo_len)
383
            uarts[i].regs.lsr |= UART_LSR_OVRRUN;
384
          else {
385
            uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_head] = uarts[i].iregs.rxser & 0xFF;
386
            uarts[i].istat.rxbuf_head = (uarts[i].istat.rxbuf_head + 1) % uarts[i].fifo_len;
387
            uarts[i].istat.rxbuf_full++;
388
          }
389
          uarts[i].regs.lsr |= UART_LSR_RDRDY;
390 355 markom
        }
391
      }
392
    }
393
 
394
    /* Check if there is something waiting, and put it into rxser */
395
    if (uarts[i].regs.mcr & UART_MCR_LOOP) {
396
      uarts[i].iregs.rxser = uarts[i].iregs.loopback;
397
      uarts[i].istat.rxser_full = 1;
398
    } else {
399
      if (!config.uarts[i].vapi_id) {
400
        if((retval = fgetc(uarts[i].rxfs)) != EOF)
401
          uarts[i].iregs.rxser = (char)retval;
402 385 markom
        uarts[i].istat.rxser_full = 1;
403 355 markom
      } else { /* VAPI */
404
        int received = 0;
405 361 markom
        /* do not handle commands while receiving */
406
        if (uarts[i].istat.rxser_full)
407
          break;
408 355 markom
        while (!received) {
409
          if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
410
            unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
411
            uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % uarts[i].fifo_len;
412
            switch (data >> 24) {
413
              case 0x00:
414
                uarts[i].vapi.lcr = (data >> 8) & 0xff;
415
                /* Put data into rx fifo */
416
                uarts[i].vapi.char_clks = char_clks (uarts[i].vapi.dll, uarts[i].vapi.dlh, uarts[i].vapi.lcr);
417
                if (uarts[i].vapi.lcr != uarts[i].regs.lcr || uarts[i].vapi.char_clks != uarts[i].char_clks
418
                 || uarts[i].vapi.skew < -MAX_SKEW || uarts[i].vapi.skew > MAX_SKEW) {
419 361 markom
                  debug (3, "WARNING: unmatched VAPI and uart modes.\n");
420 355 markom
                  /* Set error bits */
421
                  uarts[i].regs.lsr |= UART_LSR_PARITY | UART_LSR_FRAME;
422
                  break;
423
                } else {
424
                  uarts[i].iregs.rxser = data & 0xff;
425
                  uarts[i].istat.rxser_full = 1;
426
                }
427
                received = 1;
428
                break;
429
              case 0x01:
430
                uarts[i].vapi.dll = (data >> 0) & 0xff;
431
                uarts[i].vapi.dlh = (data >> 8) & 0xff;
432
                break;
433
              case 0x02:
434 361 markom
                uarts[i].vapi.lcr = (data >> 8) & 0xff;
435 355 markom
                break;
436
              case 0x03:
437
                uarts[i].vapi.skew = (signed short)(data & 0xffff);
438
                break;
439 385 markom
              case 0x04:
440
                uarts[i].vapi.next_break_cnt = data & 0xffff;
441
                uarts[i].vapi.next_break = (data >> 16) & 1;
442
                break;
443 355 markom
              default:
444 361 markom
                debug (0, "WARNING: Invalid vapi command %02x\n", data >> 24);
445 355 markom
                break;
446
            }
447
          } else break;
448
        }
449
      }
450
    }
451 341 markom
 
452 385 markom
    /***************** Loopback *****************/
453 355 markom
    if (uarts[i].regs.mcr & UART_MCR_LOOP) {
454
      debug(5, "uart_clock: Loopback\n");
455
      if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
456
          ((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
457
        uarts[i].regs.msr |= UART_MSR_DDCD;
458
      if ((uarts[i].regs.mcr & UART_MCR_AUX1) <
459
          ((uarts[i].regs.msr & UART_MSR_RI) >> 4))
460
        uarts[i].regs.msr |= UART_MSR_TERI;
461
      if ((uarts[i].regs.mcr & UART_MCR_RTS) !=
462
          ((uarts[i].regs.msr & UART_MSR_CTS) >> 3))
463
        uarts[i].regs.msr |= UART_MSR_DCTS;
464
      if ((uarts[i].regs.mcr & UART_MCR_DTR) !=
465
          ((uarts[i].regs.msr & UART_MSR_DSR) >> 5))
466
        uarts[i].regs.msr |= UART_MSR_DDSR;
467
      uarts[i].regs.msr &= ~(UART_MSR_DCD | UART_MSR_RI
468
                | UART_MSR_DSR | UART_MSR_CTS);
469
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX2) << 4);
470
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX1) << 4);
471
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_RTS) << 3);
472
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_DTR) << 5);
473
    }
474
 
475
    /* Interrupt detection in proper priority order. */
476
    uarts[i].regs.iir = UART_IIR_NO_INT;
477
    if (uarts[i].regs.ier & UART_IER_RLSI &&
478
        uarts[i].regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
479
          | UART_LSR_FRAME | UART_LSR_BREAK)) {
480
      uarts[i].regs.iir = UART_IIR_RLSI;
481
    }
482
    else if (uarts[i].regs.ier & UART_IER_RDI &&
483
        uarts[i].regs.lsr & UART_LSR_RDRDY) {
484
      uarts[i].regs.iir = UART_IIR_RDI;
485
    }
486
    else if (uarts[i].regs.ier & UART_IER_THRI &&
487
        uarts[i].regs.lsr & UART_LSR_TXBUFE &&
488
        uarts[i].istat.thre_int == 1) {
489
      uarts[i].regs.iir = UART_IIR_THRI;
490
    }
491
    else if (uarts[i].regs.ier & UART_IER_MSI &&
492
        uarts[i].regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
493
          | UART_MSR_TERI | UART_MSR_DDCD)) {
494
      uarts[i].regs.iir = UART_IIR_MSI;
495
    }
496
    if (!(uarts[i].regs.iir & UART_IIR_NO_INT))
497
      report_interrupt(config.uarts[i].irq);
498
  }
499 31 lampret
}
500
 
501
/* Print register values on stdout. */
502
void uart_status()
503
{
504 355 markom
  int i, j;
505
 
506
  for(i = 0; i < config.nuarts; i++) {
507
    if ( !config.uarts[i].baseaddr )
508
      continue;
509
    printf("\nUART%d visible registers at 0x%.8x:\n", i, config.uarts[i].baseaddr);
510
    printf("RXBUF:");
511
    for (j = uarts[i].istat.rxbuf_head; j != uarts[i].istat.rxbuf_tail; j = (j + 1) % uarts[i].fifo_len)
512
      printf (" %.2x", uarts[i].regs.rxbuf[j]);
513
    printf("  TXBUF: %.2x\n", uarts[i].regs.txbuf);
514
    printf("DLL  : %.2x  DLH  : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh);
515
    printf("IER  : %.2x  IIR  : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir);
516
    printf("LCR  : %.2x  MCR  : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
517
    printf("LSR  : %.2x  MSR  : %.2x\n", uarts[i].regs.lsr, uarts[i].regs.msr);
518
    printf("SCR  : %.2x\n", uarts[i].regs.scr);
519 31 lampret
 
520 355 markom
    printf("\nInternal registers (sim debug):\n");
521
    printf("RXSER: %.2x  TXSER: %.2x\n", uarts[i].iregs.rxser, uarts[i].iregs.txser);
522 31 lampret
 
523 355 markom
    printf("\nInternal status (sim debug):\n");
524
    printf("char_clks: %d\n", uarts[i].char_clks);
525
    printf("rxser_clks: %d  txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks);
526
    printf("rxser: %d  txser: %d\n", uarts[i].istat.rxser_full, uarts[i].istat.txser_full);
527
    printf("rxbuf: %d  txbuf: %d\n", uarts[i].istat.rxbuf_full, uarts[i].istat.txbuf_full);
528 344 markom
    printf("Using IRQ%i\n", config.uarts[i].irq);
529 336 markom
    if (config.uarts[i].vapi_id)
530
      printf ("Connected to vapi ID=%x\n\n", config.uarts[i].vapi_id);
531
    else
532 355 markom
      printf("RX fs: %p  TX fs: %p\n\n", uarts[i].rxfs, uarts[i].txfs);
533
  }
534 31 lampret
}

powered by: WebSVN 2.1.0

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