1use capsules_core::rng;
21use core::mem::MaybeUninit;
22use kernel::capabilities;
23use kernel::component::Component;
24use kernel::create_capability;
25use kernel::hil::entropy::Entropy32;
26use kernel::hil::rng::Rng;
27
28#[macro_export]
29macro_rules! rng_component_static {
30 ($E: ty $(,)?) => {{
31 let etr = kernel::static_buf!(capsules_core::rng::Entropy32ToRandom<'static, $E>);
32 let rng = kernel::static_buf!(
33 capsules_core::rng::RngDriver<
34 'static,
35 capsules_core::rng::Entropy32ToRandom<'static, $E>,
36 >
37 );
38
39 (etr, rng)
40 };};
41}
42
43pub type RngComponentType<E> =
44 rng::RngDriver<'static, capsules_core::rng::Entropy32ToRandom<'static, E>>;
45
46pub struct RngComponent<E: Entropy32<'static> + 'static> {
47 board_kernel: &'static kernel::Kernel,
48 driver_num: usize,
49 trng: &'static E,
50}
51
52impl<E: Entropy32<'static>> RngComponent<E> {
53 pub fn new(board_kernel: &'static kernel::Kernel, driver_num: usize, trng: &'static E) -> Self {
54 Self {
55 board_kernel,
56 driver_num,
57 trng,
58 }
59 }
60}
61
62impl<E: Entropy32<'static>> Component for RngComponent<E> {
63 type StaticInput = (
64 &'static mut MaybeUninit<capsules_core::rng::Entropy32ToRandom<'static, E>>,
65 &'static mut MaybeUninit<
66 capsules_core::rng::RngDriver<
67 'static,
68 capsules_core::rng::Entropy32ToRandom<'static, E>,
69 >,
70 >,
71 );
72 type Output =
73 &'static rng::RngDriver<'static, capsules_core::rng::Entropy32ToRandom<'static, E>>;
74
75 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
76 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
77
78 let entropy_to_random = static_buffer
79 .0
80 .write(rng::Entropy32ToRandom::new(self.trng));
81 let rng = static_buffer.1.write(rng::RngDriver::new(
82 entropy_to_random,
83 self.board_kernel.create_grant(self.driver_num, &grant_cap),
84 ));
85 self.trng.set_client(entropy_to_random);
86 entropy_to_random.set_client(rng);
87
88 rng
89 }
90}