Lines Matching +full:- +full:- +full:enable +full:- +full:trace +full:- +full:backend

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
15 * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
22 #include "trace.h"
26 #include "chardev/char-fe.h"
27 #include "chardev/char-serial.h"
28 #include "hw/char/cmsdk-apb-uart.h"
30 #include "hw/qdev-properties-system.h"
78 return s->bauddiv >= 16 && s->bauddiv <= s->pclk_frq; in uart_baudrate_ok()
93 ssp.speed = s->pclk_frq / s->bauddiv; in uart_update_parameters()
94 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); in uart_update_parameters()
102 * STATE and the overrun interrupt enable bit in CTRL. in cmsdk_apb_uart_update()
105 s->intstatus &= ~omask; in cmsdk_apb_uart_update()
106 s->intstatus |= (s->state & (s->ctrl >> 2) & omask); in cmsdk_apb_uart_update()
108 qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK)); in cmsdk_apb_uart_update()
109 qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK)); in cmsdk_apb_uart_update()
110 qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK)); in cmsdk_apb_uart_update()
111 qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK)); in cmsdk_apb_uart_update()
112 qemu_set_irq(s->uartint, !!(s->intstatus)); in cmsdk_apb_uart_update()
120 if (s->ctrl & R_CTRL_RX_EN_MASK && !(s->state & R_STATE_RXFULL_MASK)) { in uart_can_receive()
137 if (!(s->ctrl & R_CTRL_RX_EN_MASK)) { in uart_receive()
142 if (s->state & R_STATE_RXFULL_MASK) { in uart_receive()
143 s->state |= R_STATE_RXOVERRUN_MASK; in uart_receive()
146 s->rxbuf = *buf; in uart_receive()
147 s->state |= R_STATE_RXFULL_MASK; in uart_receive()
148 if (s->ctrl & R_CTRL_RX_INTEN_MASK) { in uart_receive()
149 s->intstatus |= R_INTSTATUS_RX_MASK; in uart_receive()
161 r = s->rxbuf; in uart_read()
162 s->state &= ~R_STATE_RXFULL_MASK; in uart_read()
164 qemu_chr_fe_accept_input(&s->chr); in uart_read()
167 r = s->state; in uart_read()
170 r = s->ctrl; in uart_read()
173 r = s->intstatus; in uart_read()
176 r = s->bauddiv; in uart_read()
179 r = uart_id[(offset - A_PID4) / 4]; in uart_read()
192 * we can't (ie the char backend is busy/blocking).
199 s->watch_tag = 0; in uart_transmit()
201 if (!(s->ctrl & R_CTRL_TX_EN_MASK) || !(s->state & R_STATE_TXFULL_MASK)) { in uart_transmit()
205 ret = qemu_chr_fe_write(&s->chr, &s->txbuf, 1); in uart_transmit()
207 s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP, in uart_transmit()
209 if (!s->watch_tag) { in uart_transmit()
210 /* Most common reason to be here is "no chardev backend": in uart_transmit()
211 * just insta-drain the buffer, so the serial output in uart_transmit()
223 trace_cmsdk_apb_uart_tx(s->txbuf); in uart_transmit()
224 s->state &= ~R_STATE_TXFULL_MASK; in uart_transmit()
226 if (s->ctrl & R_CTRL_TX_INTEN_MASK) { in uart_transmit()
227 s->intstatus |= R_INTSTATUS_TX_MASK; in uart_transmit()
235 if (s->watch_tag) { in uart_cancel_transmit()
236 g_source_remove(s->watch_tag); in uart_cancel_transmit()
237 s->watch_tag = 0; in uart_cancel_transmit()
250 s->txbuf = value; in uart_write()
251 if (s->state & R_STATE_TXFULL_MASK) { in uart_write()
252 /* Buffer already full -- note the overrun and let the in uart_write()
255 s->state |= R_STATE_TXOVERRUN_MASK; in uart_write()
258 s->state |= R_STATE_TXFULL_MASK; in uart_write()
264 s->state &= ~(value & in uart_write()
269 s->ctrl = value & 0x7f; in uart_write()
270 if ((s->ctrl & R_CTRL_TX_EN_MASK) && !uart_baudrate_ok(s)) { in uart_write()
281 s->state &= ~(value & (R_INTSTATUS_TXO_MASK | R_INTSTATUS_RXO_MASK)); in uart_write()
282 s->intstatus &= ~value; in uart_write()
286 s->bauddiv = value & 0xFFFFF; in uart_write()
313 s->state = 0; in cmsdk_apb_uart_reset()
314 s->ctrl = 0; in cmsdk_apb_uart_reset()
315 s->intstatus = 0; in cmsdk_apb_uart_reset()
316 s->bauddiv = 0; in cmsdk_apb_uart_reset()
317 s->txbuf = 0; in cmsdk_apb_uart_reset()
318 s->rxbuf = 0; in cmsdk_apb_uart_reset()
326 memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000); in cmsdk_apb_uart_init()
327 sysbus_init_mmio(sbd, &s->iomem); in cmsdk_apb_uart_init()
328 sysbus_init_irq(sbd, &s->txint); in cmsdk_apb_uart_init()
329 sysbus_init_irq(sbd, &s->rxint); in cmsdk_apb_uart_init()
330 sysbus_init_irq(sbd, &s->txovrint); in cmsdk_apb_uart_init()
331 sysbus_init_irq(sbd, &s->rxovrint); in cmsdk_apb_uart_init()
332 sysbus_init_irq(sbd, &s->uartint); in cmsdk_apb_uart_init()
339 if (s->pclk_frq == 0) { in cmsdk_apb_uart_realize()
340 error_setg(errp, "CMSDK APB UART: pclk-frq property must be set"); in cmsdk_apb_uart_realize()
347 qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive, in cmsdk_apb_uart_realize()
356 if (s->state & R_STATE_TXFULL_MASK) { in cmsdk_apb_uart_post_load()
357 s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP, in cmsdk_apb_uart_post_load()
365 .name = "cmsdk-apb-uart",
382 DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBUART, pclk_frq, 0),
389 dc->realize = cmsdk_apb_uart_realize; in cmsdk_apb_uart_class_init()
390 dc->vmsd = &cmsdk_apb_uart_vmstate; in cmsdk_apb_uart_class_init()