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