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