Line 36... |
Line 36... |
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "pic.h"
|
#include "pic.h"
|
#include "vapi.h"
|
#include "vapi.h"
|
#include "sched.h"
|
#include "sched.h"
|
#include "channel.h"
|
#include "channel.h"
|
|
#include "debug.h"
|
|
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
|
static struct dev_16450 uarts[MAX_UARTS]; /* simulation info */
|
static struct dev_16450 uarts[MAX_UARTS]; /* simulation info */
|
static struct channel * channels[MAX_UARTS] = { NULL, }; /* emulation info */
|
static struct channel * channels[MAX_UARTS] = { NULL, }; /* emulation info */
|
Line 303... |
Line 304... |
if (uarts[uart].vapi.lcr & UART_LCR_STOP)
|
if (uarts[uart].vapi.lcr & UART_LCR_STOP)
|
fe |= ((packet >> (nbits++)) & 1) ^ 1;
|
fe |= ((packet >> (nbits++)) & 1) ^ 1;
|
|
|
debug (4, "lcr vapi %02x, uart %02x\n", uarts[uart].vapi.lcr, uarts[uart].regs.lcr);
|
debug (4, "lcr vapi %02x, uart %02x\n", uarts[uart].vapi.lcr, uarts[uart].regs.lcr);
|
data |= (uarts[uart].vapi.lcr << 8) | (pe << 16) | (fe << 17) | (uarts[uart].vapi.lcr << 8);
|
data |= (uarts[uart].vapi.lcr << 8) | (pe << 16) | (fe << 17) | (uarts[uart].vapi.lcr << 8);
|
PRINTF ("vapi_send (%08x, %08x)\n", config.uarts[uart].vapi_id, data);
|
PRINTF ("vapi_send (%08lx, %08x)\n", config.uarts[uart].vapi_id, data);
|
debug (4, "vapi_send (%08x, %08x)\n", config.uarts[uart].vapi_id, data);
|
debug (4, "vapi_send (%08x, %08x)\n", config.uarts[uart].vapi_id, data);
|
vapi_send (config.uarts[uart].vapi_id, data);
|
vapi_send (config.uarts[uart].vapi_id, data);
|
} else {
|
} else {
|
char buffer[1] = { uarts[uart].iregs.txser & 0xFF };
|
char buffer[1] = { uarts[uart].iregs.txser & 0xFF };
|
channel_write(channels[uart], buffer, 1);
|
channel_write(channels[uart], buffer, 1);
|
Line 421... |
Line 422... |
} else {
|
} else {
|
if (uarts[i].istat.rxser_full) {
|
if (uarts[i].istat.rxser_full) {
|
if (uarts[i].char_clks <= uarts[i].istat.rxser_clks++) {
|
if (uarts[i].char_clks <= uarts[i].istat.rxser_clks++) {
|
/* Set unused character bits to zero and allow lsr register in fifo */
|
/* Set unused character bits to zero and allow lsr register in fifo */
|
uarts[i].iregs.rxser &= ((1 << ((uarts[i].regs.lcr & 3) + 5)) - 1) | 0xff00;
|
uarts[i].iregs.rxser &= ((1 << ((uarts[i].regs.lcr & 3) + 5)) - 1) | 0xff00;
|
debug(4, "Receiving 0x%02x'%c' via UART%d...\n", uarts[i].iregs.rxser, uarts[i].iregs.rxser, i);
|
debug(4, "Receiving 0x%02x'%c' via UART%d...\n", uarts[i].iregs.rxser,
|
|
uarts[i].iregs.rxser, i);
|
PRINTF ("%c", uarts[i].iregs.rxser);
|
PRINTF ("%c", uarts[i].iregs.rxser);
|
uarts[i].istat.rxser_full = 0;
|
uarts[i].istat.rxser_full = 0;
|
uarts[i].istat.rxser_clks = 0;
|
uarts[i].istat.rxser_clks = 0;
|
uart_add_char (i, uarts[i].iregs.rxser);
|
uart_add_char (i, uarts[i].iregs.rxser);
|
}
|
}
|
Line 574... |
Line 576... |
memset(uarts, 0, sizeof(uarts));
|
memset(uarts, 0, sizeof(uarts));
|
|
|
for(i = 0; i < config.nuarts; i++) {
|
for(i = 0; i < config.nuarts; i++) {
|
if (config.uarts[i].vapi_id) {
|
if (config.uarts[i].vapi_id) {
|
if ((config.uarts[i].vapi_id & VAPI_DEVICE_ID) != i) {
|
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);
|
fprintf (stderr, "ERROR: Wrong vapi_id (0x%lx) 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;
|
config.uarts[i].vapi_id = 0;
|
} else {
|
} else {
|
vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read);
|
vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read);
|
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, 0, uart_read_byte, uart_write_byte);
|
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, 0, uart_read_byte, uart_write_byte);
|
}
|
}
|
Line 590... |
Line 592... |
if(channel_open(channels[i]) < 0) {
|
if(channel_open(channels[i]) < 0) {
|
debug (0, "WARNING: UART%d has problems with channel \"%s\".\n", i, config.uarts[i].channel);
|
debug (0, "WARNING: UART%d has problems with channel \"%s\".\n", i, config.uarts[i].channel);
|
continue;
|
continue;
|
}
|
}
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
PRINTF("UART%d at 0x%.8x uses ", i, config.uarts[i].baseaddr);
|
PRINTF("UART%d at 0x%.8lx uses ", i, config.uarts[i].baseaddr);
|
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, 0, uart_read_byte, uart_write_byte);
|
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, 0, uart_read_byte, uart_write_byte);
|
} else {
|
} else {
|
debug (0, "WARNING: UART%d has no vapi nor channel specified\n", i);
|
debug (0, "WARNING: UART%d has no vapi nor channel specified\n", i);
|
continue;
|
continue;
|
}
|
}
|
Line 629... |
Line 631... |
int i, j;
|
int i, j;
|
|
|
for(i = 0; i < config.nuarts; i++) {
|
for(i = 0; i < config.nuarts; i++) {
|
if ( !config.uarts[i].baseaddr )
|
if ( !config.uarts[i].baseaddr )
|
continue;
|
continue;
|
PRINTF("\nUART%d visible registers at 0x%.8x:\n", i, config.uarts[i].baseaddr);
|
PRINTF("\nUART%d visible registers at 0x%.8lx:\n", i,
|
|
config.uarts[i].baseaddr);
|
PRINTF("RXBUF: ");
|
PRINTF("RXBUF: ");
|
for (j = uarts[i].istat.rxbuf_head; j != uarts[i].istat.rxbuf_tail; j = (j + 1) % uarts[i].fifo_len)
|
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 (" %.2x", uarts[i].regs.rxbuf[j]);
|
PRINTF("TXBUF: ");
|
PRINTF("TXBUF: ");
|
for (j = uarts[i].istat.txbuf_head; j != uarts[i].istat.txbuf_tail; j = (j + 1) % uarts[i].fifo_len)
|
for (j = uarts[i].istat.txbuf_head; j != uarts[i].istat.txbuf_tail; j = (j + 1) % uarts[i].fifo_len)
|
Line 644... |
Line 647... |
PRINTF("LCR : %.2x MCR : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
|
PRINTF("LCR : %.2x MCR : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
|
PRINTF("LSR : %.2x MSR : %.2x\n", uarts[i].regs.lsr, uarts[i].regs.msr);
|
PRINTF("LSR : %.2x MSR : %.2x\n", uarts[i].regs.lsr, uarts[i].regs.msr);
|
PRINTF("SCR : %.2x\n", uarts[i].regs.scr);
|
PRINTF("SCR : %.2x\n", uarts[i].regs.scr);
|
|
|
PRINTF("\nInternal registers (sim debug):\n");
|
PRINTF("\nInternal registers (sim debug):\n");
|
PRINTF("RXSER: %.2x TXSER: %.2x\n", uarts[i].iregs.rxser, uarts[i].iregs.txser);
|
PRINTF("RXSER: %.2lx TXSER: %.2lx\n", uarts[i].iregs.rxser,
|
|
uarts[i].iregs.txser);
|
|
|
PRINTF("\nInternal status (sim debug):\n");
|
PRINTF("\nInternal status (sim debug):\n");
|
PRINTF("char_clks: %d\n", uarts[i].char_clks);
|
PRINTF("char_clks: %ld\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_clks: %ld txser_clks: %ld\n", uarts[i].istat.rxser_clks,
|
|
uarts[i].istat.txser_clks);
|
PRINTF("rxser: %d txser: %d\n", uarts[i].istat.rxser_full, uarts[i].istat.txser_full);
|
PRINTF("rxser: %d txser: %d\n", uarts[i].istat.rxser_full, uarts[i].istat.txser_full);
|
PRINTF("rxbuf_full: %d txbuf_full: %d\n", uarts[i].istat.rxbuf_full, uarts[i].istat.txbuf_full);
|
PRINTF("rxbuf_full: %d txbuf_full: %d\n", uarts[i].istat.rxbuf_full, uarts[i].istat.txbuf_full);
|
PRINTF("Using IRQ%i\n", config.uarts[i].irq);
|
PRINTF("Using IRQ%i\n", config.uarts[i].irq);
|
if (config.uarts[i].vapi_id)
|
if (config.uarts[i].vapi_id)
|
PRINTF ("Connected to vapi ID=%x\n\n", config.uarts[i].vapi_id);
|
PRINTF ("Connected to vapi ID=%lx\n\n", config.uarts[i].vapi_id);
|
/* TODO: replace by a channel_status
|
/* TODO: replace by a channel_status
|
else
|
else
|
PRINTF("RX fs: %p TX fs: %p\n\n", uarts[i].rxfs, uarts[i].txfs);
|
PRINTF("RX fs: %p TX fs: %p\n\n", uarts[i].rxfs, uarts[i].txfs);
|
*/
|
*/
|
}
|
}
|