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
27
28#include "qemu/osdep.h"
29#include "hw/sysbus.h"
30#include "hw/register-dep.h"
31#include "qemu/bitops.h"
32#include "qemu/log.h"
33#include "hw/fdt_generic_util.h"
34
35#ifndef XILINX_SMMU_REG_ERR_DEBUG
36#define XILINX_SMMU_REG_ERR_DEBUG 0
37#endif
38
39#define TYPE_XILINX_SMMU_REG "xlnx.smmu-reg"
40
41#define XILINX_SMMU_REG(obj) \
42 OBJECT_CHECK(SMMU_REG, (obj), TYPE_XILINX_SMMU_REG)
43
44DEP_REG32(MISC_CTRL, 0x0)
45 DEP_FIELD(MISC_CTRL, SLVERR_ENABLE, 1, 0)
46DEP_REG32(ISR_0, 0x10)
47 DEP_FIELD(ISR_0, ADDR_DECODE_ERR, 1, 31)
48 DEP_FIELD(ISR_0, GBL_FLT_IRPT_NS, 1, 4)
49 DEP_FIELD(ISR_0, GBL_FLT_IRPT_S, 1, 3)
50 DEP_FIELD(ISR_0, COMB_PERF_IRPT_TBU, 1, 2)
51 DEP_FIELD(ISR_0, COMB_IRPT_S, 1, 1)
52 DEP_FIELD(ISR_0, COMB_IRPT_NS, 1, 0)
53DEP_REG32(IMR_0, 0x14)
54 DEP_FIELD(IMR_0, ADDR_DECODE_ERR, 1, 31)
55 DEP_FIELD(IMR_0, GBL_FLT_IRPT_NS, 1, 4)
56 DEP_FIELD(IMR_0, GBL_FLT_IRPT_S, 1, 3)
57 DEP_FIELD(IMR_0, COMB_PERF_IRPT_TBU, 1, 2)
58 DEP_FIELD(IMR_0, COMB_IRPT_S, 1, 1)
59 DEP_FIELD(IMR_0, COMB_IRPT_NS, 1, 0)
60DEP_REG32(IER_0, 0x18)
61 DEP_FIELD(IER_0, ADDR_DECODE_ERR, 1, 31)
62 DEP_FIELD(IER_0, GBL_FLT_IRPT_NS, 1, 4)
63 DEP_FIELD(IER_0, GBL_FLT_IRPT_S, 1, 3)
64 DEP_FIELD(IER_0, COMB_PERF_IRPT_TBU, 1, 2)
65 DEP_FIELD(IER_0, COMB_IRPT_S, 1, 1)
66 DEP_FIELD(IER_0, COMB_IRPT_NS, 1, 0)
67DEP_REG32(IDR_0, 0x1c)
68 DEP_FIELD(IDR_0, ADDR_DECODE_ERR, 1, 31)
69 DEP_FIELD(IDR_0, GBL_FLT_IRPT_NS, 1, 4)
70 DEP_FIELD(IDR_0, GBL_FLT_IRPT_S, 1, 3)
71 DEP_FIELD(IDR_0, COMB_PERF_IRPT_TBU, 1, 2)
72 DEP_FIELD(IDR_0, COMB_IRPT_S, 1, 1)
73 DEP_FIELD(IDR_0, COMB_IRPT_NS, 1, 0)
74DEP_REG32(ITR_0, 0x20)
75 DEP_FIELD(ITR_0, ADDR_DECODE_ERR, 1, 31)
76 DEP_FIELD(ITR_0, GBL_FLT_IRPT_NS, 1, 4)
77 DEP_FIELD(ITR_0, GBL_FLT_IRPT_S, 1, 3)
78 DEP_FIELD(ITR_0, COMB_PERF_IRPT_TBU, 1, 2)
79 DEP_FIELD(ITR_0, COMB_IRPT_S, 1, 1)
80 DEP_FIELD(ITR_0, COMB_IRPT_NS, 1, 0)
81DEP_REG32(QREQN, 0x40)
82 DEP_FIELD(QREQN, TBU_TBU5_5_CG, 1, 14)
83 DEP_FIELD(QREQN, TBU_TBU5_5_PD, 1, 13)
84 DEP_FIELD(QREQN, TBU_TBU4_4_CG, 1, 12)
85 DEP_FIELD(QREQN, TBU_TBU4_4_PD, 1, 11)
86 DEP_FIELD(QREQN, TBU_TBU3_3_CG, 1, 10)
87 DEP_FIELD(QREQN, TBU_TBU3_3_PD, 1, 9)
88 DEP_FIELD(QREQN, PD_MST_BR_TBU2_2, 1, 8)
89 DEP_FIELD(QREQN, PD_SLV_BR_TBU2_2, 1, 7)
90 DEP_FIELD(QREQN, TBU_TBU2_2_CG, 1, 6)
91 DEP_FIELD(QREQN, TBU_TBU2_2_PD, 1, 5)
92 DEP_FIELD(QREQN, TBU_TBU1_1_CG, 1, 4)
93 DEP_FIELD(QREQN, TBU_TBU1_1_PD, 1, 3)
94 DEP_FIELD(QREQN, TBU_TBU0_0_CG, 1, 2)
95 DEP_FIELD(QREQN, TBU_TBU0_0_PD, 1, 1)
96 DEP_FIELD(QREQN, TCU, 1, 0)
97DEP_REG32(MISC, 0x54)
98 DEP_FIELD(MISC, SPNIDEN, 1, 12)
99 DEP_FIELD(MISC, ARQOSARB, 4, 8)
100 DEP_FIELD(MISC, AWAKEUP_PROG, 1, 7)
101 DEP_FIELD(MISC, EMAS, 1, 6)
102 DEP_FIELD(MISC, EMAW, 2, 4)
103 DEP_FIELD(MISC, EMA, 3, 1)
104DEP_REG32(CONFIG_SIGNALS, 0x58)
105 DEP_FIELD(CONFIG_SIGNALS, CFG_NORMALIZE, 1, 1)
106DEP_REG32(ECO_INFO, 0x100)
107 DEP_FIELD(ECO_INFO, ECOREVNUM, 4, 0)
108DEP_REG32(ECO_0, 0x104)
109DEP_REG32(ECO_1, 0x108)
110
111#define R_MAX (R_ECO_1 + 1)
112
113typedef struct SMMU_REG {
114 SysBusDevice parent_obj;
115 MemoryRegion iomem;
116 qemu_irq irq_imr_0;
117
118 uint32_t irq_src;
119
120 uint32_t regs[R_MAX];
121 DepRegisterInfo regs_info[R_MAX];
122} SMMU_REG;
123
124static void imr_0_update_irq(SMMU_REG *s)
125{
126 bool global_irq;
127 bool ctxt_irq;
128 bool pending;
129
130 global_irq = s->irq_src & 1;
131 ctxt_irq = s->irq_src & (~1);
132 s->regs[R_ISR_0] |= ctxt_irq << 0;
133 s->regs[R_ISR_0] |= ctxt_irq << 1;
134 s->regs[R_ISR_0] |= global_irq << 3;
135 s->regs[R_ISR_0] |= global_irq << 4;
136
137 pending = s->regs[R_ISR_0] & ~s->regs[R_IMR_0];
138 qemu_set_irq(s->irq_imr_0, pending);
139}
140
141static void isr_0_postw(DepRegisterInfo *reg, uint64_t val64)
142{
143 SMMU_REG *s = XILINX_SMMU_REG(reg->opaque);
144 imr_0_update_irq(s);
145}
146
147static uint64_t ier_0_prew(DepRegisterInfo *reg, uint64_t val64)
148{
149 SMMU_REG *s = XILINX_SMMU_REG(reg->opaque);
150 uint32_t val = val64;
151
152 s->regs[R_IMR_0] &= ~val;
153 imr_0_update_irq(s);
154 return 0;
155}
156
157static uint64_t idr_0_prew(DepRegisterInfo *reg, uint64_t val64)
158{
159 SMMU_REG *s = XILINX_SMMU_REG(reg->opaque);
160 uint32_t val = val64;
161
162 s->regs[R_IMR_0] |= val;
163 imr_0_update_irq(s);
164 return 0;
165}
166
167static uint64_t itr_0_prew(DepRegisterInfo *reg, uint64_t val64)
168{
169 SMMU_REG *s = XILINX_SMMU_REG(reg->opaque);
170 uint32_t val = val64;
171
172 s->regs[R_ISR_0] |= val;
173 imr_0_update_irq(s);
174 return 0;
175}
176
177static DepRegisterAccessInfo smmu_reg_regs_info[] = {
178 { .name = "MISC_CTRL", .decode.addr = A_MISC_CTRL,
179 },{ .name = "ISR_0", .decode.addr = A_ISR_0,
180 .rsvd = 0x7fffffe0,
181 .ro = 0x7fffffe0,
182 .w1c = 0x8000001f,
183 .post_write = isr_0_postw,
184 },{ .name = "IMR_0", .decode.addr = A_IMR_0,
185 .reset = 0x8000001f,
186 .rsvd = 0x7fffffe0,
187 .ro = 0x7fffffff,
188 .w1c = 0x80000000,
189 },{ .name = "IER_0", .decode.addr = A_IER_0,
190 .rsvd = 0x7fffffe0,
191 .ro = 0x7fffffe0,
192 .w1c = 0x80000000,
193 .pre_write = ier_0_prew,
194 },{ .name = "IDR_0", .decode.addr = A_IDR_0,
195 .rsvd = 0x7fffffe0,
196 .ro = 0x7fffffe0,
197 .w1c = 0x80000000,
198 .pre_write = idr_0_prew,
199 },{ .name = "ITR_0", .decode.addr = A_ITR_0,
200 .rsvd = 0x7fffffe0,
201 .ro = 0x7fffffe0,
202 .w1c = 0x80000000,
203 .pre_write = itr_0_prew,
204 },{ .name = "QREQN", .decode.addr = A_QREQN,
205 .reset = 0x7fff,
206 .rsvd = 0xffff8000,
207 },{ .name = "MISC", .decode.addr = A_MISC,
208 .reset = 0x16,
209 .rsvd = 0xffffe001,
210 .ro = 0xf00,
211 },{ .name = "CONFIG_SIGNALS", .decode.addr = A_CONFIG_SIGNALS,
212 .rsvd = 0xfffffffd,
213 },{ .name = "ECO_INFO", .decode.addr = A_ECO_INFO,
214 },{ .name = "ECO_0", .decode.addr = A_ECO_0,
215 },{ .name = "ECO_1", .decode.addr = A_ECO_1,
216 .reset = 0xffffffff,
217 }
218};
219
220static void smmu_reg_reset(DeviceState *dev)
221{
222 SMMU_REG *s = XILINX_SMMU_REG(dev);
223 unsigned int i;
224
225 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
226 dep_register_reset(&s->regs_info[i]);
227 }
228
229 imr_0_update_irq(s);
230}
231
232static uint64_t smmu_reg_read(void *opaque, hwaddr addr, unsigned size)
233{
234 SMMU_REG *s = XILINX_SMMU_REG(opaque);
235 DepRegisterInfo *r = &s->regs_info[addr / 4];
236
237 if (!r->data) {
238 qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
239 object_get_canonical_path(OBJECT(s)),
240 addr);
241 return 0;
242 }
243 return dep_register_read(r);
244}
245
246static void smmu_reg_write(void *opaque, hwaddr addr, uint64_t value,
247 unsigned size)
248{
249 SMMU_REG *s = XILINX_SMMU_REG(opaque);
250 DepRegisterInfo *r = &s->regs_info[addr / 4];
251
252 if (!r->data) {
253 qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
254 object_get_canonical_path(OBJECT(s)),
255 addr, value);
256 return;
257 }
258 dep_register_write(r, value, ~0);
259}
260
261static const MemoryRegionOps smmu_reg_ops = {
262 .read = smmu_reg_read,
263 .write = smmu_reg_write,
264 .endianness = DEVICE_LITTLE_ENDIAN,
265 .valid = {
266 .min_access_size = 4,
267 .max_access_size = 4,
268 },
269};
270
271static void irq_handler(void *opaque, int irq, int level)
272{
273 SMMU_REG *s = XILINX_SMMU_REG(opaque);
274
275 s->irq_src &= ~(1 << irq);
276 s->irq_src |= level << irq;
277 imr_0_update_irq(s);
278}
279
280static void smmu_reg_realize(DeviceState *dev, Error **errp)
281{
282 SMMU_REG *s = XILINX_SMMU_REG(dev);
283 const char *prefix = object_get_canonical_path(OBJECT(dev));
284 unsigned int i;
285
286 for (i = 0; i < ARRAY_SIZE(smmu_reg_regs_info); ++i) {
287 DepRegisterInfo *r = &s->regs_info[smmu_reg_regs_info[i].decode.addr/4];
288
289 *r = (DepRegisterInfo) {
290 .data = (uint8_t *)&s->regs[
291 smmu_reg_regs_info[i].decode.addr/4],
292 .data_size = sizeof(uint32_t),
293 .access = &smmu_reg_regs_info[i],
294 .debug = XILINX_SMMU_REG_ERR_DEBUG,
295 .prefix = prefix,
296 .opaque = s,
297 };
298 }
299
300 qdev_init_gpio_in(dev, irq_handler, 17);
301}
302
303static void smmu_reg_init(Object *obj)
304{
305 SMMU_REG *s = XILINX_SMMU_REG(obj);
306 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
307
308 memory_region_init_io(&s->iomem, obj, &smmu_reg_ops, s,
309 TYPE_XILINX_SMMU_REG, R_MAX * 4);
310 sysbus_init_mmio(sbd, &s->iomem);
311 sysbus_init_irq(sbd, &s->irq_imr_0);
312}
313
314static int smmu_reg_fdt_get_irq(FDTGenericIntc *obj, qemu_irq *irqs,
315 uint32_t *cells, int ncells, int max,
316 Error **errp)
317{
318
319 (*irqs) = qdev_get_gpio_in(DEVICE(obj), cells[0]);
320 return 1;
321};
322
323static const VMStateDescription vmstate_smmu_reg = {
324 .name = TYPE_XILINX_SMMU_REG,
325 .version_id = 1,
326 .minimum_version_id = 1,
327 .minimum_version_id_old = 1,
328 .fields = (VMStateField[]) {
329 VMSTATE_UINT32_ARRAY(regs, SMMU_REG, R_MAX),
330 VMSTATE_END_OF_LIST(),
331 }
332};
333
334static void smmu_reg_class_init(ObjectClass *klass, void *data)
335{
336 DeviceClass *dc = DEVICE_CLASS(klass);
337 FDTGenericIntcClass *fgic = FDT_GENERIC_INTC_CLASS(klass);
338
339 dc->reset = smmu_reg_reset;
340 dc->realize = smmu_reg_realize;
341 dc->vmsd = &vmstate_smmu_reg;
342 fgic->get_irq = smmu_reg_fdt_get_irq;
343}
344
345static const TypeInfo smmu_reg_info = {
346 .name = TYPE_XILINX_SMMU_REG,
347 .parent = TYPE_SYS_BUS_DEVICE,
348 .instance_size = sizeof(SMMU_REG),
349 .class_init = smmu_reg_class_init,
350 .instance_init = smmu_reg_init,
351 .interfaces = (InterfaceInfo[]) {
352 { TYPE_FDT_GENERIC_INTC },
353 { }
354 },
355};
356
357static void smmu_reg_register_types(void)
358{
359 type_register_static(&smmu_reg_info);
360}
361
362type_init(smmu_reg_register_types)
363