URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 340 to Rev 341
- ↔ Reverse comparison
Rev 340 → Rev 341
/trunk/or1ksim/sim-config.h
55,6 → 55,7
unsigned long baseaddr; /* Naturally aligned base address */ |
int irq; /* IRQ of this device */ |
unsigned long vapi_id; /* VAPI id for this instance */ |
int uart16550; /* Whether this device is uart 16450 or 16550 */ |
} uarts[NR_UARTS]; |
|
int ndmas; |
/trunk/or1ksim/sim.cfg
250,6 → 250,9
irq = <value> |
irq number for this device |
|
16550 = 0/1 |
0, if this device is uart 16450 and 1, if it is 16550 |
|
jitter = <value> |
in msecs... time to block, -1 to disable it |
|
/trunk/or1ksim/testbench/pic.c
152,5 → 152,5
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << V_TICK)); |
|
report(res + 0xdeadd9f2); |
exit(0); |
return 0; |
} |
/trunk/or1ksim/testbench/README
1,213 → 1,25
This directory includes some test case programs that should be used to verify correct operation |
of the or1ksim, OR32 GCC and OR32 GNU Binutils. |
|
All programs are built from root directories. You need to have all GNU OR32 tools installed and in |
path. |
All programs are built and checked by: |
make all check |
You need to have all GNU OR32 tools installed and in the path. |
|
!!! For all test cases, or1ksim should be built with ONLY_VIRTUAL_MACHINE undefined in |
cpu/or1k/except.h !!! |
|
Dhrystone 2.1: a benchmark modified to use simulator's timing facility. It should finish with exit(0). |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
running simulation: |
|
# ./sim testbench/dhrystone/dhry.or32 |
(sim) run -1 hush |
<cut> <cut> <cut> |
MTSPR(0x1234, 20070); |
MTSPR(0x1234, 20013); |
MTSPR(0x1234, 7); |
MTSPR(0x1234, 30010); |
MTSPR(0x1234, 30010); |
MTSPR(0x1234, 8); |
MTSPR(0x1234, 20020); |
MTSPR(0x1234, 9); |
syscall exit(0) |
(sim) |
|
stdout.txt should read like this: |
|
Execution starts, 20 runs through Dhrystone |
Begin Time = 549 |
End Time = 22701 |
OR1K at 200 MHz |
Microseconds for one run through Dhrystone: 110 us / 20 runs |
Dhrystones per Second: 181 |
|
basic: a test for all instructions and all GPRs. If everything is ok, RESULT == 0xdeadead. |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
# ./sim testbench/basic.or32 |
(sim) run -1 hush |
UART 0 RX EOF detected. Shutting down to prevent endless loop. |
MTSPR(0x1234, ffff0012); |
MTSPR(0x1234, 12352af7); |
MTSPR(0x1234, 7ffffffe); |
MTSPR(0x1234, ffffa5a7); |
MTSPR(0x1234, fffff); |
MTSPR(0x1234, 2800); |
MTSPR(0x1234, a); |
All tests should exit with: |
MTSPR(0x1234, deaddead); |
syscall exit(0) |
(sim) |
|
Standard output: |
RESULT: deaddead |
If the test fails, it should print as much output as possible about the failure. |
|
|
test1: a test for "all" instructions and their combinations. If everything is ok, RESULT == 0xdeadead. |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
# ./sim testbench/cbasic.or32 |
(sim) run -1 hush |
MTSPR(0x1234, ffffffda); |
MTSPR(0x1234, ffffffc5); |
MTSPR(0x1234, 6805); |
MTSPR(0x1234, ffff97f9); |
MTSPR(0x1234, ffff97f9); |
MTSPR(0x1234, 7a77952e); |
MTSPR(0x1234, 81e5e000); |
MTSPR(0x1234, 74); |
MTSPR(0x1234, 74); |
MTSPR(0x1234, 74); |
MTSPR(0x1234, 1); |
MTSPR(0x1234, d7c); |
MTSPR(0x1234, 74); |
MTSPR(0x1234, 74); |
MTSPR(0x1234, 74); |
MTSPR(0x1234, ffffffff); |
MTSPR(0x1234, d7a); |
MTSPR(0x1234, d7a); |
MTSPR(0x1234, deaddead); |
syscall exit(0) |
(sim) |
|
Standard output: |
RESULT: deaddead |
|
pic: a test for PIC and TICK timer. All three modes of TICK timer are tested and interrupt is enabled and disabled in PIC. If everything is ok, RESULT == 0xdeadead. |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
# ./sim testbench/pic.or32 |
(sim) run -1 hush |
... |
... |
... |
MTSPR(0x1234, 178); |
MTSPR(0x1234, 178); |
MTSPR(0x1234, deaddead); |
syscall exit(0) |
(sim) |
|
Standard output: |
RESULT: deaddead |
|
excpt: a test of l.sys instruction. Checks all the delay slot issues ind other things. If everything is ok, RESULT == 0xdeadead. |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
# ./sim testbench/excpt.or32 |
(sim) run -1 hush |
UART 0 RX EOF detected. Shutting down to prevent endless loop. |
Exception 0xc00 (System Call): Iqueue[0].insn_addr: 0xc74 Eff ADDR: 0x0 |
pc: 0xc74 pcnext: 0xc78 |
MTSPR(0x1234, 1); |
MTSPR(0x1234, 1); |
MTSPR(0x1234, 1c); |
MTSPR(0x1234, 1); |
MTSPR(0x1234, 3); |
MTSPR(0x1234, deaddead); |
syscall exit(0) |
(sim) |
|
Standard output: |
RESULT: deaddead |
|
cfg: a test of SPRs (SPR_VR, SPR_CPUCFGR, SPR_DMMUCFGR, SPR_IMMUCFGR, SPR_DCCFGR, SPR_ICCFGR, SPR_DCFGR, SPR_PCCFGR). If everything is ok, RESULT == 0xdeadead. |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
# ./sim testbench/cfg.or32 |
(sim) run -1 hush |
MTSPR(0x1234, 0); |
MTSPR(0x1234, e83f); |
MTSPR(0x1234, 0); |
MTSPR(0x1234, 5); |
MTSPR(0x1234, 20); |
MTSPR(0x1234, 1d); |
MTSPR(0x1234, 1d); |
MTSPR(0x1234, 1d); |
MTSPR(0x1234, 1d); |
MTSPR(0x1234, 8); |
MTSPR(0x1234, 1); |
MTSPR(0x1234, deaddead); |
syscall exit(0) |
(sim) |
|
Standard output: |
RESULT: deaddead |
|
dma: a test of DMA in normal (software) mode. If everything is ok, RESULT == 0xdeadead. |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
# ./sim testbench/dma.or32 |
(sim) run 1000000 hush |
MTSPR(0x1234, 1); |
MTSPR(0x1234, 6); |
MTSPR(0x1234, a); |
MTSPR(0x1234, deaddead); |
syscall exit(0) |
(sim) |
|
Standard output: |
RESULT: deaddead |
|
compress: UNIX compressed modified not to use libc calls. Should finish with exit(0). |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
Simulation: |
|
./sim testbench/compress/mycompress.or32 |
(sim) run -1 hush |
Interrupt reported. |
Interrupt reported. |
syscall exit(0) |
(sim) |
|
Standard output: |
|
main: bytes_out 3... hsize 5003 |
main: hshift 4... |
main: bytes_out 3... |
main: hsize_reg 5003... |
main: before compress 1... |
main: compressing 1... |
main: compressing 2... |
main: compressing 3... |
<cut> <cut> <cut> |
main: compressing 997... |
main: compressing 998... |
main: compressing 999... |
main: output... |
main: end... |
|
mul: Test l.mul, l.mac and l.macrc instructions. Should finish with exit(0). |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
Simulation: |
./sim testbench/mul.or32 |
(sim) run -1 hush |
MTSPR(0x1234, deadbeef); |
syscall exit(0) |
(sim) |
|
Standard output: |
|
0xa6312f33, expected 0xa6312f33 |
0x0d4de375, expected 0x0d4de375 |
0x61ab48dc, expected 0x61ab48dc |
Test succesful. |
dhry: Dhrystone 2.1: a benchmark modified to use simulator's timing facility. |
basic: a test for all instructions and all GPRs. |
test1: a test for "all" instructions and their combinations. |
pic: a test for PIC and TICK timer. All three modes of TICK timer are tested and interrupt is enabled and disabled in PIC. |
excpt: a test of l.sys instruction. Checks all the delay slot issues ind other things. |
cfg: a test of SPRs (SPR_VR, SPR_CPUCFGR, SPR_DMMUCFGR, SPR_IMMUCFGR, SPR_DCCFGR, SPR_ICCFGR, SPR_DCFGR, SPR_PCCFGR). |
dma: a test of DMA in normal (software) mode. |
compress: UNIX compressed modified not to use libc calls. |
mul: Test l.mul, l.mac and l.macrc instructions. |
/trunk/or1ksim/peripheral/16450.c
68,9 → 68,9
int chipsel; |
|
debug("uart_write_byte(%x,%02x)\n", addr, (unsigned)value); |
|
|
for(chipsel = 0; chipsel < NR_UARTS; chipsel++) |
if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr) |
if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr) |
break; |
else if (chipsel == NR_UARTS) |
return; |
95,10 → 95,19
|
switch (addr % UART_ADDR_SPACE) { |
case UART_TXBUF: |
uarts[chipsel].regs.txbuf = value; |
uarts[chipsel].istat.txbuf = FULL; |
uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE; |
if (uarts[chipsel].istat.txbuf_full < uarts[chipsel].fifo_len) { |
uarts[chipsel].istat.txbuf_full++; |
uarts[chipsel].regs.txbuf[uarts[chipsel].istat.txbuf_head] = value; |
uarts[chipsel].istat.txbuf_head = (uarts[chipsel].istat.txbuf_head + 1) % uarts[chipsel].fifo_len; |
} else |
uarts[chipsel].regs.txbuf[uarts[chipsel].istat.txbuf_head] = value; |
|
if (uarts[chipsel].istat.txbuf_full < uarts[chipsel].fifo_len) |
uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE; |
else |
uarts[chipsel].regs.lsr |= UART_LSR_TXBUFE; |
uarts[chipsel].regs.lsr &= ~UART_LSR_TXSERE; |
|
uarts[chipsel].istat.thre_int = 0; |
break; |
case UART_IER: |
129,7 → 138,7
debug("uart_read_byte(%x)\n", addr); |
|
for(chipsel = 0; chipsel < NR_UARTS; chipsel++) |
if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr) |
if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr) |
break; |
else if (chipsel == NR_UARTS) |
return 0; |
150,9 → 159,16
|
switch (addr % UART_ADDR_SPACE) { |
case UART_RXBUF: |
value = uarts[chipsel].regs.rxbuf; |
uarts[chipsel].istat.rxbuf = EMPTY; |
uarts[chipsel].regs.lsr &= ~UART_LSR_RDRDY; |
if (uarts[chipsel].istat.rxbuf_full) { |
value = uarts[chipsel].regs.rxbuf[uarts[chipsel].istat.rxbuf_tail]; |
uarts[chipsel].istat.rxbuf_tail = (uarts[chipsel].istat.rxbuf_tail + 1) % uarts[chipsel].fifo_len; |
uarts[chipsel].istat.rxbuf_full--; |
} |
|
if (uarts[chipsel].istat.rxbuf_full) |
uarts[chipsel].regs.lsr |= UART_LSR_RDRDY; |
else |
uarts[chipsel].regs.lsr &= ~UART_LSR_RDRDY; |
break; |
case UART_IER: |
value = uarts[chipsel].regs.ier & UART_VALID_IER; |
189,12 → 205,20
/* Function that handles incoming VAPI data. */ |
void uart_vapi_read (unsigned long id, unsigned long data) |
{ |
printf ("UART: id %08x, data %08x\n", id, data); |
} |
int uart; |
debug("UART: id %08x, data %08x\n", id, data); |
uart = id & VAPI_DEVICE_ID; |
uarts[uart].vapi_buf[uarts[uart].vapi_buf_head_ptr] = data; |
uarts[uart].vapi_buf_head_ptr = (uarts[uart].vapi_buf_head_ptr + 1) % UART_RX_BUF; |
if (uarts[uart].vapi_buf_tail_ptr == uarts[uart].vapi_buf_head_ptr) { |
fprintf (stderr, "FATAL: uart VAPI buffer to small.\n"); |
exit (1); |
} |
} |
|
/* Reset. It initializes all registers of all UART devices to zero values, |
/* Reset. It initializes all registers of all UART devices to zero values, |
(re)opens all RX/TX file streams and places devices in memory address |
space. */ |
space. */ |
void uart_reset() |
{ |
int i; |
201,28 → 225,43
|
if (!config.uarts_enabled) |
config.nuarts = 0; |
|
printf("Resetting %u UART(s).\n", config.nuarts); |
|
if (config.sim.verbose && config.nuarts) |
printf("Resetting %u UART(s).\n", config.nuarts); |
|
memset(uarts, 0, sizeof(uarts)); |
|
for(i = 0; i < config.nuarts; i++) |
if (config.uarts[i].txfile) { /* MM: Try to create stream. */ |
for(i = 0; i < config.nuarts; i++) { |
if (config.uarts[i].vapi_id) { |
if ((config.uarts[i].vapi_id & VAPI_DEVICE_ID) != i) { |
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); |
config.uarts[i].vapi_id = 0; |
uarts[i].txfs = 0; |
} else { |
vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read); |
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte); |
} |
} else if (config.uarts[i].txfile) { /* MM: Try to create stream. */ |
if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r")) |
&& !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) { |
printf("UART%d has problems with RX file stream.\n", i); |
fprintf(stderr, "WARNING: UART%d has problems with RX file stream.\n", i); |
continue; |
} |
uarts[i].txfs = fopen(config.uarts[i].txfile, "a"); |
uarts[i].baseaddr = config.uarts[i].baseaddr; |
if (uarts[i].rxfs && uarts[i].txfs) { |
printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr); |
if (uarts[i].rxfs && uarts[i].txfs && config.sim.verbose) { |
printf("UART%d at 0x%.8x uses ", i, config.uarts[i].baseaddr); |
printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile); |
} else |
printf("UART%d has problems with TX file stream.\n", i); |
register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte); |
|
if (config.uarts[i].vapi_id) |
vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read); |
fprintf(stderr, "WARNING: UART%d has problems with TX file stream.\n", i); |
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte); |
} |
|
if (config.uarts[i].uart16550) |
uarts[i].fifo_len = 16; |
else |
uarts[i].fifo_len = 1; |
uarts[i].istat.rxbuf_head = uarts[i].istat.rxbuf_tail = 0; |
uarts[i].istat.txbuf_head = uarts[i].istat.txbuf_tail = 0; |
} |
} |
|
231,54 → 270,79
void uart_clock() |
{ |
int i, retval; |
|
|
for(i = 0; i < config.nuarts; i++) { |
if (!uarts[i].txfs) { |
continue; |
} |
/* If VAPI is not selected, UART communicates with two file streams; |
if VAPI is selected, we use VAPI streams. */ |
|
/* if txfs is corrupted, skip this uart. */ |
if (!config.uarts[i].vapi_id && !uarts[i].txfs) continue; |
|
/* Transmit */ |
if (uarts[i].istat.txser == EMPTY) { |
if (!uarts[i].istat.txser_full) { |
uarts[i].regs.lsr |= UART_LSR_TXBUFE; |
if (uarts[i].istat.txbuf == FULL) { |
uarts[i].iregs.txser = uarts[i].regs.txbuf; |
uarts[i].istat.txser = FULL; |
uarts[i].istat.txbuf = EMPTY; |
if (uarts[i].istat.txbuf_full) { |
uarts[i].iregs.txser = uarts[i].regs.txbuf[uarts[i].istat.txbuf_tail]; |
uarts[i].istat.txbuf_tail = (uarts[i].istat.txbuf_tail + 1) % uarts[i].fifo_len; |
uarts[i].istat.txser_full = 1; |
uarts[i].istat.txbuf_full--; |
uarts[i].regs.lsr &= ~UART_LSR_TXSERE; |
uarts[i].istat.thre_int = 1; |
} else |
uarts[i].regs.lsr |= UART_LSR_TXSERE; |
} else if (uarts[i].char_clks == uarts[i].istat.txser_clks++) { |
} else if (uarts[i].char_clks >= uarts[i].istat.txser_clks++) { |
debug("TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i); |
if (uarts[i].regs.mcr & UART_MCR_LOOP) |
uarts[i].iregs.loopback = uarts[i].iregs.txser; |
else { |
fputc((int)uarts[i].iregs.txser, uarts[i].txfs); |
fflush(uarts[i].txfs); |
/* Send to either VAPI or to file */ |
if (config.uarts[i].vapi_id) { |
vapi_send (config.uarts[i].vapi_id, uarts[i].iregs.txser); |
} else { |
fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs); |
fflush(uarts[i].txfs); |
} |
} |
uarts[i].istat.txser = EMPTY; |
uarts[i].istat.txser_full = 1; |
uarts[i].istat.txser_clks = 0; |
} |
|
/* Receive */ |
if (uarts[i].istat.rxser == EMPTY) |
uarts[i].istat.rxser = FULL; |
else if (uarts[i].char_clks == uarts[i].istat.rxser_clks++) { |
debug("Receiving via UART%d...\n", i); |
if (uarts[i].regs.mcr & UART_MCR_LOOP) |
uarts[i].iregs.rxser = uarts[i].iregs.loopback; |
else if((retval = fgetc(uarts[i].rxfs)) != EOF) { |
uarts[i].iregs.rxser = (char)retval; |
if (uarts[i].istat.rxbuf == FULL) |
uarts[i].regs.lsr |= UART_LSR_OVRRUN; |
uarts[i].regs.lsr |= UART_LSR_RDRDY; |
uarts[i].regs.rxbuf = uarts[i].iregs.rxser; |
uarts[i].istat.rxbuf = FULL; |
} |
uarts[i].istat.rxser = EMPTY; |
uarts[i].istat.rxser_clks = 0; |
if (uarts[i].istat.rxser_full) { |
if (uarts[i].char_clks >= uarts[i].istat.rxser_clks++) { |
debug("Receiving via UART%d...\n", i); |
uarts[i].istat.rxser_full = 0; |
uarts[i].istat.rxser_clks = 0; |
|
if (++uarts[i].istat.rxbuf_full > uarts[i].fifo_len) |
uarts[i].regs.lsr |= UART_LSR_OVRRUN; |
else { |
uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_head] = uarts[i].iregs.rxser & 0xFF; |
uarts[i].istat.rxbuf_head = (uarts[i].istat.rxbuf_head + 1) % uarts[i].fifo_len; |
uarts[i].istat.rxbuf_full++; |
} |
uarts[i].regs.lsr |= UART_LSR_RDRDY; |
} |
} |
|
|
/* Check if there is something waiting, and put it into rxser */ |
if (uarts[i].regs.mcr & UART_MCR_LOOP) { |
uarts[i].iregs.rxser = uarts[i].iregs.loopback; |
uarts[i].istat.rxser_full = 1; |
} else { |
if (!config.uarts[i].vapi_id) { |
if((retval = fgetc(uarts[i].rxfs)) != EOF) |
uarts[i].iregs.rxser = (char)retval; |
uarts[i].istat.rxser_full = 1; |
} else { /* VAPI */ |
if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) { |
uarts[i].iregs.rxser = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr]; |
uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % uarts[i].fifo_len; |
uarts[i].istat.rxser_full = 1; |
} |
} |
} |
|
/* Loopback */ |
if (uarts[i].regs.mcr & UART_MCR_LOOP) { |
debug("uart_clock: Loopback\n"); |
331,13 → 395,16
/* Print register values on stdout. */ |
void uart_status() |
{ |
int i; |
int i, j; |
|
for(i = 0; i < config.nuarts; i++) { |
if ( !uarts[i].baseaddr ) |
if ( !config.uarts[i].baseaddr ) |
continue; |
printf("\nUART%d visible registers at 0x%.8x:\n", i, uarts[i].baseaddr); |
printf("RXBUF: %.2x TXBUF: %.2x\n", uarts[i].regs.rxbuf, uarts[i].regs.txbuf); |
printf("\nUART%d visible registers at 0x%.8x:\n", i, config.uarts[i].baseaddr); |
printf("RXBUF:"); |
for (j = uarts[i].istat.rxbuf_head; j != uarts[i].istat.rxbuf_tail; j = (j + 1) % uarts[i].fifo_len) |
printf (" %.2x", uarts[i].regs.rxbuf[j]); |
printf(" TXBUF: %.2x\n", uarts[i].regs.txbuf); |
printf("DLL : %.2x DLH : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh); |
printf("IER : %.2x IIR : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir); |
printf("LCR : %.2x MCR : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr); |
350,9 → 417,9
printf("\nInternal status (sim debug):\n"); |
printf("char_clks: %d\n", uarts[i].char_clks); |
printf("rxser_clks: %d txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks); |
printf("rxser: %d txser: %d\n", uarts[i].istat.rxser, uarts[i].istat.txser); |
printf("rxbuf: %d txbuf: %d\n", uarts[i].istat.rxbuf, uarts[i].istat.txbuf); |
|
printf("rxser: %d txser: %d\n", uarts[i].istat.rxser_full, uarts[i].istat.txser_full); |
printf("rxbuf: %d txbuf: %d\n", uarts[i].istat.rxbuf_full, uarts[i].istat.txbuf_full); |
printf("Using IRQ%i", config.uarts[i].irq); |
if (config.uarts[i].vapi_id) |
printf ("Connected to vapi ID=%x\n\n", config.uarts[i].vapi_id); |
else |
/trunk/or1ksim/peripheral/16450.h
21,12 → 21,17
void uart_reset(); |
void uart_clock(); |
|
/* Definitions */ |
#define UART_ADDR_SPACE (8) /* UART memory address space size in bytes */ |
#define UART_RX_BUF (8192) /* VAPI should not send more that this amout of char before requesting something back */ |
#define UART_MAX_FIFO_LEN (16) /* rx FIFO for uart 16550 */ |
|
/* Registers */ |
|
struct dev_16450 { |
struct { |
unsigned char txbuf; |
unsigned char rxbuf; |
unsigned char txbuf[UART_MAX_FIFO_LEN]; |
unsigned char rxbuf[UART_MAX_FIFO_LEN]; |
unsigned char dll; |
unsigned char dlh; |
unsigned char ier; |
38,30 → 43,41
unsigned char scr; |
} regs; /* Visible registers */ |
struct { |
unsigned char txser; |
unsigned char rxser; |
unsigned long txser; /* Character just sending */ |
unsigned long rxser; /* Character just receiving */ |
unsigned char loopback; |
} iregs; /* Internal registers */ |
struct { |
unsigned char txser; |
unsigned char rxser; |
unsigned char txbuf; |
unsigned char rxbuf; |
int txbuf_head; |
int txbuf_tail; |
int rxbuf_head; |
int rxbuf_tail; |
unsigned int txser_full; |
unsigned int rxser_full; |
unsigned int txbuf_full; |
unsigned int rxbuf_full; |
unsigned char thre_int; |
unsigned long txser_clks; |
unsigned long rxser_clks; |
} istat; /* Internal status */ |
unsigned long char_clks; |
|
unsigned long char_clks; |
|
/* Required by VAPI - circular buffer */ |
unsigned long vapi_buf[UART_RX_BUF]; /* Buffer to store incoming characters to, |
since we cannot handle them so fast - we |
are serial */ |
int vapi_buf_head_ptr; /* Where we write to */ |
int vapi_buf_tail_ptr; /* Where we read from */ |
|
/* Length of FIFO, 16 for 16550, 1 for 16450 */ |
int fifo_len; |
|
/* Required by standard file streams */ |
FILE * rxfs; |
FILE * txfs; |
unsigned long baseaddr; |
}; |
|
/* Definitions */ |
#define FULL 1 |
#define EMPTY 0 |
#define UART_ADDR_SPACE 8 /* UART memory address space size in bytes */ |
|
/* |
* Addresses of visible registers |
* |
/trunk/or1ksim/vapi/vapi.h
34,3 → 34,5
|
/* Sends a packet to specified test */ |
int vapi_send (unsigned long id, unsigned long data); |
|
#define VAPI_DEVICE_ID (0xff) |
/trunk/or1ksim/toplevel.c
52,7 → 52,7
#include "gdbcomm.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.43 $"; |
const char rcsrev[] = "$Revision: 1.44 $"; |
|
/* Continuos run versus single step tracing switch. */ |
int cont_run; |
245,6 → 245,12
fprintf (stderr, "WARNING: dependency stats must be enabled to do history analisis.\n"); |
} |
|
/* Debug forces verbose */ |
if (config.sim.debug && !config.sim.verbose) { |
config.sim.verbose = 1; |
fprintf (stderr, "WARNING: verbose turned on.\n"); |
} |
|
/* Start VAPI before device initialization. */ |
if (config.vapi.enabled) { |
vapi_init (); |
251,7 → 257,7
if (config.sim.verbose) |
printf ("VAPI started, waiting for clients.\n"); |
} |
|
|
uart_reset(); |
dma_reset(); |
eth_reset(); |
/trunk/or1ksim/sim-config.c
233,6 → 233,7
void uart_txfile (); |
void uart_jitter (); |
void uart_irq (); |
void uart_16550 (); |
void uart_vapi_id (); |
void dma_baseaddr (); |
void dma_irq (); |
290,6 → 291,7
{2, "enddevice", "", end_device, NULL}, |
{2, "baseaddr", "=0x%x", uart_baseaddr, (void *)(&tempUL)}, |
{2, "irq", "=%i", uart_irq, (void *)(&tempL)}, |
{2, "16550", "=%i", uart_16550, (void *)(&tempL)}, |
{2, "jitter", "=%i", uart_jitter, (void *)(&tempL)}, |
{2, "rxfile", "=\"%s\"", uart_rxfile, (void *)(&tempS[0])}, |
{2, "txfile", "=\"%s\"", uart_txfile, (void *)(&tempS[0])}, |
381,9 → 383,9
} |
} |
|
void uart_rxfile () { |
void uart_irq () { |
if (current_device >= 0 && current_device < config.nuarts) |
strcpy (config.uarts[current_device].rxfile, tempS); |
config.uarts[current_device].irq = tempL; |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
390,9 → 392,9
} |
} |
|
void uart_txfile () { |
void uart_16550 () { |
if (current_device >= 0 && current_device < config.nuarts) |
strcpy (config.uarts[current_device].txfile, tempS); |
config.uarts[current_device].uart16550 = tempL; |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
399,9 → 401,9
} |
} |
|
void uart_vapi_id () { |
void uart_rxfile () { |
if (current_device >= 0 && current_device < config.nuarts) |
config.uarts[current_device].vapi_id = tempUL; |
strcpy (config.uarts[current_device].rxfile, tempS); |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
408,9 → 410,9
} |
} |
|
void uart_irq () { |
void uart_txfile () { |
if (current_device >= 0 && current_device < config.nuarts) |
config.uarts[current_device].irq = tempL; |
strcpy (config.uarts[current_device].txfile, tempS); |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
417,6 → 419,15
} |
} |
|
void uart_vapi_id () { |
if (current_device >= 0 && current_device < config.nuarts) |
config.uarts[current_device].vapi_id = tempUL; |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
} |
} |
|
void dma_baseaddr () { |
if (current_device >= 0 && current_device < config.ndmas) |
config.dmas[current_device].baseaddr = tempUL; |