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/register.h"
29#include "qemu/bitops.h"
30#include "qemu/log.h"
31
32#ifndef XLNX_AXI_GPIO_ERR_DEBUG
33#define XLNX_AXI_GPIO_ERR_DEBUG 0
34#endif
35
36#define TYPE_XLNX_AXI_GPIO "xlnx.axi-gpio"
37
38#define XLNX_AXI_GPIO(obj) \
39 OBJECT_CHECK(XlnxAXIGPIO, (obj), TYPE_XLNX_AXI_GPIO)
40
41REG32(GPIO_DATA, 0x00)
42REG32(GPIO_TRI, 0x04)
43REG32(GPIO2_DATA, 0x08)
44REG32(GPIO2_TRI, 0x0C)
45REG32(GIER, 0x11C)
46 FIELD(GIER, GIE, 1, 31)
47REG32(IP_ISR, 0x120)
48 FIELD(IP_ISR, CHANNEL1_ST, 1, 0)
49 FIELD(IP_ISR, CHANNEL2_ST, 1, 1)
50REG32(IP_IER, 0x128)
51 FIELD(IP_IER, CHANNEL1_EN, 1, 0)
52 FIELD(IP_IER, CHANNEL2_EN, 1, 1)
53
54#define R_MAX (R_IP_IER + 1)
55
56typedef struct XlnxAXIGPIO {
57 SysBusDevice parent_obj;
58 MemoryRegion iomem;
59
60 qemu_irq parent_irq;
61 qemu_irq outputs1[32], outputs2[32];
62
63 uint32_t regs[R_MAX];
64 RegisterInfo regs_info[R_MAX];
65} XlnxAXIGPIO;
66
67
68static void irq_update(XlnxAXIGPIO *s)
69{
70 bool general_enable = AF_EX32(s->regs, GIER, GIE);
71 bool pending = !!(s->regs[R_IP_ISR] & s->regs[R_IP_IER]);
72
73 qemu_set_irq(s->parent_irq, general_enable & pending);
74}
75
76static void data_handler(void *opaque, int irq, int level, int channel)
77{
78 XlnxAXIGPIO *s = XLNX_AXI_GPIO(opaque);
79 unsigned int data_regnr, tri_regnr;
80
81 assert(channel > 0 && channel < 3);
82 data_regnr = channel == 1 ? R_GPIO_DATA : R_GPIO2_DATA;
83 tri_regnr = channel == 1 ? R_GPIO_TRI : R_GPIO2_TRI;
84
85 if (!extract32(s->regs[tri_regnr], irq, 1) ||
86 extract32(s->regs[data_regnr], irq, 1) == level) {
87
88 return;
89 }
90
91 s->regs[data_regnr] = deposit32(s->regs[data_regnr], irq, 1, level);
92
93 switch (channel) {
94 case 1:
95 AF_DP32(s->regs, IP_ISR, CHANNEL1_ST, 1);
96 break;
97 case 2:
98 AF_DP32(s->regs, IP_ISR, CHANNEL2_ST, 1);
99 break;
100 }
101
102 irq_update(s);
103}
104
105static void data_handler1(void *opaque, int irq, int level)
106{
107 data_handler(opaque, irq, level, 1);
108}
109
110static void data_handler2(void *opaque, int irq, int level)
111{
112 data_handler(opaque, irq, level, 2);
113}
114
115static void xlnx_axi_gpio_data_post_write(XlnxAXIGPIO *s, uint64_t val,
116 int channel)
117{
118 unsigned int tri_regnr;
119 bool gpio_set;
120 int i;
121
122 assert(channel > 0 && channel < 3);
123 tri_regnr = channel == 1 ? R_GPIO_TRI : R_GPIO2_TRI;
124
125 for (i = 0; i < 32; i++) {
126 if (extract32(s->regs[tri_regnr], i, 1)) {
127
128 continue;
129 }
130
131 gpio_set = extract32(val, i, 1);
132
133 switch (channel) {
134 case 1:
135 qemu_set_irq(s->outputs1[i], gpio_set);
136 break;
137 case 2:
138 qemu_set_irq(s->outputs2[i], gpio_set);
139 break;
140 }
141 }
142}
143
144static void xlnx_axi_gpio_data_post_write1(RegisterInfo *reg, uint64_t val)
145{
146 XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque);
147
148 xlnx_axi_gpio_data_post_write(s, val, 1);
149}
150
151static void xlnx_axi_gpio_data_post_write2(RegisterInfo *reg, uint64_t val)
152{
153 XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque);
154
155 xlnx_axi_gpio_data_post_write(s, val, 2);
156}
157
158static void xlnx_axi_gpio_post_write(RegisterInfo *reg, uint64_t val)
159{
160 XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque);
161
162 irq_update(s);
163}
164
165static uint64_t xlnx_axi_gpi_data_read(RegisterInfo *reg, uint64_t val,
166 uint8_t channel)
167{
168 XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque);
169
170 switch (channel) {
171 case 1:
172 return val & s->regs[R_GPIO_TRI];
173 case 2:
174 return val & s->regs[R_GPIO2_TRI];
175 default:
176 return val;
177 }
178}
179
180static uint64_t xlnx_axi_gpio_data_post_read(RegisterInfo *reg, uint64_t val)
181{
182 return xlnx_axi_gpi_data_read(reg, val, 1);
183}
184
185static uint64_t xlnx_axi_gpio2_data_post_read(RegisterInfo *reg, uint64_t val)
186{
187 return xlnx_axi_gpi_data_read(reg, val, 2);
188}
189
190static RegisterAccessInfo xlnx_axi_gpio_regs_info[] = {
191 { .name = "GPIO_DATA", .decode.addr = A_GPIO_DATA,
192 .post_read = xlnx_axi_gpio_data_post_read,
193 .post_write = xlnx_axi_gpio_data_post_write1,
194 },{ .name = "GPIO_TRI", .decode.addr = A_GPIO_TRI,
195 },{ .name = "GPIO2_DATA", .decode.addr = A_GPIO2_DATA,
196 .post_read = xlnx_axi_gpio2_data_post_read,
197 .post_write = xlnx_axi_gpio_data_post_write2,
198 },{ .name = "GPIO2_TRI", .decode.addr = A_GPIO2_TRI,
199 },{ .name = "GIER", .decode.addr = A_GIER,
200 .post_write = xlnx_axi_gpio_post_write,
201 },{ .name = "IP_IER", .decode.addr = A_IP_IER,
202 .post_write = xlnx_axi_gpio_post_write,
203 },{ .name = "IP_ISR", .decode.addr = A_IP_ISR,
204 .post_write = xlnx_axi_gpio_post_write,
205 }
206};
207
208static void xlnx_axi_gpio_reset(DeviceState *dev)
209{
210 XlnxAXIGPIO *s = XLNX_AXI_GPIO(dev);
211 unsigned int i;
212
213 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
214 register_reset(&s->regs_info[i]);
215 }
216
217 irq_update(s);
218}
219
220static uint64_t xlnx_axi_gpio_read(void *opaque, hwaddr addr, unsigned size)
221{
222 XlnxAXIGPIO *s = XLNX_AXI_GPIO(opaque);
223 RegisterInfo *r = &s->regs_info[addr / 4];
224
225 if (!r->data) {
226 qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
227 object_get_canonical_path(OBJECT(s)),
228 addr);
229 return 0;
230 }
231 return register_read(r);
232}
233
234static void xlnx_axi_gpio_write(void *opaque, hwaddr addr, uint64_t value,
235 unsigned size)
236{
237 XlnxAXIGPIO *s = XLNX_AXI_GPIO(opaque);
238 RegisterInfo *r = &s->regs_info[addr / 4];
239
240 if (!r->data) {
241 qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
242 object_get_canonical_path(OBJECT(s)),
243 addr, value);
244 return;
245 }
246 register_write(r, value, ~0);
247}
248
249static const MemoryRegionOps xlnx_axi_gpio_ops = {
250 .read = xlnx_axi_gpio_read,
251 .write = xlnx_axi_gpio_write,
252 .endianness = DEVICE_LITTLE_ENDIAN,
253 .valid = {
254 .min_access_size = 4,
255 .max_access_size = 4,
256 },
257};
258
259static void xlnx_axi_gpio_realize(DeviceState *dev, Error **errp)
260{
261 XlnxAXIGPIO *s = XLNX_AXI_GPIO(dev);
262 const char *prefix = object_get_canonical_path(OBJECT(dev));
263 unsigned int i;
264
265 for (i = 0; i < ARRAY_SIZE(xlnx_axi_gpio_regs_info); ++i) {
266 RegisterInfo *r =
267 &s->regs_info[xlnx_axi_gpio_regs_info[i].decode.addr/4];
268
269 *r = (RegisterInfo) {
270 .data = (uint8_t *)&s->regs[
271 xlnx_axi_gpio_regs_info[i].decode.addr/4],
272 .data_size = sizeof(uint32_t),
273 .access = &xlnx_axi_gpio_regs_info[i],
274 .debug = XLNX_AXI_GPIO_ERR_DEBUG,
275 .prefix = prefix,
276 .opaque = s,
277 };
278 }
279
280
281 qdev_init_gpio_in(dev, data_handler1, 32);
282 qdev_init_gpio_in(dev, data_handler2, 32);
283
284
285 qdev_init_gpio_out(dev, s->outputs1, 32);
286 qdev_init_gpio_out(dev, s->outputs2, 32);
287}
288
289static void xlnx_axi_gpio_init(Object *obj)
290{
291 XlnxAXIGPIO *s = XLNX_AXI_GPIO(obj);
292 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
293
294 memory_region_init_io(&s->iomem, obj, &xlnx_axi_gpio_ops, s,
295 TYPE_XLNX_AXI_GPIO, R_MAX * 4);
296 sysbus_init_mmio(sbd, &s->iomem);
297
298 sysbus_init_irq(sbd, &s->parent_irq);
299}
300
301static const VMStateDescription vmstate_gpio = {
302 .name = TYPE_XLNX_AXI_GPIO,
303 .version_id = 1,
304 .minimum_version_id = 1,
305 .minimum_version_id_old = 1,
306 .fields = (VMStateField[]) {
307 VMSTATE_UINT32_ARRAY(regs, XlnxAXIGPIO, R_MAX),
308 VMSTATE_END_OF_LIST(),
309 }
310};
311
312static void xlnx_axi_gpio_class_init(ObjectClass *klass, void *data)
313{
314 DeviceClass *dc = DEVICE_CLASS(klass);
315
316 dc->reset = xlnx_axi_gpio_reset;
317 dc->realize = xlnx_axi_gpio_realize;
318 dc->vmsd = &vmstate_gpio;
319}
320
321static const TypeInfo xlnx_axi_gpio_info = {
322 .name = TYPE_XLNX_AXI_GPIO,
323 .parent = TYPE_SYS_BUS_DEVICE,
324 .instance_size = sizeof(XlnxAXIGPIO),
325 .class_init = xlnx_axi_gpio_class_init,
326 .instance_init = xlnx_axi_gpio_init,
327};
328
329static void xlnx_axi_gpio_register_types(void)
330{
331 type_register_static(&xlnx_axi_gpio_info);
332}
333
334type_init(xlnx_axi_gpio_register_types)
335