blob: 039fa776989769ce4caf173fc80d6a07d8d732a6 [file] [log] [blame]
Woyten8c243cd2019-12-01 15:06:20 +01001use crate::callback::Identity0Consumer;
Woytencd7597d2019-11-12 12:38:35 +01002use crate::futures;
Woyten22bc2542019-11-15 23:18:40 +01003use crate::result::TockResult;
Guillaume Endignouxb0914422019-10-04 13:37:26 +02004use crate::syscalls;
5use core::cell::Cell;
Woyten22bc2542019-11-15 23:18:40 +01006use core::mem;
Guillaume Endignouxb0914422019-10-04 13:37:26 +02007
8const DRIVER_NUMBER: usize = 0x40001;
9
10mod command_nr {
11 pub const REQUEST_RNG: usize = 1;
12}
13
14mod subscribe_nr {
15 pub const BUFFER_FILLED: usize = 0;
16}
17
18mod allow_nr {
19 pub const SHARE_BUFFER: usize = 0;
20}
21
torfmaster97c5e722020-01-02 21:30:16 +010022#[non_exhaustive]
23pub struct RngDriver;
Guillaume Endignouxb0914422019-10-04 13:37:26 +020024
torfmaster0c1aead2019-12-27 18:03:10 +010025impl RngDriver {
26 pub async fn fill_buffer(&mut self, buf: &mut [u8]) -> TockResult<()> {
27 let buf_len = buf.len();
28 let shared_memory = syscalls::allow(DRIVER_NUMBER, allow_nr::SHARE_BUFFER, buf)?;
29 let is_filled = Cell::new(false);
Woyten8c243cd2019-12-01 15:06:20 +010030 let mut is_filled_alarm = || is_filled.set(true);
31 let subscription = syscalls::subscribe::<Identity0Consumer, _>(
torfmaster0c1aead2019-12-27 18:03:10 +010032 DRIVER_NUMBER,
33 subscribe_nr::BUFFER_FILLED,
34 &mut is_filled_alarm,
35 )?;
36 syscalls::command(DRIVER_NUMBER, command_nr::REQUEST_RNG, buf_len, 0)?;
37 futures::wait_until(|| is_filled.get()).await;
38 mem::drop(subscription);
39 mem::drop(shared_memory);
40 Ok(())
41 }
Guillaume Endignouxb0914422019-10-04 13:37:26 +020042}