1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "qemu/osdep.h"
27#include "hw/sysbus.h"
28#include "hw/ptimer.h"
29#include "chardev/char.h"
30#include "chardev/char-fe.h"
31#include "hw/register.h"
32#include "qemu/log.h"
33#include "sysemu/sysemu.h"
34#include "migration/vmstate.h"
35#include "hw/qdev-properties.h"
36#include "hw/qdev-properties-system.h"
37#include "hw/irq.h"
38
39#ifndef XILINX_IO_MODULE_UART_ERR_DEBUG
40#define XILINX_IO_MODULE_UART_ERR_DEBUG 0
41#endif
42
43#define TYPE_XILINX_IO_MODULE_UART "xlnx.io_uart"
44
45#define XILINX_IO_MODULE_UART(obj) \
46 OBJECT_CHECK(XilinxUART, (obj), TYPE_XILINX_IO_MODULE_UART)
47
48REG32(IOM_UART_RX, 0x0)
49REG32(IOM_UART_TX, 0x4)
50REG32(IOM_UART_STATUS, 0x8)
51 FIELD(IOM_UART_STATUS, PARITY_ERR, 7, 1)
52 FIELD(IOM_UART_STATUS, FRAME_ERR, 6, 1)
53 FIELD(IOM_UART_STATUS, OVERRUN, 5, 1)
54 FIELD(IOM_UART_STATUS, TX_USED, 3, 1)
55 FIELD(IOM_UART_STATUS, RX_VALID, 0, 1)
56
57REG32(IOM_UART_BAUD, 0x0)
58
59#define R_MAX_0 (R_IOM_UART_STATUS + 1)
60#define R_MAX_1 (R_IOM_UART_BAUD + 1)
61
62typedef struct XilinxUART {
63 SysBusDevice parent_obj;
64 MemoryRegion iomem[2];
65 qemu_irq irq_rx;
66 qemu_irq irq_tx;
67 qemu_irq irq_err;
68
69 struct {
70 bool use_rx;
71 bool use_tx;
72 bool rx_interrupt;
73 bool tx_interrupt;
74 bool err_interrupt;
75 } cfg;
76 CharBackend chr;
77 uint32_t regs[R_MAX_0];
78 uint32_t baud;
79 RegisterInfo regs_info0[R_MAX_0];
80 RegisterInfo regs_info1[R_MAX_1];
81 RegisterInfo *regs_infos[2];
82 const char *prefix;
83} XilinxUART;
84
85static Property xlx_iom_properties[] = {
86 DEFINE_PROP_BOOL("use-uart-rx", XilinxUART, cfg.use_rx, 0),
87 DEFINE_PROP_BOOL("use-uart-tx", XilinxUART, cfg.use_tx, 0),
88 DEFINE_PROP_BOOL("uart-rx-interrupt", XilinxUART, cfg.rx_interrupt, 0),
89 DEFINE_PROP_BOOL("uart-tx-interrupt", XilinxUART, cfg.tx_interrupt, 0),
90 DEFINE_PROP_BOOL("uart-error-interrupt", XilinxUART, cfg.err_interrupt, 0),
91 DEFINE_PROP_CHR("chardev", XilinxUART, chr),
92 DEFINE_PROP_END_OF_LIST(),
93};
94
95static void uart_rx(void *opaque, const uint8_t *buf, int size)
96{
97 XilinxUART *s = opaque;
98
99 if (!s->cfg.use_rx) {
100 return;
101 }
102
103 if (s->regs[R_IOM_UART_STATUS] & R_IOM_UART_STATUS_RX_VALID_MASK) {
104 s->regs[R_IOM_UART_STATUS] |= R_IOM_UART_STATUS_OVERRUN_MASK;
105 if (s->cfg.err_interrupt) {
106 qemu_irq_pulse(s->irq_err);
107 }
108 return;
109 }
110
111 s->regs[R_IOM_UART_RX] = *buf;
112 s->regs[R_IOM_UART_STATUS] |= R_IOM_UART_STATUS_RX_VALID_MASK;
113 if (s->cfg.rx_interrupt) {
114 qemu_irq_pulse(s->irq_rx);
115 }
116}
117
118static int uart_can_rx(void *opaque)
119{
120 XilinxUART *s = opaque;
121 return s->cfg.use_rx;
122}
123
124static void uart_event(void *opaque, QEMUChrEvent event)
125{
126}
127
128static uint64_t uart_rx_pr(RegisterInfo *reg, uint64_t val)
129{
130 XilinxUART *s = XILINX_IO_MODULE_UART(reg->opaque);
131 s->regs[R_IOM_UART_STATUS] &= ~R_IOM_UART_STATUS_OVERRUN_MASK;
132 s->regs[R_IOM_UART_STATUS] &= ~R_IOM_UART_STATUS_RX_VALID_MASK;
133 return s->regs[R_IOM_UART_RX];
134}
135
136static uint64_t uart_sts_pr(RegisterInfo *reg, uint64_t val)
137{
138 XilinxUART *s = XILINX_IO_MODULE_UART(reg->opaque);
139 s->regs[R_IOM_UART_STATUS] &= ~R_IOM_UART_STATUS_OVERRUN_MASK;
140 return val;
141}
142
143static void uart_tx_pw(RegisterInfo *reg, uint64_t value)
144{
145 XilinxUART *s = XILINX_IO_MODULE_UART(reg->opaque);
146 if (s->cfg.use_tx) {
147 unsigned char ch = value;
148 qemu_chr_fe_write(&s->chr, &ch, 1);
149 if (s->cfg.tx_interrupt) {
150 qemu_irq_pulse(s->irq_tx);
151 }
152 }
153}
154
155static const RegisterAccessInfo uart_regs_info0[] = {
156 [R_IOM_UART_RX] = { .name = "UART_RX", .addr = A_IOM_UART_RX,
157 .post_read = uart_rx_pr },
158 [R_IOM_UART_TX] = { .name = "UART_TX", .addr = A_IOM_UART_TX,
159 .post_write = uart_tx_pw },
160 [R_IOM_UART_STATUS] = { .name = "UART_STATUS", .addr = A_IOM_UART_STATUS,
161 .post_read = uart_sts_pr },
162};
163
164static const RegisterAccessInfo uart_regs_info1[] = {
165 [R_IOM_UART_BAUD] = { .name = "UART_BAUD", .addr = A_IOM_UART_BAUD},
166};
167static const RegisterAccessInfo *uart_reginfos[] = {
168 &uart_regs_info0[0], &uart_regs_info1[0]
169};
170
171static const unsigned int uart_reginfo_sizes[] = {
172 ARRAY_SIZE(uart_regs_info0),
173 ARRAY_SIZE(uart_regs_info1),
174};
175
176static const unsigned int uart_rmax[] = {
177 R_MAX_0,
178 R_MAX_1
179};
180
181static const MemoryRegionOps iom_uart_ops = {
182 .read = register_read_memory,
183 .write = register_write_memory,
184 .endianness = DEVICE_LITTLE_ENDIAN,
185 .valid = {
186 .min_access_size = 4,
187 .max_access_size = 4,
188 },
189};
190
191static void iom_uart_reset(DeviceState *dev)
192{
193 XilinxUART *s = XILINX_IO_MODULE_UART(dev);
194 unsigned int i;
195 unsigned int rmap;
196
197 for (rmap = 0; rmap < ARRAY_SIZE(uart_reginfos); rmap++) {
198 for (i = 0; i < uart_reginfo_sizes[rmap]; ++i) {
199 register_reset(&s->regs_infos[rmap][i]);
200 }
201 }
202}
203
204static void xlx_iom_realize(DeviceState *dev, Error **errp)
205{
206 XilinxUART *s = XILINX_IO_MODULE_UART(dev);
207
208 if (s->cfg.use_rx || s->cfg.use_tx) {
209 qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
210 NULL, s, NULL, true);
211 }
212}
213
214static void xlx_iom_init(Object *obj)
215{
216 XilinxUART *s = XILINX_IO_MODULE_UART(obj);
217 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
218 unsigned int i;
219 RegisterInfoArray *reg_array;
220 uint32_t *regmaps[] = { s->regs, &s->baud };
221
222 s->regs_infos[0] = s->regs_info0;
223 s->regs_infos[1] = s->regs_info1;
224
225 for (i = 0; i < ARRAY_SIZE(s->iomem); i++) {
226 char *region_name = g_strdup_printf("%s-%d", TYPE_XILINX_IO_MODULE_UART,
227 i);
228 memory_region_init(&s->iomem[i], obj,
229 region_name, uart_rmax[i] * 4);
230 reg_array =
231 register_init_block32(DEVICE(obj), uart_reginfos[i],
232 uart_reginfo_sizes[i],
233 s->regs_infos[i], regmaps[i],
234 &iom_uart_ops,
235 XILINX_IO_MODULE_UART_ERR_DEBUG,
236 uart_rmax[i] * 4);
237 memory_region_add_subregion(&s->iomem[i], 0, ®_array->mem);
238 g_free(region_name);
239 sysbus_init_mmio(sbd, &s->iomem[i]);
240 }
241 sysbus_init_irq(sbd, &s->irq_err);
242 sysbus_init_irq(sbd, &s->irq_tx);
243 sysbus_init_irq(sbd, &s->irq_rx);
244}
245
246static const VMStateDescription vmstate_xlx_iom = {
247 .name = TYPE_XILINX_IO_MODULE_UART,
248 .version_id = 1,
249 .minimum_version_id = 1,
250 .fields = (VMStateField[]) {
251 VMSTATE_END_OF_LIST(),
252 }
253};
254
255static void xlx_iom_class_init(ObjectClass *klass, void *data)
256{
257 DeviceClass *dc = DEVICE_CLASS(klass);
258
259 dc->reset = iom_uart_reset;
260 dc->realize = xlx_iom_realize;
261 device_class_set_props(dc, xlx_iom_properties);
262 dc->vmsd = &vmstate_xlx_iom;
263}
264
265static const TypeInfo xlx_iom_info = {
266 .name = TYPE_XILINX_IO_MODULE_UART,
267 .parent = TYPE_SYS_BUS_DEVICE,
268 .instance_size = sizeof(XilinxUART),
269 .class_init = xlx_iom_class_init,
270 .instance_init = xlx_iom_init,
271};
272
273static void xlx_iom_register_types(void)
274{
275 type_register_static(&xlx_iom_info);
276}
277
278type_init(xlx_iom_register_types)
279