Line 75... |
Line 75... |
|
|
return (char_clks * bauds_per_char) >> 1;
|
return (char_clks * bauds_per_char) >> 1;
|
}
|
}
|
|
|
/* Set a specific UART register with value. */
|
/* Set a specific UART register with value. */
|
void uart_write_byte(oraddr_t addr, uint32_t value, void *dat)
|
void uart_write_byte(oraddr_t addr, uint8_t value, void *dat)
|
{
|
{
|
struct dev_16450 *uart = dat;
|
struct dev_16450 *uart = dat;
|
|
|
TRACE("uart_write_byte(%"PRIxADDR",%02"PRIx32")\n", addr, value);
|
TRACE("uart_write_byte(%"PRIxADDR",%02"PRIx8")\n", addr, value);
|
|
|
if (uart->regs.lcr & UART_LCR_DLAB) {
|
if (uart->regs.lcr & UART_LCR_DLAB) {
|
switch (addr % UART_ADDR_SPACE) {
|
switch (addr) {
|
case UART_DLL:
|
case UART_DLL:
|
uart->regs.dll = value;
|
uart->regs.dll = value;
|
uart->char_clks = char_clks(uart->regs.dll, uart->regs.dlh, uart->regs.lcr);
|
uart->char_clks = char_clks(uart->regs.dll, uart->regs.dlh, uart->regs.lcr);
|
TRACE("\tSetting char_clks to %li (%02x, %02x, %02x)\n", uart->char_clks,
|
TRACE("\tSetting char_clks to %li (%02x, %02x, %02x)\n", uart->char_clks,
|
uart->regs.dll, uart->regs.dlh, uart->regs.lcr);
|
uart->regs.dll, uart->regs.dlh, uart->regs.lcr);
|
Line 95... |
Line 95... |
uart->regs.dlh = value;
|
uart->regs.dlh = value;
|
return;
|
return;
|
}
|
}
|
}
|
}
|
|
|
switch (addr % UART_ADDR_SPACE) {
|
switch (addr) {
|
case UART_TXBUF:
|
case UART_TXBUF:
|
if (uart->istat.txbuf_full < uart->fifo_len) {
|
if (uart->istat.txbuf_full < uart->fifo_len) {
|
uart->istat.txbuf_full++;
|
uart->istat.txbuf_full++;
|
uart->regs.txbuf[uart->istat.txbuf_head] = value;
|
uart->regs.txbuf[uart->istat.txbuf_head] = value;
|
uart->istat.txbuf_head = (uart->istat.txbuf_head + 1) % uart->fifo_len;
|
uart->istat.txbuf_head = (uart->istat.txbuf_head + 1) % uart->fifo_len;
|
Line 147... |
Line 147... |
TRACE("write out of range (addr %x)\n", addr);
|
TRACE("write out of range (addr %x)\n", addr);
|
}
|
}
|
}
|
}
|
|
|
/* Read a specific UART register. */
|
/* Read a specific UART register. */
|
uint32_t uart_read_byte(oraddr_t addr, void *dat)
|
uint8_t uart_read_byte(oraddr_t addr, void *dat)
|
{
|
{
|
struct dev_16450 *uart = dat;
|
struct dev_16450 *uart = dat;
|
uint8_t value = 0;
|
uint8_t value = 0;
|
|
|
TRACE("uart_read_byte(%"PRIxADDR")", addr);
|
TRACE("uart_read_byte(%"PRIxADDR")", addr);
|
|
|
if (uart->regs.lcr & UART_LCR_DLAB) {
|
if (uart->regs.lcr & UART_LCR_DLAB) {
|
switch (addr % UART_ADDR_SPACE) {
|
switch (addr) {
|
case UART_DLL:
|
case UART_DLL:
|
value = uart->regs.dll;
|
value = uart->regs.dll;
|
TRACE("= %"PRIx8"\n", value);
|
TRACE("= %"PRIx8"\n", value);
|
return value;
|
return value;
|
case UART_DLH:
|
case UART_DLH:
|
Line 167... |
Line 167... |
TRACE("= %"PRIx8"\n", value);
|
TRACE("= %"PRIx8"\n", value);
|
return value;
|
return value;
|
}
|
}
|
}
|
}
|
|
|
switch (addr % UART_ADDR_SPACE) {
|
switch (addr) {
|
case UART_RXBUF:
|
case UART_RXBUF:
|
{ /* Print out FIFO for debugging */
|
{ /* Print out FIFO for debugging */
|
int i;
|
int i;
|
TRACE("(%i/%i, %i, %i:", uart->istat.rxbuf_full, uart->fifo_len,
|
TRACE("(%i/%i, %i, %i:", uart->istat.rxbuf_full, uart->fifo_len,
|
uart->istat.rxbuf_head, uart->istat.rxbuf_tail);
|
uart->istat.rxbuf_head, uart->istat.rxbuf_tail);
|
Line 587... |
Line 587... |
else
|
else
|
uart->channel = channel_init(uart->channel_str);
|
uart->channel = channel_init(uart->channel_str);
|
if(channel_open(uart->channel) < 0) {
|
if(channel_open(uart->channel) < 0) {
|
WARN ("WARNING: problem with channel \"%s\" detected.\n", uart->channel_str);
|
WARN ("WARNING: problem with channel \"%s\" detected.\n", uart->channel_str);
|
} else if (config.sim.verbose)
|
} else if (config.sim.verbose)
|
PRINTF("UART at 0x%"PRIxADDR" uses ", uart->baseaddr);
|
PRINTF("UART at 0x%"PRIxADDR"\n", uart->baseaddr);
|
} else {
|
} else {
|
WARN ("WARNING: UART at %"PRIxADDR" has no vapi nor channel specified\n",
|
WARN ("WARNING: UART at %"PRIxADDR" has no vapi nor channel specified\n",
|
uart->baseaddr);
|
uart->baseaddr);
|
}
|
}
|
|
|
Line 759... |
Line 759... |
}
|
}
|
|
|
void uart_sec_end(void *dat)
|
void uart_sec_end(void *dat)
|
{
|
{
|
struct dev_16450 *uart = dat;
|
struct dev_16450 *uart = dat;
|
|
struct mem_ops ops;
|
|
|
if(!uart->enabled) {
|
if(!uart->enabled) {
|
free(dat);
|
free(dat);
|
return;
|
return;
|
}
|
}
|
register_memoryarea(uart->baseaddr, UART_ADDR_SPACE, 1, 0, uart_read_byte,
|
|
uart_write_byte, dat);
|
memset(&ops, 0, sizeof(struct mem_ops));
|
|
|
|
ops.readfunc8 = uart_read_byte;
|
|
ops.writefunc8 = uart_write_byte;
|
|
ops.read_dat8 = dat;
|
|
ops.write_dat8 = dat;
|
|
|
|
/* FIXME: What should these be? */
|
|
ops.delayr = 2;
|
|
ops.delayw = 2;
|
|
|
|
reg_mem_area(uart->baseaddr, UART_ADDR_SPACE, 0, &ops);
|
|
|
reg_sim_reset(uart_reset, dat);
|
reg_sim_reset(uart_reset, dat);
|
reg_sim_stat(uart_status, dat);
|
reg_sim_stat(uart_status, dat);
|
}
|
}
|
|
|
void reg_uart_sec(void)
|
void reg_uart_sec(void)
|