1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use kernel::component::Component;
12use kernel::deferred_call::DeferredCallClient;
13use kernel::platform::{KernelResources, SyscallDriverLookup};
14use kernel::process::ProcessLoadingAsync;
15use kernel::process::ShortId;
16use kernel::{capabilities, create_capability, static_init};
17use nrf52840::gpio::Pin;
18use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
19
20mod app_id_assigner_name_metadata;
21mod checker_credentials_not_required;
22mod system_call_filter;
23
24const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
26const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
27
28const NUM_PROCS: usize = 8;
30
31type ChipHw = nrf52840dk_lib::ChipHw;
32static mut CHIP: Option<&'static ChipHw> = None;
33
34const FAULT_RESPONSE: capsules_system::process_policies::StopWithDebugFaultPolicy =
36    capsules_system::process_policies::StopWithDebugFaultPolicy {};
37
38const NUM_CREDENTIAL_KEYS: usize = 1;
40const SIGNATURE_KEY_LEN: usize = 64;
42const SIGNATURE_HASH_LEN: usize = 32;
44const SIGNATURE_SIG_LEN: usize = 64;
46
47pub struct PMCapability;
53unsafe impl capabilities::ProcessManagementCapability for PMCapability {}
54unsafe impl capabilities::ProcessStartCapability for PMCapability {}
55
56#[cfg(feature = "screen_ssd1306")]
57type Screen = components::ssd1306::Ssd1306ComponentType<nrf52840::i2c::TWI<'static>>;
58#[cfg(feature = "screen_sh1106")]
59type Screen = components::sh1106::Sh1106ComponentType<nrf52840::i2c::TWI<'static>>;
60type ScreenDriver = components::screen::ScreenSharedComponentType<Screen>;
61
62type ProcessInfoDriver = capsules_extra::process_info_driver::ProcessInfo<PMCapability>;
63
64type IsolatedNonvolatileStorageDriver =
65    capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage<
66        'static,
67        {
68            components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT
69        },
70    >;
71
72type FlashUser =
73    capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>;
74type NonVolatilePages = components::dynamic_binary_storage::NVPages<FlashUser>;
75
76type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
77    'static,
78    'static,
79    nrf52840::chip::NRF52<'a, Nrf52840DefaultPeripherals<'a>>,
80    kernel::process::ProcessStandardDebugFull,
81    NonVolatilePages,
82>;
83type AppLoaderDriver = capsules_extra::app_loader::AppLoader<
84    DynamicBinaryStorage<'static>,
85    DynamicBinaryStorage<'static>,
86>;
87
88type Verifier = ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>;
89type SignatureVerifyInMemoryKeys =
90    components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponentType<
91        Verifier,
92        NUM_CREDENTIAL_KEYS,
93        SIGNATURE_KEY_LEN,
94        SIGNATURE_HASH_LEN,
95        SIGNATURE_SIG_LEN,
96    >;
97type SignatureChecker = components::appid::checker_signature::AppCheckerSignatureComponentType<
98    SignatureVerifyInMemoryKeys,
99    capsules_extra::sha256::Sha256Software<'static>,
100    SIGNATURE_HASH_LEN,
101    SIGNATURE_SIG_LEN,
102>;
103
104fn create_short_id_from_name(name: &str, metadata: u8) -> ShortId {
109    let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes());
110
111    let sid = ((metadata as u32) << 28) | (sum & 0xFFFFFFF);
113
114    core::num::NonZeroU32::new(sid).into()
115}
116
117struct Platform {
122    board_kernel: &'static kernel::Kernel,
123    syscall_filter: &'static system_call_filter::DynamicPoliciesCustomFilter,
124    base: nrf52840dk_lib::Platform,
125    screen: &'static ScreenDriver,
126    process_info: &'static ProcessInfoDriver,
127    nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver,
128    dynamic_app_loader: &'static AppLoaderDriver,
129}
130
131impl SyscallDriverLookup for Platform {
133    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
134    where
135        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
136    {
137        match driver_num {
138            capsules_extra::screen::screen::DRIVER_NUM => f(Some(self.screen)),
139            capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)),
140            capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => {
141                f(Some(self.nonvolatile_storage))
142            }
143            capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
144            _ => self.base.with_driver(driver_num, f),
145        }
146    }
147}
148
149impl KernelResources<ChipHw> for Platform {
151    type SyscallDriverLookup = Self;
152    type SyscallFilter = system_call_filter::DynamicPoliciesCustomFilter;
153    type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::ProcessFault;
154    type Scheduler = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::Scheduler;
155    type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::SchedulerTimer;
156    type WatchDog = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::WatchDog;
157    type ContextSwitchCallback =
158        <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::ContextSwitchCallback;
159
160    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
161        self
162    }
163    fn syscall_filter(&self) -> &Self::SyscallFilter {
164        self.syscall_filter
165    }
166    fn process_fault(&self) -> &Self::ProcessFault {
167        self.base.process_fault()
168    }
169    fn scheduler(&self) -> &Self::Scheduler {
170        self.base.scheduler()
171    }
172    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
173        self.base.scheduler_timer()
174    }
175    fn watchdog(&self) -> &Self::WatchDog {
176        self.base.watchdog()
177    }
178    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
179        self.base.context_switch_callback()
180    }
181}
182
183impl kernel::process::ProcessLoadingAsyncClient for Platform {
185    fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {}
186
187    fn process_loading_finished(&self) {
188        kernel::debug!("Processes Loaded at Main:");
189
190        for (i, p) in self
191            .board_kernel
192            .process_iter_capability(&create_capability!(
193                capabilities::ProcessManagementCapability
194            ))
195            .enumerate()
196        {
197            kernel::debug!("[{}] {}", i, p.get_process_name());
198            kernel::debug!("    ShortId: {}", p.short_app_id());
199        }
200    }
201}
202
203#[no_mangle]
209pub unsafe fn main() {
210    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
211
212    let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
214        nrf52840dk_lib::start();
215
216    CHIP = Some(chip);
217
218    let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
223        .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
224    nrf52840_peripherals.nrf52.twi1.configure(
225        nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
226        nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
227    );
228    nrf52840_peripherals
229        .nrf52
230        .twi1
231        .set_speed(nrf52840::i2c::Speed::K400);
232
233    let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
235        .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
236
237    #[cfg(feature = "screen_ssd1306")]
239    let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
240        .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
241
242    #[cfg(feature = "screen_sh1106")]
243    let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
244        .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
245
246    let apps_regions = kernel::static_init!(
247        [capsules_extra::screen::screen_shared::AppScreenRegion; 3],
248        [
249            capsules_extra::screen::screen_shared::AppScreenRegion::new(
250                create_short_id_from_name("process_manager", 0x0),
251                0,      0,      16 * 8, 7 * 8   ),
256            capsules_extra::screen::screen_shared::AppScreenRegion::new(
257                create_short_id_from_name("counter", 0x0),
258                0,     7 * 8, 8 * 8, 1 * 8  ),
263            capsules_extra::screen::screen_shared::AppScreenRegion::new(
264                create_short_id_from_name("temperature", 0x0),
265                8 * 8, 7 * 8, 8 * 8, 1 * 8  )
270        ]
271    );
272
273    let screen = components::screen::ScreenSharedComponent::new(
274        board_kernel,
275        capsules_extra::screen::screen::DRIVER_NUM,
276        ssd1306_sh1106,
277        apps_regions,
278    )
279    .finalize(components::screen_shared_component_static!(1032, Screen));
280
281    ssd1306_sh1106.init_screen();
282
283    let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc)
288        .finalize(components::flash_mux_component_static!(
289            nrf52840::nvmc::Nvmc
290        ));
291
292    let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize(
294        components::flash_user_component_static!(nrf52840::nvmc::Nvmc),
295    );
296
297    let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize(
299        components::flash_user_component_static!(nrf52840::nvmc::Nvmc),
300    );
301
302    kernel::storage_volume!(APP_STORAGE, 32);
308
309    let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new(
310        board_kernel,
311        capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM,
312        virtual_flash_nvm,
313        core::ptr::addr_of!(APP_STORAGE) as usize,
314        APP_STORAGE.len()
315    )
316    .finalize(components::isolated_nonvolatile_storage_component_static!(
317        capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>,
318        { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT }
319    ));
320
321    let process_info = components::process_info_driver::ProcessInfoComponent::new(
326        board_kernel,
327        capsules_extra::process_info_driver::DRIVER_NUM,
328        PMCapability,
329    )
330    .finalize(components::process_info_component_static!(PMCapability));
331
332    let syscall_filter = static_init!(
337        system_call_filter::DynamicPoliciesCustomFilter,
338        system_call_filter::DynamicPoliciesCustomFilter {}
339    );
340
341    let sha = components::sha::ShaSoftware256Component::new()
347        .finalize(components::sha_software_256_component_static!());
348
349    let verifying_key0 = kernel::static_init!(
376        [u8; SIGNATURE_KEY_LEN],
377        [
378            0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
379            0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
380            0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
381            0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
382            0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
383        ]
384    );
385    let verifying_keys = kernel::static_init!(
386        [&'static mut [u8; SIGNATURE_KEY_LEN]; NUM_CREDENTIAL_KEYS],
387        [verifying_key0]
388    );
389    let ecdsa_p256_verifying_key =
391        kernel::static_init!([u8; SIGNATURE_KEY_LEN], [0; SIGNATURE_KEY_LEN]);
392    let ecdsa_p256_verifier = kernel::static_init!(
393        ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
394        ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(ecdsa_p256_verifying_key)
395    );
396    ecdsa_p256_verifier.register();
397
398    let verifier_multiple_keys =
400        components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponent::new(
401            ecdsa_p256_verifier,
402            verifying_keys,
403        )
404        .finalize(
405            components::signature_verify_in_memory_keys_component_static!(
406                Verifier,
407                NUM_CREDENTIAL_KEYS,
408                SIGNATURE_KEY_LEN,
409                SIGNATURE_HASH_LEN,
410                SIGNATURE_SIG_LEN,
411            ),
412        );
413
414    let checking_policy_signature =
416        components::appid::checker_signature::AppCheckerSignatureComponent::new(
417            sha,
418            verifier_multiple_keys,
419            tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
420        )
421        .finalize(components::app_checker_signature_component_static!(
422            SignatureVerifyInMemoryKeys,
423            capsules_extra::sha256::Sha256Software<'static>,
424            SIGNATURE_HASH_LEN,
425            SIGNATURE_SIG_LEN,
426        ));
427
428    let checking_policy = static_init!(
433        checker_credentials_not_required::AppCheckerCredentialsNotRequired<
434            SignatureChecker,
435        >,
436        checker_credentials_not_required::AppCheckerCredentialsNotRequired::new(
437            checking_policy_signature
438        ),
439    );
440
441    let assigner = static_init!(
443        app_id_assigner_name_metadata::AppIdAssignerNameMetadata,
444        app_id_assigner_name_metadata::AppIdAssignerNameMetadata::new()
445    );
446
447    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
449        .finalize(components::process_checker_machine_component_static!());
450
451    let storage_permissions_policy =
456        components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
457            components::storage_permissions_null_component_static!(
458                nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
459                kernel::process::ProcessStandardDebugFull,
460            ),
461        );
462
463    extern "C" {
469        static _sapps: u8;
471        static _eapps: u8;
473        static mut _sappmem: u8;
475        static _eappmem: u8;
477    }
478
479    let app_flash = core::slice::from_raw_parts(
480        core::ptr::addr_of!(_sapps),
481        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
482    );
483    let app_memory = core::slice::from_raw_parts_mut(
484        core::ptr::addr_of_mut!(_sappmem),
485        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
486    );
487
488    let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
490        checker,
491        board_kernel,
492        chip,
493        &FAULT_RESPONSE,
494        assigner,
495        storage_permissions_policy,
496        app_flash,
497        app_memory,
498    )
499    .finalize(components::process_loader_sequential_component_static!(
500        nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
501        kernel::process::ProcessStandardDebugFull,
502        NUM_PROCS
503    ));
504
505    let dynamic_binary_storage =
511        components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
512            virtual_flash_dbs,
513            loader,
514        )
515        .finalize(components::sequential_binary_storage_component_static!(
516            FlashUser,
517            nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
518            kernel::process::ProcessStandardDebugFull,
519        ));
520
521    let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
523        board_kernel,
524        capsules_extra::app_loader::DRIVER_NUM,
525        dynamic_binary_storage,
526        dynamic_binary_storage,
527    )
528    .finalize(components::app_loader_component_static!(
529        DynamicBinaryStorage<'static>,
530        DynamicBinaryStorage<'static>,
531    ));
532
533    let platform = static_init!(
538        Platform,
539        Platform {
540            board_kernel,
541            syscall_filter,
542            base: base_platform,
543            screen,
544            process_info,
545            nonvolatile_storage,
546            dynamic_app_loader,
547        }
548    );
549    loader.set_client(platform);
550
551    board_kernel.kernel_loop(
552        platform,
553        chip,
554        Some(&platform.base.ipc),
555        &main_loop_capability,
556    );
557}