1use capsules_core::rng;
34use core::mem::MaybeUninit;
35use kernel::capabilities;
36use kernel::component::Component;
37use kernel::create_capability;
38use kernel::hil::entropy::Entropy32;
39use kernel::hil::rng::Rng;
40
41#[macro_export]
42macro_rules! rng_component_static {
43 ($E: ty $(,)?) => {{
44 let etr = kernel::static_buf!(capsules_core::rng::Entropy32ToRandom<'static, $E>);
45 let rng = kernel::static_buf!(
46 capsules_core::rng::RngDriver<
47 'static,
48 capsules_core::rng::Entropy32ToRandom<'static, $E>,
49 >
50 );
51
52 (etr, rng)
53 };};
54}
55
56pub type RngComponentType<E> =
57 rng::RngDriver<'static, capsules_core::rng::Entropy32ToRandom<'static, E>>;
58
59pub struct RngComponent<E: Entropy32<'static> + 'static> {
60 board_kernel: &'static kernel::Kernel,
61 driver_num: usize,
62 trng: &'static E,
63}
64
65impl<E: Entropy32<'static>> RngComponent<E> {
66 pub fn new(board_kernel: &'static kernel::Kernel, driver_num: usize, trng: &'static E) -> Self {
67 Self {
68 board_kernel,
69 driver_num,
70 trng,
71 }
72 }
73}
74
75impl<E: Entropy32<'static>> Component for RngComponent<E> {
76 type StaticInput = (
77 &'static mut MaybeUninit<capsules_core::rng::Entropy32ToRandom<'static, E>>,
78 &'static mut MaybeUninit<
79 capsules_core::rng::RngDriver<
80 'static,
81 capsules_core::rng::Entropy32ToRandom<'static, E>,
82 >,
83 >,
84 );
85 type Output =
86 &'static rng::RngDriver<'static, capsules_core::rng::Entropy32ToRandom<'static, E>>;
87
88 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
89 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
90
91 let entropy_to_random = static_buffer
92 .0
93 .write(rng::Entropy32ToRandom::new(self.trng));
94 let rng = static_buffer.1.write(rng::RngDriver::new(
95 entropy_to_random,
96 self.board_kernel.create_grant(self.driver_num, &grant_cap),
97 ));
98 self.trng.set_client(entropy_to_random);
99 entropy_to_random.set_client(rng);
100
101 rng
102 }
103}
104
105#[macro_export]
106macro_rules! rng_random_component_static {
107 ($R: ty $(,)?) => {{
108 let rng = kernel::static_buf!(capsules_core::rng::RngDriver<'static, $R>);
109
110 rng
111 };};
112}
113
114pub type RngRandomComponentType<R> = rng::RngDriver<'static, R>;
115
116pub struct RngRandomComponent<R: Rng<'static> + 'static> {
117 board_kernel: &'static kernel::Kernel,
118 driver_num: usize,
119 rng: &'static R,
120}
121
122impl<R: Rng<'static>> RngRandomComponent<R> {
123 pub fn new(board_kernel: &'static kernel::Kernel, driver_num: usize, rng: &'static R) -> Self {
124 Self {
125 board_kernel,
126 driver_num,
127 rng,
128 }
129 }
130}
131
132impl<R: Rng<'static>> Component for RngRandomComponent<R> {
133 type StaticInput = &'static mut MaybeUninit<capsules_core::rng::RngDriver<'static, R>>;
134 type Output = &'static rng::RngDriver<'static, R>;
135
136 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
137 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
138
139 let rng_driver = static_buffer.write(rng::RngDriver::new(
140 self.rng,
141 self.board_kernel.create_grant(self.driver_num, &grant_cap),
142 ));
143 self.rng.set_client(rng_driver);
144
145 rng_driver
146 }
147}