nrf52840dk_root_of_trust_tutorial/
main.rs
1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use kernel::component::Component;
12use kernel::debug;
13use kernel::platform::{KernelResources, SyscallDriverLookup};
14use kernel::static_init;
15use kernel::{capabilities, create_capability};
16use nrf52840::gpio::Pin;
17
18const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
21 capsules_system::process_policies::PanicFaultPolicy {};
22
23const CRYPT_SIZE: usize = 7 * kernel::hil::symmetric_encryption::AES128_BLOCK_SIZE;
24
25type ScreenDriver = components::screen::ScreenComponentType;
27
28struct Platform {
29 base: nrf52840dk_lib::Platform,
30 screen: &'static ScreenDriver,
31 oracle: &'static capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver<
32 'static,
33 nrf52840::aes::AesECB<'static>,
34 >,
35}
36
37impl SyscallDriverLookup for Platform {
38 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
39 where
40 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
41 {
42 match driver_num {
43 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
44 capsules_extra::tutorials::encryption_oracle_chkpt5::DRIVER_NUM => f(Some(self.oracle)),
45 _ => self.base.with_driver(driver_num, f),
46 }
47 }
48}
49
50type Chip = nrf52840dk_lib::Chip;
51
52impl KernelResources<Chip> for Platform {
53 type SyscallDriverLookup = Self;
54 type SyscallFilter = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SyscallFilter;
55 type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
56 type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
57 type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
58 type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
59 type ContextSwitchCallback =
60 <nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;
61
62 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
63 self
64 }
65 fn syscall_filter(&self) -> &Self::SyscallFilter {
66 self.base.syscall_filter()
67 }
68 fn process_fault(&self) -> &Self::ProcessFault {
69 self.base.process_fault()
70 }
71 fn scheduler(&self) -> &Self::Scheduler {
72 self.base.scheduler()
73 }
74 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
75 self.base.scheduler_timer()
76 }
77 fn watchdog(&self) -> &Self::WatchDog {
78 self.base.watchdog()
79 }
80 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
81 self.base.context_switch_callback()
82 }
83}
84
85#[no_mangle]
87pub unsafe fn main() {
88 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
89
90 let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
92 nrf52840dk_lib::start_no_pconsole();
93
94 const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
99 const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
100
101 let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
102 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
103 nrf52840_peripherals.nrf52.twi1.configure(
104 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
105 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
106 );
107 nrf52840_peripherals
108 .nrf52
109 .twi1
110 .set_speed(nrf52840::i2c::Speed::K400);
111
112 let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
114 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
115
116 #[cfg(feature = "screen_ssd1306")]
118 let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
119 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
120
121 #[cfg(feature = "screen_sh1106")]
122 let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
123 .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
124
125 let screen = components::screen::ScreenComponent::new(
126 board_kernel,
127 capsules_extra::screen::DRIVER_NUM,
128 ssd1306_sh1106,
129 None,
130 )
131 .finalize(components::screen_component_static!(1032));
132
133 ssd1306_sh1106.init_screen();
134
135 let aes_src_buffer = kernel::static_init!([u8; 16], [0; 16]);
140 let aes_dst_buffer = kernel::static_init!([u8; CRYPT_SIZE], [0; CRYPT_SIZE]);
141
142 let oracle = static_init!(
143 capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver<
144 'static,
145 nrf52840::aes::AesECB<'static>,
146 >,
147 capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver::new(
148 &nrf52840_peripherals.nrf52.ecb,
149 aes_src_buffer,
150 aes_dst_buffer,
151 board_kernel.create_grant(
152 capsules_extra::tutorials::encryption_oracle_chkpt5::DRIVER_NUM, &create_capability!(capabilities::MemoryAllocationCapability)
154 ),
155 ),
156 );
157
158 kernel::hil::symmetric_encryption::AES128::set_client(&nrf52840_peripherals.nrf52.ecb, oracle);
159
160 let platform = Platform {
165 base: base_platform,
166 screen,
167 oracle,
168 };
169
170 extern "C" {
172 static _sapps: u8;
174 static _eapps: u8;
176 static mut _sappmem: u8;
178 static _eappmem: u8;
180 }
181
182 let process_management_capability =
183 create_capability!(capabilities::ProcessManagementCapability);
184
185 kernel::process::load_processes(
186 board_kernel,
187 chip,
188 core::slice::from_raw_parts(
189 core::ptr::addr_of!(_sapps),
190 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
191 ),
192 core::slice::from_raw_parts_mut(
193 core::ptr::addr_of_mut!(_sappmem),
194 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
195 ),
196 &FAULT_RESPONSE,
197 &process_management_capability,
198 )
199 .unwrap_or_else(|err| {
200 debug!("Error loading processes!");
201 debug!("{:?}", err);
202 });
203
204 board_kernel.kernel_loop(
205 &platform,
206 chip,
207 Some(&platform.base.ipc),
208 &main_loop_capability,
209 );
210}