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