]> git.proxmox.com Git - mirror_qemu.git/blame - hw/char/cmsdk-apb-uart.c
hw/char: sifive_uart: Register device in 'input' category
[mirror_qemu.git] / hw / char / cmsdk-apb-uart.c
CommitLineData
775df84e
PM
1/*
2 * ARM CMSDK APB UART emulation
3 *
4 * Copyright (c) 2017 Linaro Limited
5 * Written by Peter Maydell
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 or
9 * (at your option) any later version.
10 */
11
12/* This is a model of the "APB UART" which is part of the Cortex-M
13 * System Design Kit (CMSDK) and documented in the Cortex-M System
14 * Design Kit Technical Reference Manual (ARM DDI0479C):
15 * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
16 */
17
18#include "qemu/osdep.h"
19#include "qemu/log.h"
0b8fa32f 20#include "qemu/module.h"
775df84e
PM
21#include "qapi/error.h"
22#include "trace.h"
23#include "hw/sysbus.h"
d6454270 24#include "migration/vmstate.h"
775df84e
PM
25#include "hw/registerfields.h"
26#include "chardev/char-fe.h"
27#include "chardev/char-serial.h"
28#include "hw/char/cmsdk-apb-uart.h"
64552b6b 29#include "hw/irq.h"
ce35e229 30#include "hw/qdev-properties-system.h"
775df84e
PM
31
32REG32(DATA, 0)
33REG32(STATE, 4)
34 FIELD(STATE, TXFULL, 0, 1)
35 FIELD(STATE, RXFULL, 1, 1)
36 FIELD(STATE, TXOVERRUN, 2, 1)
37 FIELD(STATE, RXOVERRUN, 3, 1)
38REG32(CTRL, 8)
39 FIELD(CTRL, TX_EN, 0, 1)
40 FIELD(CTRL, RX_EN, 1, 1)
41 FIELD(CTRL, TX_INTEN, 2, 1)
42 FIELD(CTRL, RX_INTEN, 3, 1)
43 FIELD(CTRL, TXO_INTEN, 4, 1)
44 FIELD(CTRL, RXO_INTEN, 5, 1)
45 FIELD(CTRL, HSTEST, 6, 1)
46REG32(INTSTATUS, 0xc)
47 FIELD(INTSTATUS, TX, 0, 1)
48 FIELD(INTSTATUS, RX, 1, 1)
49 FIELD(INTSTATUS, TXO, 2, 1)
50 FIELD(INTSTATUS, RXO, 3, 1)
51REG32(BAUDDIV, 0x10)
52REG32(PID4, 0xFD0)
53REG32(PID5, 0xFD4)
54REG32(PID6, 0xFD8)
55REG32(PID7, 0xFDC)
56REG32(PID0, 0xFE0)
57REG32(PID1, 0xFE4)
58REG32(PID2, 0xFE8)
59REG32(PID3, 0xFEC)
60REG32(CID0, 0xFF0)
61REG32(CID1, 0xFF4)
62REG32(CID2, 0xFF8)
63REG32(CID3, 0xFFC)
64
65/* PID/CID values */
66static const int uart_id[] = {
67 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
68 0x21, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
69 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
70};
71
72static bool uart_baudrate_ok(CMSDKAPBUART *s)
73{
74 /* The minimum permitted bauddiv setting is 16, so we just ignore
75 * settings below that (usually this means the device has just
76 * been reset and not yet programmed).
77 */
78 return s->bauddiv >= 16 && s->bauddiv <= s->pclk_frq;
79}
80
81static void uart_update_parameters(CMSDKAPBUART *s)
82{
83 QEMUSerialSetParams ssp;
84
85 /* This UART is always 8N1 but the baud rate is programmable. */
86 if (!uart_baudrate_ok(s)) {
87 return;
88 }
89
90 ssp.data_bits = 8;
91 ssp.parity = 'N';
92 ssp.stop_bits = 1;
93 ssp.speed = s->pclk_frq / s->bauddiv;
94 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
95 trace_cmsdk_apb_uart_set_params(ssp.speed);
96}
97
98static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
99{
100 /* update outbound irqs, including handling the way the rxo and txo
101 * interrupt status bits are just logical AND of the overrun bit in
102 * STATE and the overrun interrupt enable bit in CTRL.
103 */
104 uint32_t omask = (R_INTSTATUS_RXO_MASK | R_INTSTATUS_TXO_MASK);
105 s->intstatus &= ~omask;
106 s->intstatus |= (s->state & (s->ctrl >> 2) & omask);
107
108 qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK));
109 qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK));
110 qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK));
111 qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK));
112 qemu_set_irq(s->uartint, !!(s->intstatus));
113}
114
115static int uart_can_receive(void *opaque)
116{
117 CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
118
119 /* We can take a char if RX is enabled and the buffer is empty */
120 if (s->ctrl & R_CTRL_RX_EN_MASK && !(s->state & R_STATE_RXFULL_MASK)) {
121 return 1;
122 }
123 return 0;
124}
125
126static void uart_receive(void *opaque, const uint8_t *buf, int size)
127{
128 CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
129
130 trace_cmsdk_apb_uart_receive(*buf);
131
132 /* In fact uart_can_receive() ensures that we can't be
133 * called unless RX is enabled and the buffer is empty,
134 * but we include this logic as documentation of what the
135 * hardware does if a character arrives in these circumstances.
136 */
137 if (!(s->ctrl & R_CTRL_RX_EN_MASK)) {
138 /* Just drop the character on the floor */
139 return;
140 }
141
142 if (s->state & R_STATE_RXFULL_MASK) {
143 s->state |= R_STATE_RXOVERRUN_MASK;
144 }
145
146 s->rxbuf = *buf;
147 s->state |= R_STATE_RXFULL_MASK;
148 if (s->ctrl & R_CTRL_RX_INTEN_MASK) {
149 s->intstatus |= R_INTSTATUS_RX_MASK;
150 }
151 cmsdk_apb_uart_update(s);
152}
153
154static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
155{
156 CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
157 uint64_t r;
158
159 switch (offset) {
160 case A_DATA:
161 r = s->rxbuf;
162 s->state &= ~R_STATE_RXFULL_MASK;
163 cmsdk_apb_uart_update(s);
0c6a108e 164 qemu_chr_fe_accept_input(&s->chr);
775df84e
PM
165 break;
166 case A_STATE:
167 r = s->state;
168 break;
169 case A_CTRL:
170 r = s->ctrl;
171 break;
172 case A_INTSTATUS:
173 r = s->intstatus;
174 break;
175 case A_BAUDDIV:
176 r = s->bauddiv;
177 break;
178 case A_PID4 ... A_CID3:
179 r = uart_id[(offset - A_PID4) / 4];
180 break;
181 default:
182 qemu_log_mask(LOG_GUEST_ERROR,
183 "CMSDK APB UART read: bad offset %x\n", (int) offset);
184 r = 0;
185 break;
186 }
187 trace_cmsdk_apb_uart_read(offset, r, size);
188 return r;
189}
190
191/* Try to send tx data, and arrange to be called back later if
192 * we can't (ie the char backend is busy/blocking).
193 */
bf7b1eab 194static gboolean uart_transmit(void *do_not_use, GIOCondition cond, void *opaque)
775df84e
PM
195{
196 CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
197 int ret;
198
199 s->watch_tag = 0;
200
201 if (!(s->ctrl & R_CTRL_TX_EN_MASK) || !(s->state & R_STATE_TXFULL_MASK)) {
202 return FALSE;
203 }
204
205 ret = qemu_chr_fe_write(&s->chr, &s->txbuf, 1);
206 if (ret <= 0) {
207 s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
208 uart_transmit, s);
209 if (!s->watch_tag) {
210 /* Most common reason to be here is "no chardev backend":
211 * just insta-drain the buffer, so the serial output
212 * goes into a void, rather than blocking the guest.
213 */
214 goto buffer_drained;
215 }
216 /* Transmit pending */
217 trace_cmsdk_apb_uart_tx_pending();
218 return FALSE;
219 }
220
221buffer_drained:
222 /* Character successfully sent */
223 trace_cmsdk_apb_uart_tx(s->txbuf);
224 s->state &= ~R_STATE_TXFULL_MASK;
225 /* Going from TXFULL set to clear triggers the tx interrupt */
226 if (s->ctrl & R_CTRL_TX_INTEN_MASK) {
227 s->intstatus |= R_INTSTATUS_TX_MASK;
228 }
229 cmsdk_apb_uart_update(s);
230 return FALSE;
231}
232
233static void uart_cancel_transmit(CMSDKAPBUART *s)
234{
235 if (s->watch_tag) {
236 g_source_remove(s->watch_tag);
237 s->watch_tag = 0;
238 }
239}
240
241static void uart_write(void *opaque, hwaddr offset, uint64_t value,
242 unsigned size)
243{
244 CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
245
246 trace_cmsdk_apb_uart_write(offset, value, size);
247
248 switch (offset) {
249 case A_DATA:
250 s->txbuf = value;
251 if (s->state & R_STATE_TXFULL_MASK) {
252 /* Buffer already full -- note the overrun and let the
253 * existing pending transmit callback handle the new char.
254 */
255 s->state |= R_STATE_TXOVERRUN_MASK;
256 cmsdk_apb_uart_update(s);
257 } else {
258 s->state |= R_STATE_TXFULL_MASK;
259 uart_transmit(NULL, G_IO_OUT, s);
260 }
261 break;
262 case A_STATE:
263 /* Bits 0 and 1 are read only; bits 2 and 3 are W1C */
264 s->state &= ~(value &
265 (R_STATE_TXOVERRUN_MASK | R_STATE_RXOVERRUN_MASK));
266 cmsdk_apb_uart_update(s);
267 break;
268 case A_CTRL:
269 s->ctrl = value & 0x7f;
270 if ((s->ctrl & R_CTRL_TX_EN_MASK) && !uart_baudrate_ok(s)) {
271 qemu_log_mask(LOG_GUEST_ERROR,
272 "CMSDK APB UART: Tx enabled with invalid baudrate\n");
273 }
274 cmsdk_apb_uart_update(s);
275 break;
276 case A_INTSTATUS:
277 /* All bits are W1C. Clearing the overrun interrupt bits really
278 * clears the overrun status bits in the STATE register (which
279 * is then reflected into the intstatus value by the update function).
280 */
281 s->state &= ~(value & (R_INTSTATUS_TXO_MASK | R_INTSTATUS_RXO_MASK));
6670b494 282 s->intstatus &= ~value;
775df84e
PM
283 cmsdk_apb_uart_update(s);
284 break;
285 case A_BAUDDIV:
286 s->bauddiv = value & 0xFFFFF;
287 uart_update_parameters(s);
288 break;
289 case A_PID4 ... A_CID3:
290 qemu_log_mask(LOG_GUEST_ERROR,
291 "CMSDK APB UART write: write to RO offset 0x%x\n",
292 (int)offset);
293 break;
294 default:
295 qemu_log_mask(LOG_GUEST_ERROR,
296 "CMSDK APB UART write: bad offset 0x%x\n", (int) offset);
297 break;
298 }
299}
300
301static const MemoryRegionOps uart_ops = {
302 .read = uart_read,
303 .write = uart_write,
304 .endianness = DEVICE_LITTLE_ENDIAN,
305};
306
307static void cmsdk_apb_uart_reset(DeviceState *dev)
308{
309 CMSDKAPBUART *s = CMSDK_APB_UART(dev);
310
311 trace_cmsdk_apb_uart_reset();
312 uart_cancel_transmit(s);
313 s->state = 0;
314 s->ctrl = 0;
315 s->intstatus = 0;
316 s->bauddiv = 0;
317 s->txbuf = 0;
318 s->rxbuf = 0;
319}
320
321static void cmsdk_apb_uart_init(Object *obj)
322{
323 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
324 CMSDKAPBUART *s = CMSDK_APB_UART(obj);
325
326 memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000);
327 sysbus_init_mmio(sbd, &s->iomem);
328 sysbus_init_irq(sbd, &s->txint);
329 sysbus_init_irq(sbd, &s->rxint);
330 sysbus_init_irq(sbd, &s->txovrint);
331 sysbus_init_irq(sbd, &s->rxovrint);
332 sysbus_init_irq(sbd, &s->uartint);
333}
334
335static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
336{
337 CMSDKAPBUART *s = CMSDK_APB_UART(dev);
338
339 if (s->pclk_frq == 0) {
340 error_setg(errp, "CMSDK APB UART: pclk-frq property must be set");
341 return;
342 }
343
344 /* This UART has no flow control, so we do not need to register
345 * an event handler to deal with CHR_EVENT_BREAK.
346 */
347 qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
977a15f4 348 NULL, NULL, s, NULL, true);
775df84e
PM
349}
350
351static int cmsdk_apb_uart_post_load(void *opaque, int version_id)
352{
353 CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
354
355 /* If we have a pending character, arrange to resend it. */
356 if (s->state & R_STATE_TXFULL_MASK) {
357 s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
358 uart_transmit, s);
359 }
360 uart_update_parameters(s);
361 return 0;
362}
363
364static const VMStateDescription cmsdk_apb_uart_vmstate = {
365 .name = "cmsdk-apb-uart",
366 .version_id = 1,
367 .minimum_version_id = 1,
368 .post_load = cmsdk_apb_uart_post_load,
369 .fields = (VMStateField[]) {
370 VMSTATE_UINT32(state, CMSDKAPBUART),
371 VMSTATE_UINT32(ctrl, CMSDKAPBUART),
372 VMSTATE_UINT32(intstatus, CMSDKAPBUART),
373 VMSTATE_UINT32(bauddiv, CMSDKAPBUART),
374 VMSTATE_UINT8(txbuf, CMSDKAPBUART),
375 VMSTATE_UINT8(rxbuf, CMSDKAPBUART),
376 VMSTATE_END_OF_LIST()
377 }
378};
379
380static Property cmsdk_apb_uart_properties[] = {
381 DEFINE_PROP_CHR("chardev", CMSDKAPBUART, chr),
382 DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBUART, pclk_frq, 0),
383 DEFINE_PROP_END_OF_LIST(),
384};
385
386static void cmsdk_apb_uart_class_init(ObjectClass *klass, void *data)
387{
388 DeviceClass *dc = DEVICE_CLASS(klass);
389
390 dc->realize = cmsdk_apb_uart_realize;
391 dc->vmsd = &cmsdk_apb_uart_vmstate;
392 dc->reset = cmsdk_apb_uart_reset;
4f67d30b 393 device_class_set_props(dc, cmsdk_apb_uart_properties);
775df84e
PM
394}
395
396static const TypeInfo cmsdk_apb_uart_info = {
397 .name = TYPE_CMSDK_APB_UART,
398 .parent = TYPE_SYS_BUS_DEVICE,
399 .instance_size = sizeof(CMSDKAPBUART),
400 .instance_init = cmsdk_apb_uart_init,
401 .class_init = cmsdk_apb_uart_class_init,
402};
403
404static void cmsdk_apb_uart_register_types(void)
405{
406 type_register_static(&cmsdk_apb_uart_info);
407}
408
409type_init(cmsdk_apb_uart_register_types);