2 * QEMU model of the Xilinx XRAM Controller.
4 * Copyright (c) 2021 Xilinx Inc.
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9 #include "qemu/osdep.h"
10 #include "qemu/units.h"
11 #include "qapi/error.h"
12 #include "migration/vmstate.h"
13 #include "hw/sysbus.h"
14 #include "hw/register.h"
15 #include "hw/qdev-properties.h"
17 #include "hw/misc/xlnx-versal-xramc.h"
19 #ifndef XLNX_XRAM_CTRL_ERR_DEBUG
20 #define XLNX_XRAM_CTRL_ERR_DEBUG 0
23 static void xram_update_irq(XlnxXramCtrl
*s
)
25 bool pending
= s
->regs
[R_XRAM_ISR
] & ~s
->regs
[R_XRAM_IMR
];
26 qemu_set_irq(s
->irq
, pending
);
29 static void xram_isr_postw(RegisterInfo
*reg
, uint64_t val64
)
31 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(reg
->opaque
);
35 static uint64_t xram_ien_prew(RegisterInfo
*reg
, uint64_t val64
)
37 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(reg
->opaque
);
40 s
->regs
[R_XRAM_IMR
] &= ~val
;
45 static uint64_t xram_ids_prew(RegisterInfo
*reg
, uint64_t val64
)
47 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(reg
->opaque
);
50 s
->regs
[R_XRAM_IMR
] |= val
;
55 static const RegisterAccessInfo xram_ctrl_regs_info
[] = {
56 { .name
= "XRAM_ERR_CTRL", .addr
= A_XRAM_ERR_CTRL
,
59 },{ .name
= "XRAM_ISR", .addr
= A_XRAM_ISR
,
62 .post_write
= xram_isr_postw
,
63 },{ .name
= "XRAM_IMR", .addr
= A_XRAM_IMR
,
67 },{ .name
= "XRAM_IEN", .addr
= A_XRAM_IEN
,
69 .pre_write
= xram_ien_prew
,
70 },{ .name
= "XRAM_IDS", .addr
= A_XRAM_IDS
,
72 .pre_write
= xram_ids_prew
,
73 },{ .name
= "XRAM_ECC_CNTL", .addr
= A_XRAM_ECC_CNTL
,
75 },{ .name
= "XRAM_CLR_EXE", .addr
= A_XRAM_CLR_EXE
,
77 },{ .name
= "XRAM_CE_FFA", .addr
= A_XRAM_CE_FFA
,
80 },{ .name
= "XRAM_CE_FFD0", .addr
= A_XRAM_CE_FFD0
,
82 },{ .name
= "XRAM_CE_FFD1", .addr
= A_XRAM_CE_FFD1
,
84 },{ .name
= "XRAM_CE_FFD2", .addr
= A_XRAM_CE_FFD2
,
86 },{ .name
= "XRAM_CE_FFD3", .addr
= A_XRAM_CE_FFD3
,
88 },{ .name
= "XRAM_CE_FFE", .addr
= A_XRAM_CE_FFE
,
91 },{ .name
= "XRAM_UE_FFA", .addr
= A_XRAM_UE_FFA
,
94 },{ .name
= "XRAM_UE_FFD0", .addr
= A_XRAM_UE_FFD0
,
96 },{ .name
= "XRAM_UE_FFD1", .addr
= A_XRAM_UE_FFD1
,
98 },{ .name
= "XRAM_UE_FFD2", .addr
= A_XRAM_UE_FFD2
,
100 },{ .name
= "XRAM_UE_FFD3", .addr
= A_XRAM_UE_FFD3
,
102 },{ .name
= "XRAM_UE_FFE", .addr
= A_XRAM_UE_FFE
,
105 },{ .name
= "XRAM_FI_D0", .addr
= A_XRAM_FI_D0
,
106 },{ .name
= "XRAM_FI_D1", .addr
= A_XRAM_FI_D1
,
107 },{ .name
= "XRAM_FI_D2", .addr
= A_XRAM_FI_D2
,
108 },{ .name
= "XRAM_FI_D3", .addr
= A_XRAM_FI_D3
,
109 },{ .name
= "XRAM_FI_SY", .addr
= A_XRAM_FI_SY
,
111 },{ .name
= "XRAM_RMW_UE_FFA", .addr
= A_XRAM_RMW_UE_FFA
,
114 },{ .name
= "XRAM_FI_CNTR", .addr
= A_XRAM_FI_CNTR
,
116 },{ .name
= "XRAM_IMP", .addr
= A_XRAM_IMP
,
120 },{ .name
= "XRAM_PRDY_DBG", .addr
= A_XRAM_PRDY_DBG
,
124 },{ .name
= "XRAM_SAFETY_CHK", .addr
= A_XRAM_SAFETY_CHK
,
128 static void xram_ctrl_reset_enter(Object
*obj
, ResetType type
)
130 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(obj
);
133 for (i
= 0; i
< ARRAY_SIZE(s
->regs_info
); ++i
) {
134 register_reset(&s
->regs_info
[i
]);
137 ARRAY_FIELD_DP32(s
->regs
, XRAM_IMP
, SIZE
, s
->cfg
.encoded_size
);
140 static void xram_ctrl_reset_hold(Object
*obj
)
142 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(obj
);
147 static const MemoryRegionOps xram_ctrl_ops
= {
148 .read
= register_read_memory
,
149 .write
= register_write_memory
,
150 .endianness
= DEVICE_LITTLE_ENDIAN
,
152 .min_access_size
= 4,
153 .max_access_size
= 4,
157 static void xram_ctrl_realize(DeviceState
*dev
, Error
**errp
)
159 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
160 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(dev
);
162 switch (s
->cfg
.size
) {
164 s
->cfg
.encoded_size
= 0;
167 s
->cfg
.encoded_size
= 1;
170 s
->cfg
.encoded_size
= 2;
173 s
->cfg
.encoded_size
= 3;
176 s
->cfg
.encoded_size
= 4;
179 error_setg(errp
, "Unsupported XRAM size %" PRId64
, s
->cfg
.size
);
183 memory_region_init_ram(&s
->ram
, OBJECT(s
),
184 object_get_canonical_path_component(OBJECT(s
)),
185 s
->cfg
.size
, &error_fatal
);
186 sysbus_init_mmio(sbd
, &s
->ram
);
189 static void xram_ctrl_init(Object
*obj
)
191 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(obj
);
192 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
195 register_init_block32(DEVICE(obj
), xram_ctrl_regs_info
,
196 ARRAY_SIZE(xram_ctrl_regs_info
),
197 s
->regs_info
, s
->regs
,
199 XLNX_XRAM_CTRL_ERR_DEBUG
,
200 XRAM_CTRL_R_MAX
* 4);
201 sysbus_init_mmio(sbd
, &s
->reg_array
->mem
);
202 sysbus_init_irq(sbd
, &s
->irq
);
205 static void xram_ctrl_finalize(Object
*obj
)
207 XlnxXramCtrl
*s
= XLNX_XRAM_CTRL(obj
);
208 register_finalize_block(s
->reg_array
);
211 static const VMStateDescription vmstate_xram_ctrl
= {
212 .name
= TYPE_XLNX_XRAM_CTRL
,
214 .minimum_version_id
= 1,
215 .fields
= (VMStateField
[]) {
216 VMSTATE_UINT32_ARRAY(regs
, XlnxXramCtrl
, XRAM_CTRL_R_MAX
),
217 VMSTATE_END_OF_LIST(),
221 static Property xram_ctrl_properties
[] = {
222 DEFINE_PROP_UINT64("size", XlnxXramCtrl
, cfg
.size
, 1 * MiB
),
223 DEFINE_PROP_END_OF_LIST(),
226 static void xram_ctrl_class_init(ObjectClass
*klass
, void *data
)
228 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
229 DeviceClass
*dc
= DEVICE_CLASS(klass
);
231 dc
->realize
= xram_ctrl_realize
;
232 dc
->vmsd
= &vmstate_xram_ctrl
;
233 device_class_set_props(dc
, xram_ctrl_properties
);
235 rc
->phases
.enter
= xram_ctrl_reset_enter
;
236 rc
->phases
.hold
= xram_ctrl_reset_hold
;
239 static const TypeInfo xram_ctrl_info
= {
240 .name
= TYPE_XLNX_XRAM_CTRL
,
241 .parent
= TYPE_SYS_BUS_DEVICE
,
242 .instance_size
= sizeof(XlnxXramCtrl
),
243 .class_init
= xram_ctrl_class_init
,
244 .instance_init
= xram_ctrl_init
,
245 .instance_finalize
= xram_ctrl_finalize
,
248 static void xram_ctrl_register_types(void)
250 type_register_static(&xram_ctrl_info
);
253 type_init(xram_ctrl_register_types
)