From 656bfb87d55002c67a51674b2957ae95d5eeec20 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 06:23:35 +0000 Subject: [PATCH 01/10] crates/sel4/bitfield-types: Clean up Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 128 ++++++++++++-------------- crates/sel4/sys/src/ipc_buffer.rs | 6 +- 2 files changed, 62 insertions(+), 72 deletions(-) diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index ae7abf8bf..6765ff2d7 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -4,14 +4,14 @@ use core::mem; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not, Range, Shl, Shr}; #[repr(C)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] pub struct Bitfield { arr: [T; N], } impl Bitfield where - T: BitfieldPrimitive, + T: UnsignedPrimInt, { pub fn from_arr(arr: [T; N]) -> Self { Self { arr } @@ -42,26 +42,26 @@ where } } -pub trait BitfieldPrimitive: - BitfieldPrimitiveSealed +pub trait UnsignedPrimInt: + UnsignedPrimIntSealed + Copy + Eq + Not + BitAnd + BitOr - + BitOrAssign + BitAndAssign + + BitOrAssign + Shl + Shr - + From // HACK for generic 0 + + Default // HACK for generic 0 { } -trait BitfieldPrimitiveExt: BitfieldPrimitive { +trait UnsignedPrimIntExt: UnsignedPrimInt { const NUM_BITS: usize = mem::size_of::() * 8; fn zero() -> Self { - false.into() + Default::default() } fn mask(range: Range) -> Self { @@ -81,36 +81,36 @@ trait BitfieldPrimitiveExt: BitfieldPrimitive { } } -impl BitfieldPrimitiveExt for T {} +impl UnsignedPrimIntExt for T {} -impl BitfieldPrimitive for u128 {} -impl BitfieldPrimitive for u64 {} -impl BitfieldPrimitive for u32 {} -impl BitfieldPrimitive for u16 {} -impl BitfieldPrimitive for u8 {} +impl UnsignedPrimInt for u8 {} +impl UnsignedPrimInt for u16 {} +impl UnsignedPrimInt for u32 {} +impl UnsignedPrimInt for u64 {} +impl UnsignedPrimInt for u128 {} -use bitfield_primative_sealing::BitfieldPrimitiveSealed; +use unsigned_prim_int_sealing::UnsignedPrimIntSealed; -mod bitfield_primative_sealing { - pub trait BitfieldPrimitiveSealed {} +mod unsigned_prim_int_sealing { + pub trait UnsignedPrimIntSealed {} - impl BitfieldPrimitiveSealed for u128 {} - impl BitfieldPrimitiveSealed for u64 {} - impl BitfieldPrimitiveSealed for u32 {} - impl BitfieldPrimitiveSealed for u16 {} - impl BitfieldPrimitiveSealed for u8 {} + impl UnsignedPrimIntSealed for u8 {} + impl UnsignedPrimIntSealed for u16 {} + impl UnsignedPrimIntSealed for u32 {} + impl UnsignedPrimIntSealed for u64 {} + impl UnsignedPrimIntSealed for u128 {} } -pub trait BitfieldPrimitiveMaybeSigned: BitfieldPrimitiveMaybeSignedSealed { - type Unsigned: BitfieldPrimitive; +pub trait PrimInt: PrimIntSealed { + type Unsigned: UnsignedPrimInt; fn cast_from_unsigned(val: Self::Unsigned) -> Self; fn cast_to_unsigned(val: Self) -> Self::Unsigned; } -impl BitfieldPrimitiveMaybeSigned for T +impl PrimInt for T where - T: BitfieldPrimitive + BitfieldPrimitiveMaybeSignedSealed, + T: UnsignedPrimInt + PrimIntSealed, { type Unsigned = Self; @@ -123,9 +123,9 @@ where } } -macro_rules! impl_bitfield_primitive_maybe_unsigned { +macro_rules! impl_prim_int { ($maybe_signed:ty, $unsigned:ty) => { - impl BitfieldPrimitiveMaybeSigned for $maybe_signed { + impl PrimInt for $maybe_signed { type Unsigned = $unsigned; fn cast_from_unsigned(val: Self::Unsigned) -> Self { @@ -139,31 +139,29 @@ macro_rules! impl_bitfield_primitive_maybe_unsigned { }; } -impl_bitfield_primitive_maybe_unsigned!(i128, u128); -impl_bitfield_primitive_maybe_unsigned!(i64, u64); -impl_bitfield_primitive_maybe_unsigned!(i32, u32); -impl_bitfield_primitive_maybe_unsigned!(i16, u16); -impl_bitfield_primitive_maybe_unsigned!(i8, u8); +impl_prim_int!(i8, u8); +impl_prim_int!(i16, u16); +impl_prim_int!(i32, u32); +impl_prim_int!(i64, u64); +impl_prim_int!(i128, u128); -use bitfield_primative_maybe_signed_sealing::BitfieldPrimitiveMaybeSignedSealed; +use prim_int_sealing::PrimIntSealed; -mod bitfield_primative_maybe_signed_sealing { - use super::BitfieldPrimitiveSealed; +mod prim_int_sealing { + use super::UnsignedPrimIntSealed; - pub trait BitfieldPrimitiveMaybeSignedSealed {} + pub trait PrimIntSealed {} - impl BitfieldPrimitiveMaybeSignedSealed for T {} + impl PrimIntSealed for T {} - impl BitfieldPrimitiveMaybeSignedSealed for i128 {} - impl BitfieldPrimitiveMaybeSignedSealed for i64 {} - impl BitfieldPrimitiveMaybeSignedSealed for i32 {} - impl BitfieldPrimitiveMaybeSignedSealed for i16 {} - impl BitfieldPrimitiveMaybeSignedSealed for i8 {} + impl PrimIntSealed for i8 {} + impl PrimIntSealed for i16 {} + impl PrimIntSealed for i32 {} + impl PrimIntSealed for i64 {} + impl PrimIntSealed for i128 {} } -// - -pub fn get_bits>( +pub fn get_bits>( arr: &[T; N], range: Range, ) -> U { @@ -192,21 +190,7 @@ pub fn get_bits( - arr: &[T; N], - range: Range, -) -> U -where - U::Unsigned: TryFrom, -{ - U::cast_from_unsigned(get_bits(arr, range)) -} - -pub fn set_bits>( +pub fn set_bits>( arr: &mut [T; N], range: Range, bits: U, @@ -243,11 +227,17 @@ pub fn set_bits( +pub fn get_bits_maybe_signed( + arr: &[T; N], + range: Range, +) -> U +where + U::Unsigned: TryFrom, +{ + U::cast_from_unsigned(get_bits(arr, range)) +} + +pub fn set_bits_maybe_signed( arr: &mut [T; N], range: Range, bits: U, @@ -257,7 +247,7 @@ pub fn set_bits_maybe_signed< set_bits(arr, range, U::cast_to_unsigned(bits)) } -fn check_range(range: &Range) { +fn check_range(range: &Range) { assert!(range.start <= range.end); assert!(range.end <= N * T::NUM_BITS); assert!(range.end - range.start <= U::NUM_BITS); @@ -284,9 +274,9 @@ mod test { } fn set_and_get< - T: BitfieldPrimitive, + T: UnsignedPrimInt, const N: usize, - U: BitfieldPrimitive + TryInto + TryFrom + fmt::Debug, + U: UnsignedPrimInt + TryInto + TryFrom + fmt::Debug, >( range: Range, val: U, diff --git a/crates/sel4/sys/src/ipc_buffer.rs b/crates/sel4/sys/src/ipc_buffer.rs index 8edeb2d07..01e563124 100644 --- a/crates/sel4/sys/src/ipc_buffer.rs +++ b/crates/sel4/sys/src/ipc_buffer.rs @@ -3,7 +3,7 @@ use core::ops::Range; use core::slice; use sel4_bitfield_types::{ - get_bits_maybe_signed, set_bits_maybe_signed, BitfieldPrimitiveMaybeSigned, + get_bits_maybe_signed, set_bits_maybe_signed, PrimInt, }; use crate::{seL4_CPtr, seL4_IPCBuffer, seL4_Word}; @@ -19,7 +19,7 @@ impl seL4_IPCBuffer { pub(crate) fn get_mr_bits(&self, range: Range) -> T where - T: BitfieldPrimitiveMaybeSigned, + T: PrimInt, T::Unsigned: TryFrom, { get_bits_maybe_signed(&self.msg, range) @@ -27,7 +27,7 @@ impl seL4_IPCBuffer { pub(crate) fn set_mr_bits(&mut self, range: Range, value: T) where - T: BitfieldPrimitiveMaybeSigned, + T: PrimInt, T::Unsigned: TryInto, { set_bits_maybe_signed(&mut self.msg, range, value) From 775c7a8f82c3de456fe2c3c03736a6d02a880a64 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 06:51:20 +0000 Subject: [PATCH 02/10] crates/sel4/bitfield-types: Operate on slices instead of arrays Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 25 +++++++++++-------------- crates/sel4/sys/src/ipc_buffer.rs | 4 +--- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index 6765ff2d7..8ee360733 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -161,11 +161,11 @@ mod prim_int_sealing { impl PrimIntSealed for i128 {} } -pub fn get_bits>( - arr: &[T; N], +pub fn get_bits>( + arr: &[T], range: Range, ) -> U { - check_range::(&range); + check_range::(arr, &range); let num_bits = range.end - range.start; let index_of_first_primitive = range.start / T::NUM_BITS; @@ -190,12 +190,12 @@ pub fn get_bits>( - arr: &mut [T; N], +pub fn set_bits>( + arr: &mut [T], range: Range, bits: U, ) { - check_range::(&range); + check_range::(arr, &range); let num_bits = range.end - range.start; @@ -227,18 +227,15 @@ pub fn set_bits( - arr: &[T; N], - range: Range, -) -> U +pub fn get_bits_maybe_signed(arr: &[T], range: Range) -> U where U::Unsigned: TryFrom, { U::cast_from_unsigned(get_bits(arr, range)) } -pub fn set_bits_maybe_signed( - arr: &mut [T; N], +pub fn set_bits_maybe_signed( + arr: &mut [T], range: Range, bits: U, ) where @@ -247,9 +244,9 @@ pub fn set_bits_maybe_signed( set_bits(arr, range, U::cast_to_unsigned(bits)) } -fn check_range(range: &Range) { +fn check_range(arr: &[T], range: &Range) { assert!(range.start <= range.end); - assert!(range.end <= N * T::NUM_BITS); + assert!(range.end <= arr.len() * T::NUM_BITS); assert!(range.end - range.start <= U::NUM_BITS); } diff --git a/crates/sel4/sys/src/ipc_buffer.rs b/crates/sel4/sys/src/ipc_buffer.rs index 01e563124..09cf12775 100644 --- a/crates/sel4/sys/src/ipc_buffer.rs +++ b/crates/sel4/sys/src/ipc_buffer.rs @@ -2,9 +2,7 @@ use core::mem; use core::ops::Range; use core::slice; -use sel4_bitfield_types::{ - get_bits_maybe_signed, set_bits_maybe_signed, PrimInt, -}; +use sel4_bitfield_types::{get_bits_maybe_signed, set_bits_maybe_signed, PrimInt}; use crate::{seL4_CPtr, seL4_IPCBuffer, seL4_Word}; From ad5629d25424ad4a3f09978a7db5ac3ad0179333 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 06:56:45 +0000 Subject: [PATCH 03/10] crates/sel4/bitfield-types: Add instances for {u,i}size Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index 8ee360733..7bbc9bdcc 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -88,6 +88,7 @@ impl UnsignedPrimInt for u16 {} impl UnsignedPrimInt for u32 {} impl UnsignedPrimInt for u64 {} impl UnsignedPrimInt for u128 {} +impl UnsignedPrimInt for usize {} use unsigned_prim_int_sealing::UnsignedPrimIntSealed; @@ -99,6 +100,7 @@ mod unsigned_prim_int_sealing { impl UnsignedPrimIntSealed for u32 {} impl UnsignedPrimIntSealed for u64 {} impl UnsignedPrimIntSealed for u128 {} + impl UnsignedPrimIntSealed for usize {} } pub trait PrimInt: PrimIntSealed { @@ -144,6 +146,7 @@ impl_prim_int!(i16, u16); impl_prim_int!(i32, u32); impl_prim_int!(i64, u64); impl_prim_int!(i128, u128); +impl_prim_int!(isize, usize); use prim_int_sealing::PrimIntSealed; @@ -159,6 +162,7 @@ mod prim_int_sealing { impl PrimIntSealed for i32 {} impl PrimIntSealed for i64 {} impl PrimIntSealed for i128 {} + impl PrimIntSealed for isize {} } pub fn get_bits>( From e87ab55daf86cdd7b566d4f2b6c76864db85426d Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 07:00:48 +0000 Subject: [PATCH 04/10] crates/sel4/bitfield-types: Improve parameter names Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index 7bbc9bdcc..33da9e693 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -166,17 +166,17 @@ mod prim_int_sealing { } pub fn get_bits>( - arr: &[T], - range: Range, + src: &[T], + src_range: Range, ) -> U { - check_range::(arr, &range); + check_range::(src, &src_range); - let num_bits = range.end - range.start; - let index_of_first_primitive = range.start / T::NUM_BITS; - let offset_into_first_primitive = range.start % T::NUM_BITS; + let num_bits = src_range.end - src_range.start; + let index_of_first_primitive = src_range.start / T::NUM_BITS; + let offset_into_first_primitive = src_range.start % T::NUM_BITS; let num_bits_from_first_primitive = (T::NUM_BITS - offset_into_first_primitive).min(num_bits); - let bits_from_first_primitive = (arr[index_of_first_primitive] >> offset_into_first_primitive) + let bits_from_first_primitive = (src[index_of_first_primitive] >> offset_into_first_primitive) .take(num_bits_from_first_primitive); let mut bits = checked_cast::(bits_from_first_primitive); @@ -185,7 +185,7 @@ pub fn get_bits>( while num_bits_so_far < num_bits { let num_bits_from_cur_primitive = (num_bits - num_bits_so_far).min(T::NUM_BITS); - let bits_from_cur_primitive = arr[index_of_cur_primitive].take(num_bits_from_cur_primitive); + let bits_from_cur_primitive = src[index_of_cur_primitive].take(num_bits_from_cur_primitive); bits |= checked_cast::(bits_from_cur_primitive) << num_bits_so_far; num_bits_so_far += num_bits_from_cur_primitive; index_of_cur_primitive += 1; @@ -195,22 +195,22 @@ pub fn get_bits>( } pub fn set_bits>( - arr: &mut [T], - range: Range, - bits: U, + dst: &mut [T], + dst_range: Range, + src: U, ) { - check_range::(arr, &range); + check_range::(dst, &dst_range); - let num_bits = range.end - range.start; + let num_bits = dst_range.end - dst_range.start; - assert!(num_bits == U::NUM_BITS || bits >> num_bits == U::zero()); + assert!(num_bits == U::NUM_BITS || src >> num_bits == U::zero()); - let index_of_first_primitive = range.start / T::NUM_BITS; - let offset_into_first_primitive = range.start % T::NUM_BITS; + let index_of_first_primitive = dst_range.start / T::NUM_BITS; + let offset_into_first_primitive = dst_range.start % T::NUM_BITS; let num_bits_for_first_primitive = (T::NUM_BITS - offset_into_first_primitive).min(num_bits); - let bits_for_first_primitive = bits.take(num_bits_for_first_primitive); + let bits_for_first_primitive = src.take(num_bits_for_first_primitive); - arr[index_of_first_primitive] = (arr[index_of_first_primitive] + dst[index_of_first_primitive] = (dst[index_of_first_primitive] & !T::mask( offset_into_first_primitive ..(offset_into_first_primitive + num_bits_for_first_primitive), @@ -222,8 +222,8 @@ pub fn set_bits>( while num_bits_so_far < num_bits { let num_bits_for_cur_primitive = (num_bits - num_bits_so_far).min(T::NUM_BITS); - let bits_for_cur_primitive = (bits >> num_bits_so_far).take(num_bits_for_cur_primitive); - arr[index_of_cur_primitive] = (arr[index_of_cur_primitive] + let bits_for_cur_primitive = (src >> num_bits_so_far).take(num_bits_for_cur_primitive); + dst[index_of_cur_primitive] = (dst[index_of_cur_primitive] & T::mask(num_bits_for_cur_primitive..T::NUM_BITS)) | checked_cast(bits_for_cur_primitive); num_bits_so_far += num_bits_for_cur_primitive; From 49a28b2628d08c8498469ef31ac6a72ead0e19eb Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 07:15:37 +0000 Subject: [PATCH 05/10] crates/sel4/bitfield-types: Add set_bits_from_slice Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index 33da9e693..2b030a0d1 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -231,6 +231,33 @@ pub fn set_bits>( } } +pub fn set_bits_from_slice( + dst: &mut [T], + dst_range: Range, + src: &[U], + src_start: usize, +) where + T: TryFrom, + usize: TryFrom, +{ + let num_bits = dst_range.len(); + + assert!(dst_range.start <= dst_range.end); + assert!(dst_range.end <= dst.len() * T::NUM_BITS); + assert!(src_start + num_bits <= src.len() * U::NUM_BITS); + + let mut cur_xfer_start = 0; + while cur_xfer_start < num_bits { + let cur_xfer_end = num_bits.min(cur_xfer_start + mem::size_of::()); + let cur_xfer_src_range = (src_start + cur_xfer_start)..(src_start + cur_xfer_end); + let cur_xfer_dst_range = + (dst_range.start + cur_xfer_start)..(dst_range.start + cur_xfer_end); + let xfer: usize = get_bits(src, cur_xfer_src_range); + set_bits(dst, cur_xfer_dst_range, xfer); + cur_xfer_start = cur_xfer_end; + } +} + pub fn get_bits_maybe_signed(arr: &[T], range: Range) -> U where U::Unsigned: TryFrom, From b4088ba9642e4ff3386313bec0483319fc720990 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 07:30:50 +0000 Subject: [PATCH 06/10] crates/sel4/bitfield-types: Clean up Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 217 ++++++++++++-------------- 1 file changed, 102 insertions(+), 115 deletions(-) diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index 2b030a0d1..c8caef60a 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -3,45 +3,6 @@ use core::mem; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not, Range, Shl, Shr}; -#[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) - } -} - pub trait UnsignedPrimInt: UnsignedPrimIntSealed + Copy @@ -55,52 +16,11 @@ pub trait UnsignedPrimInt: + Shr + Default // HACK for generic 0 { -} - -trait UnsignedPrimIntExt: UnsignedPrimInt { const NUM_BITS: usize = mem::size_of::() * 8; fn zero() -> Self { Default::default() } - - fn mask(range: Range) -> Self { - debug_assert!(range.start <= range.end); - debug_assert!(range.end <= Self::NUM_BITS); - let num_bits = range.end - range.start; - // avoid overflow - match num_bits { - 0 => Self::zero(), - _ if num_bits == Self::NUM_BITS => !Self::zero(), - _ => !(!Self::zero() << num_bits) << range.start, - } - } - - fn take(self, num_bits: usize) -> Self { - self & Self::mask(0..num_bits) - } -} - -impl UnsignedPrimIntExt for T {} - -impl UnsignedPrimInt for u8 {} -impl UnsignedPrimInt for u16 {} -impl UnsignedPrimInt for u32 {} -impl UnsignedPrimInt for u64 {} -impl UnsignedPrimInt for u128 {} -impl UnsignedPrimInt for usize {} - -use unsigned_prim_int_sealing::UnsignedPrimIntSealed; - -mod unsigned_prim_int_sealing { - pub trait UnsignedPrimIntSealed {} - - impl UnsignedPrimIntSealed for u8 {} - impl UnsignedPrimIntSealed for u16 {} - impl UnsignedPrimIntSealed for u32 {} - impl UnsignedPrimIntSealed for u64 {} - impl UnsignedPrimIntSealed for u128 {} - impl UnsignedPrimIntSealed for usize {} } pub trait PrimInt: PrimIntSealed { @@ -125,9 +45,21 @@ where } } +use sealing::{PrimIntSealed, UnsignedPrimIntSealed}; + +mod sealing { + pub trait UnsignedPrimIntSealed {} + + pub trait PrimIntSealed {} + + impl PrimIntSealed for T {} +} + macro_rules! impl_prim_int { - ($maybe_signed:ty, $unsigned:ty) => { - impl PrimInt for $maybe_signed { + ($unsigned:ty, $signed:ty) => { + impl UnsignedPrimInt for $unsigned {} + + impl PrimInt for $signed { type Unsigned = $unsigned; fn cast_from_unsigned(val: Self::Unsigned) -> Self { @@ -138,32 +70,43 @@ macro_rules! impl_prim_int { val as Self::Unsigned } } + + impl UnsignedPrimIntSealed for $unsigned {} + + impl PrimIntSealed for $signed {} }; } -impl_prim_int!(i8, u8); -impl_prim_int!(i16, u16); -impl_prim_int!(i32, u32); -impl_prim_int!(i64, u64); -impl_prim_int!(i128, u128); -impl_prim_int!(isize, usize); +impl_prim_int!(u8, i8); +impl_prim_int!(u16, i16); +impl_prim_int!(u32, i32); +impl_prim_int!(u64, i64); +impl_prim_int!(u128, i128); +impl_prim_int!(usize, isize); -use prim_int_sealing::PrimIntSealed; +// // // -mod prim_int_sealing { - use super::UnsignedPrimIntSealed; +trait UnsignedPrimIntExt: UnsignedPrimInt { + fn mask(range: Range) -> Self { + debug_assert!(range.start <= range.end); + debug_assert!(range.end <= Self::NUM_BITS); + let num_bits = range.end - range.start; + // avoid overflow + match num_bits { + 0 => Self::zero(), + _ if num_bits == Self::NUM_BITS => !Self::zero(), + _ => !(!Self::zero() << num_bits) << range.start, + } + } - pub trait PrimIntSealed {} + fn take(self, num_bits: usize) -> Self { + self & Self::mask(0..num_bits) + } +} - impl PrimIntSealed for T {} +impl UnsignedPrimIntExt for T {} - impl PrimIntSealed for i8 {} - impl PrimIntSealed for i16 {} - impl PrimIntSealed for i32 {} - impl PrimIntSealed for i64 {} - impl PrimIntSealed for i128 {} - impl PrimIntSealed for isize {} -} +// // // pub fn get_bits>( src: &[T], @@ -231,6 +174,16 @@ pub fn set_bits>( } } +fn check_range(arr: &[T], range: &Range) { + assert!(range.start <= range.end); + assert!(range.end <= arr.len() * T::NUM_BITS); + assert!(range.end - range.start <= U::NUM_BITS); +} + +fn checked_cast, U>(val: T) -> U { + val.try_into().map_err(|_| unreachable!()).unwrap() +} + pub fn set_bits_from_slice( dst: &mut [T], dst_range: Range, @@ -248,7 +201,7 @@ pub fn set_bits_from_slice( let mut cur_xfer_start = 0; while cur_xfer_start < num_bits { - let cur_xfer_end = num_bits.min(cur_xfer_start + mem::size_of::()); + let cur_xfer_end = num_bits.min(cur_xfer_start + usize::NUM_BITS); let cur_xfer_src_range = (src_start + cur_xfer_start)..(src_start + cur_xfer_end); let cur_xfer_dst_range = (dst_range.start + cur_xfer_start)..(dst_range.start + cur_xfer_end); @@ -258,33 +211,67 @@ pub fn set_bits_from_slice( } } -pub fn get_bits_maybe_signed(arr: &[T], range: Range) -> U +// // // + +pub fn get(src: &[T], src_start_bit: usize) -> U where U::Unsigned: TryFrom, { - U::cast_from_unsigned(get_bits(arr, range)) + let src_range = src_start_bit..(src_start_bit + U::Unsigned::NUM_BITS); + U::cast_from_unsigned(get_bits(src, src_range)) } -pub fn set_bits_maybe_signed( - arr: &mut [T], - range: Range, - bits: U, -) where +pub fn set(dst: &mut [T], dst_start_bit: usize, src: U) +where U::Unsigned: TryInto, { - set_bits(arr, range, U::cast_to_unsigned(bits)) + let dst_range = dst_start_bit..(dst_start_bit + U::Unsigned::NUM_BITS); + set_bits(dst, dst_range, U::cast_to_unsigned(src)) } -fn check_range(arr: &[T], range: &Range) { - assert!(range.start <= range.end); - assert!(range.end <= arr.len() * T::NUM_BITS); - assert!(range.end - range.start <= U::NUM_BITS); +// // // + +#[repr(C)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +pub struct Bitfield { + arr: [T; N], } -fn checked_cast, U>(val: T) -> U { - val.try_into().map_err(|_| unreachable!()).unwrap() +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) + } } +// // // + #[cfg(test)] mod test { #![allow(unused_imports)] From 99b70f35da73d862d495354e5c06034db21350f3 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 08:05:10 +0000 Subject: [PATCH 07/10] crates/sel4/bitfield-types: Move Bitfield type into sel4-sys Signed-off-by: Nick Spinale --- crates/sel4/bitfield-types/src/lib.rs | 41 -------------------- crates/sel4/sys/src/{bf.rs => bf/mod.rs} | 4 +- crates/sel4/sys/src/bf/types.rs | 42 +++++++++++++++++++++ crates/sel4/sys/src/ipc_buffer.rs | 6 +-- crates/sel4/sys/src/syscalls/helpers/mod.rs | 2 +- 5 files changed, 49 insertions(+), 46 deletions(-) rename crates/sel4/sys/src/{bf.rs => bf/mod.rs} (73%) create mode 100644 crates/sel4/sys/src/bf/types.rs diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-types/src/lib.rs index c8caef60a..e4fc6c4fa 100644 --- a/crates/sel4/bitfield-types/src/lib.rs +++ b/crates/sel4/bitfield-types/src/lib.rs @@ -231,47 +231,6 @@ where // // // -#[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) - } -} - -// // // - #[cfg(test)] mod test { #![allow(unused_imports)] diff --git a/crates/sel4/sys/src/bf.rs b/crates/sel4/sys/src/bf/mod.rs similarity index 73% rename from crates/sel4/sys/src/bf.rs rename to crates/sel4/sys/src/bf/mod.rs index 1c9e08188..bdc8bf272 100644 --- a/crates/sel4/sys/src/bf.rs +++ b/crates/sel4/sys/src/bf/mod.rs @@ -1,6 +1,8 @@ use core::fmt; -use sel4_bitfield_types::Bitfield; +pub(crate) mod types; + +use types::Bitfield; 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 new file mode 100644 index 000000000..306dd044e --- /dev/null +++ b/crates/sel4/sys/src/bf/types.rs @@ -0,0 +1,42 @@ +use core::ops::Range; + +use sel4_bitfield_types::{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/ipc_buffer.rs b/crates/sel4/sys/src/ipc_buffer.rs index 09cf12775..8ecf4e03e 100644 --- a/crates/sel4/sys/src/ipc_buffer.rs +++ b/crates/sel4/sys/src/ipc_buffer.rs @@ -2,7 +2,7 @@ use core::mem; use core::ops::Range; use core::slice; -use sel4_bitfield_types::{get_bits_maybe_signed, set_bits_maybe_signed, PrimInt}; +use sel4_bitfield_types::{get_bits, set_bits, PrimInt}; use crate::{seL4_CPtr, seL4_IPCBuffer, seL4_Word}; @@ -20,7 +20,7 @@ impl seL4_IPCBuffer { T: PrimInt, T::Unsigned: TryFrom, { - get_bits_maybe_signed(&self.msg, range) + T::cast_from_unsigned(get_bits(&self.msg, range)) } pub(crate) fn set_mr_bits(&mut self, range: Range, value: T) @@ -28,7 +28,7 @@ impl seL4_IPCBuffer { T: PrimInt, T::Unsigned: TryInto, { - set_bits_maybe_signed(&mut self.msg, range, value) + set_bits(&mut self.msg, range, T::cast_to_unsigned(value)) } pub(crate) fn msg_bytes_mut(&mut self) -> &'static mut [u8] { diff --git a/crates/sel4/sys/src/syscalls/helpers/mod.rs b/crates/sel4/sys/src/syscalls/helpers/mod.rs index 7b3fad444..f701f7596 100644 --- a/crates/sel4/sys/src/syscalls/helpers/mod.rs +++ b/crates/sel4/sys/src/syscalls/helpers/mod.rs @@ -1,4 +1,4 @@ -use sel4_bitfield_types::Bitfield; +use crate::bf::types::Bitfield; use crate::{seL4_MessageInfo, seL4_Word}; From 6f8ac12cc7019f6544a1f898ec3a6ba532fff640 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 08:20:53 +0000 Subject: [PATCH 08/10] Rename sel4-bitfield-types -> sel4-bitfield-ops Signed-off-by: Nick Spinale --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- .../sel4/{bitfield-types => bitfield-ops}/Cargo.toml | 2 +- .../sel4/{bitfield-types => bitfield-ops}/src/lib.rs | 0 crates/sel4/sys/Cargo.toml | 2 +- crates/sel4/sys/src/bf/types.rs | 2 +- crates/sel4/sys/src/ipc_buffer.rs | 2 +- .../crates/sel4/bitfield-ops/crate.nix | 5 +++++ .../crates/sel4/bitfield-types/crate.nix | 5 ----- .../cargo-manifest-sources/crates/sel4/sys/crate.nix | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) rename crates/sel4/{bitfield-types => bitfield-ops}/Cargo.toml (81%) rename crates/sel4/{bitfield-types => bitfield-ops}/src/lib.rs (100%) create mode 100644 hacking/cargo-manifest-sources/crates/sel4/bitfield-ops/crate.nix delete mode 100644 hacking/cargo-manifest-sources/crates/sel4/bitfield-types/crate.nix diff --git a/Cargo.lock b/Cargo.lock index b08aacc5b..711df63cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3610,6 +3610,10 @@ dependencies = [ "serde", ] +[[package]] +name = "sel4-bitfield-ops" +version = "0.1.0" + [[package]] name = "sel4-bitfield-parser" version = "0.1.0" @@ -3628,10 +3632,6 @@ dependencies = [ "sel4-bitfield-parser", ] -[[package]] -name = "sel4-bitfield-types" -version = "0.1.0" - [[package]] name = "sel4-bounce-buffer-allocator" version = "0.1.0" @@ -4203,8 +4203,8 @@ dependencies = [ "proc-macro2", "quote", "regex", + "sel4-bitfield-ops", "sel4-bitfield-parser", - "sel4-bitfield-types", "sel4-build-env", "sel4-config", "sel4-config-data", diff --git a/Cargo.toml b/Cargo.toml index ef60b5aca..7d092cc81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,9 +110,9 @@ members = [ "crates/sel4-shared-ring-buffer/block-io/types", "crates/sel4-shared-ring-buffer/smoltcp", "crates/sel4-sync", + "crates/sel4/bitfield-ops", "crates/sel4/bitfield-parser", "crates/sel4/bitfield-parser/test", - "crates/sel4/bitfield-types", "crates/sel4/build-env", "crates/sel4/config", "crates/sel4/config/data", diff --git a/crates/sel4/bitfield-types/Cargo.toml b/crates/sel4/bitfield-ops/Cargo.toml similarity index 81% rename from crates/sel4/bitfield-types/Cargo.toml rename to crates/sel4/bitfield-ops/Cargo.toml index f9cc4c007..0a2233e5c 100644 --- a/crates/sel4/bitfield-types/Cargo.toml +++ b/crates/sel4/bitfield-ops/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sel4-bitfield-types" +name = "sel4-bitfield-ops" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" diff --git a/crates/sel4/bitfield-types/src/lib.rs b/crates/sel4/bitfield-ops/src/lib.rs similarity index 100% rename from crates/sel4/bitfield-types/src/lib.rs rename to crates/sel4/bitfield-ops/src/lib.rs diff --git a/crates/sel4/sys/Cargo.toml b/crates/sel4/sys/Cargo.toml index 4882e9fb8..0ec0d2513 100644 --- a/crates/sel4/sys/Cargo.toml +++ b/crates/sel4/sys/Cargo.toml @@ -11,7 +11,7 @@ wrappers = [] [dependencies] log = "0.4.17" -sel4-bitfield-types = { path = "../bitfield-types" } +sel4-bitfield-ops = { path = "../bitfield-ops" } sel4-config = { path = "../config" } [build-dependencies] diff --git a/crates/sel4/sys/src/bf/types.rs b/crates/sel4/sys/src/bf/types.rs index 306dd044e..2a97c1c8d 100644 --- a/crates/sel4/sys/src/bf/types.rs +++ b/crates/sel4/sys/src/bf/types.rs @@ -1,6 +1,6 @@ use core::ops::Range; -use sel4_bitfield_types::{get_bits, set_bits, UnsignedPrimInt}; +use sel4_bitfield_ops::{get_bits, set_bits, UnsignedPrimInt}; #[repr(C)] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] diff --git a/crates/sel4/sys/src/ipc_buffer.rs b/crates/sel4/sys/src/ipc_buffer.rs index 8ecf4e03e..8e2eb69f1 100644 --- a/crates/sel4/sys/src/ipc_buffer.rs +++ b/crates/sel4/sys/src/ipc_buffer.rs @@ -2,7 +2,7 @@ use core::mem; use core::ops::Range; use core::slice; -use sel4_bitfield_types::{get_bits, set_bits, PrimInt}; +use sel4_bitfield_ops::{get_bits, set_bits, PrimInt}; use crate::{seL4_CPtr, seL4_IPCBuffer, seL4_Word}; diff --git a/hacking/cargo-manifest-sources/crates/sel4/bitfield-ops/crate.nix b/hacking/cargo-manifest-sources/crates/sel4/bitfield-ops/crate.nix new file mode 100644 index 000000000..0100bc7ab --- /dev/null +++ b/hacking/cargo-manifest-sources/crates/sel4/bitfield-ops/crate.nix @@ -0,0 +1,5 @@ +{ mk }: + +mk { + package.name = "sel4-bitfield-ops"; +} diff --git a/hacking/cargo-manifest-sources/crates/sel4/bitfield-types/crate.nix b/hacking/cargo-manifest-sources/crates/sel4/bitfield-types/crate.nix deleted file mode 100644 index 381bfe743..000000000 --- a/hacking/cargo-manifest-sources/crates/sel4/bitfield-types/crate.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ mk }: - -mk { - package.name = "sel4-bitfield-types"; -} diff --git a/hacking/cargo-manifest-sources/crates/sel4/sys/crate.nix b/hacking/cargo-manifest-sources/crates/sel4/sys/crate.nix index 4533ac1c7..36672bbff 100644 --- a/hacking/cargo-manifest-sources/crates/sel4/sys/crate.nix +++ b/hacking/cargo-manifest-sources/crates/sel4/sys/crate.nix @@ -20,7 +20,7 @@ mk { }; nix.local.dependencies = with localCrates; [ sel4-config - sel4-bitfield-types + sel4-bitfield-ops ]; nix.local.build-dependencies = with localCrates; [ sel4-build-env From 56955905cffa383f6e86cf0b2c4b60bb844afb54 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 08:25:02 +0000 Subject: [PATCH 09/10] crates/sel4/bitfield-ops: Re-introduce Bitfield type Signed-off-by: Nick Spinale --- 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 { From ad979bf046afd9baebdedde7a13be9860e0def09 Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 4 Oct 2023 09:29:09 +0000 Subject: [PATCH 10/10] crates/sel4/sys: Support multi-word bitfields in object invocations Signed-off-by: Nick Spinale --- crates/sel4/sys/build/xml/invocations/mod.rs | 2 +- crates/sel4/sys/src/ipc_buffer.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/sel4/sys/build/xml/invocations/mod.rs b/crates/sel4/sys/build/xml/invocations/mod.rs index df1dd518f..91113f436 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.inner()[0]); + self.set_mr_bits_from_slice(#start..#end, #name.0.inner()); }), ParameterType::Struct { members } => { assert!(self.parameter_types.get(¶m.ty).pass_by_reference()); diff --git a/crates/sel4/sys/src/ipc_buffer.rs b/crates/sel4/sys/src/ipc_buffer.rs index 8e2eb69f1..3569cfc72 100644 --- a/crates/sel4/sys/src/ipc_buffer.rs +++ b/crates/sel4/sys/src/ipc_buffer.rs @@ -2,7 +2,7 @@ use core::mem; use core::ops::Range; use core::slice; -use sel4_bitfield_ops::{get_bits, set_bits, PrimInt}; +use sel4_bitfield_ops::{get_bits, set_bits, set_bits_from_slice, PrimInt, UnsignedPrimInt}; use crate::{seL4_CPtr, seL4_IPCBuffer, seL4_Word}; @@ -31,6 +31,14 @@ impl seL4_IPCBuffer { set_bits(&mut self.msg, range, T::cast_to_unsigned(value)) } + pub(crate) fn set_mr_bits_from_slice(&mut self, range: Range, value: &[T]) + where + T: UnsignedPrimInt, + usize: TryFrom, + { + set_bits_from_slice(&mut self.msg, range, value, 0) + } + pub(crate) fn msg_bytes_mut(&mut self) -> &'static mut [u8] { let msg = &mut self.msg; unsafe {