2 * Freescale i.MX RNGC emulation
4 * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
9 * This driver provides the minimum functionality to initialize and seed
10 * an rngc and to read random numbers. The rngb that is found in imx25
11 * chipsets is also supported.
14 #include "qemu/osdep.h"
15 #include "qemu/main-loop.h"
16 #include "qemu/module.h"
18 #include "qemu/guest-random.h"
20 #include "hw/misc/imx_rngc.h"
21 #include "migration/vmstate.h"
23 #define RNGC_NAME "i.MX RNGC"
25 #define RNGC_VER_ID 0x00
26 #define RNGC_COMMAND 0x04
27 #define RNGC_CONTROL 0x08
28 #define RNGC_STATUS 0x0C
29 #define RNGC_FIFO 0x14
31 /* These version info are reported by the rngb in an imx258 chip. */
32 #define RNG_TYPE_RNGB 0x1
36 #define RNGC_CMD_BIT_SW_RST 0x40
37 #define RNGC_CMD_BIT_CLR_ERR 0x20
38 #define RNGC_CMD_BIT_CLR_INT 0x10
39 #define RNGC_CMD_BIT_SEED 0x02
40 #define RNGC_CMD_BIT_SELF_TEST 0x01
42 #define RNGC_CTRL_BIT_MASK_ERR 0x40
43 #define RNGC_CTRL_BIT_MASK_DONE 0x20
44 #define RNGC_CTRL_BIT_AUTO_SEED 0x10
46 /* the current status for self-test and seed operations */
51 static uint64_t imx_rngc_read(void *opaque
, hwaddr offset
, unsigned size
)
53 IMXRNGCState
*s
= IMX_RNGC(opaque
);
58 val
|= RNG_TYPE_RNGB
<< 28 | V_MAJ
<< 8 | V_MIN
;
62 if (s
->op_seed
== OP_RUN
) {
63 val
|= RNGC_CMD_BIT_SEED
;
65 if (s
->op_self_test
== OP_RUN
) {
66 val
|= RNGC_CMD_BIT_SELF_TEST
;
72 * The CTL_ACC and VERIF_MODE bits are not supported yet.
77 val
|= RNGC_CTRL_BIT_AUTO_SEED
;
80 * We don't have an internal fifo like the real hardware.
81 * There's no need for strategy to handle fifo underflows.
82 * We return the FIFO_UFLOW_RESPONSE bits as 0.
88 * We never report any statistics test or self-test errors or any
89 * other errors. STAT_TEST_PF, ST_PF and ERROR are always 0.
93 * We don't have an internal fifo, see above. Therefore, we
94 * report back the default fifo size (5 32-bit words) and
95 * indicate that our fifo is always full.
97 val
|= 5 << 12 | 5 << 8;
99 /* We always have a new seed available. */
102 if (s
->op_seed
== OP_DONE
) {
105 if (s
->op_self_test
== OP_DONE
) {
108 if (s
->op_seed
== OP_RUN
|| s
->op_self_test
== OP_RUN
) {
110 * We're busy if self-test is running or if we're
116 * We're ready to provide secure random numbers whenever
124 qemu_guest_getrandom_nofail(&val
, sizeof(val
));
131 static void imx_rngc_do_reset(IMXRNGCState
*s
)
133 s
->op_self_test
= OP_IDLE
;
134 s
->op_seed
= OP_IDLE
;
136 s
->auto_seed
= false;
139 static void imx_rngc_write(void *opaque
, hwaddr offset
, uint64_t value
,
142 IMXRNGCState
*s
= IMX_RNGC(opaque
);
146 if (value
& RNGC_CMD_BIT_SW_RST
) {
147 imx_rngc_do_reset(s
);
151 * For now, both CLR_ERR and CLR_INT clear the interrupt. We
152 * don't report any errors yet.
154 if (value
& (RNGC_CMD_BIT_CLR_ERR
| RNGC_CMD_BIT_CLR_INT
)) {
155 qemu_irq_lower(s
->irq
);
158 if (value
& RNGC_CMD_BIT_SEED
) {
160 qemu_bh_schedule(s
->seed_bh
);
163 if (value
& RNGC_CMD_BIT_SELF_TEST
) {
164 s
->op_self_test
= OP_RUN
;
165 qemu_bh_schedule(s
->self_test_bh
);
171 * The CTL_ACC and VERIF_MODE bits are not supported yet.
172 * We ignore them if they're set by the caller.
175 if (value
& RNGC_CTRL_BIT_MASK_ERR
) {
176 s
->mask
|= RNGC_CTRL_BIT_MASK_ERR
;
178 s
->mask
&= ~RNGC_CTRL_BIT_MASK_ERR
;
181 if (value
& RNGC_CTRL_BIT_MASK_DONE
) {
182 s
->mask
|= RNGC_CTRL_BIT_MASK_DONE
;
184 s
->mask
&= ~RNGC_CTRL_BIT_MASK_DONE
;
187 if (value
& RNGC_CTRL_BIT_AUTO_SEED
) {
190 s
->auto_seed
= false;
196 static const MemoryRegionOps imx_rngc_ops
= {
197 .read
= imx_rngc_read
,
198 .write
= imx_rngc_write
,
199 .endianness
= DEVICE_NATIVE_ENDIAN
,
202 static void imx_rngc_self_test(void *opaque
)
204 IMXRNGCState
*s
= IMX_RNGC(opaque
);
206 s
->op_self_test
= OP_DONE
;
207 if (!(s
->mask
& RNGC_CTRL_BIT_MASK_DONE
)) {
208 qemu_irq_raise(s
->irq
);
212 static void imx_rngc_seed(void *opaque
)
214 IMXRNGCState
*s
= IMX_RNGC(opaque
);
216 s
->op_seed
= OP_DONE
;
217 if (!(s
->mask
& RNGC_CTRL_BIT_MASK_DONE
)) {
218 qemu_irq_raise(s
->irq
);
222 static void imx_rngc_realize(DeviceState
*dev
, Error
**errp
)
224 IMXRNGCState
*s
= IMX_RNGC(dev
);
225 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
227 memory_region_init_io(&s
->iomem
, OBJECT(s
), &imx_rngc_ops
, s
,
228 TYPE_IMX_RNGC
, 0x1000);
229 sysbus_init_mmio(sbd
, &s
->iomem
);
231 sysbus_init_irq(sbd
, &s
->irq
);
232 s
->self_test_bh
= qemu_bh_new(imx_rngc_self_test
, s
);
233 s
->seed_bh
= qemu_bh_new(imx_rngc_seed
, s
);
236 static void imx_rngc_reset(DeviceState
*dev
)
238 IMXRNGCState
*s
= IMX_RNGC(dev
);
240 imx_rngc_do_reset(s
);
243 static const VMStateDescription vmstate_imx_rngc
= {
246 .minimum_version_id
= 1,
247 .fields
= (VMStateField
[]) {
248 VMSTATE_UINT8(op_self_test
, IMXRNGCState
),
249 VMSTATE_UINT8(op_seed
, IMXRNGCState
),
250 VMSTATE_UINT8(mask
, IMXRNGCState
),
251 VMSTATE_BOOL(auto_seed
, IMXRNGCState
),
252 VMSTATE_END_OF_LIST()
256 static void imx_rngc_class_init(ObjectClass
*klass
, void *data
)
258 DeviceClass
*dc
= DEVICE_CLASS(klass
);
260 dc
->realize
= imx_rngc_realize
;
261 dc
->reset
= imx_rngc_reset
;
262 dc
->desc
= RNGC_NAME
,
263 dc
->vmsd
= &vmstate_imx_rngc
;
266 static const TypeInfo imx_rngc_info
= {
267 .name
= TYPE_IMX_RNGC
,
268 .parent
= TYPE_SYS_BUS_DEVICE
,
269 .instance_size
= sizeof(IMXRNGCState
),
270 .class_init
= imx_rngc_class_init
,
273 static void imx_rngc_register_types(void)
275 type_register_static(&imx_rngc_info
);
278 type_init(imx_rngc_register_types
)