Line 257... |
Line 257... |
|
|
uarts[i].istat.rxbuf_head = uarts[i].istat.rxbuf_tail = 0;
|
uarts[i].istat.rxbuf_head = uarts[i].istat.rxbuf_tail = 0;
|
uarts[i].istat.txbuf_head = uarts[i].istat.txbuf_tail = 0;
|
uarts[i].istat.txbuf_head = uarts[i].istat.txbuf_tail = 0;
|
|
|
uarts[i].regs.lcr = UART_LCR_RESET;
|
uarts[i].regs.lcr = UART_LCR_RESET;
|
|
uarts[i].vapi.cur_break = uarts[i].vapi.cur_break_cnt = uarts[i].vapi.next_break = 0;
|
|
uarts[i].vapi.next_break_cnt = -1;
|
}
|
}
|
}
|
}
|
|
|
/* Simulation hook. Must be called every clock cycle to simulate all UART
|
/* Simulation hook. Must be called every clock cycle to simulate all UART
|
devices. It does internal functional UART simulation. */
|
devices. It does internal functional UART simulation. */
|
Line 273... |
Line 275... |
if VAPI is selected, we use VAPI streams. */
|
if VAPI is selected, we use VAPI streams. */
|
|
|
/* if txfs is corrupted, skip this uart. */
|
/* if txfs is corrupted, skip this uart. */
|
if (!config.uarts[i].vapi_id && !uarts[i].txfs) continue;
|
if (!config.uarts[i].vapi_id && !uarts[i].txfs) continue;
|
|
|
/* Transmit */
|
if (uarts[i].vapi.next_break_cnt >= 0)
|
|
if (--uarts[i].vapi.next_break_cnt < 0)
|
|
uarts[i].vapi.cur_break = uarts[i].vapi.next_break;
|
|
|
|
/***************** Transmit *****************/
|
if (!uarts[i].istat.txser_full) {
|
if (!uarts[i].istat.txser_full) {
|
uarts[i].regs.lsr |= UART_LSR_TXBUFE;
|
uarts[i].regs.lsr |= UART_LSR_TXBUFE;
|
if (uarts[i].istat.txbuf_full) {
|
if (uarts[i].istat.txbuf_full) {
|
uarts[i].iregs.txser = uarts[i].regs.txbuf[uarts[i].istat.txbuf_tail];
|
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.txbuf_tail = (uarts[i].istat.txbuf_tail + 1) % uarts[i].fifo_len;
|
Line 354... |
Line 360... |
}
|
}
|
uarts[i].istat.txser_full = 0;
|
uarts[i].istat.txser_full = 0;
|
uarts[i].istat.txser_clks = 0;
|
uarts[i].istat.txser_clks = 0;
|
}
|
}
|
|
|
/* Receive */
|
/***************** Receive *****************/
|
|
|
|
/* Is there a break? */
|
|
if (uarts[i].vapi.cur_break)
|
|
uarts[i].vapi.cur_break_cnt++;
|
|
if (uarts[i].vapi.cur_break_cnt > MAX_BREAK_COUNT * uarts[i].istat.rxser_clks) {
|
|
if (uarts[i].vapi.cur_break)
|
|
uarts[i].regs.lsr |= UART_LSR_BREAK;
|
|
else
|
|
uarts[i].vapi.cur_break_cnt = 0;
|
|
} 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++) {
|
debug(4, "Receiving via UART%d...\n", i);
|
debug(4, "Receiving via UART%d...\n", i);
|
uarts[i].istat.rxser_full = 0;
|
uarts[i].istat.rxser_full = 0;
|
uarts[i].istat.rxser_clks = 0;
|
uarts[i].istat.rxser_clks = 0;
|
Line 371... |
Line 387... |
uarts[i].istat.rxbuf_full++;
|
uarts[i].istat.rxbuf_full++;
|
}
|
}
|
uarts[i].regs.lsr |= UART_LSR_RDRDY;
|
uarts[i].regs.lsr |= UART_LSR_RDRDY;
|
}
|
}
|
}
|
}
|
|
}
|
|
|
/* Check if there is something waiting, and put it into rxser */
|
/* Check if there is something waiting, and put it into rxser */
|
if (uarts[i].regs.mcr & UART_MCR_LOOP) {
|
if (uarts[i].regs.mcr & UART_MCR_LOOP) {
|
uarts[i].iregs.rxser = uarts[i].iregs.loopback;
|
uarts[i].iregs.rxser = uarts[i].iregs.loopback;
|
uarts[i].istat.rxser_full = 1;
|
uarts[i].istat.rxser_full = 1;
|
Line 417... |
Line 434... |
uarts[i].vapi.lcr = (data >> 8) & 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;
|
|
case 0x04:
|
|
uarts[i].vapi.next_break_cnt = data & 0xffff;
|
|
uarts[i].vapi.next_break = (data >> 16) & 1;
|
|
break;
|
default:
|
default:
|
debug (0, "WARNING: Invalid vapi command %02x\n", data >> 24);
|
debug (0, "WARNING: Invalid vapi command %02x\n", data >> 24);
|
break;
|
break;
|
}
|
}
|
} else break;
|
} else break;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/* Loopback */
|
/***************** Loopback *****************/
|
if (uarts[i].regs.mcr & UART_MCR_LOOP) {
|
if (uarts[i].regs.mcr & UART_MCR_LOOP) {
|
debug(5, "uart_clock: Loopback\n");
|
debug(5, "uart_clock: Loopback\n");
|
if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
|
if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
|
((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
|
((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
|
uarts[i].regs.msr |= UART_MSR_DDCD;
|
uarts[i].regs.msr |= UART_MSR_DDCD;
|