Skip to content

Commit fbc6d55

Browse files
committed
[Workaround] Implement virtio-rng device
1 parent 7074c77 commit fbc6d55

File tree

5 files changed

+360
-0
lines changed

5 files changed

+360
-0
lines changed

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ ifeq ($(call has, VIRTIOBLK), 1)
3434
endif
3535
endif
3636

37+
# virtio-rng
38+
ENABLE_VIRTIORNG ?= 1
39+
$(call set-feature, VIRTIORNG)
40+
ifeq ($(call has, VIRTIORNG), 1)
41+
OBJS_EXTRA += virtio-rng.o
42+
endif
43+
3744
NETDEV ?= tap
3845
# virtio-net
3946
ENABLE_VIRTIONET ?= 1

device.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,52 @@ void virtio_input_update_mouse_button_state(uint32_t button, bool pressed);
286286
void virtio_input_update_cursor(uint32_t x, uint32_t y);
287287
#endif /* SEMU_HAS(VIRTIOINPUT) */
288288

289+
/* VirtIO-RNG */
290+
291+
#if SEMU_HAS(VIRTIORNG)
292+
293+
#define IRQ_VRNG 7
294+
#define IRQ_VRNG_BIT (1 << IRQ_VRNG)
295+
296+
typedef struct {
297+
uint32_t QueueNum;
298+
uint32_t QueueDesc;
299+
uint32_t QueueAvail;
300+
uint32_t QueueUsed;
301+
uint16_t last_avail;
302+
bool ready;
303+
} virtio_rng_queue_t;
304+
305+
typedef struct {
306+
/* feature negotiation */
307+
uint32_t DeviceFeaturesSel;
308+
uint32_t DriverFeatures;
309+
uint32_t DriverFeaturesSel;
310+
/* queue config */
311+
uint32_t QueueSel;
312+
virtio_rng_queue_t queues[1];
313+
/* status */
314+
uint32_t Status;
315+
uint32_t InterruptStatus;
316+
/* supplied by environment */
317+
uint32_t *ram;
318+
} virtio_rng_state_t;
319+
320+
void virtio_rng_read(hart_t *vm,
321+
virtio_rng_state_t *rng,
322+
uint32_t addr,
323+
uint8_t width,
324+
uint32_t *value);
325+
326+
void virtio_rng_write(hart_t *vm,
327+
virtio_rng_state_t *vrng,
328+
uint32_t addr,
329+
uint8_t width,
330+
uint32_t value);
331+
332+
void virtio_rng_init(virtio_rng_state_t *vrng);
333+
#endif /* SEMU_HAS(VIRTIORNG) */
334+
289335
/* ACLINT MTIMER */
290336
typedef struct {
291337
/* A MTIMER device has two separate base addresses: one for the MTIME
@@ -393,6 +439,9 @@ typedef struct {
393439
#if SEMU_HAS(VIRTIOINPUT)
394440
virtio_input_state_t vkeyboard;
395441
virtio_input_state_t vmouse;
442+
#endif
443+
#if SEMU_HAS(VIRTIORNG)
444+
virtio_rng_state_t vrng;
396445
#endif
397446
/* ACLINT */
398447
mtimer_state_t mtimer;

main.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ static void emu_update_vinput_mouse_interrupts(vm_t *vm)
107107
}
108108
#endif
109109

110+
#if SEMU_HAS(VIRTIORNG)
111+
static void emu_update_vrng_interrupts(vm_t *vm)
112+
{
113+
emu_state_t *data = PRIV(vm->hart[0]);
114+
if (data->vrng.InterruptStatus)
115+
data->plic.active |= IRQ_VRNG_BIT;
116+
else
117+
data->plic.active &= ~IRQ_VRNG_BIT;
118+
plic_update_interrupts(vm, &data->plic);
119+
}
120+
#endif
121+
110122
static void emu_update_timer_interrupt(hart_t *hart)
111123
{
112124
emu_state_t *data = PRIV(hart);
@@ -189,6 +201,12 @@ static void mem_load(hart_t *hart,
189201
value);
190202
emu_update_vinput_mouse_interrupts(hart->vm);
191203
return;
204+
#endif
205+
#if SEMU_HAS(VIRTIORNG)
206+
case 0x49: /* virtio-rng */
207+
virtio_rng_read(hart, &data->vrng, addr & 0xFFFFF, width, value);
208+
emu_update_vrng_interrupts(hart->vm);
209+
return;
192210
#endif
193211
}
194212
}
@@ -261,6 +279,12 @@ static void mem_store(hart_t *hart,
261279
value);
262280
emu_update_vinput_mouse_interrupts(hart->vm);
263281
return;
282+
#endif
283+
#if SEMU_HAS(VIRTIORNG)
284+
case 0x49: /* virtio-rng */
285+
virtio_rng_write(hart, &data->vrng, addr & 0xFFFFF, width, value);
286+
emu_update_vrng_interrupts(hart->vm);
287+
return;
264288
#endif
265289
}
266290
}
@@ -709,6 +733,10 @@ static int semu_start(int argc, char **argv)
709733
emu.vmouse.ram = emu.ram;
710734
virtio_input_init(&(emu.vmouse));
711735
#endif
736+
#if SEMU_HAS(VIRTIORNG)
737+
emu.vrng.ram = emu.ram;
738+
virtio_rng_init(&(emu.vrng));
739+
#endif
712740

713741
/* Emulate */
714742
uint32_t peripheral_update_ctr = 0;

minimal.dts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,13 @@
8686
interrupts = <6>;
8787
};
8888
#endif
89+
90+
#if SEMU_FEATURE_VIRTIORNG
91+
rng0: virtio@4900000 {
92+
compatible = "virtio,mmio";
93+
reg = <0x4900000 0x200>;
94+
interrupts = <7>;
95+
};
96+
#endif
8997
};
9098
};

0 commit comments

Comments
 (0)