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/irq.h"
37
38#ifndef XILINX_IO_MODULE_UART_ERR_DEBUG
39#define XILINX_IO_MODULE_UART_ERR_DEBUG 0
40#endif
41
42#define TYPE_XILINX_IO_MODULE_UART "xlnx.io_uart"
43
44#define XILINX_IO_MODULE_UART(obj) \
45 OBJECT_CHECK(XilinxUART, (obj), TYPE_XILINX_IO_MODULE_UART)
46
47REG32(IOM_UART_RX, 0x0)
48REG32(IOM_UART_TX, 0x4)
49REG32(IOM_UART_STATUS, 0x8)
50 FIELD(IOM_UART_STATUS, PARITY_ERR, 7, 1)
51 FIELD(IOM_UART_STATUS, FRAME_ERR, 6, 1)
52 FIELD(IOM_UART_STATUS, OVERRUN, 5, 1)
53 FIELD(IOM_UART_STATUS, TX_USED, 3, 1)
54 FIELD(IOM_UART_STATUS, RX_VALID, 0, 1)
55
56REG32(IOM_UART_BAUD, 0x0)
57
58#define R_MAX_0 (R_IOM_UART_STATUS + 1)
59#define R_MAX_1 (R_IOM_UART_BAUD + 1)
60
61typedef struct XilinxUART {
62 SysBusDevice parent_obj;
63 MemoryRegion iomem[2];
64 qemu_irq irq_rx;
65 qemu_irq irq_tx;
66 qemu_irq irq_err;
67
68 struct {
69 bool use_rx;
70 bool use_tx;
71 bool rx_interrupt;
72 bool tx_interrupt;
73 bool err_interrupt;
74 } cfg;
75 CharBackend chr;
76 uint32_t regs[R_MAX_0];
77 uint32_t baud;
78 RegisterInfo regs_info0[R_MAX_0];
79 RegisterInfo regs_info1[R_MAX_1];
80 RegisterInfo *regs_infos[2];
81 const char *prefix;
82} XilinxUART;
83
84static Property xlx_iom_properties[] = {
85 DEFINE_PROP_BOOL("use-uart-rx", XilinxUART, cfg.use_rx, 0),
86 DEFINE_PROP_BOOL("use-uart-tx", XilinxUART, cfg.use_tx, 0),
87 DEFINE_PROP_BOOL("uart-rx-interrupt", XilinxUART, cfg.rx_interrupt, 0),
88 DEFINE_PROP_BOOL("uart-tx-interrupt", XilinxUART, cfg.tx_interrupt, 0),
89 DEFINE_PROP_BOOL("uart-error-interrupt", XilinxUART, cfg.err_interrupt, 0),
90 DEFINE_PROP_CHR("chardev", XilinxUART, chr),
91 DEFINE_PROP_END_OF_LIST(),
92};
93
94static void uart_rx(void *opaque, const uint8_t *buf, int size)
95{
96 XilinxUART *s = opaque;
97
98 if (!s->cfg.use_rx) {
99 return;
100 }
101
102 if (s->regs[R_IOM_UART_STATUS] & R_IOM_UART_STATUS_RX_VALID_MASK) {
103 s->regs[R_IOM_UART_STATUS] |= R_IOM_UART_STATUS_OVERRUN_MASK;
104 if (s->cfg.err_interrupt) {
105 qemu_irq_pulse(s->irq_err);
106 }
107 return;
108 }
109
110 s->regs[R_IOM_UART_RX] = *buf;
111 s->regs[R_IOM_UART_STATUS] |= R_IOM_UART_STATUS_RX_VALID_MASK;
112 if (s->cfg.rx_interrupt) {
113 qemu_irq_pulse(s->irq_rx);
114 }
115}
116
117static int uart_can_rx(void *opaque)
118{
119 XilinxUART *s = opaque;
120 return s->cfg.use_rx;
121}
122
123static void uart_event(void *opaque, int event)
124{
125}
126
127static uint64_t uart_rx_pr(RegisterInfo *reg, uint64_t val)
128{
129 XilinxUART *s = XILINX_IO_MODULE_UART(reg->opaque);
130 s->regs[R_IOM_UART_STATUS] &= ~R_IOM_UART_STATUS_OVERRUN_MASK;
131 s->regs[R_IOM_UART_STATUS] &= ~R_IOM_UART_STATUS_RX_VALID_MASK;
132 return s->regs[R_IOM_UART_RX];
133}
134
135static uint64_t uart_sts_pr(RegisterInfo *reg, uint64_t val)
136{
137 XilinxUART *s = XILINX_IO_MODULE_UART(reg->opaque);
138 s->regs[R_IOM_UART_STATUS] &= ~R_IOM_UART_STATUS_OVERRUN_MASK;
139 return val;
140}
141
142static void uart_tx_pw(RegisterInfo *reg, uint64_t value)
143{
144 XilinxUART *s = XILINX_IO_MODULE_UART(reg->opaque);
145 if (s->cfg.use_tx) {
146 unsigned char ch = value;
147 qemu_chr_fe_write(&s->chr, &ch, 1);
148 if (s->cfg.tx_interrupt) {
149 qemu_irq_pulse(s->irq_tx);
150 }
151 }
152}
153
154static const RegisterAccessInfo uart_regs_info0[] = {
155 [R_IOM_UART_RX] = { .name = "UART_RX", .addr = A_IOM_UART_RX,
156 .post_read = uart_rx_pr },
157 [R_IOM_UART_TX] = { .name = "UART_TX", .addr = A_IOM_UART_TX,
158 .post_write = uart_tx_pw },
159 [R_IOM_UART_STATUS] = { .name = "UART_STATUS", .addr = A_IOM_UART_STATUS,
160 .post_read = uart_sts_pr },
161};
162
163static const RegisterAccessInfo uart_regs_info1[] = {
164 [R_IOM_UART_BAUD] = { .name = "UART_BAUD", .addr = A_IOM_UART_BAUD},
165};
166static const RegisterAccessInfo *uart_reginfos[] = {
167 &uart_regs_info0[0], &uart_regs_info1[0]
168};
169
170static const unsigned int uart_reginfo_sizes[] = {
171 ARRAY_SIZE(uart_regs_info0),
172 ARRAY_SIZE(uart_regs_info1),
173};
174
175static const unsigned int uart_rmax[] = {
176 R_MAX_0,
177 R_MAX_1
178};
179
180static const MemoryRegionOps iom_uart_ops = {
181 .read = register_read_memory,
182 .write = register_write_memory,
183 .endianness = DEVICE_LITTLE_ENDIAN,
184 .valid = {
185 .min_access_size = 4,
186 .max_access_size = 4,
187 },
188};
189
190static void iom_uart_reset(DeviceState *dev)
191{
192 XilinxUART *s = XILINX_IO_MODULE_UART(dev);
193 unsigned int i;
194 unsigned int rmap;
195
196 for (rmap = 0; rmap < ARRAY_SIZE(uart_reginfos); rmap++) {
197 for (i = 0; i < uart_reginfo_sizes[rmap]; ++i) {
198 register_reset(&s->regs_infos[rmap][i]);
199 }
200 }
201}
202
203static void xlx_iom_realize(DeviceState *dev, Error **errp)
204{
205 XilinxUART *s = XILINX_IO_MODULE_UART(dev);
206
207 if (s->cfg.use_rx || s->cfg.use_tx) {
208 qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
209 NULL, s, NULL, true);
210 }
211}
212
213static void xlx_iom_init(Object *obj)
214{
215 XilinxUART *s = XILINX_IO_MODULE_UART(obj);
216 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
217 unsigned int i;
218 RegisterInfoArray *reg_array;
219 uint32_t *regmaps[] = { s->regs, &s->baud };
220
221 s->regs_infos[0] = s->regs_info0;
222 s->regs_infos[1] = s->regs_info1;
223
224 for (i = 0; i < ARRAY_SIZE(s->iomem); i++) {
225 char *region_name = g_strdup_printf("%s-%d", TYPE_XILINX_IO_MODULE_UART,
226 i);
227 memory_region_init(&s->iomem[i], obj,
228 region_name, uart_rmax[i] * 4);
229 reg_array =
230 register_init_block32(DEVICE(obj), uart_reginfos[i],
231 uart_reginfo_sizes[i],
232 s->regs_infos[i], regmaps[i],
233 &iom_uart_ops,
234 XILINX_IO_MODULE_UART_ERR_DEBUG,
235 uart_rmax[i] * 4);
236 memory_region_add_subregion(&s->iomem[i], 0, ®_array->mem);
237 g_free(region_name);
238 sysbus_init_mmio(sbd, &s->iomem[i]);
239 }
240 sysbus_init_irq(sbd, &s->irq_err);
241 sysbus_init_irq(sbd, &s->irq_tx);
242 sysbus_init_irq(sbd, &s->irq_rx);
243}
244
245static const VMStateDescription vmstate_xlx_iom = {
246 .name = TYPE_XILINX_IO_MODULE_UART,
247 .version_id = 1,
248 .minimum_version_id = 1,
249 .minimum_version_id_old = 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 dc->props = 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