1#![no_std]
8#![no_main]
9
10use kernel::capabilities;
11use kernel::component::Component;
12use kernel::deferred_call::DeferredCallClient;
13use kernel::platform::KernelResources;
14use kernel::platform::SyscallDriverLookup;
15use kernel::{create_capability, debug, static_init};
16
17mod checker_credentials_not_required;
18
19pub const NUM_PROCS: usize = 4;
24
25const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
27    capsules_system::process_policies::PanicFaultPolicy {};
28
29const NUM_CREDENTIAL_KEYS: usize = 1;
31const SIGNATURE_KEY_LEN: usize = 64;
33const SIGNATURE_HASH_LEN: usize = 32;
35const SIGNATURE_SIG_LEN: usize = 64;
37
38type ScreenDriver = capsules_extra::screen::screen::Screen<'static>;
43type ScreenAdapter = capsules_extra::screen::screen_adapters::ScreenARGB8888ToMono8BitPage<
44    'static,
45    qemu_rv32_virt_lib::ScreenHw,
46>;
47type ScreenSplitUser = components::screen::ScreenSplitUserComponentType<ScreenAdapter>;
48type ScreenOnLed = components::screen_on::ScreenOnLedComponentType<ScreenSplitUser, 4, 128, 64>;
49type ScreenOnLedSingle =
50    capsules_extra::screen::screen_on_led::ScreenOnLedSingle<'static, ScreenOnLed>;
51
52type LedDriver = capsules_core::led::LedDriver<'static, ScreenOnLedSingle, 4>;
53
54type ButtonDriver = capsules_extra::button_keyboard::ButtonKeyboard<'static>;
55
56type Verifier = ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>;
57type SignatureVerifyInMemoryKeys =
58    components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponentType<
59        Verifier,
60        NUM_CREDENTIAL_KEYS,
61        SIGNATURE_KEY_LEN,
62        SIGNATURE_HASH_LEN,
63        SIGNATURE_SIG_LEN,
64    >;
65type SignatureChecker = components::appid::checker_signature::AppCheckerSignatureComponentType<
66    SignatureVerifyInMemoryKeys,
67    capsules_extra::sha256::Sha256Software<'static>,
68    SIGNATURE_HASH_LEN,
69    SIGNATURE_SIG_LEN,
70>;
71
72struct Platform {
77    base: qemu_rv32_virt_lib::QemuRv32VirtPlatform,
78    screen: Option<&'static ScreenDriver>,
79    led: Option<&'static LedDriver>,
80    buttons: Option<&'static ButtonDriver>,
81}
82
83impl SyscallDriverLookup for Platform {
84    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
85    where
86        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
87    {
88        match driver_num {
89            capsules_extra::screen::screen::DRIVER_NUM => {
90                if let Some(screen_driver) = self.screen {
91                    f(Some(screen_driver))
92                } else {
93                    f(None)
94                }
95            }
96            capsules_core::led::DRIVER_NUM => {
97                if let Some(led_driver) = self.led {
98                    f(Some(led_driver))
99                } else {
100                    f(None)
101                }
102            }
103            capsules_core::button::DRIVER_NUM => {
104                if let Some(button_driver) = self.buttons {
105                    f(Some(button_driver))
106                } else {
107                    f(None)
108                }
109            }
110
111            _ => self.base.with_driver(driver_num, f),
112        }
113    }
114}
115
116impl KernelResources<qemu_rv32_virt_lib::ChipHw> for Platform {
117    type SyscallDriverLookup = Self;
118    type SyscallFilter = <qemu_rv32_virt_lib::QemuRv32VirtPlatform as KernelResources<
119        qemu_rv32_virt_lib::ChipHw,
120    >>::SyscallFilter;
121    type ProcessFault = <qemu_rv32_virt_lib::QemuRv32VirtPlatform as KernelResources<
122        qemu_rv32_virt_lib::ChipHw,
123    >>::ProcessFault;
124    type Scheduler = <qemu_rv32_virt_lib::QemuRv32VirtPlatform as KernelResources<
125        qemu_rv32_virt_lib::ChipHw,
126    >>::Scheduler;
127    type SchedulerTimer = <qemu_rv32_virt_lib::QemuRv32VirtPlatform as KernelResources<
128        qemu_rv32_virt_lib::ChipHw,
129    >>::SchedulerTimer;
130    type WatchDog = <qemu_rv32_virt_lib::QemuRv32VirtPlatform as KernelResources<
131        qemu_rv32_virt_lib::ChipHw,
132    >>::WatchDog;
133    type ContextSwitchCallback = <qemu_rv32_virt_lib::QemuRv32VirtPlatform as KernelResources<
134        qemu_rv32_virt_lib::ChipHw,
135    >>::ContextSwitchCallback;
136
137    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
138        self
139    }
140    fn syscall_filter(&self) -> &Self::SyscallFilter {
141        self.base.syscall_filter()
142    }
143    fn process_fault(&self) -> &Self::ProcessFault {
144        self.base.process_fault()
145    }
146    fn scheduler(&self) -> &Self::Scheduler {
147        self.base.scheduler()
148    }
149    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
150        self.base.scheduler_timer()
151    }
152    fn watchdog(&self) -> &Self::WatchDog {
153        self.base.watchdog()
154    }
155    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
156        self.base.context_switch_callback()
157    }
158}
159
160#[no_mangle]
162pub unsafe fn main() {
163    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
164
165    let (board_kernel, base_platform, chip) = qemu_rv32_virt_lib::start();
166
167    let (screen, led) = base_platform
172        .virtio_gpu_screen
173        .map_or((None, None), |screen| {
174            let screen_split = components::screen::ScreenSplitMuxComponent::new(screen).finalize(
175                components::screen_split_mux_component_static!(ScreenAdapter),
176            );
177
178            let screen_split_userspace =
179                components::screen::ScreenSplitUserComponent::new(screen_split, 0, 0, 128, 64)
180                    .finalize(components::screen_split_user_component_static!(
181                        ScreenAdapter
182                    ));
183
184            let screen_split_kernel =
185                components::screen::ScreenSplitUserComponent::new(screen_split, 0, 64, 128, 64)
186                    .finalize(components::screen_split_user_component_static!(
187                        ScreenAdapter
188                    ));
189
190            let screen = components::screen::ScreenComponent::new(
191                board_kernel,
192                capsules_extra::screen::screen::DRIVER_NUM,
193                screen_split_userspace,
194                None,
195            )
196            .finalize(components::screen_component_static!(1032));
197
198            let screen_on_leds =
199                components::screen_on::ScreenOnLedComponent::new(screen_split_kernel).finalize(
200                    components::screen_on_led_component_static!(ScreenSplitUser, 4, 128, 64),
201                );
202
203            let led =
204                components::led::LedsComponent::new().finalize(components::led_component_static!(
205                    ScreenOnLedSingle,
206                    capsules_extra::screen::screen_on_led::ScreenOnLedSingle::new(
207                        screen_on_leds,
208                        0
209                    ),
210                    capsules_extra::screen::screen_on_led::ScreenOnLedSingle::new(
211                        screen_on_leds,
212                        1
213                    ),
214                    capsules_extra::screen::screen_on_led::ScreenOnLedSingle::new(
215                        screen_on_leds,
216                        2
217                    ),
218                    capsules_extra::screen::screen_on_led::ScreenOnLedSingle::new(
219                        screen_on_leds,
220                        3
221                    ),
222                ));
223
224            (Some(screen), Some(led))
225        });
226
227    let buttons = base_platform.virtio_input_keyboard.map(|keyboard| {
232        let key_mappings = static_init!(
233            [u16; 4],
234            [
235                103, 14,  108, 28,  ]
240        );
241
242        components::button_keyboard::KeyboardButtonComponent::new(
243            board_kernel,
244            capsules_extra::button_keyboard::DRIVER_NUM,
245            keyboard,
246            key_mappings,
247        )
248        .finalize(components::keyboard_button_component_static!())
249    });
250
251    let platform = Platform {
252        base: base_platform,
253        screen,
254        led,
255        buttons,
256    };
257
258    let _ = platform.base.pconsole.start();
260
261    let sha = components::sha::ShaSoftware256Component::new()
267        .finalize(components::sha_software_256_component_static!());
268
269    let verifying_key0 = kernel::static_init!(
296        [u8; SIGNATURE_KEY_LEN],
297        [
298            0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
299            0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
300            0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
301            0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
302            0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
303        ]
304    );
305    let verifying_keys = kernel::static_init!(
306        [&'static mut [u8; SIGNATURE_KEY_LEN]; NUM_CREDENTIAL_KEYS],
307        [verifying_key0]
308    );
309    let ecdsa_p256_verifying_key =
311        kernel::static_init!([u8; SIGNATURE_KEY_LEN], [0; SIGNATURE_KEY_LEN]);
312    let ecdsa_p256_verifier = kernel::static_init!(
313        ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
314        ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(ecdsa_p256_verifying_key)
315    );
316    ecdsa_p256_verifier.register();
317
318    let verifier_multiple_keys =
320        components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponent::new(
321            ecdsa_p256_verifier,
322            verifying_keys,
323        )
324        .finalize(
325            components::signature_verify_in_memory_keys_component_static!(
326                Verifier,
327                NUM_CREDENTIAL_KEYS,
328                SIGNATURE_KEY_LEN,
329                SIGNATURE_HASH_LEN,
330                SIGNATURE_SIG_LEN,
331            ),
332        );
333
334    let checking_policy_signature =
336        components::appid::checker_signature::AppCheckerSignatureComponent::new(
337            sha,
338            verifier_multiple_keys,
339            tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
340        )
341        .finalize(components::app_checker_signature_component_static!(
342            SignatureVerifyInMemoryKeys,
343            capsules_extra::sha256::Sha256Software<'static>,
344            SIGNATURE_HASH_LEN,
345            SIGNATURE_SIG_LEN,
346        ));
347
348    let checking_policy = static_init!(
353        checker_credentials_not_required::AppCheckerCredentialsNotRequired<
354            SignatureChecker,
355        >,
356        checker_credentials_not_required::AppCheckerCredentialsNotRequired::new(
357            checking_policy_signature
358        ),
359    );
360
361    let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
363        .finalize(components::appid_assigner_names_component_static!());
364
365    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
367        .finalize(components::process_checker_machine_component_static!());
368
369    let storage_permissions_policy =
374        components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
375            components::storage_permissions_null_component_static!(
376                qemu_rv32_virt_lib::ChipHw,
377                kernel::process::ProcessStandardDebugFull,
378            ),
379        );
380
381    extern "C" {
387        static _sapps: u8;
389        static _eapps: u8;
391        static mut _sappmem: u8;
393        static _eappmem: u8;
395    }
396
397    let app_flash = core::slice::from_raw_parts(
398        core::ptr::addr_of!(_sapps),
399        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
400    );
401    let app_memory = core::slice::from_raw_parts_mut(
402        core::ptr::addr_of_mut!(_sappmem),
403        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
404    );
405
406    let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
408        checker,
409        board_kernel,
410        chip,
411        &FAULT_RESPONSE,
412        assigner,
413        storage_permissions_policy,
414        app_flash,
415        app_memory,
416    )
417    .finalize(components::process_loader_sequential_component_static!(
418        qemu_rv32_virt_lib::ChipHw,
419        kernel::process::ProcessStandardDebugFull,
420        NUM_PROCS
421    ));
422
423    debug!("Starting main kernel loop.");
424
425    board_kernel.kernel_loop(
426        &platform,
427        chip,
428        Some(&platform.base.ipc),
429        &main_loop_capability,
430    );
431}