components/loader/
sequential.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2024.
4
5//! Component for creating a sequential process loader.
6//!
7//! `ProcessLoaderSequentialComponent` uses the standard Tock assumptions about
8//! where processes are stored in flash and what RAM is allocated for process
9//! use.
10
11use core::mem::MaybeUninit;
12use kernel::component::Component;
13use kernel::deferred_call::DeferredCallClient;
14use kernel::platform::chip::Chip;
15use kernel::process::ProcessLoadingAsync;
16use kernel::process::ProcessStandardDebug;
17
18#[macro_export]
19macro_rules! process_loader_sequential_component_static {
20    ($C:ty, $D:ty, $NUMPROCS:expr $(,)?) => {{
21        let loader = kernel::static_buf!(kernel::process::SequentialProcessLoaderMachine<
22            $C, $D
23        >);
24        let process_binary_array = kernel::static_buf!(
25            [Option<kernel::process::ProcessBinary>; $NUMPROCS]
26        );
27
28       (loader, process_binary_array)
29    };};
30}
31
32pub type ProcessLoaderSequentialComponentType<C, D> =
33    kernel::process::SequentialProcessLoaderMachine<'static, C, D>;
34
35pub struct ProcessLoaderSequentialComponent<
36    C: Chip + 'static,
37    D: ProcessStandardDebug + 'static,
38    const NUM_PROCS: usize,
39> {
40    checker: &'static kernel::process::ProcessCheckerMachine,
41    processes: &'static mut [Option<&'static dyn kernel::process::Process>],
42    kernel: &'static kernel::Kernel,
43    chip: &'static C,
44    fault_policy: &'static dyn kernel::process::ProcessFaultPolicy,
45    appid_policy: &'static dyn kernel::process_checker::AppIdPolicy,
46    storage_policy: &'static dyn kernel::process::ProcessStandardStoragePermissionsPolicy<C, D>,
47}
48
49impl<C: Chip, D: ProcessStandardDebug, const NUM_PROCS: usize>
50    ProcessLoaderSequentialComponent<C, D, NUM_PROCS>
51{
52    pub fn new(
53        checker: &'static kernel::process::ProcessCheckerMachine,
54        processes: &'static mut [Option<&'static dyn kernel::process::Process>],
55        kernel: &'static kernel::Kernel,
56        chip: &'static C,
57        fault_policy: &'static dyn kernel::process::ProcessFaultPolicy,
58        appid_policy: &'static dyn kernel::process_checker::AppIdPolicy,
59        storage_policy: &'static dyn kernel::process::ProcessStandardStoragePermissionsPolicy<C, D>,
60    ) -> Self {
61        Self {
62            checker,
63            processes,
64            kernel,
65            chip,
66            fault_policy,
67            appid_policy,
68            storage_policy,
69        }
70    }
71}
72
73impl<C: Chip, D: ProcessStandardDebug, const NUM_PROCS: usize> Component
74    for ProcessLoaderSequentialComponent<C, D, NUM_PROCS>
75{
76    type StaticInput = (
77        &'static mut MaybeUninit<kernel::process::SequentialProcessLoaderMachine<'static, C, D>>,
78        &'static mut MaybeUninit<[Option<kernel::process::ProcessBinary>; NUM_PROCS]>,
79    );
80
81    type Output = &'static kernel::process::SequentialProcessLoaderMachine<'static, C, D>;
82
83    fn finalize(mut self, s: Self::StaticInput) -> Self::Output {
84        let proc_manage_cap =
85            kernel::create_capability!(kernel::capabilities::ProcessManagementCapability);
86
87        const ARRAY_REPEAT_VALUE: Option<kernel::process::ProcessBinary> = None;
88        let process_binary_array = s.1.write([ARRAY_REPEAT_VALUE; NUM_PROCS]);
89
90        // These symbols are defined in the standard Tock linker script.
91        extern "C" {
92            /// Beginning of the ROM region containing app images.
93            static _sapps: u8;
94            /// End of the ROM region containing app images.
95            static _eapps: u8;
96            /// Beginning of the RAM region for app memory.
97            static mut _sappmem: u8;
98            /// End of the RAM region for app memory.
99            static _eappmem: u8;
100        }
101
102        let loader = unsafe {
103            s.0.write(kernel::process::SequentialProcessLoaderMachine::new(
104                self.checker,
105                *core::ptr::addr_of_mut!(self.processes),
106                process_binary_array,
107                self.kernel,
108                self.chip,
109                core::slice::from_raw_parts(
110                    core::ptr::addr_of!(_sapps),
111                    core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
112                ),
113                core::slice::from_raw_parts_mut(
114                    core::ptr::addr_of_mut!(_sappmem),
115                    core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
116                ),
117                self.fault_policy,
118                self.storage_policy,
119                self.appid_policy,
120                &proc_manage_cap,
121            ))
122        };
123        self.checker.set_client(loader);
124        loader.register();
125        loader.start();
126        loader
127    }
128}