1#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7pub enum UpdatePriority {
8 Low = 0,
9 High,
10}
11
12pub trait RegisterState<T> {
15 fn write(&self, priority: UpdatePriority, perms: &T, value: u64) -> u64;
20
21 fn set(&self, priority: UpdatePriority, perms: &T, value: u64);
26
27 fn read(&self, perms: &T) -> u64;
29
30 fn value(&self) -> u64;
32
33 fn reset_sync(&self);
38
39 fn reset_async(&self);
41}
42
43#[macro_export]
44macro_rules! build_register_state {
45 (
46 $(#[$($reg_attrs:tt)*])*
47 $reg:ident, $reg_num_bits:expr ;
48 $(
49 $(#[$($field_attrs:tt)*])*
50 $field:ident : $num_bits:expr, $reset:expr
51 ),+ $(,)*
52 ) => {
53 $crate::registers::paste! {
54 #[doc=concat!("Structure used to define the permissions of the ", stringify!($reg), " register.")]
55 pub struct [< $reg StatePerms >] {
56 $(
57 #[doc=concat!("Permissions for the value for the ", stringify!($field), " field.")]
58 pub $field: $crate::registers::Permission,
59 )+
60 }
61
62 #[derive(Clone)]
63 #[doc=concat!("The underlying state for the ", stringify!($reg), " register.")]
64 pub struct [< $reg State >] {
65 $(
66 $(#[$($field_attrs)*])*
67 #[doc=concat!("(", stringify!($num_bits), " bits, ", stringify!($reset), " at reset).")]
68 pub $field: $crate::registers::field::Field,
69 )+
70
71 #[doc=concat!("The value of the ", stringify!($reg), " register.")]
72 register_value: std::cell::RefCell<u64>,
73
74 #[doc=concat!("A bitmask of the existing bits in the ", stringify!($reg), " register.")]
75 existing_bits_mask: u64,
76
77 pending: std::cell::RefCell<Vec<(UpdatePriority, u64)>>,
78 }
79
80 $(#[$($reg_attrs)*])*
81 impl [< $reg State >] {
82 #[must_use] pub fn new() -> Self {
83 let start_bit = 0;
84 $(
85 let $field = $crate::registers::field::Field::new($num_bits, start_bit, $reset);
86 let start_bit = $field.last_bit() + 1;
87 )+
88 let mask = if start_bit >= $reg_num_bits { !0 } else { (1 << start_bit) - 1 };
89 let state = Self {
90 register_value: std::cell::RefCell::new(0),
91 $( $field, )+
92 existing_bits_mask: mask,
93 pending: std::cell::RefCell::new(Vec::new()),
94 };
95 state.reset_async();
96 state
97 }
98 }
99
100 impl RegisterState< [< $reg StatePerms >] > for [< $reg State >] {
101 fn write(&self, priority: $crate::registers::state::UpdatePriority, perms: &[< $reg StatePerms >], value: u64) -> u64 {
105 let mask = self.existing_bits_mask;
106 $(
107 let mask = self.$field.apply_write_permissions(mask, &perms.$field);
108 )+
109
110 let value = (*self.register_value.borrow() & !mask) | (value & mask);
111 self.pending.borrow_mut().push((priority, value));
112
113 value
114 }
115
116 fn set(&self, priority: $crate::registers::state::UpdatePriority, perms: &[< $reg StatePerms >], value: u64) {
117 let value = value & self.existing_bits_mask;
118 $(
119 let value = self.$field.apply_set_permissions(value, &perms.$field);
120 )+
121 self.pending.borrow_mut().push((priority, value));
122 }
123
124 fn read(&self, perms: &[< $reg StatePerms >]) -> u64 {
125 let value = *self.register_value.borrow();
126 $(
127 let value = self.$field.apply_read_permissions(value, &perms.$field);
128 )+
129 value
130 }
131
132 fn value(&self) -> u64 {
133 *self.register_value.borrow()
134 }
135
136 fn reset_sync(&self) {
137 let value = 0;
138 $(
139 let value = self.$field.apply_reset_value(value);
140 )+
141 self.pending.borrow_mut().push(($crate::registers::state::UpdatePriority::High, value));
142 }
143
144 fn reset_async(&self) {
145 let value = 0;
146 $(
147 let value = self.$field.apply_reset_value(value);
148 )+
149 *self.register_value.borrow_mut() = value;
150 }
151 }
152
153 impl Resolve for [< $reg State >] {
154 fn resolve(&self) {
155 if !self.pending.borrow().is_empty() {
157 *self.register_value.borrow_mut() = self.pending.borrow().iter().reduce(|max, x| x.max(max)).unwrap().1;
159 self.pending.borrow_mut().clear();
160 }
161 }
162 }
163
164 impl Default for [< $reg State >] {
165 fn default() -> Self {
166 Self::new()
167 }
168 }
169
170 }}
171}
172
173#[macro_export]
178macro_rules! array {
179 (@accum (0, $($_es:expr),*) -> ($($body:tt)*))
180 => {$crate::array!(@as_expr [$($body)*])};
181 (@accum (1, $($es:expr),*) -> ($($body:tt)*))
182 => {$crate::array!(@accum (0, $($es),*) -> ($($body)* $($es,)*))};
183 (@accum (2, $($es:expr),*) -> ($($body:tt)*))
184 => {$crate::array!(@accum (0, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
185 (@accum (3, $($es:expr),*) -> ($($body:tt)*))
186 => {$crate::array!(@accum (2, $($es),*) -> ($($body)* $($es,)*))};
187 (@accum (4, $($es:expr),*) -> ($($body:tt)*))
188 => {$crate::array!(@accum (2, $($es,)* $($es),*) -> ($($body)*))};
189 (@accum (5, $($es:expr),*) -> ($($body:tt)*))
190 => {$crate::array!(@accum (4, $($es),*) -> ($($body)* $($es,)*))};
191 (@accum (6, $($es:expr),*) -> ($($body:tt)*))
192 => {$crate::array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
193 (@accum (7, $($es:expr),*) -> ($($body:tt)*))
194 => {$crate::array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)* $($es,)*))};
195 (@accum (8, $($es:expr),*) -> ($($body:tt)*))
196 => {$crate::array!(@accum (4, $($es,)* $($es),*) -> ($($body)*))};
197
198 (@as_expr $e:expr) => {$e};
199
200 [$e:expr; $n:tt] => { $crate::array!(@accum ($n, $e) -> ()) };
201}
202
203#[macro_export]
204macro_rules! build_register_states {
205 (
206 $(#[$($rf_attrs:tt)*])*
207 $state_name:ident ;
208 $(
209 $state:ident, $num:expr
210 ),+ $(,)*
211 ) => {
212 $crate::registers::paste! {
213 $(#[$($rf_attrs)*])*
214 pub struct $state_name {
215 $( pub [< $state:lower >] : [ std::rc::Rc< [< $state State >] > ; $num ], )+
216 }
217
218 impl $state_name {
219 #[must_use] pub fn new() -> Self {
220 $(
221 let [< $state:lower >] = $crate::array![ std::rc::Rc::new([< $state State >]::new()) ; $num ];
222 )+
223 Self {
224 $( [< $state:lower >], )+
225 }
226 }
227 }
228
229 impl Default for $state_name {
230 fn default() -> Self {
231 Self::new()
232 }
233 }
234 }}
235}