1use std::boxed::Box;
6use std::cmp::max;
7use std::cmp::min;
8use std::cmp::Ord;
9use std::cmp::Ordering;
10use std::cmp::PartialOrd;
11use std::mem::size_of;
12use std::sync::Arc;
13use std::sync::MutexGuard;
14
15use base::error;
16use sync::Mutex;
17use zerocopy::FromBytes;
18use zerocopy::IntoBytes;
19
20pub type RegisterOffset = u64;
22
23#[derive(Debug, Eq, PartialEq, Copy, Clone)]
26pub struct RegisterRange {
27 pub from: RegisterOffset,
28 pub to: RegisterOffset,
29}
30
31impl Ord for RegisterRange {
32 fn cmp(&self, other: &RegisterRange) -> Ordering {
33 self.from.cmp(&other.from)
34 }
35}
36
37impl PartialOrd for RegisterRange {
38 fn partial_cmp(&self, other: &RegisterRange) -> Option<Ordering> {
39 Some(self.cmp(other))
40 }
41}
42
43impl RegisterRange {
44 pub fn overlap_with(&self, other: &RegisterRange) -> bool {
46 !(self.from > other.to || self.to < other.from)
47 }
48
49 pub fn overlap_range(&self, other: &RegisterRange) -> Option<RegisterRange> {
53 if !self.overlap_with(other) {
54 return None;
55 }
56 Some(RegisterRange {
57 from: max(self.from, other.from),
58 to: min(self.to, other.to),
59 })
60 }
61}
62
63pub trait RegisterValue:
65 'static
66 + Into<u64>
67 + Clone
68 + FromBytes
69 + IntoBytes
70 + Send
71 + Sync
72 + Copy
73 + std::ops::BitOr<Self, Output = Self>
74 + std::ops::BitAnd<Self, Output = Self>
75 + std::ops::Not<Output = Self>
76 + std::fmt::LowerHex
77{
78 fn get_byte(&self, offset: usize) -> u8 {
80 let val: u64 = (*self).into();
81 (val >> (offset * 8)) as u8
82 }
83 fn set_bits(&mut self, mask: Self) {
85 *self = *self | mask;
86 }
87 fn clear_bits(&mut self, mask: Self) {
89 *self = *self & (!mask);
90 }
91}
92impl RegisterValue for u8 {}
93impl RegisterValue for u16 {}
94impl RegisterValue for u32 {}
95impl RegisterValue for u64 {}
96
97fn read_reg_helper<T: RegisterValue>(
100 val: T,
101 val_range: RegisterRange,
102 addr: RegisterOffset,
103 data: &mut [u8],
104) {
105 let read_range = RegisterRange {
106 from: addr,
107 to: addr + data.len() as u64 - 1,
108 };
109
110 let overlap = match val_range.overlap_range(&read_range) {
111 Some(overlap) => overlap,
112 None => {
113 error!("calling read_reg_helper with non overlapping range. mmio_register might have a bug");
114 return;
115 }
116 };
117 let val_start_idx = (overlap.from - val_range.from) as usize;
118 let read_start_idx = (overlap.from - read_range.from) as usize;
119 let total_size = (overlap.to - overlap.from) as usize + 1;
120 for i in 0..total_size {
121 data[read_start_idx + i] = val.get_byte(val_start_idx + i);
122 }
123}
124
125pub trait RegisterInterface: Send {
127 fn range(&self) -> RegisterRange;
129 fn read(&self, addr: RegisterOffset, data: &mut [u8]);
131 fn write(&self, _addr: RegisterOffset, _data: &[u8]) {}
133 #[allow(dead_code)]
135 fn reset(&self) {}
136}
137
138pub struct StaticRegisterSpec<T: RegisterValue> {
141 pub offset: RegisterOffset,
142 pub value: T,
143}
144
145#[derive(Clone)]
148pub struct StaticRegister<T>
149where
150 T: RegisterValue,
151{
152 spec: &'static StaticRegisterSpec<T>,
153}
154
155impl<T> StaticRegister<T>
156where
157 T: RegisterValue,
158{
159 pub fn new(spec: &'static StaticRegisterSpec<T>) -> StaticRegister<T> {
161 StaticRegister { spec }
162 }
163}
164
165impl<T> RegisterInterface for StaticRegister<T>
166where
167 T: RegisterValue,
168{
169 fn range(&self) -> RegisterRange {
170 RegisterRange {
171 from: self.spec.offset,
172 to: self.spec.offset + (size_of::<T>() as u64) - 1,
173 }
174 }
175
176 fn read(&self, addr: RegisterOffset, data: &mut [u8]) {
177 let val_range = self.range();
178 read_reg_helper(self.spec.value, val_range, addr, data);
179 }
180}
181
182#[macro_export]
184macro_rules! static_register {
185 (ty: $ty:ty,offset: $offset:expr,value: $value:expr,) => {{
186 use $crate::register_space::*;
187 static REG_SPEC: StaticRegisterSpec<$ty> = StaticRegisterSpec::<$ty> {
188 offset: $offset,
189 value: $value,
190 };
191 StaticRegister::new(®_SPEC)
192 }};
193}
194
195pub struct RegisterSpec<T> {
198 pub name: String,
199 pub offset: RegisterOffset,
200 pub reset_value: T,
201 pub guest_writeable_mask: T,
203 pub guest_write_1_to_clear_mask: T,
206}
207
208struct RegisterInner<T: RegisterValue> {
209 spec: RegisterSpec<T>,
210 value: T,
211 pending_value: Option<T>,
212 write_cb: Option<Box<dyn Fn(T) -> T + Send>>,
213}
214
215impl<T: RegisterValue> RegisterInner<T> {
216 fn value(&self) -> T {
217 self.value
218 }
219
220 fn pending_value(&self) -> T {
221 match self.pending_value {
222 Some(pending_value) => pending_value,
223 None => self.value,
224 }
225 }
226
227 fn set(&mut self, value: T) {
228 self.pending_value = Some(value);
229 }
230
231 fn commit(&mut self) {
232 if let Some(value) = self.pending_value {
233 self.value = value;
234 self.pending_value = None;
235 }
236 }
237
238 fn set_and_commit(&mut self, value: T) {
239 self.set(value);
240 self.commit();
241 }
242}
243
244#[derive(Clone)]
246pub struct Register<T: RegisterValue> {
247 inner: Arc<Mutex<RegisterInner<T>>>,
248}
249
250impl<T: RegisterValue> Register<T> {
251 pub fn new(spec: RegisterSpec<T>, val: T) -> Self {
252 Register {
253 inner: Arc::new(Mutex::new(RegisterInner {
254 spec,
255 value: val,
256 pending_value: None,
257 write_cb: None,
258 })),
259 }
260 }
261
262 fn lock(&self) -> MutexGuard<RegisterInner<T>> {
263 self.inner.lock()
264 }
265}
266
267impl<T: RegisterValue> RegisterInterface for Register<T> {
269 fn range(&self) -> RegisterRange {
270 let locked = self.lock();
271 let spec = &locked.spec;
272 RegisterRange {
273 from: spec.offset,
274 to: spec.offset + (size_of::<T>() as u64) - 1,
275 }
276 }
277
278 fn read(&self, addr: RegisterOffset, data: &mut [u8]) {
279 let val_range = self.range();
280 let value = self.lock().value();
281 read_reg_helper(value, val_range, addr, data);
282 }
283
284 fn write(&self, addr: RegisterOffset, data: &[u8]) {
285 let my_range = self.range();
286 let write_range = RegisterRange {
287 from: addr,
288 to: addr + data.len() as u64 - 1,
289 };
290
291 let overlap = match my_range.overlap_range(&write_range) {
292 Some(range) => range,
293 None => {
294 error!("write should not be invoked on this register");
295 return;
296 }
297 };
298 let my_start_idx = (overlap.from - my_range.from) as usize;
299 let write_start_idx = (overlap.from - write_range.from) as usize;
300 let total_size = (overlap.to - overlap.from) as usize + 1;
301
302 let mut reg_value: T = self.lock().pending_value();
303 let value: &mut [u8] = reg_value.as_mut_bytes();
304 for i in 0..total_size {
305 value[my_start_idx + i] = self.apply_write_masks_to_byte(
306 value[my_start_idx + i],
307 data[write_start_idx + i],
308 my_start_idx + i,
309 );
310 }
311
312 if my_range.to != overlap.to {
315 self.lock().set(reg_value);
318 return;
319 }
320
321 let cb = {
325 let mut inner = self.lock();
326 match inner.write_cb.take() {
327 Some(cb) => cb,
328 None => {
329 inner.set_and_commit(reg_value);
331 return;
332 }
333 }
334 };
335 let value = cb(reg_value);
337 let mut inner = self.lock();
338 inner.set_and_commit(value);
339 inner.write_cb = Some(cb);
340 }
341
342 fn reset(&self) {
343 let mut locked = self.lock();
344 let reset_value = locked.spec.reset_value;
345 locked.set_and_commit(reset_value);
346 }
347}
348
349impl<T: RegisterValue> Register<T> {
350 pub fn get_value(&self) -> T {
352 self.lock().value
353 }
354
355 pub fn apply_write_masks_to_byte(&self, old_byte: u8, write_byte: u8, offset: usize) -> u8 {
359 let locked = self.lock();
360 let spec = &locked.spec;
361 let guest_write_1_to_clear_mask: u64 = spec.guest_write_1_to_clear_mask.into();
362 let guest_writeable_mask: u64 = spec.guest_writeable_mask.into();
363 let w1c_mask = (guest_write_1_to_clear_mask >> (offset * 8)) as u8;
365 let val = (!w1c_mask & write_byte) | (w1c_mask & old_byte & !write_byte);
366 let w_mask = (guest_writeable_mask >> (offset * 8)) as u8;
368 (old_byte & (!w_mask)) | (val & w_mask)
369 }
370
371 pub fn set_write_cb<C: 'static + Fn(T) -> T + Send>(&self, callback: C) {
373 self.lock().write_cb = Some(Box::new(callback));
374 }
375
376 pub fn set_value(&self, val: T) {
378 self.lock().value = val;
379 }
380
381 pub fn set_bits(&self, mask: T) {
383 self.lock().value.set_bits(mask);
384 }
385
386 pub fn clear_bits(&self, mask: T) {
388 self.lock().value.clear_bits(mask);
389 }
390}
391
392#[macro_export]
393macro_rules! register {
394 (
395 name: $name:tt,
396 ty: $ty:ty,
397 offset: $offset:expr,
398 reset_value: $rv:expr,
399 guest_writeable_mask: $mask:expr,
400 guest_write_1_to_clear_mask: $w1tcm:expr,
401 ) => {{
402 use $crate::register_space::*;
403 let spec: RegisterSpec<$ty> = RegisterSpec::<$ty> {
404 name: String::from($name),
405 offset: $offset,
406 reset_value: $rv,
407 guest_writeable_mask: $mask,
408 guest_write_1_to_clear_mask: $w1tcm,
409 };
410 Register::<$ty>::new(spec, $rv)
411 }};
412 (name: $name:tt, ty: $ty:ty,offset: $offset:expr,reset_value: $rv:expr,) => {{
413 use $crate::register_space::*;
414 let spec: RegisterSpec<$ty> = RegisterSpec::<$ty> {
415 name: String::from($name),
416 offset: $offset,
417 reset_value: $rv,
418 guest_writeable_mask: !0,
419 guest_write_1_to_clear_mask: 0,
420 };
421 Register::<$ty>::new(spec, $rv)
422 }};
423}
424
425#[macro_export]
426macro_rules! register_array {
427 (
428 name: $name:tt,
429 ty:
430 $ty:ty,cnt:
431 $cnt:expr,base_offset:
432 $base_offset:expr,stride:
433 $stride:expr,reset_value:
434 $rv:expr,guest_writeable_mask:
435 $gwm:expr,guest_write_1_to_clear_mask:
436 $gw1tcm:expr,
437 ) => {{
438 use $crate::register_space::*;
439 let mut v: Vec<Register<$ty>> = Vec::new();
440 for i in 0..$cnt {
441 let offset = $base_offset + ($stride * i) as RegisterOffset;
442 let spec: RegisterSpec<$ty> = RegisterSpec::<$ty> {
443 name: format!("{}-{}", $name, i),
444 offset,
445 reset_value: $rv,
446 guest_writeable_mask: $gwm,
447 guest_write_1_to_clear_mask: $gw1tcm,
448 };
449 v.push(Register::<$ty>::new(spec, $rv));
450 }
451 v
452 }};
453}
454
455#[cfg(test)]
456mod tests {
457 use super::*;
458
459 static REG_SPEC0: StaticRegisterSpec<u8> = StaticRegisterSpec::<u8> {
460 offset: 3,
461 value: 32,
462 };
463
464 static REG_SPEC1: StaticRegisterSpec<u16> = StaticRegisterSpec::<u16> {
465 offset: 3,
466 value: 32,
467 };
468
469 #[test]
470 fn static_register_basic_test_u8() {
471 let r = StaticRegister::<u8> { spec: ®_SPEC0 };
472 let mut data: [u8; 4] = [0, 0, 0, 0];
473 assert_eq!(r.range().from, 3);
474 assert_eq!(r.range().to, 3);
475 r.read(0, &mut data);
476 assert_eq!(data, [0, 0, 0, 32]);
477 r.read(2, &mut data);
478 assert_eq!(data, [0, 32, 0, 32]);
479 }
480
481 #[test]
482 fn static_register_basic_test_u16() {
483 let r = StaticRegister::<u16> { spec: ®_SPEC1 };
484 let mut data: [u8; 4] = [0, 0, 0, 0];
485 assert_eq!(r.range().from, 3);
486 assert_eq!(r.range().to, 4);
487 r.read(0, &mut data);
488 assert_eq!(data, [0, 0, 0, 32]);
489 r.read(2, &mut data);
490 assert_eq!(data, [0, 32, 0, 32]);
491 }
492
493 #[test]
494 fn static_register_interface_test() {
495 let r: Box<dyn RegisterInterface> = Box::new(static_register! {
496 ty: u8,
497 offset: 3,
498 value: 32,
499 });
500 let mut data: [u8; 4] = [0, 0, 0, 0];
501 assert_eq!(r.range().from, 3);
502 assert_eq!(r.range().to, 3);
503 r.read(0, &mut data);
504 assert_eq!(data, [0, 0, 0, 32]);
505 r.read(2, &mut data);
506 assert_eq!(data, [0, 32, 0, 32]);
507 }
508
509 #[test]
510 fn register_basic_rw_test() {
511 let r = register! {
512 name: "",
513 ty: u8,
514 offset: 3,
515 reset_value: 0xf1,
516 guest_writeable_mask: 0xff,
517 guest_write_1_to_clear_mask: 0x0,
518 };
519 let mut data: [u8; 4] = [0, 0, 0, 0];
520 assert_eq!(r.range().from, 3);
521 assert_eq!(r.range().to, 3);
522 r.read(0, &mut data);
523 assert_eq!(data, [0, 0, 0, 0xf1]);
524 r.read(2, &mut data);
525 assert_eq!(data, [0, 0xf1, 0, 0xf1]);
526 data = [0, 0, 0, 0xab];
527 r.write(0, &data);
528 assert_eq!(r.get_value(), 0xab);
529 r.reset();
530 assert_eq!(r.get_value(), 0xf1);
531 r.set_value(0xcc);
532 assert_eq!(r.get_value(), 0xcc);
533 }
534
535 #[test]
536 fn register_basic_writeable_mask_test() {
537 let r = register! {
538 name: "",
539 ty: u8,
540 offset: 3,
541 reset_value: 0x0,
542 guest_writeable_mask: 0xf,
543 guest_write_1_to_clear_mask: 0x0,
544 };
545 let mut data: [u8; 4] = [0, 0, 0, 0];
546 assert_eq!(r.range().from, 3);
547 assert_eq!(r.range().to, 3);
548 r.read(0, &mut data);
549 assert_eq!(data, [0, 0, 0, 0]);
550 data = [0, 0, 0, 0xab];
551 r.write(0, &data);
552 assert_eq!(r.get_value(), 0x0b);
553 r.reset();
554 assert_eq!(r.get_value(), 0x0);
555 r.set_value(0xcc);
556 assert_eq!(r.get_value(), 0xcc);
557 }
558
559 #[test]
560 fn register_basic_write_1_to_clear_mask_test() {
561 let r = register! {
562 name: "",
563 ty: u8,
564 offset: 3,
565 reset_value: 0xf1,
566 guest_writeable_mask: 0xff,
567 guest_write_1_to_clear_mask: 0xf0,
568 };
569 let mut data: [u8; 4] = [0, 0, 0, 0];
570 assert_eq!(r.range().from, 3);
571 assert_eq!(r.range().to, 3);
572 r.read(0, &mut data);
573 assert_eq!(data, [0, 0, 0, 0xf1]);
574 data = [0, 0, 0, 0xfa];
575 r.write(0, &data);
576 assert_eq!(r.get_value(), 0x0a);
577 r.reset();
578 assert_eq!(r.get_value(), 0xf1);
579 r.set_value(0xcc);
580 assert_eq!(r.get_value(), 0xcc);
581 }
582
583 #[test]
584 fn register_basic_write_1_to_clear_mask_test_u32() {
585 let r = register! {
586 name: "",
587 ty: u32,
588 offset: 0,
589 reset_value: 0xfff1,
590 guest_writeable_mask: 0xff,
591 guest_write_1_to_clear_mask: 0xf0,
592 };
593 let mut data: [u8; 4] = [0, 0, 0, 0];
594 assert_eq!(r.range().from, 0);
595 assert_eq!(r.range().to, 3);
596 r.read(0, &mut data);
597 assert_eq!(data, [0xf1, 0xff, 0, 0]);
598 data = [0xfa, 0, 0, 0];
599 r.write(0, &data);
600 assert_eq!(r.get_value(), 0xff0a);
601 r.reset();
602 assert_eq!(r.get_value(), 0xfff1);
603 r.set_value(0xcc);
604 assert_eq!(r.get_value(), 0xcc);
605 }
606
607 #[test]
608 fn register_callback_test() {
609 let state = Arc::new(Mutex::new(0u8));
610 let r = register! {
611 name: "",
612 ty: u8,
613 offset: 3,
614 reset_value: 0xf1,
615 guest_writeable_mask: 0xff,
616 guest_write_1_to_clear_mask: 0xf0,
617 };
618
619 let s2 = state.clone();
620 r.set_write_cb(move |val: u8| {
621 *s2.lock() = val;
622 val
623 });
624 let data: [u8; 4] = [0, 0, 0, 0xff];
625 r.write(0, &data);
626 assert_eq!(*state.lock(), 0xf);
627 r.set_value(0xab);
628 assert_eq!(*state.lock(), 0xf);
629 let data: [u8; 1] = [0xfc];
630 r.write(3, &data);
631 assert_eq!(*state.lock(), 0xc);
632 }
633}