119790847SJulia Suvorova /* 219790847SJulia Suvorova * nRF51 SoC UART emulation 319790847SJulia Suvorova * 419790847SJulia Suvorova * See nRF51 Series Reference Manual, "29 Universal Asynchronous 519790847SJulia Suvorova * Receiver/Transmitter" for hardware specifications: 619790847SJulia Suvorova * http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf 719790847SJulia Suvorova * 819790847SJulia Suvorova * Copyright (c) 2018 Julia Suvorova <jusual@mail.ru> 919790847SJulia Suvorova * 1019790847SJulia Suvorova * This program is free software; you can redistribute it and/or modify 1119790847SJulia Suvorova * it under the terms of the GNU General Public License version 2 or 1219790847SJulia Suvorova * (at your option) any later version. 1319790847SJulia Suvorova */ 1419790847SJulia Suvorova 1519790847SJulia Suvorova #include "qemu/osdep.h" 1619790847SJulia Suvorova #include "qemu/log.h" 170b8fa32fSMarkus Armbruster #include "qemu/module.h" 1819790847SJulia Suvorova #include "hw/char/nrf51_uart.h" 1964552b6bSMarkus Armbruster #include "hw/irq.h" 20*a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 21d6454270SMarkus Armbruster #include "migration/vmstate.h" 2219790847SJulia Suvorova #include "trace.h" 2319790847SJulia Suvorova 2419790847SJulia Suvorova static void nrf51_uart_update_irq(NRF51UARTState *s) 2519790847SJulia Suvorova { 2619790847SJulia Suvorova bool irq = false; 2719790847SJulia Suvorova 2819790847SJulia Suvorova irq |= (s->reg[R_UART_RXDRDY] && 2919790847SJulia Suvorova (s->reg[R_UART_INTEN] & R_UART_INTEN_RXDRDY_MASK)); 3019790847SJulia Suvorova irq |= (s->reg[R_UART_TXDRDY] && 3119790847SJulia Suvorova (s->reg[R_UART_INTEN] & R_UART_INTEN_TXDRDY_MASK)); 3219790847SJulia Suvorova irq |= (s->reg[R_UART_ERROR] && 3319790847SJulia Suvorova (s->reg[R_UART_INTEN] & R_UART_INTEN_ERROR_MASK)); 3419790847SJulia Suvorova irq |= (s->reg[R_UART_RXTO] && 3519790847SJulia Suvorova (s->reg[R_UART_INTEN] & R_UART_INTEN_RXTO_MASK)); 3619790847SJulia Suvorova 3719790847SJulia Suvorova qemu_set_irq(s->irq, irq); 3819790847SJulia Suvorova } 3919790847SJulia Suvorova 4019790847SJulia Suvorova static uint64_t uart_read(void *opaque, hwaddr addr, unsigned int size) 4119790847SJulia Suvorova { 4219790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 4319790847SJulia Suvorova uint64_t r; 4419790847SJulia Suvorova 4519790847SJulia Suvorova if (!s->enabled) { 4619790847SJulia Suvorova return 0; 4719790847SJulia Suvorova } 4819790847SJulia Suvorova 4919790847SJulia Suvorova switch (addr) { 5019790847SJulia Suvorova case A_UART_RXD: 5119790847SJulia Suvorova r = s->rx_fifo[s->rx_fifo_pos]; 5219790847SJulia Suvorova if (s->rx_started && s->rx_fifo_len) { 5319790847SJulia Suvorova s->rx_fifo_pos = (s->rx_fifo_pos + 1) % UART_FIFO_LENGTH; 5419790847SJulia Suvorova s->rx_fifo_len--; 5519790847SJulia Suvorova if (s->rx_fifo_len) { 5619790847SJulia Suvorova s->reg[R_UART_RXDRDY] = 1; 5719790847SJulia Suvorova nrf51_uart_update_irq(s); 5819790847SJulia Suvorova } 5919790847SJulia Suvorova qemu_chr_fe_accept_input(&s->chr); 6019790847SJulia Suvorova } 6119790847SJulia Suvorova break; 6219790847SJulia Suvorova case A_UART_INTENSET: 6319790847SJulia Suvorova case A_UART_INTENCLR: 6419790847SJulia Suvorova case A_UART_INTEN: 6519790847SJulia Suvorova r = s->reg[R_UART_INTEN]; 6619790847SJulia Suvorova break; 6719790847SJulia Suvorova default: 6819790847SJulia Suvorova r = s->reg[addr / 4]; 6919790847SJulia Suvorova break; 7019790847SJulia Suvorova } 7119790847SJulia Suvorova 7219790847SJulia Suvorova trace_nrf51_uart_read(addr, r, size); 7319790847SJulia Suvorova 7419790847SJulia Suvorova return r; 7519790847SJulia Suvorova } 7619790847SJulia Suvorova 7719790847SJulia Suvorova static gboolean uart_transmit(GIOChannel *chan, GIOCondition cond, void *opaque) 7819790847SJulia Suvorova { 7919790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 8019790847SJulia Suvorova int r; 8119790847SJulia Suvorova uint8_t c = s->reg[R_UART_TXD]; 8219790847SJulia Suvorova 8319790847SJulia Suvorova s->watch_tag = 0; 8419790847SJulia Suvorova 8519790847SJulia Suvorova r = qemu_chr_fe_write(&s->chr, &c, 1); 8619790847SJulia Suvorova if (r <= 0) { 8719790847SJulia Suvorova s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP, 8819790847SJulia Suvorova uart_transmit, s); 8919790847SJulia Suvorova if (!s->watch_tag) { 9019790847SJulia Suvorova /* The hardware has no transmit error reporting, 9119790847SJulia Suvorova * so silently drop the byte 9219790847SJulia Suvorova */ 9319790847SJulia Suvorova goto buffer_drained; 9419790847SJulia Suvorova } 9519790847SJulia Suvorova return FALSE; 9619790847SJulia Suvorova } 9719790847SJulia Suvorova 9819790847SJulia Suvorova buffer_drained: 9919790847SJulia Suvorova s->reg[R_UART_TXDRDY] = 1; 10019790847SJulia Suvorova s->pending_tx_byte = false; 10119790847SJulia Suvorova return FALSE; 10219790847SJulia Suvorova } 10319790847SJulia Suvorova 10419790847SJulia Suvorova static void uart_cancel_transmit(NRF51UARTState *s) 10519790847SJulia Suvorova { 10619790847SJulia Suvorova if (s->watch_tag) { 10719790847SJulia Suvorova g_source_remove(s->watch_tag); 10819790847SJulia Suvorova s->watch_tag = 0; 10919790847SJulia Suvorova } 11019790847SJulia Suvorova } 11119790847SJulia Suvorova 11219790847SJulia Suvorova static void uart_write(void *opaque, hwaddr addr, 11319790847SJulia Suvorova uint64_t value, unsigned int size) 11419790847SJulia Suvorova { 11519790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 11619790847SJulia Suvorova 11719790847SJulia Suvorova trace_nrf51_uart_write(addr, value, size); 11819790847SJulia Suvorova 11919790847SJulia Suvorova if (!s->enabled && (addr != A_UART_ENABLE)) { 12019790847SJulia Suvorova return; 12119790847SJulia Suvorova } 12219790847SJulia Suvorova 12319790847SJulia Suvorova switch (addr) { 12419790847SJulia Suvorova case A_UART_TXD: 12519790847SJulia Suvorova if (!s->pending_tx_byte && s->tx_started) { 12619790847SJulia Suvorova s->reg[R_UART_TXD] = value; 12719790847SJulia Suvorova s->pending_tx_byte = true; 12819790847SJulia Suvorova uart_transmit(NULL, G_IO_OUT, s); 12919790847SJulia Suvorova } 13019790847SJulia Suvorova break; 13119790847SJulia Suvorova case A_UART_INTEN: 13219790847SJulia Suvorova s->reg[R_UART_INTEN] = value; 13319790847SJulia Suvorova break; 13419790847SJulia Suvorova case A_UART_INTENSET: 13519790847SJulia Suvorova s->reg[R_UART_INTEN] |= value; 13619790847SJulia Suvorova break; 13719790847SJulia Suvorova case A_UART_INTENCLR: 13819790847SJulia Suvorova s->reg[R_UART_INTEN] &= ~value; 13919790847SJulia Suvorova break; 14019790847SJulia Suvorova case A_UART_TXDRDY ... A_UART_RXTO: 14119790847SJulia Suvorova s->reg[addr / 4] = value; 14219790847SJulia Suvorova break; 14319790847SJulia Suvorova case A_UART_ERRORSRC: 14419790847SJulia Suvorova s->reg[addr / 4] &= ~value; 14519790847SJulia Suvorova break; 14619790847SJulia Suvorova case A_UART_RXD: 14719790847SJulia Suvorova break; 14819790847SJulia Suvorova case A_UART_RXDRDY: 14919790847SJulia Suvorova if (value == 0) { 15019790847SJulia Suvorova s->reg[R_UART_RXDRDY] = 0; 15119790847SJulia Suvorova } 15219790847SJulia Suvorova break; 15319790847SJulia Suvorova case A_UART_STARTTX: 15419790847SJulia Suvorova if (value == 1) { 15519790847SJulia Suvorova s->tx_started = true; 15619790847SJulia Suvorova } 15719790847SJulia Suvorova break; 15819790847SJulia Suvorova case A_UART_STARTRX: 15919790847SJulia Suvorova if (value == 1) { 16019790847SJulia Suvorova s->rx_started = true; 16119790847SJulia Suvorova } 16219790847SJulia Suvorova break; 16319790847SJulia Suvorova case A_UART_ENABLE: 16419790847SJulia Suvorova if (value) { 16519790847SJulia Suvorova if (value == 4) { 16619790847SJulia Suvorova s->enabled = true; 16719790847SJulia Suvorova } 16819790847SJulia Suvorova break; 16919790847SJulia Suvorova } 17019790847SJulia Suvorova s->enabled = false; 17119790847SJulia Suvorova value = 1; 17219790847SJulia Suvorova /* fall through */ 17319790847SJulia Suvorova case A_UART_SUSPEND: 17419790847SJulia Suvorova case A_UART_STOPTX: 17519790847SJulia Suvorova if (value == 1) { 17619790847SJulia Suvorova s->tx_started = false; 17719790847SJulia Suvorova } 17819790847SJulia Suvorova /* fall through */ 17919790847SJulia Suvorova case A_UART_STOPRX: 18019790847SJulia Suvorova if (addr != A_UART_STOPTX && value == 1) { 18119790847SJulia Suvorova s->rx_started = false; 18219790847SJulia Suvorova s->reg[R_UART_RXTO] = 1; 18319790847SJulia Suvorova } 18419790847SJulia Suvorova break; 18519790847SJulia Suvorova default: 18619790847SJulia Suvorova s->reg[addr / 4] = value; 18719790847SJulia Suvorova break; 18819790847SJulia Suvorova } 18919790847SJulia Suvorova nrf51_uart_update_irq(s); 19019790847SJulia Suvorova } 19119790847SJulia Suvorova 19219790847SJulia Suvorova static const MemoryRegionOps uart_ops = { 19319790847SJulia Suvorova .read = uart_read, 19419790847SJulia Suvorova .write = uart_write, 19519790847SJulia Suvorova .endianness = DEVICE_LITTLE_ENDIAN, 19619790847SJulia Suvorova }; 19719790847SJulia Suvorova 19819790847SJulia Suvorova static void nrf51_uart_reset(DeviceState *dev) 19919790847SJulia Suvorova { 20019790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(dev); 20119790847SJulia Suvorova 20219790847SJulia Suvorova s->pending_tx_byte = 0; 20319790847SJulia Suvorova 20419790847SJulia Suvorova uart_cancel_transmit(s); 20519790847SJulia Suvorova 20619790847SJulia Suvorova memset(s->reg, 0, sizeof(s->reg)); 20719790847SJulia Suvorova 20819790847SJulia Suvorova s->reg[R_UART_PSELRTS] = 0xFFFFFFFF; 20919790847SJulia Suvorova s->reg[R_UART_PSELTXD] = 0xFFFFFFFF; 21019790847SJulia Suvorova s->reg[R_UART_PSELCTS] = 0xFFFFFFFF; 21119790847SJulia Suvorova s->reg[R_UART_PSELRXD] = 0xFFFFFFFF; 21219790847SJulia Suvorova s->reg[R_UART_BAUDRATE] = 0x4000000; 21319790847SJulia Suvorova 21419790847SJulia Suvorova s->rx_fifo_len = 0; 21519790847SJulia Suvorova s->rx_fifo_pos = 0; 21619790847SJulia Suvorova s->rx_started = false; 21719790847SJulia Suvorova s->tx_started = false; 21819790847SJulia Suvorova s->enabled = false; 21919790847SJulia Suvorova } 22019790847SJulia Suvorova 22119790847SJulia Suvorova static void uart_receive(void *opaque, const uint8_t *buf, int size) 22219790847SJulia Suvorova { 22319790847SJulia Suvorova 22419790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 22519790847SJulia Suvorova int i; 22619790847SJulia Suvorova 22719790847SJulia Suvorova if (size == 0 || s->rx_fifo_len >= UART_FIFO_LENGTH) { 22819790847SJulia Suvorova return; 22919790847SJulia Suvorova } 23019790847SJulia Suvorova 23119790847SJulia Suvorova for (i = 0; i < size; i++) { 23219790847SJulia Suvorova uint32_t pos = (s->rx_fifo_pos + s->rx_fifo_len) % UART_FIFO_LENGTH; 23319790847SJulia Suvorova s->rx_fifo[pos] = buf[i]; 23419790847SJulia Suvorova s->rx_fifo_len++; 23519790847SJulia Suvorova } 23619790847SJulia Suvorova 23719790847SJulia Suvorova s->reg[R_UART_RXDRDY] = 1; 23819790847SJulia Suvorova nrf51_uart_update_irq(s); 23919790847SJulia Suvorova } 24019790847SJulia Suvorova 24119790847SJulia Suvorova static int uart_can_receive(void *opaque) 24219790847SJulia Suvorova { 24319790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 24419790847SJulia Suvorova 24519790847SJulia Suvorova return s->rx_started ? (UART_FIFO_LENGTH - s->rx_fifo_len) : 0; 24619790847SJulia Suvorova } 24719790847SJulia Suvorova 24819790847SJulia Suvorova static void uart_event(void *opaque, int event) 24919790847SJulia Suvorova { 25019790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 25119790847SJulia Suvorova 25219790847SJulia Suvorova if (event == CHR_EVENT_BREAK) { 25319790847SJulia Suvorova s->reg[R_UART_ERRORSRC] |= 3; 25419790847SJulia Suvorova s->reg[R_UART_ERROR] = 1; 25519790847SJulia Suvorova nrf51_uart_update_irq(s); 25619790847SJulia Suvorova } 25719790847SJulia Suvorova } 25819790847SJulia Suvorova 25919790847SJulia Suvorova static void nrf51_uart_realize(DeviceState *dev, Error **errp) 26019790847SJulia Suvorova { 26119790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(dev); 26219790847SJulia Suvorova 26319790847SJulia Suvorova qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive, 26419790847SJulia Suvorova uart_event, NULL, s, NULL, true); 26519790847SJulia Suvorova } 26619790847SJulia Suvorova 26719790847SJulia Suvorova static void nrf51_uart_init(Object *obj) 26819790847SJulia Suvorova { 26919790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(obj); 27019790847SJulia Suvorova SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 27119790847SJulia Suvorova 27219790847SJulia Suvorova memory_region_init_io(&s->iomem, obj, &uart_ops, s, 27319790847SJulia Suvorova "nrf51_soc.uart", UART_SIZE); 27419790847SJulia Suvorova sysbus_init_mmio(sbd, &s->iomem); 27519790847SJulia Suvorova sysbus_init_irq(sbd, &s->irq); 27619790847SJulia Suvorova } 27719790847SJulia Suvorova 27819790847SJulia Suvorova static int nrf51_uart_post_load(void *opaque, int version_id) 27919790847SJulia Suvorova { 28019790847SJulia Suvorova NRF51UARTState *s = NRF51_UART(opaque); 28119790847SJulia Suvorova 28219790847SJulia Suvorova if (s->pending_tx_byte) { 28319790847SJulia Suvorova s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP, 28419790847SJulia Suvorova uart_transmit, s); 28519790847SJulia Suvorova } 28619790847SJulia Suvorova 28719790847SJulia Suvorova return 0; 28819790847SJulia Suvorova } 28919790847SJulia Suvorova 29019790847SJulia Suvorova static const VMStateDescription nrf51_uart_vmstate = { 29119790847SJulia Suvorova .name = "nrf51_soc.uart", 29219790847SJulia Suvorova .post_load = nrf51_uart_post_load, 29319790847SJulia Suvorova .fields = (VMStateField[]) { 29419790847SJulia Suvorova VMSTATE_UINT32_ARRAY(reg, NRF51UARTState, 0x56C), 29519790847SJulia Suvorova VMSTATE_UINT8_ARRAY(rx_fifo, NRF51UARTState, UART_FIFO_LENGTH), 29619790847SJulia Suvorova VMSTATE_UINT32(rx_fifo_pos, NRF51UARTState), 29719790847SJulia Suvorova VMSTATE_UINT32(rx_fifo_len, NRF51UARTState), 29819790847SJulia Suvorova VMSTATE_BOOL(rx_started, NRF51UARTState), 29919790847SJulia Suvorova VMSTATE_BOOL(tx_started, NRF51UARTState), 30019790847SJulia Suvorova VMSTATE_BOOL(pending_tx_byte, NRF51UARTState), 30119790847SJulia Suvorova VMSTATE_BOOL(enabled, NRF51UARTState), 30219790847SJulia Suvorova VMSTATE_END_OF_LIST() 30319790847SJulia Suvorova } 30419790847SJulia Suvorova }; 30519790847SJulia Suvorova 30619790847SJulia Suvorova static Property nrf51_uart_properties[] = { 30719790847SJulia Suvorova DEFINE_PROP_CHR("chardev", NRF51UARTState, chr), 30819790847SJulia Suvorova DEFINE_PROP_END_OF_LIST(), 30919790847SJulia Suvorova }; 31019790847SJulia Suvorova 31119790847SJulia Suvorova static void nrf51_uart_class_init(ObjectClass *klass, void *data) 31219790847SJulia Suvorova { 31319790847SJulia Suvorova DeviceClass *dc = DEVICE_CLASS(klass); 31419790847SJulia Suvorova 31519790847SJulia Suvorova dc->reset = nrf51_uart_reset; 31619790847SJulia Suvorova dc->realize = nrf51_uart_realize; 31719790847SJulia Suvorova dc->props = nrf51_uart_properties; 31819790847SJulia Suvorova dc->vmsd = &nrf51_uart_vmstate; 31919790847SJulia Suvorova } 32019790847SJulia Suvorova 32119790847SJulia Suvorova static const TypeInfo nrf51_uart_info = { 32219790847SJulia Suvorova .name = TYPE_NRF51_UART, 32319790847SJulia Suvorova .parent = TYPE_SYS_BUS_DEVICE, 32419790847SJulia Suvorova .instance_size = sizeof(NRF51UARTState), 32519790847SJulia Suvorova .instance_init = nrf51_uart_init, 32619790847SJulia Suvorova .class_init = nrf51_uart_class_init 32719790847SJulia Suvorova }; 32819790847SJulia Suvorova 32919790847SJulia Suvorova static void nrf51_uart_register_types(void) 33019790847SJulia Suvorova { 33119790847SJulia Suvorova type_register_static(&nrf51_uart_info); 33219790847SJulia Suvorova } 33319790847SJulia Suvorova 33419790847SJulia Suvorova type_init(nrf51_uart_register_types) 335