qemu/hw/char/nrf51_uart.c
<<
>>
Prefs
   1/*
   2 * nRF51 SoC UART emulation
   3 *
   4 * See nRF51 Series Reference Manual, "29 Universal Asynchronous
   5 * Receiver/Transmitter" for hardware specifications:
   6 * http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
   7 *
   8 * Copyright (c) 2018 Julia Suvorova <jusual@mail.ru>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 or
  12 * (at your option) any later version.
  13 */
  14
  15#include "qemu/osdep.h"
  16#include "qemu/log.h"
  17#include "qemu/module.h"
  18#include "hw/char/nrf51_uart.h"
  19#include "trace.h"
  20
  21static void nrf51_uart_update_irq(NRF51UARTState *s)
  22{
  23    bool irq = false;
  24
  25    irq |= (s->reg[R_UART_RXDRDY] &&
  26            (s->reg[R_UART_INTEN] & R_UART_INTEN_RXDRDY_MASK));
  27    irq |= (s->reg[R_UART_TXDRDY] &&
  28            (s->reg[R_UART_INTEN] & R_UART_INTEN_TXDRDY_MASK));
  29    irq |= (s->reg[R_UART_ERROR]  &&
  30            (s->reg[R_UART_INTEN] & R_UART_INTEN_ERROR_MASK));
  31    irq |= (s->reg[R_UART_RXTO]   &&
  32            (s->reg[R_UART_INTEN] & R_UART_INTEN_RXTO_MASK));
  33
  34    qemu_set_irq(s->irq, irq);
  35}
  36
  37static uint64_t uart_read(void *opaque, hwaddr addr, unsigned int size)
  38{
  39    NRF51UARTState *s = NRF51_UART(opaque);
  40    uint64_t r;
  41
  42    if (!s->enabled) {
  43        return 0;
  44    }
  45
  46    switch (addr) {
  47    case A_UART_RXD:
  48        r = s->rx_fifo[s->rx_fifo_pos];
  49        if (s->rx_started && s->rx_fifo_len) {
  50            s->rx_fifo_pos = (s->rx_fifo_pos + 1) % UART_FIFO_LENGTH;
  51            s->rx_fifo_len--;
  52            if (s->rx_fifo_len) {
  53                s->reg[R_UART_RXDRDY] = 1;
  54                nrf51_uart_update_irq(s);
  55            }
  56            qemu_chr_fe_accept_input(&s->chr);
  57        }
  58        break;
  59    case A_UART_INTENSET:
  60    case A_UART_INTENCLR:
  61    case A_UART_INTEN:
  62        r = s->reg[R_UART_INTEN];
  63        break;
  64    default:
  65        r = s->reg[addr / 4];
  66        break;
  67    }
  68
  69    trace_nrf51_uart_read(addr, r, size);
  70
  71    return r;
  72}
  73
  74static gboolean uart_transmit(GIOChannel *chan, GIOCondition cond, void *opaque)
  75{
  76    NRF51UARTState *s = NRF51_UART(opaque);
  77    int r;
  78    uint8_t c = s->reg[R_UART_TXD];
  79
  80    s->watch_tag = 0;
  81
  82    r = qemu_chr_fe_write(&s->chr, &c, 1);
  83    if (r <= 0) {
  84        s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
  85                                             uart_transmit, s);
  86        if (!s->watch_tag) {
  87            /* The hardware has no transmit error reporting,
  88             * so silently drop the byte
  89             */
  90            goto buffer_drained;
  91        }
  92        return FALSE;
  93    }
  94
  95buffer_drained:
  96    s->reg[R_UART_TXDRDY] = 1;
  97    s->pending_tx_byte = false;
  98    return FALSE;
  99}
 100
 101static void uart_cancel_transmit(NRF51UARTState *s)
 102{
 103    if (s->watch_tag) {
 104        g_source_remove(s->watch_tag);
 105        s->watch_tag = 0;
 106    }
 107}
 108
 109static void uart_write(void *opaque, hwaddr addr,
 110                       uint64_t value, unsigned int size)
 111{
 112    NRF51UARTState *s = NRF51_UART(opaque);
 113
 114    trace_nrf51_uart_write(addr, value, size);
 115
 116    if (!s->enabled && (addr != A_UART_ENABLE)) {
 117        return;
 118    }
 119
 120    switch (addr) {
 121    case A_UART_TXD:
 122        if (!s->pending_tx_byte && s->tx_started) {
 123            s->reg[R_UART_TXD] = value;
 124            s->pending_tx_byte = true;
 125            uart_transmit(NULL, G_IO_OUT, s);
 126        }
 127        break;
 128    case A_UART_INTEN:
 129        s->reg[R_UART_INTEN] = value;
 130        break;
 131    case A_UART_INTENSET:
 132        s->reg[R_UART_INTEN] |= value;
 133        break;
 134    case A_UART_INTENCLR:
 135        s->reg[R_UART_INTEN] &= ~value;
 136        break;
 137    case A_UART_TXDRDY ... A_UART_RXTO:
 138        s->reg[addr / 4] = value;
 139        break;
 140    case A_UART_ERRORSRC:
 141        s->reg[addr / 4] &= ~value;
 142        break;
 143    case A_UART_RXD:
 144        break;
 145    case A_UART_RXDRDY:
 146        if (value == 0) {
 147            s->reg[R_UART_RXDRDY] = 0;
 148        }
 149        break;
 150    case A_UART_STARTTX:
 151        if (value == 1) {
 152            s->tx_started = true;
 153        }
 154        break;
 155    case A_UART_STARTRX:
 156        if (value == 1) {
 157            s->rx_started = true;
 158        }
 159        break;
 160    case A_UART_ENABLE:
 161        if (value) {
 162            if (value == 4) {
 163                s->enabled = true;
 164            }
 165            break;
 166        }
 167        s->enabled = false;
 168        value = 1;
 169        /* fall through */
 170    case A_UART_SUSPEND:
 171    case A_UART_STOPTX:
 172        if (value == 1) {
 173            s->tx_started = false;
 174        }
 175        /* fall through */
 176    case A_UART_STOPRX:
 177        if (addr != A_UART_STOPTX && value == 1) {
 178            s->rx_started = false;
 179            s->reg[R_UART_RXTO] = 1;
 180        }
 181        break;
 182    default:
 183        s->reg[addr / 4] = value;
 184        break;
 185    }
 186    nrf51_uart_update_irq(s);
 187}
 188
 189static const MemoryRegionOps uart_ops = {
 190    .read =  uart_read,
 191    .write = uart_write,
 192    .endianness = DEVICE_LITTLE_ENDIAN,
 193};
 194
 195static void nrf51_uart_reset(DeviceState *dev)
 196{
 197    NRF51UARTState *s = NRF51_UART(dev);
 198
 199    s->pending_tx_byte = 0;
 200
 201    uart_cancel_transmit(s);
 202
 203    memset(s->reg, 0, sizeof(s->reg));
 204
 205    s->reg[R_UART_PSELRTS] = 0xFFFFFFFF;
 206    s->reg[R_UART_PSELTXD] = 0xFFFFFFFF;
 207    s->reg[R_UART_PSELCTS] = 0xFFFFFFFF;
 208    s->reg[R_UART_PSELRXD] = 0xFFFFFFFF;
 209    s->reg[R_UART_BAUDRATE] = 0x4000000;
 210
 211    s->rx_fifo_len = 0;
 212    s->rx_fifo_pos = 0;
 213    s->rx_started = false;
 214    s->tx_started = false;
 215    s->enabled = false;
 216}
 217
 218static void uart_receive(void *opaque, const uint8_t *buf, int size)
 219{
 220
 221    NRF51UARTState *s = NRF51_UART(opaque);
 222    int i;
 223
 224    if (size == 0 || s->rx_fifo_len >= UART_FIFO_LENGTH) {
 225        return;
 226    }
 227
 228    for (i = 0; i < size; i++) {
 229        uint32_t pos = (s->rx_fifo_pos + s->rx_fifo_len) % UART_FIFO_LENGTH;
 230        s->rx_fifo[pos] = buf[i];
 231        s->rx_fifo_len++;
 232    }
 233
 234    s->reg[R_UART_RXDRDY] = 1;
 235    nrf51_uart_update_irq(s);
 236}
 237
 238static int uart_can_receive(void *opaque)
 239{
 240    NRF51UARTState *s = NRF51_UART(opaque);
 241
 242    return s->rx_started ? (UART_FIFO_LENGTH - s->rx_fifo_len) : 0;
 243}
 244
 245static void uart_event(void *opaque, int event)
 246{
 247    NRF51UARTState *s = NRF51_UART(opaque);
 248
 249    if (event == CHR_EVENT_BREAK) {
 250        s->reg[R_UART_ERRORSRC] |= 3;
 251        s->reg[R_UART_ERROR] = 1;
 252        nrf51_uart_update_irq(s);
 253    }
 254}
 255
 256static void nrf51_uart_realize(DeviceState *dev, Error **errp)
 257{
 258    NRF51UARTState *s = NRF51_UART(dev);
 259
 260    qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
 261                             uart_event, NULL, s, NULL, true);
 262}
 263
 264static void nrf51_uart_init(Object *obj)
 265{
 266    NRF51UARTState *s = NRF51_UART(obj);
 267    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 268
 269    memory_region_init_io(&s->iomem, obj, &uart_ops, s,
 270                          "nrf51_soc.uart", UART_SIZE);
 271    sysbus_init_mmio(sbd, &s->iomem);
 272    sysbus_init_irq(sbd, &s->irq);
 273}
 274
 275static int nrf51_uart_post_load(void *opaque, int version_id)
 276{
 277    NRF51UARTState *s = NRF51_UART(opaque);
 278
 279    if (s->pending_tx_byte) {
 280        s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
 281                                             uart_transmit, s);
 282    }
 283
 284    return 0;
 285}
 286
 287static const VMStateDescription nrf51_uart_vmstate = {
 288    .name = "nrf51_soc.uart",
 289    .post_load = nrf51_uart_post_load,
 290    .fields = (VMStateField[]) {
 291        VMSTATE_UINT32_ARRAY(reg, NRF51UARTState, 0x56C),
 292        VMSTATE_UINT8_ARRAY(rx_fifo, NRF51UARTState, UART_FIFO_LENGTH),
 293        VMSTATE_UINT32(rx_fifo_pos, NRF51UARTState),
 294        VMSTATE_UINT32(rx_fifo_len, NRF51UARTState),
 295        VMSTATE_BOOL(rx_started, NRF51UARTState),
 296        VMSTATE_BOOL(tx_started, NRF51UARTState),
 297        VMSTATE_BOOL(pending_tx_byte, NRF51UARTState),
 298        VMSTATE_BOOL(enabled, NRF51UARTState),
 299        VMSTATE_END_OF_LIST()
 300    }
 301};
 302
 303static Property nrf51_uart_properties[] = {
 304    DEFINE_PROP_CHR("chardev", NRF51UARTState, chr),
 305    DEFINE_PROP_END_OF_LIST(),
 306};
 307
 308static void nrf51_uart_class_init(ObjectClass *klass, void *data)
 309{
 310    DeviceClass *dc = DEVICE_CLASS(klass);
 311
 312    dc->reset = nrf51_uart_reset;
 313    dc->realize = nrf51_uart_realize;
 314    dc->props = nrf51_uart_properties;
 315    dc->vmsd = &nrf51_uart_vmstate;
 316}
 317
 318static const TypeInfo nrf51_uart_info = {
 319    .name = TYPE_NRF51_UART,
 320    .parent = TYPE_SYS_BUS_DEVICE,
 321    .instance_size = sizeof(NRF51UARTState),
 322    .instance_init = nrf51_uart_init,
 323    .class_init = nrf51_uart_class_init
 324};
 325
 326static void nrf51_uart_register_types(void)
 327{
 328    type_register_static(&nrf51_uart_info);
 329}
 330
 331type_init(nrf51_uart_register_types)
 332