Example #1
0
static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size)
{
    UartState *s = (UartState *)opaque;
    uint64_t new_rx_time = qemu_get_clock_ns(vm_clock);
    int i;

    if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {
        return;
    }

    s->r[R_SR] &= ~UART_SR_INTR_REMPTY;

    if (s->rx_count == RX_FIFO_SIZE) {
        s->r[R_CISR] |= UART_INTR_ROVR;
    } else {
        for (i = 0; i < size; i++) {
            s->r_fifo[s->rx_wpos] = buf[i];
            s->rx_wpos = (s->rx_wpos + 1) % RX_FIFO_SIZE;
            s->rx_count++;

            if (s->rx_count == RX_FIFO_SIZE) {
                s->r[R_SR] |= UART_SR_INTR_RFUL;
                break;
            }

            if (s->rx_count >= s->r[R_RTRIG]) {
                s->r[R_SR] |= UART_SR_INTR_RTRIG;
            }
        }
        qemu_mod_timer(s->fifo_trigger_handle, new_rx_time +
                                                (s->char_tx_time * 4));
    }
    uart_update_status(s);
}
Example #2
0
static uint64_t
uart_read(void *opaque, hwaddr addr, unsigned int size)
{
    struct xlx_uartlite *s = opaque;
    uint32_t r = 0;
    addr >>= 2;
    switch (addr)
    {
        case R_RX:
            r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 7];
            if (s->rx_fifo_len)
                s->rx_fifo_len--;
            uart_update_status(s);
            uart_update_irq(s);
            qemu_chr_accept_input(s->chr);
            break;

        default:
            if (addr < ARRAY_SIZE(s->regs))
                r = s->regs[addr];
            DUART(qemu_log("%s addr=%x v=%x\n", __func__, addr, r));
            break;
    }
    return r;
}
Example #3
0
static void uart_read_rx_fifo(UartState *s, uint32_t *c)
{
    if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {
        return;
    }

    s->r[R_SR] &= ~UART_SR_INTR_RFUL;

    if (s->rx_count) {
        uint32_t rx_rpos =
                (RX_FIFO_SIZE + s->rx_wpos - s->rx_count) % RX_FIFO_SIZE;
        *c = s->r_fifo[rx_rpos];
        s->rx_count--;

        if (!s->rx_count) {
            s->r[R_SR] |= UART_SR_INTR_REMPTY;
        }
        qemu_chr_accept_input(s->chr);
    } else {
        *c = 0;
        s->r[R_SR] |= UART_SR_INTR_REMPTY;
    }

    if (s->rx_count < s->r[R_RTRIG]) {
        s->r[R_SR] &= ~UART_SR_INTR_RTRIG;
    }
    uart_update_status(s);
}
Example #4
0
static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
                                  void *opaque)
{
    UartState *s = opaque;
    int ret;

    /* instant drain the fifo when there's no back-end */
    if (!s->chr) {
        s->tx_count = 0;
    }

    if (!s->tx_count) {
        return FALSE;
    }

    ret = qemu_chr_fe_write(s->chr, s->tx_fifo, s->tx_count);
    s->tx_count -= ret;
    memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_count);

    if (s->tx_count) {
        int r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT, cadence_uart_xmit, s);
        assert(r);
    }

    uart_update_status(s);
    return FALSE;
}
Example #5
0
static void fifo_trigger_update(void *opaque)
{
    UartState *s = (UartState *)opaque;

    s->r[R_CISR] |= UART_INTR_TIMEOUT;

    uart_update_status(s);
}
Example #6
0
static void fifo_trigger_update(void *opaque)
{
    CadenceUARTState *s = opaque;

    s->r[R_CISR] |= UART_INTR_TIMEOUT;

    uart_update_status(s);
}
Example #7
0
static int cadence_uart_post_load(void *opaque, int version_id)
{
    UartState *s = opaque;

    uart_parameters_setup(s);
    uart_update_status(s);
    return 0;
}
Example #8
0
static void uart_tx_redo(UartState *s)
{
    uint64_t new_tx_time = qemu_get_clock_ns(vm_clock);

    qemu_mod_timer(s->tx_time_handle, new_tx_time + s->char_tx_time);

    s->r[R_SR] |= UART_SR_INTR_TEMPTY;

    uart_update_status(s);
}
Example #9
0
static void uart_event(void *opaque, int event)
{
    UartState *s = (UartState *)opaque;
    uint8_t buf = '\0';

    if (event == CHR_EVENT_BREAK) {
        uart_write_rx_fifo(opaque, &buf, 1);
    }

    uart_update_status(s);
}
Example #10
0
static int xilinx_uartlite_init(SysBusDevice *dev)
{
    struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);

    sysbus_init_irq(dev, &s->irq);

    uart_update_status(s);
    memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4);
    sysbus_init_mmio(dev, &s->mmio);

    s->chr = qdev_init_chardev(&dev->qdev);
    if (s->chr)
        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
    return 0;
}
Example #11
0
static void cadence_uart_reset(DeviceState *dev)
{
    UartState *s = CADENCE_UART(dev);

    s->r[R_CR] = 0x00000128;
    s->r[R_IMR] = 0;
    s->r[R_CISR] = 0;
    s->r[R_RTRIG] = 0x00000020;
    s->r[R_BRGR] = 0x0000000F;
    s->r[R_TTRIG] = 0x00000020;

    uart_rx_reset(s);
    uart_tx_reset(s);

    uart_update_status(s);
}
Example #12
0
static int xilinx_uartlite_init(SysBusDevice *dev)
{
    XilinxUARTLite *s = XILINX_UARTLITE(dev);

    sysbus_init_irq(dev, &s->irq);

    uart_update_status(s);
    memory_region_init_io(&s->mmio, OBJECT(s), &uart_ops, s,
                          TYPE_XILINX_UARTLITE, R_MAX * 4);
    sysbus_init_mmio(dev, &s->mmio);

    s->chr = qemu_char_get_next_serial();
    if (s->chr)
        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
    return 0;
}
Example #13
0
static int xilinx_uartlite_init(SysBusDevice *dev)
{
    struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
    int uart_regs;

    sysbus_init_irq(dev, &s->irq);

    uart_update_status(s);
    uart_regs = cpu_register_io_memory(uart_read, uart_write, s,
                                       DEVICE_NATIVE_ENDIAN);
    sysbus_init_mmio(dev, R_MAX * 4, uart_regs);

    s->chr = qdev_init_chardev(&dev->qdev);
    if (s->chr)
        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
    return 0;
}
Example #14
0
static void uart_rx(void *opaque, const uint8_t *buf, int size)
{
    struct xlx_uartlite *s = opaque;

    /* Got a byte.  */
    if (s->rx_fifo_len >= 8) {
        printf("WARNING: UART dropped char.\n");
        return;
    }
    s->rx_fifo[s->rx_fifo_pos] = *buf;
    s->rx_fifo_pos++;
    s->rx_fifo_pos &= 0x7;
    s->rx_fifo_len++;

    uart_update_status(s);
    uart_update_irq(s);
}
Example #15
0
static void uart_write(void *opaque, hwaddr offset,
                          uint64_t value, unsigned size)
{
    CadenceUARTState *s = opaque;

    DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
    offset >>= 2;
    if (offset >= CADENCE_UART_R_MAX) {
        return;
    }
    switch (offset) {
    case R_IER: /* ier (wts imr) */
        s->r[R_IMR] |= value;
        break;
    case R_IDR: /* idr (wtc imr) */
        s->r[R_IMR] &= ~value;
        break;
    case R_IMR: /* imr (read only) */
        break;
    case R_CISR: /* cisr (wtc) */
        s->r[R_CISR] &= ~value;
        break;
    case R_TX_RX: /* UARTDR */
        switch (s->r[R_MR] & UART_MR_CHMODE) {
        case NORMAL_MODE:
            uart_write_tx_fifo(s, (uint8_t *) &value, 1);
            break;
        case LOCAL_LOOPBACK:
            uart_write_rx_fifo(opaque, (uint8_t *) &value, 1);
            break;
        }
        break;
    default:
        s->r[offset] = value;
    }

    switch (offset) {
    case R_CR:
        uart_ctrl_update(s);
        break;
    case R_MR:
        uart_parameters_setup(s);
        break;
    }
    uart_update_status(s);
}
Example #16
0
static void uart_read_rx_fifo(UartState *s, uint32_t *c)
{
    if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {
        return;
    }

    if (s->rx_count) {
        uint32_t rx_rpos =
                (RX_FIFO_SIZE + s->rx_wpos - s->rx_count) % RX_FIFO_SIZE;
        *c = s->rx_fifo[rx_rpos];
        s->rx_count--;

        qemu_chr_accept_input(s->chr);
    } else {
        *c = 0;
    }

    uart_update_status(s);
}
Example #17
0
static void
uart_write(void *opaque, hwaddr addr,
           uint64_t val64, unsigned int size)
{
    struct xlx_uartlite *s = opaque;
    uint32_t value = val64;
    unsigned char ch = value;

    addr >>= 2;
    switch (addr)
    {
        case R_STATUS:
            hw_error("write to UART STATUS?\n");
            break;

        case R_CTRL:
            if (value & CONTROL_RST_RX) {
                s->rx_fifo_pos = 0;
                s->rx_fifo_len = 0;
            }
            s->regs[addr] = value;
            break;

        case R_TX:
            if (s->chr)
                qemu_chr_fe_write(s->chr, &ch, 1);

            s->regs[addr] = value;

            /* hax.  */
            s->regs[R_STATUS] |= STATUS_IE;
            break;

        default:
            DUART(printf("%s addr=%x v=%x\n", __func__, addr, value));
            if (addr < ARRAY_SIZE(s->regs))
                s->regs[addr] = value;
            break;
    }
    uart_update_status(s);
    uart_update_irq(s);
}
Example #18
0
static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size)
{
    UartState *s = (UartState *)opaque;
    uint64_t new_rx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    int i;

    if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {
        return;
    }

    if (s->rx_count == RX_FIFO_SIZE) {
        s->r[R_CISR] |= UART_INTR_ROVR;
    } else {
        for (i = 0; i < size; i++) {
            s->rx_fifo[s->rx_wpos] = buf[i];
            s->rx_wpos = (s->rx_wpos + 1) % RX_FIFO_SIZE;
            s->rx_count++;
        }
        timer_mod(s->fifo_trigger_handle, new_rx_time +
                                                (s->char_tx_time * 4));
    }
    uart_update_status(s);
}
Example #19
0
static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
{
    struct xlx_uartlite *s = opaque;
    uint32_t r = 0;
    addr >>= 2;
    switch (addr)
    {
        case R_RX:
            r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 7];
            if (s->rx_fifo_len)
                s->rx_fifo_len--;
            uart_update_status(s);
            uart_update_irq(s);
            break;

        default:
            if (addr < ARRAY_SIZE(s->regs))
                r = s->regs[addr];
            DUART(qemu_log("%s addr=%x v=%x\n", __func__, addr, r));
            break;
    }
    return r;
}