bitfield.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // SPDX-License-Identifier: GPL-2.0
  2. //! Bitfield library for Rust structures
  3. //!
  4. //! Support for defining bitfields in Rust structures. Also used by the [`register!`] macro.
  5. /// Defines a struct with accessors to access bits within an inner unsigned integer.
  6. ///
  7. /// # Syntax
  8. ///
  9. /// ```rust
  10. /// use nova_core::bitfield;
  11. ///
  12. /// #[derive(Debug, Clone, Copy, Default)]
  13. /// enum Mode {
  14. /// #[default]
  15. /// Low = 0,
  16. /// High = 1,
  17. /// Auto = 2,
  18. /// }
  19. ///
  20. /// impl TryFrom<u8> for Mode {
  21. /// type Error = u8;
  22. /// fn try_from(value: u8) -> Result<Self, Self::Error> {
  23. /// match value {
  24. /// 0 => Ok(Mode::Low),
  25. /// 1 => Ok(Mode::High),
  26. /// 2 => Ok(Mode::Auto),
  27. /// _ => Err(value),
  28. /// }
  29. /// }
  30. /// }
  31. ///
  32. /// impl From<Mode> for u8 {
  33. /// fn from(mode: Mode) -> u8 {
  34. /// mode as u8
  35. /// }
  36. /// }
  37. ///
  38. /// #[derive(Debug, Clone, Copy, Default)]
  39. /// enum State {
  40. /// #[default]
  41. /// Inactive = 0,
  42. /// Active = 1,
  43. /// }
  44. ///
  45. /// impl From<bool> for State {
  46. /// fn from(value: bool) -> Self {
  47. /// if value { State::Active } else { State::Inactive }
  48. /// }
  49. /// }
  50. ///
  51. /// impl From<State> for bool {
  52. /// fn from(state: State) -> bool {
  53. /// match state {
  54. /// State::Inactive => false,
  55. /// State::Active => true,
  56. /// }
  57. /// }
  58. /// }
  59. ///
  60. /// bitfield! {
  61. /// pub struct ControlReg(u32) {
  62. /// 7:7 state as bool => State;
  63. /// 3:0 mode as u8 ?=> Mode;
  64. /// }
  65. /// }
  66. /// ```
  67. ///
  68. /// This generates a struct with:
  69. /// - Field accessors: `mode()`, `state()`, etc.
  70. /// - Field setters: `set_mode()`, `set_state()`, etc. (supports chaining with builder pattern).
  71. /// Note that the compiler will error out if the size of the setter's arg exceeds the
  72. /// struct's storage size.
  73. /// - Debug and Default implementations.
  74. ///
  75. /// Note: Field accessors and setters inherit the same visibility as the struct itself.
  76. /// In the example above, both `mode()` and `set_mode()` methods will be `pub`.
  77. ///
  78. /// Fields are defined as follows:
  79. ///
  80. /// - `as <type>` simply returns the field value casted to <type>, typically `u32`, `u16`, `u8` or
  81. /// `bool`. Note that `bool` fields must have a range of 1 bit.
  82. /// - `as <type> => <into_type>` calls `<into_type>`'s `From::<<type>>` implementation and returns
  83. /// the result.
  84. /// - `as <type> ?=> <try_into_type>` calls `<try_into_type>`'s `TryFrom::<<type>>` implementation
  85. /// and returns the result. This is useful with fields for which not all values are valid.
  86. macro_rules! bitfield {
  87. // Main entry point - defines the bitfield struct with fields
  88. ($vis:vis struct $name:ident($storage:ty) $(, $comment:literal)? { $($fields:tt)* }) => {
  89. bitfield!(@core $vis $name $storage $(, $comment)? { $($fields)* });
  90. };
  91. // All rules below are helpers.
  92. // Defines the wrapper `$name` type, as well as its relevant implementations (`Debug`,
  93. // `Default`, and conversion to the value type) and field accessor methods.
  94. (@core $vis:vis $name:ident $storage:ty $(, $comment:literal)? { $($fields:tt)* }) => {
  95. $(
  96. #[doc=$comment]
  97. )?
  98. #[repr(transparent)]
  99. #[derive(Clone, Copy)]
  100. $vis struct $name($storage);
  101. impl ::core::convert::From<$name> for $storage {
  102. fn from(val: $name) -> $storage {
  103. val.0
  104. }
  105. }
  106. bitfield!(@fields_dispatcher $vis $name $storage { $($fields)* });
  107. };
  108. // Captures the fields and passes them to all the implementers that require field information.
  109. //
  110. // Used to simplify the matching rules for implementers, so they don't need to match the entire
  111. // complex fields rule even though they only make use of part of it.
  112. (@fields_dispatcher $vis:vis $name:ident $storage:ty {
  113. $($hi:tt:$lo:tt $field:ident as $type:tt
  114. $(?=> $try_into_type:ty)?
  115. $(=> $into_type:ty)?
  116. $(, $comment:literal)?
  117. ;
  118. )*
  119. }
  120. ) => {
  121. bitfield!(@field_accessors $vis $name $storage {
  122. $(
  123. $hi:$lo $field as $type
  124. $(?=> $try_into_type)?
  125. $(=> $into_type)?
  126. $(, $comment)?
  127. ;
  128. )*
  129. });
  130. bitfield!(@debug $name { $($field;)* });
  131. bitfield!(@default $name { $($field;)* });
  132. };
  133. // Defines all the field getter/setter methods for `$name`.
  134. (
  135. @field_accessors $vis:vis $name:ident $storage:ty {
  136. $($hi:tt:$lo:tt $field:ident as $type:tt
  137. $(?=> $try_into_type:ty)?
  138. $(=> $into_type:ty)?
  139. $(, $comment:literal)?
  140. ;
  141. )*
  142. }
  143. ) => {
  144. $(
  145. bitfield!(@check_field_bounds $hi:$lo $field as $type);
  146. )*
  147. #[allow(dead_code)]
  148. impl $name {
  149. $(
  150. bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as $type
  151. $(?=> $try_into_type)?
  152. $(=> $into_type)?
  153. $(, $comment)?
  154. ;
  155. );
  156. )*
  157. }
  158. };
  159. // Boolean fields must have `$hi == $lo`.
  160. (@check_field_bounds $hi:tt:$lo:tt $field:ident as bool) => {
  161. #[allow(clippy::eq_op)]
  162. const _: () = {
  163. ::kernel::build_assert!(
  164. $hi == $lo,
  165. concat!("boolean field `", stringify!($field), "` covers more than one bit")
  166. );
  167. };
  168. };
  169. // Non-boolean fields must have `$hi >= $lo`.
  170. (@check_field_bounds $hi:tt:$lo:tt $field:ident as $type:tt) => {
  171. #[allow(clippy::eq_op)]
  172. const _: () = {
  173. ::kernel::build_assert!(
  174. $hi >= $lo,
  175. concat!("field `", stringify!($field), "`'s MSB is smaller than its LSB")
  176. );
  177. };
  178. };
  179. // Catches fields defined as `bool` and convert them into a boolean value.
  180. (
  181. @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as bool
  182. => $into_type:ty $(, $comment:literal)?;
  183. ) => {
  184. bitfield!(
  185. @leaf_accessor $vis $name $storage, $hi:$lo $field
  186. { |f| <$into_type>::from(f != 0) }
  187. bool $into_type => $into_type $(, $comment)?;
  188. );
  189. };
  190. // Shortcut for fields defined as `bool` without the `=>` syntax.
  191. (
  192. @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as bool
  193. $(, $comment:literal)?;
  194. ) => {
  195. bitfield!(
  196. @field_accessor $vis $name $storage, $hi:$lo $field as bool => bool $(, $comment)?;
  197. );
  198. };
  199. // Catches the `?=>` syntax for non-boolean fields.
  200. (
  201. @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as $type:tt
  202. ?=> $try_into_type:ty $(, $comment:literal)?;
  203. ) => {
  204. bitfield!(@leaf_accessor $vis $name $storage, $hi:$lo $field
  205. { |f| <$try_into_type>::try_from(f as $type) } $type $try_into_type =>
  206. ::core::result::Result<
  207. $try_into_type,
  208. <$try_into_type as ::core::convert::TryFrom<$type>>::Error
  209. >
  210. $(, $comment)?;);
  211. };
  212. // Catches the `=>` syntax for non-boolean fields.
  213. (
  214. @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as $type:tt
  215. => $into_type:ty $(, $comment:literal)?;
  216. ) => {
  217. bitfield!(@leaf_accessor $vis $name $storage, $hi:$lo $field
  218. { |f| <$into_type>::from(f as $type) } $type $into_type => $into_type $(, $comment)?;);
  219. };
  220. // Shortcut for non-boolean fields defined without the `=>` or `?=>` syntax.
  221. (
  222. @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as $type:tt
  223. $(, $comment:literal)?;
  224. ) => {
  225. bitfield!(
  226. @field_accessor $vis $name $storage, $hi:$lo $field as $type => $type $(, $comment)?;
  227. );
  228. };
  229. // Generates the accessor methods for a single field.
  230. (
  231. @leaf_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident
  232. { $process:expr } $prim_type:tt $to_type:ty => $res_type:ty $(, $comment:literal)?;
  233. ) => {
  234. ::kernel::macros::paste!(
  235. const [<$field:upper _RANGE>]: ::core::ops::RangeInclusive<u8> = $lo..=$hi;
  236. const [<$field:upper _MASK>]: $storage = {
  237. // Generate mask for shifting
  238. match ::core::mem::size_of::<$storage>() {
  239. 1 => ::kernel::bits::genmask_u8($lo..=$hi) as $storage,
  240. 2 => ::kernel::bits::genmask_u16($lo..=$hi) as $storage,
  241. 4 => ::kernel::bits::genmask_u32($lo..=$hi) as $storage,
  242. 8 => ::kernel::bits::genmask_u64($lo..=$hi) as $storage,
  243. _ => ::kernel::build_error!("Unsupported storage type size")
  244. }
  245. };
  246. const [<$field:upper _SHIFT>]: u32 = $lo;
  247. );
  248. $(
  249. #[doc="Returns the value of this field:"]
  250. #[doc=$comment]
  251. )?
  252. #[inline(always)]
  253. $vis fn $field(self) -> $res_type {
  254. ::kernel::macros::paste!(
  255. const MASK: $storage = $name::[<$field:upper _MASK>];
  256. const SHIFT: u32 = $name::[<$field:upper _SHIFT>];
  257. );
  258. let field = ((self.0 & MASK) >> SHIFT);
  259. $process(field)
  260. }
  261. ::kernel::macros::paste!(
  262. $(
  263. #[doc="Sets the value of this field:"]
  264. #[doc=$comment]
  265. )?
  266. #[inline(always)]
  267. $vis fn [<set_ $field>](mut self, value: $to_type) -> Self {
  268. const MASK: $storage = $name::[<$field:upper _MASK>];
  269. const SHIFT: u32 = $name::[<$field:upper _SHIFT>];
  270. let value = ($storage::from($prim_type::from(value)) << SHIFT) & MASK;
  271. self.0 = (self.0 & !MASK) | value;
  272. self
  273. }
  274. );
  275. };
  276. // Generates the `Debug` implementation for `$name`.
  277. (@debug $name:ident { $($field:ident;)* }) => {
  278. impl ::kernel::fmt::Debug for $name {
  279. fn fmt(&self, f: &mut ::kernel::fmt::Formatter<'_>) -> ::kernel::fmt::Result {
  280. f.debug_struct(stringify!($name))
  281. .field("<raw>", &::kernel::prelude::fmt!("{:#x}", &self.0))
  282. $(
  283. .field(stringify!($field), &self.$field())
  284. )*
  285. .finish()
  286. }
  287. }
  288. };
  289. // Generates the `Default` implementation for `$name`.
  290. (@default $name:ident { $($field:ident;)* }) => {
  291. /// Returns a value for the bitfield where all fields are set to their default value.
  292. impl ::core::default::Default for $name {
  293. fn default() -> Self {
  294. #[allow(unused_mut)]
  295. let mut value = Self(Default::default());
  296. ::kernel::macros::paste!(
  297. $(
  298. value.[<set_ $field>](Default::default());
  299. )*
  300. );
  301. value
  302. }
  303. }
  304. };
  305. }