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