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