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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [peripheral/] [16450.c] - Blame information for rev 361

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 336 markom
  }
263 31 lampret
}
264 261 markom
 
265 31 lampret
/* Simulation hook. Must be called every clock cycle to simulate all UART
266
   devices. It does internal functional UART simulation. */
267
void uart_clock()
268
{
269 355 markom
  int i, retval;
270 341 markom
 
271 355 markom
  for(i = 0; i < config.nuarts; i++) {
272 341 markom
    /* If VAPI is not selected, UART communicates with two file streams;
273
       if VAPI is selected, we use VAPI streams.  */
274
 
275
    /* if txfs is corrupted, skip this uart. */
276 355 markom
    if (!config.uarts[i].vapi_id && !uarts[i].txfs) continue;
277 31 lampret
 
278 355 markom
    /* Transmit */
279
    if (!uarts[i].istat.txser_full) {
280
      uarts[i].regs.lsr |= UART_LSR_TXBUFE;
281
      if (uarts[i].istat.txbuf_full) {
282
        uarts[i].iregs.txser = uarts[i].regs.txbuf[uarts[i].istat.txbuf_tail];
283
        uarts[i].istat.txbuf_tail = (uarts[i].istat.txbuf_tail + 1) % uarts[i].fifo_len;
284
        uarts[i].istat.txser_full = 1;
285
        uarts[i].istat.txbuf_full--;
286
        uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
287
        uarts[i].istat.thre_int = 1;
288
      } else
289
        uarts[i].regs.lsr |= UART_LSR_TXSERE;
290
    } else if (uarts[i].char_clks >= uarts[i].istat.txser_clks++) {
291
      debug(4, "TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
292
      if (uarts[i].regs.mcr & UART_MCR_LOOP)
293
        uarts[i].iregs.loopback = uarts[i].iregs.txser;
294
      else {
295
        /* Send to either VAPI or to file */
296
        if (config.uarts[i].vapi_id) {
297
          int par, pe, fe, nbits = (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5;
298 361 markom
          int j, data;
299 355 markom
          unsigned long packet = 0;
300 361 markom
 
301 355 markom
          /* Encode a packet */
302 361 markom
          packet = uarts[i].iregs.txser & ((1 << nbits) - 1);
303 31 lampret
 
304 355 markom
          /* Calculate parity */
305 361 markom
          for (j = 0, par = 0; j < nbits; j++)
306
            par ^= (packet >> j) & 1;
307 355 markom
 
308
          if (uarts[i].regs.lcr & UART_LCR_PARITY) {
309
            if (uarts[i].regs.lcr & UART_LCR_SPAR) {
310
              packet |= 1 << nbits;
311
            } else {
312
              if (uarts[i].regs.lcr & UART_LCR_EPAR)
313
                packet |= par << nbits;
314
              else
315
                packet |= (par ^ 1) << nbits;
316
            }
317
            nbits++;
318
          }
319
          packet |= 1 << (nbits++);
320
          if (uarts[i].regs.lcr & UART_LCR_STOP)
321
            packet |= 1 << (nbits++);
322
 
323
          /* Decode a packet */
324
          nbits = (uarts[i].vapi.lcr & UART_LCR_WLEN8) + 5;
325
          data = packet & ((1 << nbits) - 1);
326
 
327
          /* Calculate parity, including parity bit */
328 361 markom
          for (j = 0, par = 0; j < nbits + 1; j++)
329
            par ^= (packet >> j) & 1;
330 355 markom
 
331
          if (uarts[i].vapi.lcr & UART_LCR_PARITY) {
332
            if (uarts[i].vapi.lcr & UART_LCR_SPAR) {
333
              pe = !((packet >> nbits) & 1);
334
            } else {
335
              if (uarts[i].vapi.lcr & UART_LCR_EPAR)
336
                pe = par != 0;
337
              else
338
                pe = par != 1;
339
            }
340
            nbits++;
341
          } else
342
            pe = 0;
343
 
344 361 markom
          fe = ((packet >> (nbits++)) & 1) ^ 1;
345 355 markom
          if (uarts[i].vapi.lcr & UART_LCR_STOP)
346
            fe |= ((packet >> (nbits++)) & 1) ^ 1;
347
 
348 361 markom
          debug (4, "vapi_send (%08x, %08x)\n", config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
349 355 markom
          vapi_send (config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
350
        } else {
351
          fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs);
352
          fflush(uarts[i].txfs);
353
        }
354 341 markom
      }
355 355 markom
      uarts[i].istat.txser_full = 0;
356
      uarts[i].istat.txser_clks = 0;
357
    }
358 341 markom
 
359 355 markom
    /* Receive */
360
    if (uarts[i].istat.rxser_full) {
361
      if (uarts[i].char_clks >= uarts[i].istat.rxser_clks++) {
362
        debug(4, "Receiving via UART%d...\n", i);
363
        uarts[i].istat.rxser_full = 0;
364
        uarts[i].istat.rxser_clks = 0;
365
 
366
        if (++uarts[i].istat.rxbuf_full > uarts[i].fifo_len)
367
          uarts[i].regs.lsr |= UART_LSR_OVRRUN;
368
        else {
369
          uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_head] = uarts[i].iregs.rxser & 0xFF;
370
          uarts[i].istat.rxbuf_head = (uarts[i].istat.rxbuf_head + 1) % uarts[i].fifo_len;
371
          uarts[i].istat.rxbuf_full++;
372
        }
373
        uarts[i].regs.lsr |= UART_LSR_RDRDY;
374
      }
375
    }
376
 
377
    /* Check if there is something waiting, and put it into rxser */
378
    if (uarts[i].regs.mcr & UART_MCR_LOOP) {
379
      uarts[i].iregs.rxser = uarts[i].iregs.loopback;
380
      uarts[i].istat.rxser_full = 1;
381
    } else {
382
      if (!config.uarts[i].vapi_id) {
383
        if((retval = fgetc(uarts[i].rxfs)) != EOF)
384
          uarts[i].iregs.rxser = (char)retval;
385
          uarts[i].istat.rxser_full = 1;
386
      } else { /* VAPI */
387
        int received = 0;
388 361 markom
        /* do not handle commands while receiving */
389
        if (uarts[i].istat.rxser_full)
390
          break;
391 355 markom
        while (!received) {
392
          if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
393
            unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
394
            uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % uarts[i].fifo_len;
395
            switch (data >> 24) {
396
              case 0x00:
397
                uarts[i].vapi.lcr = (data >> 8) & 0xff;
398
                /* Put data into rx fifo */
399
                uarts[i].vapi.char_clks = char_clks (uarts[i].vapi.dll, uarts[i].vapi.dlh, uarts[i].vapi.lcr);
400
                if (uarts[i].vapi.lcr != uarts[i].regs.lcr || uarts[i].vapi.char_clks != uarts[i].char_clks
401
                 || uarts[i].vapi.skew < -MAX_SKEW || uarts[i].vapi.skew > MAX_SKEW) {
402 361 markom
                  debug (3, "WARNING: unmatched VAPI and uart modes.\n");
403 355 markom
                  /* Set error bits */
404
                  uarts[i].regs.lsr |= UART_LSR_PARITY | UART_LSR_FRAME;
405
                  break;
406
                } else {
407
                  uarts[i].iregs.rxser = data & 0xff;
408
                  uarts[i].istat.rxser_full = 1;
409
                }
410
                received = 1;
411
                break;
412
              case 0x01:
413
                uarts[i].vapi.dll = (data >> 0) & 0xff;
414
                uarts[i].vapi.dlh = (data >> 8) & 0xff;
415
                break;
416
              case 0x02:
417 361 markom
                uarts[i].vapi.lcr = (data >> 8) & 0xff;
418 355 markom
                break;
419
              case 0x03:
420
                uarts[i].vapi.skew = (signed short)(data & 0xffff);
421
                break;
422
              default:
423 361 markom
                debug (0, "WARNING: Invalid vapi command %02x\n", data >> 24);
424 355 markom
                break;
425
            }
426
          } else break;
427
        }
428
      }
429
    }
430 341 markom
 
431 355 markom
    /* Loopback */
432
    if (uarts[i].regs.mcr & UART_MCR_LOOP) {
433
      debug(5, "uart_clock: Loopback\n");
434
      if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
435
          ((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
436
        uarts[i].regs.msr |= UART_MSR_DDCD;
437
      if ((uarts[i].regs.mcr & UART_MCR_AUX1) <
438
          ((uarts[i].regs.msr & UART_MSR_RI) >> 4))
439
        uarts[i].regs.msr |= UART_MSR_TERI;
440
      if ((uarts[i].regs.mcr & UART_MCR_RTS) !=
441
          ((uarts[i].regs.msr & UART_MSR_CTS) >> 3))
442
        uarts[i].regs.msr |= UART_MSR_DCTS;
443
      if ((uarts[i].regs.mcr & UART_MCR_DTR) !=
444
          ((uarts[i].regs.msr & UART_MSR_DSR) >> 5))
445
        uarts[i].regs.msr |= UART_MSR_DDSR;
446
      uarts[i].regs.msr &= ~(UART_MSR_DCD | UART_MSR_RI
447
                | UART_MSR_DSR | UART_MSR_CTS);
448
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX2) << 4);
449
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX1) << 4);
450
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_RTS) << 3);
451
      uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_DTR) << 5);
452
    }
453
 
454
    /* Interrupt detection in proper priority order. */
455
    uarts[i].regs.iir = UART_IIR_NO_INT;
456
    if (uarts[i].regs.ier & UART_IER_RLSI &&
457
        uarts[i].regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
458
          | UART_LSR_FRAME | UART_LSR_BREAK)) {
459
      uarts[i].regs.iir = UART_IIR_RLSI;
460
    }
461
    else if (uarts[i].regs.ier & UART_IER_RDI &&
462
        uarts[i].regs.lsr & UART_LSR_RDRDY) {
463
      uarts[i].regs.iir = UART_IIR_RDI;
464
    }
465
    else if (uarts[i].regs.ier & UART_IER_THRI &&
466
        uarts[i].regs.lsr & UART_LSR_TXBUFE &&
467
        uarts[i].istat.thre_int == 1) {
468
      uarts[i].regs.iir = UART_IIR_THRI;
469
    }
470
    else if (uarts[i].regs.ier & UART_IER_MSI &&
471
        uarts[i].regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
472
          | UART_MSR_TERI | UART_MSR_DDCD)) {
473
      uarts[i].regs.iir = UART_IIR_MSI;
474
    }
475
    if (!(uarts[i].regs.iir & UART_IIR_NO_INT))
476
      report_interrupt(config.uarts[i].irq);
477
  }
478 31 lampret
}
479
 
480
/* Print register values on stdout. */
481
void uart_status()
482
{
483 355 markom
  int i, j;
484
 
485
  for(i = 0; i < config.nuarts; i++) {
486
    if ( !config.uarts[i].baseaddr )
487
      continue;
488
    printf("\nUART%d visible registers at 0x%.8x:\n", i, config.uarts[i].baseaddr);
489
    printf("RXBUF:");
490
    for (j = uarts[i].istat.rxbuf_head; j != uarts[i].istat.rxbuf_tail; j = (j + 1) % uarts[i].fifo_len)
491
      printf (" %.2x", uarts[i].regs.rxbuf[j]);
492
    printf("  TXBUF: %.2x\n", uarts[i].regs.txbuf);
493
    printf("DLL  : %.2x  DLH  : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh);
494
    printf("IER  : %.2x  IIR  : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir);
495
    printf("LCR  : %.2x  MCR  : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
496
    printf("LSR  : %.2x  MSR  : %.2x\n", uarts[i].regs.lsr, uarts[i].regs.msr);
497
    printf("SCR  : %.2x\n", uarts[i].regs.scr);
498 31 lampret
 
499 355 markom
    printf("\nInternal registers (sim debug):\n");
500
    printf("RXSER: %.2x  TXSER: %.2x\n", uarts[i].iregs.rxser, uarts[i].iregs.txser);
501 31 lampret
 
502 355 markom
    printf("\nInternal status (sim debug):\n");
503
    printf("char_clks: %d\n", uarts[i].char_clks);
504
    printf("rxser_clks: %d  txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks);
505
    printf("rxser: %d  txser: %d\n", uarts[i].istat.rxser_full, uarts[i].istat.txser_full);
506
    printf("rxbuf: %d  txbuf: %d\n", uarts[i].istat.rxbuf_full, uarts[i].istat.txbuf_full);
507 344 markom
    printf("Using IRQ%i\n", config.uarts[i].irq);
508 336 markom
    if (config.uarts[i].vapi_id)
509
      printf ("Connected to vapi ID=%x\n\n", config.uarts[i].vapi_id);
510
    else
511 355 markom
      printf("RX fs: %p  TX fs: %p\n\n", uarts[i].rxfs, uarts[i].txfs);
512
  }
513 31 lampret
}

powered by: WebSVN 2.1.0

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