Line 236... |
Line 236... |
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
|
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. */
|
} else if (config.uarts[i].txfile) { /* MM: Try to create stream. */
|
if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
|
if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
|
&& !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
|
&& !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
|
fprintf(stderr, "WARNING: UART%d has problems with RX file stream.\n", i);
|
debug (0, "WARNING: UART%d has problems with RX file stream.\n", i);
|
continue;
|
continue;
|
}
|
}
|
uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
|
uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
|
if (uarts[i].rxfs && uarts[i].txfs && config.sim.verbose) {
|
if (uarts[i].rxfs && uarts[i].txfs && config.sim.verbose) {
|
printf("UART%d at 0x%.8x uses ", i, config.uarts[i].baseaddr);
|
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);
|
printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile);
|
} else
|
} else
|
fprintf(stderr, "WARNING: UART%d has problems with TX file stream.\n", i);
|
debug (1, "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);
|
register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
|
}
|
}
|
|
|
if (config.uarts[i].uart16550)
|
if (config.uarts[i].uart16550)
|
uarts[i].fifo_len = 16;
|
uarts[i].fifo_len = 16;
|
Line 293... |
Line 293... |
uarts[i].iregs.loopback = uarts[i].iregs.txser;
|
uarts[i].iregs.loopback = uarts[i].iregs.txser;
|
else {
|
else {
|
/* Send to either VAPI or to file */
|
/* Send to either VAPI or to file */
|
if (config.uarts[i].vapi_id) {
|
if (config.uarts[i].vapi_id) {
|
int par, pe, fe, nbits = (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5;
|
int par, pe, fe, nbits = (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5;
|
int i, data;
|
int j, data;
|
unsigned long packet = 0;
|
unsigned long packet = 0;
|
|
|
/* Encode a packet */
|
/* Encode a packet */
|
packet = uarts[i].regs.lcr & ((1 << nbits) - 1);
|
packet = uarts[i].iregs.txser & ((1 << nbits) - 1);
|
|
|
/* Calculate parity */
|
/* Calculate parity */
|
for (i = 0; i < nbits; i++)
|
for (j = 0, par = 0; j < nbits; j++)
|
par ^= (packet >> i) & 1;
|
par ^= (packet >> j) & 1;
|
|
|
if (uarts[i].regs.lcr & UART_LCR_PARITY) {
|
if (uarts[i].regs.lcr & UART_LCR_PARITY) {
|
if (uarts[i].regs.lcr & UART_LCR_SPAR) {
|
if (uarts[i].regs.lcr & UART_LCR_SPAR) {
|
packet |= 1 << nbits;
|
packet |= 1 << nbits;
|
} else {
|
} else {
|
Line 323... |
Line 323... |
/* Decode a packet */
|
/* Decode a packet */
|
nbits = (uarts[i].vapi.lcr & UART_LCR_WLEN8) + 5;
|
nbits = (uarts[i].vapi.lcr & UART_LCR_WLEN8) + 5;
|
data = packet & ((1 << nbits) - 1);
|
data = packet & ((1 << nbits) - 1);
|
|
|
/* Calculate parity, including parity bit */
|
/* Calculate parity, including parity bit */
|
for (i = 0; i < nbits + 1; i++)
|
for (j = 0, par = 0; j < nbits + 1; j++)
|
par ^= (packet >> i) & 1;
|
par ^= (packet >> j) & 1;
|
|
|
if (uarts[i].vapi.lcr & UART_LCR_PARITY) {
|
if (uarts[i].vapi.lcr & UART_LCR_PARITY) {
|
if (uarts[i].vapi.lcr & UART_LCR_SPAR) {
|
if (uarts[i].vapi.lcr & UART_LCR_SPAR) {
|
pe = !((packet >> nbits) & 1);
|
pe = !((packet >> nbits) & 1);
|
} else {
|
} else {
|
Line 339... |
Line 339... |
}
|
}
|
nbits++;
|
nbits++;
|
} else
|
} else
|
pe = 0;
|
pe = 0;
|
|
|
fe |= ((packet >> (nbits++)) & 1) ^ 1;
|
fe = ((packet >> (nbits++)) & 1) ^ 1;
|
if (uarts[i].vapi.lcr & UART_LCR_STOP)
|
if (uarts[i].vapi.lcr & UART_LCR_STOP)
|
fe |= ((packet >> (nbits++)) & 1) ^ 1;
|
fe |= ((packet >> (nbits++)) & 1) ^ 1;
|
|
|
printf ("%08x %08x\n", config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
|
debug (4, "vapi_send (%08x, %08x)\n", config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
|
vapi_send (config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
|
vapi_send (config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
|
} else {
|
} else {
|
fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs);
|
fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs);
|
fflush(uarts[i].txfs);
|
fflush(uarts[i].txfs);
|
}
|
}
|
Line 383... |
Line 383... |
if((retval = fgetc(uarts[i].rxfs)) != EOF)
|
if((retval = fgetc(uarts[i].rxfs)) != EOF)
|
uarts[i].iregs.rxser = (char)retval;
|
uarts[i].iregs.rxser = (char)retval;
|
uarts[i].istat.rxser_full = 1;
|
uarts[i].istat.rxser_full = 1;
|
} else { /* VAPI */
|
} else { /* VAPI */
|
int received = 0;
|
int received = 0;
|
|
/* do not handle commands while receiving */
|
|
if (uarts[i].istat.rxser_full)
|
|
break;
|
while (!received) {
|
while (!received) {
|
if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
|
if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
|
unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
|
unsigned long data = 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].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % uarts[i].fifo_len;
|
switch (data >> 24) {
|
switch (data >> 24) {
|
Line 394... |
Line 397... |
uarts[i].vapi.lcr = (data >> 8) & 0xff;
|
uarts[i].vapi.lcr = (data >> 8) & 0xff;
|
/* Put data into rx fifo */
|
/* Put data into rx fifo */
|
uarts[i].vapi.char_clks = char_clks (uarts[i].vapi.dll, uarts[i].vapi.dlh, uarts[i].vapi.lcr);
|
uarts[i].vapi.char_clks = char_clks (uarts[i].vapi.dll, uarts[i].vapi.dlh, uarts[i].vapi.lcr);
|
if (uarts[i].vapi.lcr != uarts[i].regs.lcr || uarts[i].vapi.char_clks != uarts[i].char_clks
|
if (uarts[i].vapi.lcr != uarts[i].regs.lcr || uarts[i].vapi.char_clks != uarts[i].char_clks
|
|| uarts[i].vapi.skew < -MAX_SKEW || uarts[i].vapi.skew > MAX_SKEW) {
|
|| uarts[i].vapi.skew < -MAX_SKEW || uarts[i].vapi.skew > MAX_SKEW) {
|
fprintf (stderr, "WARNING: unmatched VAPI and uart modes.\n");
|
debug (3, "WARNING: unmatched VAPI and uart modes.\n");
|
/* Set error bits */
|
/* Set error bits */
|
uarts[i].regs.lsr |= UART_LSR_PARITY | UART_LSR_FRAME;
|
uarts[i].regs.lsr |= UART_LSR_PARITY | UART_LSR_FRAME;
|
break;
|
break;
|
} else {
|
} else {
|
uarts[i].iregs.rxser = data & 0xff;
|
uarts[i].iregs.rxser = data & 0xff;
|
Line 409... |
Line 412... |
case 0x01:
|
case 0x01:
|
uarts[i].vapi.dll = (data >> 0) & 0xff;
|
uarts[i].vapi.dll = (data >> 0) & 0xff;
|
uarts[i].vapi.dlh = (data >> 8) & 0xff;
|
uarts[i].vapi.dlh = (data >> 8) & 0xff;
|
break;
|
break;
|
case 0x02:
|
case 0x02:
|
uarts[i].vapi.lcr = data & 0xff;
|
uarts[i].vapi.lcr = (data >> 8) & 0xff;
|
break;
|
break;
|
case 0x03:
|
case 0x03:
|
uarts[i].vapi.skew = (signed short)(data & 0xffff);
|
uarts[i].vapi.skew = (signed short)(data & 0xffff);
|
break;
|
break;
|
default:
|
default:
|
fprintf (stderr, "WARNING: Invalid vapi command %02x\n", data >> 24);
|
debug (0, "WARNING: Invalid vapi command %02x\n", data >> 24);
|
break;
|
break;
|
}
|
}
|
} else break;
|
} else break;
|
}
|
}
|
}
|
}
|