1use kernel::deferred_call::{DeferredCall, DeferredCallClient};
6use kernel::hil::entropy::{self, Client32, Continue, Entropy32};
7use kernel::utilities::cells::OptionalCell;
8use kernel::utilities::registers::interfaces::Readable;
9use kernel::utilities::registers::{register_structs, ReadOnly};
10use kernel::utilities::StaticRef;
11use kernel::ErrorCode;
12
13const RNG_DATA_REG: StaticRef<RngRegister> =
14 unsafe { StaticRef::new(0x6002_60B0 as *const RngRegister) };
15
16register_structs! {
17 pub RngRegister {
18 (0x0 => data: ReadOnly<u32>),
19 (0x4 => @END),
20 }
21}
22
23pub struct Rng<'a> {
24 register: StaticRef<RngRegister>,
25 client: OptionalCell<&'a dyn entropy::Client32>,
26 value: OptionalCell<u32>,
27 deferred_call: DeferredCall,
28}
29
30impl<'a> Rng<'a> {
31 pub fn new() -> Rng<'a> {
32 Rng {
33 register: RNG_DATA_REG,
34 client: OptionalCell::empty(),
35 value: OptionalCell::empty(),
36 deferred_call: DeferredCall::new(),
37 }
38 }
39}
40
41impl DeferredCallClient for Rng<'_> {
42 fn register(&'static self) {
43 self.deferred_call.register(self);
44 }
45
46 fn handle_deferred_call(&self) {
47 self.value.set(self.register.data.get());
48 self.client.map(|client| {
49 if let Continue::More = client.entropy_available(&mut RngIter(self), Ok(())) {
50 self.deferred_call.set();
51 }
52 });
53 }
54}
55
56impl<'a> Entropy32<'a> for Rng<'a> {
57 fn get(&self) -> Result<(), ErrorCode> {
58 self.deferred_call.set();
59 Ok(())
60 }
61
62 fn cancel(&self) -> Result<(), ErrorCode> {
63 Err(ErrorCode::NOSUPPORT)
64 }
65
66 fn set_client(&self, client: &'a dyn Client32) {
67 self.client.set(client);
68 }
69}
70
71struct RngIter<'a, 'b: 'a>(&'a Rng<'b>);
72
73impl Iterator for RngIter<'_, '_> {
74 type Item = u32;
75
76 fn next(&mut self) -> Option<u32> {
77 self.0.value.take()
78 }
79}