1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use kernel::component::Component;
12use kernel::deferred_call::DeferredCallClient;
13use kernel::hil::led::LedLow;
14use kernel::hil::time::Counter;
15use kernel::platform::{KernelResources, SyscallDriverLookup};
16use kernel::process::ProcessArray;
17use kernel::scheduler::round_robin::RoundRobinSched;
18use kernel::{capabilities, create_capability, static_init};
19use nrf52840::gpio::Pin;
20use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
21use nrf52_components::{UartChannel, UartPins};
22
23const LED1_PIN: Pin = Pin::P0_13;
25const LED2_PIN: Pin = Pin::P0_14;
26const LED3_PIN: Pin = Pin::P0_15;
27const LED4_PIN: Pin = Pin::P0_16;
28
29const BUTTON_RST_PIN: Pin = Pin::P0_18;
30
31const UART_RTS: Option<Pin> = Some(Pin::P0_05);
32const UART_TXD: Pin = Pin::P0_06;
33const UART_CTS: Option<Pin> = Some(Pin::P0_07);
34const UART_RXD: Pin = Pin::P0_08;
35
36pub mod io;
38
39const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
42    capsules_system::process_policies::PanicFaultPolicy {};
43
44const NUM_PROCS: usize = 8;
46
47static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
49static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
50
51kernel::stack_size! {0x2000}
52
53type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
58
59type Verifier = ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>;
60type SignatureVerifyInMemoryKeys =
61    components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponentType<
62        Verifier,
63        2,
64        64,
65        32,
66        64,
67    >;
68
69pub struct Platform {
71    console: &'static capsules_core::console::Console<'static>,
72    led: &'static capsules_core::led::LedDriver<
73        'static,
74        kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
75        4,
76    >,
77    alarm: &'static AlarmDriver,
78    scheduler: &'static RoundRobinSched<'static>,
79    systick: cortexm4::systick::SysTick,
80}
81
82impl SyscallDriverLookup for Platform {
83    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
84    where
85        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
86    {
87        match driver_num {
88            capsules_core::console::DRIVER_NUM => f(Some(self.console)),
89            capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
90            capsules_core::led::DRIVER_NUM => f(Some(self.led)),
91            _ => f(None),
92        }
93    }
94}
95
96#[inline(never)]
100unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
101    let ieee802154_ack_buf = static_init!(
102        [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
103        [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
104    );
105    let nrf52840_peripherals = static_init!(
107        Nrf52840DefaultPeripherals,
108        Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
109    );
110
111    nrf52840_peripherals
112}
113
114impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
115    for Platform
116{
117    type SyscallDriverLookup = Self;
118    type SyscallFilter = ();
119    type ProcessFault = ();
120    type Scheduler = RoundRobinSched<'static>;
121    type SchedulerTimer = cortexm4::systick::SysTick;
122    type WatchDog = ();
123    type ContextSwitchCallback = ();
124
125    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
126        self
127    }
128    fn syscall_filter(&self) -> &Self::SyscallFilter {
129        &()
130    }
131    fn process_fault(&self) -> &Self::ProcessFault {
132        &()
133    }
134    fn scheduler(&self) -> &Self::Scheduler {
135        self.scheduler
136    }
137    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
138        &self.systick
139    }
140    fn watchdog(&self) -> &Self::WatchDog {
141        &()
142    }
143    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
144        &()
145    }
146}
147
148#[no_mangle]
150pub unsafe fn main() {
151    nrf52840::init();
157
158    let nrf52840_peripherals = create_peripherals();
161
162    nrf52840_peripherals.init();
164    let base_peripherals = &nrf52840_peripherals.nrf52;
165
166    let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
170
171    let processes = components::process_array::ProcessArrayComponent::new()
173        .finalize(components::process_array_component_static!(NUM_PROCS));
174    PROCESSES = Some(processes);
175
176    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
178
179    let chip = static_init!(
182        nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
183        nrf52840::chip::NRF52::new(nrf52840_peripherals)
184    );
185    CHIP = Some(chip);
186
187    nrf52_components::startup::NrfStartupComponent::new(
190        false,
191        BUTTON_RST_PIN,
192        nrf52840::uicr::Regulator0Output::DEFAULT,
193        &base_peripherals.nvmc,
194    )
195    .finalize(());
196
197    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
204
205    let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
210        LedLow<'static, nrf52840::gpio::GPIOPin>,
211        LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
212        LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
213        LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
214        LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
215    ));
216
217    let rtc = &base_peripherals.rtc;
222    let _ = rtc.start();
223    let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
224        .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc));
225    let alarm = components::alarm::AlarmDriverComponent::new(
226        board_kernel,
227        capsules_core::alarm::DRIVER_NUM,
228        mux_alarm,
229    )
230    .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc));
231
232    let uart_channel = nrf52_components::UartChannelComponent::new(
237        uart_channel,
238        mux_alarm,
239        &base_peripherals.uarte0,
240    )
241    .finalize(nrf52_components::uart_channel_component_static!(
242        nrf52840::rtc::Rtc
243    ));
244
245    let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200)
247        .finalize(components::uart_mux_component_static!());
248
249    let console = components::console::ConsoleComponent::new(
251        board_kernel,
252        capsules_core::console::DRIVER_NUM,
253        uart_mux,
254    )
255    .finalize(components::console_component_static!());
256
257    nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
262
263    let sha = components::sha::ShaSoftware256Component::new()
269        .finalize(components::sha_software_256_component_static!());
270
271    let verifying_key0 = kernel::static_init!(
298        [u8; 64],
299        [
300            0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
301            0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
302            0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
303            0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
304            0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
305        ]
306    );
307    let verifying_key1 = kernel::static_init!(
324        [u8; 64],
325        [
326            0xc9, 0x3d, 0x38, 0x79, 0xc0, 0x0b, 0x4a, 0x2f, 0x5c, 0xbf, 0xca, 0xfc, 0x03, 0x24,
327            0x14, 0x7b, 0xef, 0xa8, 0x9f, 0xe5, 0xf5, 0x2b, 0x77, 0x9c, 0xd9, 0xf3, 0x51, 0xfd,
328            0xbc, 0x37, 0xe7, 0x0c, 0x29, 0xe6, 0xee, 0xc3, 0xc4, 0xed, 0x57, 0x6d, 0x95, 0x8d,
329            0xc3, 0xc0, 0x73, 0x87, 0x4d, 0xf5, 0x8d, 0xa6, 0x3e, 0x8d, 0xef, 0xf8, 0xd3, 0xf0,
330            0xa7, 0x08, 0x22, 0xad, 0xf7, 0xf7, 0xa3, 0xaa,
331        ]
332    );
333    let verifying_keys =
334        kernel::static_init!([&'static mut [u8; 64]; 2], [verifying_key0, verifying_key1]);
335    let ecdsa_p256_verifying_key = kernel::static_init!([u8; 64], [0; 64]);
338    let ecdsa_p256_verifier = kernel::static_init!(
339        ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
340        ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(ecdsa_p256_verifying_key)
341    );
342    ecdsa_p256_verifier.register();
343
344    let verifier_multiple_keys =
346        components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponent::new(
347            ecdsa_p256_verifier,
348            verifying_keys,
349        )
350        .finalize(
351            components::signature_verify_in_memory_keys_component_static!(Verifier, 2, 64, 32, 64,),
352        );
353
354    let checking_policy = components::appid::checker_signature::AppCheckerSignatureComponent::new(
356        sha,
357        verifier_multiple_keys,
358        tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
359    )
360    .finalize(components::app_checker_signature_component_static!(
361        SignatureVerifyInMemoryKeys,
362        capsules_extra::sha256::Sha256Software<'static>,
363        32,
364        64,
365    ));
366
367    let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
369        .finalize(components::appid_assigner_names_component_static!());
370
371    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
373        .finalize(components::process_checker_machine_component_static!());
374
375    let storage_permissions_policy =
380        components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
381            components::storage_permissions_null_component_static!(
382                nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
383                kernel::process::ProcessStandardDebugFull,
384            ),
385        );
386
387    extern "C" {
393        static _sapps: u8;
395        static _eapps: u8;
397        static mut _sappmem: u8;
399        static _eappmem: u8;
401    }
402
403    let app_flash = core::slice::from_raw_parts(
404        core::ptr::addr_of!(_sapps),
405        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
406    );
407    let app_memory = core::slice::from_raw_parts_mut(
408        core::ptr::addr_of_mut!(_sappmem),
409        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
410    );
411
412    let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
414        checker,
415        board_kernel,
416        chip,
417        &FAULT_RESPONSE,
418        assigner,
419        storage_permissions_policy,
420        app_flash,
421        app_memory,
422    )
423    .finalize(components::process_loader_sequential_component_static!(
424        nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
425        kernel::process::ProcessStandardDebugFull,
426        NUM_PROCS
427    ));
428
429    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
434        .finalize(components::round_robin_component_static!(NUM_PROCS));
435
436    let platform = Platform {
437        console,
438        led,
439        alarm,
440        scheduler,
441        systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
442    };
443
444    board_kernel.kernel_loop(
445        &platform,
446        chip,
447        None::<&kernel::ipc::IPC<0>>,
448        &main_loop_capability,
449    );
450}