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.h"
31#include "qemu/bitops.h"
32#include "migration/vmstate.h"
33#include "hw/irq.h"
34#include "qemu/log.h"
35
36
37
38#ifndef XILINX_FPD_SLCR_SECURE_ERR_DEBUG
39#define XILINX_FPD_SLCR_SECURE_ERR_DEBUG 0
40#endif
41
42#define TYPE_XILINX_FPD_SLCR_SECURE "xlnx,versal-fpd-slcr-secure"
43
44#define XILINX_FPD_SLCR_SECURE(obj) \
45 OBJECT_CHECK(FPD_SLCR_SECURE, (obj), TYPE_XILINX_FPD_SLCR_SECURE)
46
47REG32(WPROT0, 0x0)
48 FIELD(WPROT0, ACTIVE, 0, 1)
49REG32(CTRL, 0x4)
50 FIELD(CTRL, SLVERR_ENABLE, 0, 1)
51REG32(ISR, 0x8)
52 FIELD(ISR, ADDR_DECODE_ERR, 0, 1)
53REG32(IMR, 0xc)
54 FIELD(IMR, ADDR_DECODE_ERR, 0, 1)
55REG32(IER, 0x10)
56 FIELD(IER, ADDR_DECODE_ERR, 0, 1)
57REG32(IDR, 0x14)
58 FIELD(IDR, ADDR_DECODE_ERR, 0, 1)
59REG32(ITR, 0x18)
60 FIELD(ITR, ADDR_DECODE_ERR, 0, 1)
61REG32(FPD_TZ_CTRL_TZ_APU_DUAL, 0x104)
62 FIELD(FPD_TZ_CTRL_TZ_APU_DUAL, N, 0, 1)
63REG32(FPD_TZ_CTRL_TZ_XMPU, 0x108)
64 FIELD(FPD_TZ_CTRL_TZ_XMPU, N, 0, 1)
65REG32(FPD_TZ_CTRL_TZ_FPD_SLCR, 0x10c)
66 FIELD(FPD_TZ_CTRL_TZ_FPD_SLCR, N, 0, 1)
67REG32(FPD_TZ_CTRL_TZ_CRF, 0x110)
68 FIELD(FPD_TZ_CTRL_TZ_CRF, N, 0, 1)
69REG32(FPD_TZ_CTRL_TZ_AFIFM0, 0x114)
70 FIELD(FPD_TZ_CTRL_TZ_AFIFM0, AXI_N, 0, 1)
71REG32(FPD_TZ_CTRL_TZ_AFIFM2, 0x118)
72 FIELD(FPD_TZ_CTRL_TZ_AFIFM2, AXI_N, 0, 1)
73REG32(FPD_TZ_CTRL_CCI, 0x11c)
74 FIELD(FPD_TZ_CTRL_CCI, TZ_N, 0, 1)
75REG32(FPD_TZ_CTRL_SMMU, 0x120)
76 FIELD(FPD_TZ_CTRL_SMMU, TZ_N, 0, 1)
77REG32(TZPROT, 0xff8)
78 FIELD(TZPROT, ACTIVE, 0, 1)
79REG32(ECO, 0xffc)
80
81#define FPD_SLCR_SECURE_R_MAX (R_ECO + 1)
82
83typedef struct FPD_SLCR_SECURE {
84 SysBusDevice parent_obj;
85 MemoryRegion iomem;
86 qemu_irq irq_imr;
87
88 uint32_t regs[FPD_SLCR_SECURE_R_MAX];
89 RegisterInfo regs_info[FPD_SLCR_SECURE_R_MAX];
90} FPD_SLCR_SECURE;
91
92static void imr_update_irq(FPD_SLCR_SECURE *s)
93{
94 bool pending = s->regs[R_ISR] & ~s->regs[R_IMR];
95 qemu_set_irq(s->irq_imr, pending);
96}
97
98static void isr_postw(RegisterInfo *reg, uint64_t val64)
99{
100 FPD_SLCR_SECURE *s = XILINX_FPD_SLCR_SECURE(reg->opaque);
101 imr_update_irq(s);
102}
103
104static uint64_t ier_prew(RegisterInfo *reg, uint64_t val64)
105{
106 FPD_SLCR_SECURE *s = XILINX_FPD_SLCR_SECURE(reg->opaque);
107 uint32_t val = val64;
108
109 s->regs[R_IMR] &= ~val;
110 imr_update_irq(s);
111 return 0;
112}
113
114static uint64_t idr_prew(RegisterInfo *reg, uint64_t val64)
115{
116 FPD_SLCR_SECURE *s = XILINX_FPD_SLCR_SECURE(reg->opaque);
117 uint32_t val = val64;
118
119 s->regs[R_IMR] |= val;
120 imr_update_irq(s);
121 return 0;
122}
123
124static uint64_t itr_prew(RegisterInfo *reg, uint64_t val64)
125{
126 FPD_SLCR_SECURE *s = XILINX_FPD_SLCR_SECURE(reg->opaque);
127 uint32_t val = val64;
128
129 s->regs[R_ISR] |= val;
130 imr_update_irq(s);
131 return 0;
132}
133
134static const RegisterAccessInfo fpd_slcr_secure_regs_info[] = {
135 { .name = "WPROT0", .addr = A_WPROT0,
136 },{ .name = "CTRL", .addr = A_CTRL,
137 .rsvd = 0xfffffffe,
138 },{ .name = "ISR", .addr = A_ISR,
139 .rsvd = 0xfffffffe,
140 .w1c = 0x1,
141 .post_write = isr_postw,
142 },{ .name = "IMR", .addr = A_IMR,
143 .reset = 0x1,
144 .rsvd = 0xfffffffe,
145 .ro = 0x1,
146 },{ .name = "IER", .addr = A_IER,
147 .rsvd = 0xfffffffe,
148 .pre_write = ier_prew,
149 },{ .name = "IDR", .addr = A_IDR,
150 .rsvd = 0xfffffffe,
151 .pre_write = idr_prew,
152 },{ .name = "ITR", .addr = A_ITR,
153 .rsvd = 0xfffffffe,
154 .pre_write = itr_prew,
155 },{ .name = "FPD_TZ_CTRL_TZ_APU_DUAL", .addr = A_FPD_TZ_CTRL_TZ_APU_DUAL,
156 .reset = 0x1,
157 .rsvd = 0xfffffffe,
158 },{ .name = "FPD_TZ_CTRL_TZ_XMPU", .addr = A_FPD_TZ_CTRL_TZ_XMPU,
159 .reset = 0x1,
160 .rsvd = 0xfffffffe,
161 },{ .name = "FPD_TZ_CTRL_TZ_FPD_SLCR", .addr = A_FPD_TZ_CTRL_TZ_FPD_SLCR,
162 .reset = 0x1,
163 .rsvd = 0xfffffffe,
164 },{ .name = "FPD_TZ_CTRL_TZ_CRF", .addr = A_FPD_TZ_CTRL_TZ_CRF,
165 .reset = 0x1,
166 .rsvd = 0xfffffffe,
167 },{ .name = "FPD_TZ_CTRL_TZ_AFIFM0", .addr = A_FPD_TZ_CTRL_TZ_AFIFM0,
168 .reset = 0x1,
169 .rsvd = 0xfffffffe,
170 },{ .name = "FPD_TZ_CTRL_TZ_AFIFM2", .addr = A_FPD_TZ_CTRL_TZ_AFIFM2,
171 .reset = 0x1,
172 .rsvd = 0xfffffffe,
173 },{ .name = "FPD_TZ_CTRL_CCI", .addr = A_FPD_TZ_CTRL_CCI,
174 .reset = 0x1,
175 .rsvd = 0xfffffffe,
176 },{ .name = "FPD_TZ_CTRL_SMMU", .addr = A_FPD_TZ_CTRL_SMMU,
177 .reset = 0x1,
178 .rsvd = 0xfffffffe,
179 },{ .name = "TZPROT", .addr = A_TZPROT,
180 },{ .name = "ECO", .addr = A_ECO,
181 }
182};
183
184static void fpd_slcr_secure_reset(DeviceState *dev)
185{
186 FPD_SLCR_SECURE *s = XILINX_FPD_SLCR_SECURE(dev);
187 unsigned int i;
188
189 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
190 register_reset(&s->regs_info[i]);
191 }
192
193 imr_update_irq(s);
194}
195
196static const MemoryRegionOps fpd_slcr_secure_ops = {
197 .read = register_read_memory,
198 .write = register_write_memory,
199 .endianness = DEVICE_LITTLE_ENDIAN,
200 .valid = {
201 .min_access_size = 4,
202 .max_access_size = 4,
203 },
204};
205
206static void fpd_slcr_secure_init(Object *obj)
207{
208 FPD_SLCR_SECURE *s = XILINX_FPD_SLCR_SECURE(obj);
209 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
210 RegisterInfoArray *reg_array;
211
212 memory_region_init(&s->iomem, obj, TYPE_XILINX_FPD_SLCR_SECURE,
213 FPD_SLCR_SECURE_R_MAX * 4);
214 reg_array =
215 register_init_block32(DEVICE(obj), fpd_slcr_secure_regs_info,
216 ARRAY_SIZE(fpd_slcr_secure_regs_info),
217 s->regs_info, s->regs,
218 &fpd_slcr_secure_ops,
219 XILINX_FPD_SLCR_SECURE_ERR_DEBUG,
220 FPD_SLCR_SECURE_R_MAX * 4);
221 memory_region_add_subregion(&s->iomem,
222 0x0,
223 ®_array->mem);
224 sysbus_init_mmio(sbd, &s->iomem);
225 sysbus_init_irq(sbd, &s->irq_imr);
226}
227
228static const VMStateDescription vmstate_fpd_slcr_secure = {
229 .name = TYPE_XILINX_FPD_SLCR_SECURE,
230 .version_id = 1,
231 .minimum_version_id = 1,
232 .fields = (VMStateField[]) {
233 VMSTATE_UINT32_ARRAY(regs, FPD_SLCR_SECURE, FPD_SLCR_SECURE_R_MAX),
234 VMSTATE_END_OF_LIST(),
235 }
236};
237
238static void fpd_slcr_secure_class_init(ObjectClass *klass, void *data)
239{
240 DeviceClass *dc = DEVICE_CLASS(klass);
241
242 dc->reset = fpd_slcr_secure_reset;
243 dc->vmsd = &vmstate_fpd_slcr_secure;
244}
245
246static const TypeInfo fpd_slcr_secure_info = {
247 .name = TYPE_XILINX_FPD_SLCR_SECURE,
248 .parent = TYPE_SYS_BUS_DEVICE,
249 .instance_size = sizeof(FPD_SLCR_SECURE),
250 .class_init = fpd_slcr_secure_class_init,
251 .instance_init = fpd_slcr_secure_init,
252};
253
254static void fpd_slcr_secure_register_types(void)
255{
256 type_register_static(&fpd_slcr_secure_info);
257}
258
259type_init(fpd_slcr_secure_register_types)
260