From 0b118ba82df0ca754d44aea9b40015bc1bd9e18b Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 08:25:02 +0000 Subject: [PATCH] crates/sel4/bitfield-ops: Re-introduce Bitfield type --- crates/sel4/bitfield-ops/src/lib.rs | 118 +++++++++++++++++-- crates/sel4/src/cnode_cap_data.rs | 2 +- crates/sel4/sys/build/bf/mod.rs | 2 +- crates/sel4/sys/build/xml/invocations/mod.rs | 2 +- crates/sel4/sys/src/{bf/mod.rs => bf.rs} | 4 +- crates/sel4/sys/src/bf/types.rs | 42 ------- crates/sel4/sys/src/syscalls/helpers/mod.rs | 6 +- 7 files changed, 115 insertions(+), 61 deletions(-) rename crates/sel4/sys/src/{bf/mod.rs => bf.rs} (54%) delete mode 100644 crates/sel4/sys/src/bf/types.rs diff --git a/crates/sel4/bitfield-ops/src/lib.rs b/crates/sel4/bitfield-ops/src/lib.rs index e4fc6c4fa..8a3ea70cd 100644 --- a/crates/sel4/bitfield-ops/src/lib.rs +++ b/crates/sel4/bitfield-ops/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] +use core::marker::PhantomData; use core::mem; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not, Range, Shl, Shr}; @@ -231,6 +232,101 @@ where // // // +#[repr(transparent)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +pub struct Bitfield { + inner: T, + _phantom: PhantomData, +} + +impl Bitfield { + pub fn new(inner: T) -> Self { + Self { + inner, + _phantom: PhantomData, + } + } + + pub fn into_inner(self) -> T { + self.inner + } + + pub fn inner(&self) -> &T { + &self.inner + } + + pub fn inner_mut(&mut self) -> &mut T { + &mut self.inner + } +} + +impl Bitfield<[T; N], T> { + pub fn zeroed() -> Self { + Self::new([T::zero(); N]) + } +} + +impl, U: UnsignedPrimInt> Bitfield { + pub fn bits(&self) -> &[U] { + self.inner().as_ref() + } + + pub fn get_bits>(&self, range: Range) -> V { + get_bits(self.bits(), range) + } + + pub fn get_bits_into_slice( + &self, + range: Range, + dst: &mut [V], + dst_start: usize, + ) where + V: TryFrom, + usize: TryFrom, + { + let dst_range = dst_start..(dst_start + range.len()); + set_bits_from_slice(dst, dst_range, self.bits(), range.start) + } + + pub fn get(&self, start_bit: usize) -> V + where + V::Unsigned: TryFrom, + { + get(self.bits(), start_bit) + } +} + +impl, U: UnsignedPrimInt> Bitfield { + pub fn bits_mut(&mut self) -> &mut [U] { + self.inner_mut().as_mut() + } + + pub fn set_bits>(&mut self, range: Range, src: V) { + set_bits(self.bits_mut(), range, src) + } + + pub fn set_bits_from_slice( + &mut self, + range: Range, + src: &[V], + src_start: usize, + ) where + U: TryFrom, + usize: TryFrom, + { + set_bits_from_slice(self.bits_mut(), range, src, src_start) + } + + pub fn set(&mut self, start_bit: usize, src: V) + where + V::Unsigned: TryInto, + { + set(self.bits_mut(), start_bit, src) + } +} + +// // // + #[cfg(test)] mod test { #![allow(unused_imports)] @@ -244,7 +340,7 @@ mod test { #[test] fn zero_gets_zero() { - assert_eq!(Bitfield::::zeroed().get_bits(50..80), 0); + assert_eq!(Bitfield::<[u64; 2], _>::zeroed().get_bits::(50..80), 0); } fn set_and_get< @@ -255,9 +351,9 @@ mod test { range: Range, val: U, ) { - let mut arr = Bitfield::::zeroed(); - set_bits(arr.as_mut_arr(), range.clone(), val); - let observed_val: U = get_bits(arr.as_arr(), range); + let mut arr = Bitfield::<[T; N], _>::zeroed(); + set_bits(arr.inner_mut(), range.clone(), val); + let observed_val: U = get_bits(arr.inner(), range); assert_eq!(observed_val, val); } @@ -271,13 +367,13 @@ mod test { #[test] fn this_works_too() { for init in [0, !0] { - let mut arr = Bitfield::::from_arr([init]); - arr.set_bits(0..2, 0b11); - arr.set_bits(60..64, 0b1111); - arr.set_bits(10..11, 0b1); - assert_eq!(arr.get_bits(0..2), 0b11); - assert_eq!(arr.get_bits(60..64), 0b1111); - assert_eq!(arr.get_bits(10..11), 0b1); + let mut arr = Bitfield::<[u64; 1], u64>::new([init]); + arr.set_bits::(0..2, 0b11); + arr.set_bits::(60..64, 0b1111); + arr.set_bits::(10..11, 0b1); + assert_eq!(arr.get_bits::(0..2), 0b11); + assert_eq!(arr.get_bits::(60..64), 0b1111); + assert_eq!(arr.get_bits::(10..11), 0b1); } } } diff --git a/crates/sel4/src/cnode_cap_data.rs b/crates/sel4/src/cnode_cap_data.rs index 2808adb25..3ce704c83 100644 --- a/crates/sel4/src/cnode_cap_data.rs +++ b/crates/sel4/src/cnode_cap_data.rs @@ -23,7 +23,7 @@ impl CNodeCapData { } pub fn into_word(self) -> Word { - let arr = self.inner().0.as_arr(); + let arr = self.inner().0.inner(); assert_eq!(arr.len(), 1); // TODO assert at compile time instead arr[0] } diff --git a/crates/sel4/sys/build/bf/mod.rs b/crates/sel4/sys/build/bf/mod.rs index 07328c132..1389a57da 100644 --- a/crates/sel4/sys/build/bf/mod.rs +++ b/crates/sel4/sys/build/bf/mod.rs @@ -389,7 +389,7 @@ impl BackingType { fn bitfield(&self) -> TokenStream { let primitive = self.primitive(); let multiple = self.multiple; - quote!(Bitfield<#primitive, #multiple>) + quote!(SeL4Bitfield<#primitive, #multiple>) } } diff --git a/crates/sel4/sys/build/xml/invocations/mod.rs b/crates/sel4/sys/build/xml/invocations/mod.rs index 274521d88..df1dd518f 100644 --- a/crates/sel4/sys/build/xml/invocations/mod.rs +++ b/crates/sel4/sys/build/xml/invocations/mod.rs @@ -270,7 +270,7 @@ impl<'a> InvocationGenerator<'a> { }); } ParameterType::Bitfield => toks.extend(quote! { - self.set_mr_bits(#start..#end, #name.0.as_arr()[0]); + self.set_mr_bits(#start..#end, #name.0.inner()[0]); }), ParameterType::Struct { members } => { assert!(self.parameter_types.get(¶m.ty).pass_by_reference()); diff --git a/crates/sel4/sys/src/bf/mod.rs b/crates/sel4/sys/src/bf.rs similarity index 54% rename from crates/sel4/sys/src/bf/mod.rs rename to crates/sel4/sys/src/bf.rs index bdc8bf272..f6994779c 100644 --- a/crates/sel4/sys/src/bf/mod.rs +++ b/crates/sel4/sys/src/bf.rs @@ -1,8 +1,8 @@ use core::fmt; -pub(crate) mod types; +use sel4_bitfield_ops::Bitfield; -use types::Bitfield; +pub(crate) type SeL4Bitfield = Bitfield<[T; N], T>; include!(concat!(env!("OUT_DIR"), "/types.rs")); include!(concat!(env!("OUT_DIR"), "/shared_types.rs")); diff --git a/crates/sel4/sys/src/bf/types.rs b/crates/sel4/sys/src/bf/types.rs deleted file mode 100644 index 2a97c1c8d..000000000 --- a/crates/sel4/sys/src/bf/types.rs +++ /dev/null @@ -1,42 +0,0 @@ -use core::ops::Range; - -use sel4_bitfield_ops::{get_bits, set_bits, UnsignedPrimInt}; - -#[repr(C)] -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -pub struct Bitfield { - arr: [T; N], -} - -impl Bitfield -where - T: UnsignedPrimInt, -{ - pub fn from_arr(arr: [T; N]) -> Self { - Self { arr } - } - - pub fn into_arr(self) -> [T; N] { - self.arr - } - - pub fn as_arr(&self) -> &[T; N] { - &self.arr - } - - pub fn as_mut_arr(&mut self) -> &mut [T; N] { - &mut self.arr - } - - pub fn zeroed() -> Self { - Self::from_arr([T::zero(); N]) - } - - pub fn get_bits(&self, range: Range) -> T { - get_bits(&self.arr, range) - } - - pub fn set_bits(&mut self, range: Range, bits: T) { - set_bits(&mut self.arr, range, bits) - } -} diff --git a/crates/sel4/sys/src/syscalls/helpers/mod.rs b/crates/sel4/sys/src/syscalls/helpers/mod.rs index f701f7596..9b43dcd35 100644 --- a/crates/sel4/sys/src/syscalls/helpers/mod.rs +++ b/crates/sel4/sys/src/syscalls/helpers/mod.rs @@ -1,4 +1,4 @@ -use crate::bf::types::Bitfield; +use crate::bf::SeL4Bitfield; use crate::{seL4_MessageInfo, seL4_Word}; @@ -8,11 +8,11 @@ pub use arch::*; impl seL4_MessageInfo { pub(crate) fn from_word(word: seL4_Word) -> Self { - Self(Bitfield::from_arr([word])) + Self(SeL4Bitfield::new([word])) } pub(crate) fn into_word(self) -> seL4_Word { - self.0.into_arr()[0] + self.0.into_inner()[0] } pub(crate) fn msg_helper(&self, msg: Option, i: seL4_Word) -> seL4_Word {