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"
17 #include "qemu/guest-random.h"
19 #include "hw/misc/imx_rngc.h"
20 #include "migration/vmstate.h"
22 #define RNGC_NAME "i.MX RNGC"
24 #define RNGC_VER_ID 0x00
25 #define RNGC_COMMAND 0x04
26 #define RNGC_CONTROL 0x08
27 #define RNGC_STATUS 0x0C
28 #define RNGC_FIFO 0x14
30 /* These version info are reported by the rngb in an imx258 chip. */
31 #define RNG_TYPE_RNGB 0x1
35 #define RNGC_CMD_BIT_SW_RST 0x40
36 #define RNGC_CMD_BIT_CLR_ERR 0x20
37 #define RNGC_CMD_BIT_CLR_INT 0x10
38 #define RNGC_CMD_BIT_SEED 0x02
39 #define RNGC_CMD_BIT_SELF_TEST 0x01
41 #define RNGC_CTRL_BIT_MASK_ERR 0x40
42 #define RNGC_CTRL_BIT_MASK_DONE 0x20
43 #define RNGC_CTRL_BIT_AUTO_SEED 0x10
45 /* the current status for self-test and seed operations */
50 static uint64_t imx_rngc_read(void *opaque
, hwaddr offset
, unsigned size
)
52 IMXRNGCState
*s
= IMX_RNGC(opaque
);
57 val
|= RNG_TYPE_RNGB
<< 28 | V_MAJ
<< 8 | V_MIN
;
61 if (s
->op_seed
== OP_RUN
) {
62 val
|= RNGC_CMD_BIT_SEED
;
64 if (s
->op_self_test
== OP_RUN
) {
65 val
|= RNGC_CMD_BIT_SELF_TEST
;
71 * The CTL_ACC and VERIF_MODE bits are not supported yet.
76 val
|= RNGC_CTRL_BIT_AUTO_SEED
;
79 * We don't have an internal fifo like the real hardware.
80 * There's no need for strategy to handle fifo underflows.
81 * We return the FIFO_UFLOW_RESPONSE bits as 0.
87 * We never report any statistics test or self-test errors or any
88 * other errors. STAT_TEST_PF, ST_PF and ERROR are always 0.
92 * We don't have an internal fifo, see above. Therefore, we
93 * report back the default fifo size (5 32-bit words) and
94 * indicate that our fifo is always full.
96 val
|= 5 << 12 | 5 << 8;
98 /* We always have a new seed available. */
101 if (s
->op_seed
== OP_DONE
) {
104 if (s
->op_self_test
== OP_DONE
) {
107 if (s
->op_seed
== OP_RUN
|| s
->op_self_test
== OP_RUN
) {
109 * We're busy if self-test is running or if we're
115 * We're ready to provide secure random numbers whenever
123 qemu_guest_getrandom_nofail(&val
, sizeof(val
));
130 static void imx_rngc_do_reset(IMXRNGCState
*s
)
132 s
->op_self_test
= OP_IDLE
;
133 s
->op_seed
= OP_IDLE
;
135 s
->auto_seed
= false;
138 static void imx_rngc_write(void *opaque
, hwaddr offset
, uint64_t value
,
141 IMXRNGCState
*s
= IMX_RNGC(opaque
);
145 if (value
& RNGC_CMD_BIT_SW_RST
) {
146 imx_rngc_do_reset(s
);
150 * For now, both CLR_ERR and CLR_INT clear the interrupt. We
151 * don't report any errors yet.
153 if (value
& (RNGC_CMD_BIT_CLR_ERR
| RNGC_CMD_BIT_CLR_INT
)) {
154 qemu_irq_lower(s
->irq
);
157 if (value
& RNGC_CMD_BIT_SEED
) {
159 qemu_bh_schedule(s
->seed_bh
);
162 if (value
& RNGC_CMD_BIT_SELF_TEST
) {
163 s
->op_self_test
= OP_RUN
;
164 qemu_bh_schedule(s
->self_test_bh
);
170 * The CTL_ACC and VERIF_MODE bits are not supported yet.
171 * We ignore them if they're set by the caller.
174 if (value
& RNGC_CTRL_BIT_MASK_ERR
) {
175 s
->mask
|= RNGC_CTRL_BIT_MASK_ERR
;
177 s
->mask
&= ~RNGC_CTRL_BIT_MASK_ERR
;
180 if (value
& RNGC_CTRL_BIT_MASK_DONE
) {
181 s
->mask
|= RNGC_CTRL_BIT_MASK_DONE
;
183 s
->mask
&= ~RNGC_CTRL_BIT_MASK_DONE
;
186 if (value
& RNGC_CTRL_BIT_AUTO_SEED
) {
189 s
->auto_seed
= false;
195 static const MemoryRegionOps imx_rngc_ops
= {
196 .read
= imx_rngc_read
,
197 .write
= imx_rngc_write
,
198 .endianness
= DEVICE_NATIVE_ENDIAN
,
201 static void imx_rngc_self_test(void *opaque
)
203 IMXRNGCState
*s
= IMX_RNGC(opaque
);
205 s
->op_self_test
= OP_DONE
;
206 if (!(s
->mask
& RNGC_CTRL_BIT_MASK_DONE
)) {
207 qemu_irq_raise(s
->irq
);
211 static void imx_rngc_seed(void *opaque
)
213 IMXRNGCState
*s
= IMX_RNGC(opaque
);
215 s
->op_seed
= OP_DONE
;
216 if (!(s
->mask
& RNGC_CTRL_BIT_MASK_DONE
)) {
217 qemu_irq_raise(s
->irq
);
221 static void imx_rngc_realize(DeviceState
*dev
, Error
**errp
)
223 IMXRNGCState
*s
= IMX_RNGC(dev
);
224 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
226 memory_region_init_io(&s
->iomem
, OBJECT(s
), &imx_rngc_ops
, s
,
227 TYPE_IMX_RNGC
, 0x1000);
228 sysbus_init_mmio(sbd
, &s
->iomem
);
230 sysbus_init_irq(sbd
, &s
->irq
);
231 s
->self_test_bh
= qemu_bh_new(imx_rngc_self_test
, s
);
232 s
->seed_bh
= qemu_bh_new(imx_rngc_seed
, s
);
235 static void imx_rngc_reset(DeviceState
*dev
)
237 IMXRNGCState
*s
= IMX_RNGC(dev
);
239 imx_rngc_do_reset(s
);
242 static const VMStateDescription vmstate_imx_rngc
= {
245 .minimum_version_id
= 1,
246 .fields
= (VMStateField
[]) {
247 VMSTATE_UINT8(op_self_test
, IMXRNGCState
),
248 VMSTATE_UINT8(op_seed
, IMXRNGCState
),
249 VMSTATE_UINT8(mask
, IMXRNGCState
),
250 VMSTATE_BOOL(auto_seed
, IMXRNGCState
),
251 VMSTATE_END_OF_LIST()
255 static void imx_rngc_class_init(ObjectClass
*klass
, void *data
)
257 DeviceClass
*dc
= DEVICE_CLASS(klass
);
259 dc
->realize
= imx_rngc_realize
;
260 dc
->reset
= imx_rngc_reset
;
261 dc
->desc
= RNGC_NAME
,
262 dc
->vmsd
= &vmstate_imx_rngc
;
265 static const TypeInfo imx_rngc_info
= {
266 .name
= TYPE_IMX_RNGC
,
267 .parent
= TYPE_SYS_BUS_DEVICE
,
268 .instance_size
= sizeof(IMXRNGCState
),
269 .class_init
= imx_rngc_class_init
,
272 static void imx_rngc_register_types(void)
274 type_register_static(&imx_rngc_info
);
277 type_init(imx_rngc_register_types
)