diff --git a/crates/sel4-capdl-initializer/add-spec/src/main.rs b/crates/sel4-capdl-initializer/add-spec/src/main.rs index 1f8bbe093..8fb4a6989 100644 --- a/crates/sel4-capdl-initializer/add-spec/src/main.rs +++ b/crates/sel4-capdl-initializer/add-spec/src/main.rs @@ -4,9 +4,6 @@ // SPDX-License-Identifier: BSD-2-Clause // -#![feature(never_type)] -#![feature(unwrap_infallible)] - use std::fs; use anyhow::Result; diff --git a/crates/sel4-capdl-initializer/add-spec/src/reserialize_spec.rs b/crates/sel4-capdl-initializer/add-spec/src/reserialize_spec.rs index c987efc81..8890adc56 100644 --- a/crates/sel4-capdl-initializer/add-spec/src/reserialize_spec.rs +++ b/crates/sel4-capdl-initializer/add-spec/src/reserialize_spec.rs @@ -24,29 +24,26 @@ pub fn reserialize_spec<'a>( let mut sources = SourcesBuilder::new(); let mut num_embedded_frames = 0; let final_spec: SpecWithIndirection<'a> = input_spec - .traverse_names_with_context::<_, !>(|named_obj| { - Ok(object_names_level + .traverse_names_with_context(|named_obj| { + object_names_level .apply(named_obj) .map(|s| IndirectObjectName { range: sources.append(s.as_bytes()), - })) + }) }) - .into_ok() .split_embedded_frames(embed_frames, granule_size_bits) - .traverse_data::(|key| { + .traverse_data(|key| { let compressed = DeflatedBytesContent::pack(fill_map.get(key)); - Ok(IndirectDeflatedBytesContent { + IndirectDeflatedBytesContent { deflated_bytes_range: sources.append(&compressed), - }) + } }) - .into_ok() - .traverse_embedded_frames::(|fill| { + .traverse_embedded_frames(|fill| { num_embedded_frames += 1; sources.align_to(granule_size); let range = sources.append(&fill_map.get_frame(granule_size, fill)); - Ok(IndirectEmbeddedFrame::new(range.start)) - }) - .into_ok(); + IndirectEmbeddedFrame::new(range.start) + }); if verbose { eprintln!("embedded frames count: {}", num_embedded_frames); diff --git a/crates/sel4-capdl-initializer/core/src/lib.rs b/crates/sel4-capdl-initializer/core/src/lib.rs index 37a18f819..fcdfb6a3f 100644 --- a/crates/sel4-capdl-initializer/core/src/lib.rs +++ b/crates/sel4-capdl-initializer/core/src/lib.rs @@ -5,7 +5,6 @@ // #![no_std] -#![feature(never_type)] use core::array; use core::borrow::BorrowMut; @@ -63,11 +62,11 @@ impl<'a, N: ObjectName, D: Content, M: GetEmbeddedFrame, B: BorrowMut<[PerObject user_image_bounds: Range, spec_with_sources: &SpecWithSources, buffers: &mut InitializerBuffers, - ) -> Result { + ) -> ! { info!("Starting CapDL initializer"); let (small_frame_copy_addr, large_frame_copy_addr) = - init_copy_addrs(bootinfo, &user_image_bounds)?; + init_copy_addrs(bootinfo, &user_image_bounds).unwrap(); let mut cslot_allocator = CSlotAllocator::new(bootinfo.empty()); @@ -81,6 +80,13 @@ impl<'a, N: ObjectName, D: Content, M: GetEmbeddedFrame, B: BorrowMut<[PerObject buffers, } .run() + .unwrap_or_else(|err| panic!("Error: {}", err)); + + info!("CapDL initializer done, suspending"); + + BootInfo::init_thread_tcb().tcb_suspend().unwrap(); + + unreachable!() } fn spec(&self) -> &'a Spec<'a, N, D, M> { @@ -93,7 +99,7 @@ impl<'a, N: ObjectName, D: Content, M: GetEmbeddedFrame, B: BorrowMut<[PerObject // // // - fn run(&mut self) -> Result { + fn run(&mut self) -> Result<()> { self.create_objects()?; self.init_irqs()?; @@ -112,11 +118,7 @@ impl<'a, N: ObjectName, D: Content, M: GetEmbeddedFrame, B: BorrowMut<[PerObject self.start_threads()?; - info!("CapDL initializer done, suspending"); - - BootInfo::init_thread_tcb().tcb_suspend()?; - - unreachable!() + Ok(()) } fn create_objects(&mut self) -> Result<()> { diff --git a/crates/sel4-capdl-initializer/embed-spec/src/lib.rs b/crates/sel4-capdl-initializer/embed-spec/src/lib.rs index 781e34e6a..dfa7f6e19 100644 --- a/crates/sel4-capdl-initializer/embed-spec/src/lib.rs +++ b/crates/sel4-capdl-initializer/embed-spec/src/lib.rs @@ -4,9 +4,6 @@ // SPDX-License-Identifier: BSD-2-Clause // -#![feature(never_type)] -#![feature(unwrap_infallible)] - // TODO(nspin) // In a few cases, we use a local const declaration to appease the borrow checker. // Using an exposed constructor of `Indirect` would be one way around this. @@ -323,7 +320,7 @@ impl<'a> Embedding<'a> { let mut embedded_frame_count = 0usize; let spec = self .spec() - .traverse_data::(|data| { + .traverse_data(|data| { let id = hex::encode_upper(format!( "{},{},{}", data.file_range().start, @@ -338,10 +335,9 @@ impl<'a> Embedding<'a> { }); self.pack_fill(self.fill_map.get(data)) }); - Ok(ident) + ident }) - .into_ok() - .traverse_embedded_frames::(|fill| { + .traverse_embedded_frames(|fill| { let ident = format_ident!("FRAME_{}", embedded_frame_count); let fname = format!("frame.{}.bin", embedded_frame_count); file_inclusion_toks.extend(quote! { @@ -351,9 +347,8 @@ impl<'a> Embedding<'a> { }); files_for_inclusion.insert(fname, self.fill_map.get_frame(self.granule_size(), fill)); embedded_frame_count += 1; - Ok(ident) - }) - .into_ok(); + ident + }); let types_mod = self.types_mod(); let name_type = self.name_type(true); diff --git a/crates/sel4-capdl-initializer/src/main.rs b/crates/sel4-capdl-initializer/src/main.rs index c26225647..09fe85626 100644 --- a/crates/sel4-capdl-initializer/src/main.rs +++ b/crates/sel4-capdl-initializer/src/main.rs @@ -49,7 +49,6 @@ fn main(bootinfo: &BootInfo) -> ! { &spec_with_sources, &mut buffers, ) - .unwrap_or_else(|err| panic!("Error: {}", err)) } #[no_mangle] diff --git a/crates/sel4-capdl-initializer/types/src/frame_init.rs b/crates/sel4-capdl-initializer/types/src/frame_init.rs index de490390d..1166a2439 100644 --- a/crates/sel4-capdl-initializer/types/src/frame_init.rs +++ b/crates/sel4-capdl-initializer/types/src/frame_init.rs @@ -51,17 +51,17 @@ impl<'a, D, M> FrameInit<'a, D, M> { } } -impl<'a, D> FrameInit<'a, D, !> { +impl<'a, D> FrameInit<'a, D, NeverEmbedded> { #[allow(clippy::explicit_auto_deref)] pub const fn as_fill_infallible(&self) -> &Fill<'a, D> { match self { Self::Fill(fill) => fill, - Self::Embedded(never) => *never, + Self::Embedded(absurdity) => match *absurdity {}, } } } -impl<'a, D> object::Frame<'a, D, !> { +impl<'a, D> object::Frame<'a, D, NeverEmbedded> { pub fn can_embed(&self, granule_size_bits: usize, is_root: bool) -> bool { is_root && self.paddr.is_none() @@ -73,6 +73,11 @@ impl<'a, D> object::Frame<'a, D, !> { // // // +#[derive(Copy, Clone)] +pub enum NeverEmbedded {} + +// // // + #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct EmbeddedFrame { ptr: *const u8, diff --git a/crates/sel4-capdl-initializer/types/src/lib.rs b/crates/sel4-capdl-initializer/types/src/lib.rs index 7abde3ddf..713393618 100644 --- a/crates/sel4-capdl-initializer/types/src/lib.rs +++ b/crates/sel4-capdl-initializer/types/src/lib.rs @@ -5,8 +5,6 @@ // #![cfg_attr(not(feature = "std"), no_std)] -#![feature(never_type)] -#![feature(unwrap_infallible)] #[cfg(feature = "alloc")] extern crate alloc; @@ -36,7 +34,7 @@ pub use footprint::Footprint; pub use frame_init::{ BytesContent, Content, EmbeddedFrame, Fill, FillEntry, FillEntryContent, FillEntryContentBootInfo, FillEntryContentBootInfoId, FrameInit, GetEmbeddedFrame, - IndirectBytesContent, IndirectEmbeddedFrame, SelfContainedContent, + IndirectBytesContent, IndirectEmbeddedFrame, NeverEmbedded, SelfContainedContent, SelfContainedGetEmbeddedFrame, }; pub use indirect::Indirect; diff --git a/crates/sel4-capdl-initializer/types/src/traverse.rs b/crates/sel4-capdl-initializer/types/src/traverse.rs index dd559b1c1..d61c01072 100644 --- a/crates/sel4-capdl-initializer/types/src/traverse.rs +++ b/crates/sel4-capdl-initializer/types/src/traverse.rs @@ -4,7 +4,11 @@ // SPDX-License-Identifier: BSD-2-Clause // -use crate::{object, Fill, FillEntry, FillEntryContent, FrameInit, NamedObject, Object, Spec}; +use core::convert::Infallible; + +use crate::{ + object, Fill, FillEntry, FillEntryContent, FrameInit, NamedObject, NeverEmbedded, Object, Spec, +}; impl<'a, N, D, M> Spec<'a, N, D, M> { pub(crate) fn traverse( @@ -51,18 +55,29 @@ impl<'a, N, D, M> Spec<'a, N, D, M> { } impl<'a, N, D: Clone, M: Clone> Spec<'a, N, D, M> { - pub fn traverse_names_with_context( + pub fn traverse_names_with_context_fallible( &self, f: impl FnMut(&NamedObject<'a, N, D, M>) -> Result, ) -> Result, E> { self.traverse(f, |frame, _is_root| Ok(frame.init.clone())) } - pub fn traverse_names( + pub fn traverse_names_with_context( + &self, + mut f: impl FnMut(&NamedObject<'a, N, D, M>) -> N1, + ) -> Spec<'a, N1, D, M> { + unwrap_infallible(self.traverse_names_with_context_fallible(|x| Ok(f(x)))) + } + + pub fn traverse_names_fallible( &self, mut f: impl FnMut(&N) -> Result, ) -> Result, E> { - self.traverse_names_with_context(|named_object| f(&named_object.name)) + self.traverse_names_with_context_fallible(|named_object| f(&named_object.name)) + } + + pub fn traverse_names(&self, mut f: impl FnMut(&N) -> N1) -> Spec<'a, N1, D, M> { + unwrap_infallible(self.traverse_names_fallible(|x| Ok(f(x)))) } } @@ -76,7 +91,7 @@ impl<'a, N: Clone, D, M> Spec<'a, N, D, M> { } impl<'a, N: Clone, D, M: Clone> Spec<'a, N, D, M> { - pub fn traverse_data_with_context( + pub fn traverse_data_with_context_fallible( &self, mut f: impl FnMut(usize, &D) -> Result, ) -> Result, E> { @@ -106,16 +121,27 @@ impl<'a, N: Clone, D, M: Clone> Spec<'a, N, D, M> { }) } - pub fn traverse_data( + pub fn traverse_data_with_context( + &self, + mut f: impl FnMut(usize, &D) -> D1, + ) -> Spec<'a, N, D1, M> { + unwrap_infallible(self.traverse_data_with_context_fallible(|x1, x2| Ok(f(x1, x2)))) + } + + pub fn traverse_data_fallible( &self, mut f: impl FnMut(&D) -> Result, ) -> Result, E> { - self.traverse_data_with_context(|_length, data| f(data)) + self.traverse_data_with_context_fallible(|_length, data| f(data)) + } + + pub fn traverse_data(&self, mut f: impl FnMut(&D) -> D1) -> Spec<'a, N, D1, M> { + unwrap_infallible(self.traverse_data_fallible(|x| Ok(f(x)))) } } impl<'a, N: Clone, D: Clone, M> Spec<'a, N, D, M> { - pub fn traverse_embedded_frames( + pub fn traverse_embedded_frames_fallible( &self, mut f: impl FnMut(&M) -> Result, ) -> Result, E> { @@ -126,24 +152,33 @@ impl<'a, N: Clone, D: Clone, M> Spec<'a, N, D, M> { }) }) } + + pub fn traverse_embedded_frames(&self, mut f: impl FnMut(&M) -> M1) -> Spec<'a, N, D, M1> { + unwrap_infallible(self.traverse_embedded_frames_fallible(|x| Ok(f(x)))) + } } -impl<'a, N: Clone, D: Clone> Spec<'a, N, D, !> { +impl<'a, N: Clone, D: Clone> Spec<'a, N, D, NeverEmbedded> { pub fn split_embedded_frames( &self, embed_frames: bool, granule_size_bits: usize, ) -> Spec<'a, N, D, Fill<'a, D>> { - self.traverse_frame_init::<_, _, !>(|frame, is_root| { - let fill = frame.init.as_fill_infallible(); - Ok( - if embed_frames && frame.can_embed(granule_size_bits, is_root) { - FrameInit::Embedded(fill.clone()) - } else { - FrameInit::Fill(fill.clone()) - }, - ) - }) - .into_ok() + unwrap_infallible( + self.traverse_frame_init::<_, _, Infallible>(|frame, is_root| { + let fill = frame.init.as_fill_infallible(); + Ok( + if embed_frames && frame.can_embed(granule_size_bits, is_root) { + FrameInit::Embedded(fill.clone()) + } else { + FrameInit::Fill(fill.clone()) + }, + ) + }), + ) } } + +fn unwrap_infallible(result: Result) -> T { + result.unwrap_or_else(|absurdity| match absurdity {}) +} diff --git a/crates/sel4-capdl-initializer/types/src/when_std.rs b/crates/sel4-capdl-initializer/types/src/when_std.rs index 21a87bb4c..d064779b5 100644 --- a/crates/sel4-capdl-initializer/types/src/when_std.rs +++ b/crates/sel4-capdl-initializer/types/src/when_std.rs @@ -11,23 +11,21 @@ use std::ops::Deref; use std::os::unix::fs::FileExt; use std::path::{Path, PathBuf}; -use crate::{FileContent, FileContentRange, Fill, Spec}; +use crate::{FileContent, FileContentRange, Fill, NeverEmbedded, Spec}; -pub type InputSpec = Spec<'static, String, FileContentRange, !>; +pub type InputSpec = Spec<'static, String, FileContentRange, NeverEmbedded>; impl InputSpec { pub fn parse(s: &str) -> Self { serde_json::from_str::>(s) .unwrap() - .traverse_embedded_frames::(|_| panic!()) - .into_ok() - .traverse_data_with_context(|length, data| Ok::<_, !>(data.with_length(length))) - .into_ok() + .traverse_embedded_frames::(|_| panic!()) + .traverse_data_with_context(|length, data| data.with_length(length)) } pub fn collect_fill(&self, fill_dirs: impl IntoIterator>) -> FillMap { let mut builder = FillMapBuilder::new(fill_dirs); - self.traverse_data(|key| builder.add(key)).unwrap(); + self.traverse_data_fallible(|key| builder.add(key)).unwrap(); builder.build() } } diff --git a/crates/sel4-capdl-initializer/with-embedded-spec/build-env/src/lib.rs b/crates/sel4-capdl-initializer/with-embedded-spec/build-env/src/lib.rs index 6944c0703..01d78c2fe 100644 --- a/crates/sel4-capdl-initializer/with-embedded-spec/build-env/src/lib.rs +++ b/crates/sel4-capdl-initializer/with-embedded-spec/build-env/src/lib.rs @@ -4,8 +4,6 @@ // SPDX-License-Identifier: BSD-2-Clause // -#![feature(never_type)] - use std::borrow::Cow; use std::env; use std::fs; diff --git a/crates/sel4-capdl-initializer/with-embedded-spec/embedded-spec/validate/src/lib.rs b/crates/sel4-capdl-initializer/with-embedded-spec/embedded-spec/validate/src/lib.rs index a9e7a3f2a..1c8ffeb0c 100644 --- a/crates/sel4-capdl-initializer/with-embedded-spec/embedded-spec/validate/src/lib.rs +++ b/crates/sel4-capdl-initializer/with-embedded-spec/embedded-spec/validate/src/lib.rs @@ -4,9 +4,6 @@ // SPDX-License-Identifier: BSD-2-Clause // -#![feature(never_type)] -#![feature(unwrap_infallible)] - use std::slice; use sel4_capdl_initializer_types::*; @@ -23,38 +20,30 @@ pub fn run(tell_cargo: bool) { let embedded = &sel4_capdl_initializer_with_embedded_spec_embedded_spec::SPEC; let adapted_embedded: SpecCommon = embedded - .traverse_names_with_context::<_, !>(|named_obj| { - Ok(named_obj.name.inner().to_common().map(ToOwned::to_owned)) + .traverse_names_with_context(|named_obj| { + named_obj.name.inner().to_common().map(ToOwned::to_owned) }) - .into_ok() - .traverse_data_with_context::<_, !>(|length, data| { + .traverse_data_with_context(|length, data| { let mut buf = vec![0; length]; data.inner().self_contained_copy_out(&mut buf); - Ok(buf) - }) - .into_ok() - .traverse_embedded_frames::<_, !>(|frame| { - Ok(unsafe { - slice::from_raw_parts(frame.inner().ptr(), embedding.granule_size()).to_vec() - }) + buf }) - .into_ok(); + .traverse_embedded_frames(|frame| unsafe { + slice::from_raw_parts(frame.inner().ptr(), embedding.granule_size()).to_vec() + }); let input = &embedding.spec; let adapted_input: SpecCommon = input - .traverse_names_with_context::<_, !>(|named_obj| { - Ok(embedding + .traverse_names_with_context(|named_obj| { + embedding .object_names_level .apply(named_obj) - .map(Clone::clone)) - }) - .into_ok() - .traverse_data::<_, !>(|key| Ok(embedding.fill_map.get(key).to_vec())) - .into_ok() - .traverse_embedded_frames::<_, !>(|fill| { - Ok(embedding.fill_map.get_frame(embedding.granule_size(), fill)) + .map(Clone::clone) }) - .into_ok(); + .traverse_data(|key| embedding.fill_map.get(key).to_vec()) + .traverse_embedded_frames(|fill| { + embedding.fill_map.get_frame(embedding.granule_size(), fill) + }); if adapted_embedded != adapted_input { // NOTE for debugging: diff --git a/crates/sel4-capdl-initializer/with-embedded-spec/src/main.rs b/crates/sel4-capdl-initializer/with-embedded-spec/src/main.rs index df8c7d103..b295231fd 100644 --- a/crates/sel4-capdl-initializer/with-embedded-spec/src/main.rs +++ b/crates/sel4-capdl-initializer/with-embedded-spec/src/main.rs @@ -42,7 +42,6 @@ fn main(bootinfo: &BootInfo) -> ! { Initializer::initialize(bootinfo, user_image_bounds(), &spec_with_sources, unsafe { &mut BUFFERS }) - .unwrap_or_else(|err| panic!("Error: {}", err)) } extern "C" {