• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::boxed::Box;
6 use std::cmp::{max, min, Ord, Ordering, PartialOrd};
7 use std::mem::size_of;
8 use std::sync::{Arc, MutexGuard};
9 use sync::Mutex;
10 
11 use base::error;
12 use data_model::DataInit;
13 
14 /// Type of offset in the register space.
15 pub type RegisterOffset = u64;
16 
17 /// This represents a range of memory in the register space starting.
18 /// Both from and to are inclusive.
19 #[derive(Debug, Eq, PartialEq, Copy, Clone)]
20 pub struct RegisterRange {
21     pub from: RegisterOffset,
22     pub to: RegisterOffset,
23 }
24 
25 impl Ord for RegisterRange {
cmp(&self, other: &RegisterRange) -> Ordering26     fn cmp(&self, other: &RegisterRange) -> Ordering {
27         self.from.cmp(&other.from)
28     }
29 }
30 
31 impl PartialOrd for RegisterRange {
partial_cmp(&self, other: &RegisterRange) -> Option<Ordering>32     fn partial_cmp(&self, other: &RegisterRange) -> Option<Ordering> {
33         self.from.partial_cmp(&other.from)
34     }
35 }
36 
37 impl RegisterRange {
38     /// Return true if those range overlaps.
overlap_with(&self, other: &RegisterRange) -> bool39     pub fn overlap_with(&self, other: &RegisterRange) -> bool {
40         !(self.from > other.to || self.to < other.from)
41     }
42 
43     /// Get the overlapping part of two RegisterRange.
44     /// Return is Option(overlap_from, overlap_to).
45     /// For example, (4,7).overlap_range(5, 8) will be Some(5, 7).
overlap_range(&self, other: &RegisterRange) -> Option<RegisterRange>46     pub fn overlap_range(&self, other: &RegisterRange) -> Option<RegisterRange> {
47         if !self.overlap_with(other) {
48             return None;
49         }
50         Some(RegisterRange {
51             from: max(self.from, other.from),
52             to: min(self.to, other.to),
53         })
54     }
55 }
56 
57 /// RegisterValue trait should be satisfied by register value types.
58 pub trait RegisterValue:
59     'static
60     + Into<u64>
61     + Clone
62     + DataInit
63     + std::ops::BitOr<Self, Output = Self>
64     + std::ops::BitAnd<Self, Output = Self>
65     + std::ops::Not<Output = Self>
66     + std::fmt::LowerHex
67 {
68     // Get byte of the offset.
get_byte(&self, offset: usize) -> u869     fn get_byte(&self, offset: usize) -> u8 {
70         let val: u64 = (*self).into();
71         (val >> (offset * 8)) as u8
72     }
73     // Set masked bits.
set_bits(&mut self, mask: Self)74     fn set_bits(&mut self, mask: Self) {
75         *self = *self | mask;
76     }
77     // Clear masked bits.
clear_bits(&mut self, mask: Self)78     fn clear_bits(&mut self, mask: Self) {
79         *self = *self & (!mask);
80     }
81 }
82 impl RegisterValue for u8 {}
83 impl RegisterValue for u16 {}
84 impl RegisterValue for u32 {}
85 impl RegisterValue for u64 {}
86 
87 // Helper function to read a register. If the read range overlaps with value's range, it will load
88 // corresponding bytes into data.
read_reg_helper<T: RegisterValue>( val: T, val_range: RegisterRange, addr: RegisterOffset, data: &mut [u8], )89 fn read_reg_helper<T: RegisterValue>(
90     val: T,
91     val_range: RegisterRange,
92     addr: RegisterOffset,
93     data: &mut [u8],
94 ) {
95     let read_range = RegisterRange {
96         from: addr,
97         to: addr + data.len() as u64 - 1,
98     };
99 
100     let overlap = match val_range.overlap_range(&read_range) {
101         Some(overlap) => overlap,
102         None => {
103             error!("calling read_reg_helper with non overlapping range. mmio_register might have a bug");
104             return;
105         }
106     };
107     let val_start_idx = (overlap.from - val_range.from) as usize;
108     let read_start_idx = (overlap.from - read_range.from) as usize;
109     let total_size = (overlap.to - overlap.from) as usize + 1;
110     for i in 0..total_size {
111         data[read_start_idx + i] = val.get_byte(val_start_idx + i);
112     }
113 }
114 
115 /// Interface for register, as seen by guest driver.
116 pub trait RegisterInterface: Send {
117     /// Range of this register.
range(&self) -> RegisterRange118     fn range(&self) -> RegisterRange;
119     /// Handle read.
read(&self, addr: RegisterOffset, data: &mut [u8])120     fn read(&self, addr: RegisterOffset, data: &mut [u8]);
121     /// Handle write.
write(&self, _addr: RegisterOffset, _data: &[u8])122     fn write(&self, _addr: RegisterOffset, _data: &[u8]) {}
123     /// Reset this register to default value.
reset(&self)124     fn reset(&self) {}
125 }
126 
127 // Spec for hardware init Read Only Registers.
128 // The value of this register won't change.
129 pub struct StaticRegisterSpec<T: RegisterValue> {
130     pub offset: RegisterOffset,
131     pub value: T,
132 }
133 
134 /// A static register is a register inited by hardware. The value won't change in it's lifetime.
135 /// All functions implemented on this one is thread safe.
136 #[derive(Clone)]
137 pub struct StaticRegister<T>
138 where
139     T: RegisterValue,
140 {
141     spec: &'static StaticRegisterSpec<T>,
142 }
143 
144 impl<T> StaticRegister<T>
145 where
146     T: RegisterValue,
147 {
148     /// Create an new static register from spec.
new(spec: &'static StaticRegisterSpec<T>) -> StaticRegister<T>149     pub fn new(spec: &'static StaticRegisterSpec<T>) -> StaticRegister<T> {
150         StaticRegister { spec }
151     }
152 }
153 
154 impl<T> RegisterInterface for StaticRegister<T>
155 where
156     T: RegisterValue,
157 {
range(&self) -> RegisterRange158     fn range(&self) -> RegisterRange {
159         RegisterRange {
160             from: self.spec.offset,
161             to: self.spec.offset + (size_of::<T>() as u64) - 1,
162         }
163     }
164 
read(&self, addr: RegisterOffset, data: &mut [u8])165     fn read(&self, addr: RegisterOffset, data: &mut [u8]) {
166         let val_range = self.range();
167         read_reg_helper(self.spec.value, val_range, addr, data);
168     }
169 }
170 
171 /// Macro helps to build a static register.
172 #[macro_export]
173 macro_rules! static_register {
174     (ty: $ty:ty,offset: $offset:expr,value: $value:expr,) => {{
175         use crate::register_space::*;
176         static REG_SPEC: StaticRegisterSpec<$ty> = StaticRegisterSpec::<$ty> {
177             offset: $offset,
178             value: $value,
179         };
180         StaticRegister::new(&REG_SPEC)
181     }};
182 }
183 
184 /// Spec for a regular register. It specifies it's location on register space, guest writable mask
185 /// and guest write to clear mask.
186 pub struct RegisterSpec<T> {
187     pub name: String,
188     pub offset: RegisterOffset,
189     pub reset_value: T,
190     /// Only masked bits could be written by guest.
191     pub guest_writeable_mask: T,
192     /// When write 1 to bits masked, those bits will be cleared. See Xhci spec 5.1
193     /// for more details.
194     pub guest_write_1_to_clear_mask: T,
195 }
196 
197 struct RegisterInner<T: RegisterValue> {
198     spec: RegisterSpec<T>,
199     value: T,
200     write_cb: Option<Box<dyn Fn(T) -> T + Send>>,
201 }
202 
203 /// Register is a thread safe struct. It can be safely changed from any thread.
204 #[derive(Clone)]
205 pub struct Register<T: RegisterValue> {
206     inner: Arc<Mutex<RegisterInner<T>>>,
207 }
208 
209 impl<T: RegisterValue> Register<T> {
new(spec: RegisterSpec<T>, val: T) -> Self210     pub fn new(spec: RegisterSpec<T>, val: T) -> Self {
211         Register {
212             inner: Arc::new(Mutex::new(RegisterInner {
213                 spec,
214                 value: val,
215                 write_cb: None,
216             })),
217         }
218     }
219 
lock(&self) -> MutexGuard<RegisterInner<T>>220     fn lock(&self) -> MutexGuard<RegisterInner<T>> {
221         self.inner.lock()
222     }
223 }
224 
225 // All functions implemented on this one is thread safe.
226 impl<T: RegisterValue> RegisterInterface for Register<T> {
range(&self) -> RegisterRange227     fn range(&self) -> RegisterRange {
228         let locked = self.lock();
229         let spec = &locked.spec;
230         RegisterRange {
231             from: spec.offset,
232             to: spec.offset + (size_of::<T>() as u64) - 1,
233         }
234     }
235 
read(&self, addr: RegisterOffset, data: &mut [u8])236     fn read(&self, addr: RegisterOffset, data: &mut [u8]) {
237         let val_range = self.range();
238         let value = self.lock().value;
239         read_reg_helper(value, val_range, addr, data);
240     }
241 
write(&self, addr: RegisterOffset, data: &[u8])242     fn write(&self, addr: RegisterOffset, data: &[u8]) {
243         let my_range = self.range();
244         let write_range = RegisterRange {
245             from: addr,
246             to: addr + data.len() as u64 - 1,
247         };
248 
249         let overlap = match my_range.overlap_range(&write_range) {
250             Some(range) => range,
251             None => {
252                 error!("write should not be invoked on this register");
253                 return;
254             }
255         };
256         let my_start_idx = (overlap.from - my_range.from) as usize;
257         let write_start_idx = (overlap.from - write_range.from) as usize;
258         let total_size = (overlap.to - overlap.from) as usize + 1;
259 
260         let mut reg_value: T = self.lock().value;
261         let value: &mut [u8] = reg_value.as_mut_slice();
262         for i in 0..total_size {
263             value[my_start_idx + i] = self.apply_write_masks_to_byte(
264                 value[my_start_idx + i],
265                 data[write_start_idx + i],
266                 my_start_idx + i,
267             );
268         }
269 
270         // A single u64 register is done by write to lower 32 bit and then higher 32 bit. Callback
271         // should only be invoked when higher is written.
272         if my_range.to != overlap.to {
273             self.lock().value = reg_value;
274             return;
275         }
276 
277         // Taking the callback out of register when executing it. This prevent dead lock if
278         // callback want to read current register value.
279         // Note that the only source of callback comes from mmio writing, which is synchronized.
280         let cb = {
281             let mut inner = self.lock();
282             match inner.write_cb.take() {
283                 Some(cb) => cb,
284                 None => {
285                     // Write value if there is no callback.
286                     inner.value = reg_value;
287                     return;
288                 }
289             }
290         };
291         // Callback is invoked without holding any lock.
292         let value = cb(reg_value);
293         let mut inner = self.lock();
294         inner.value = value;
295         inner.write_cb = Some(cb);
296     }
297 
reset(&self)298     fn reset(&self) {
299         let mut locked = self.lock();
300         locked.value = locked.spec.reset_value;
301     }
302 }
303 
304 impl<T: RegisterValue> Register<T> {
305     /// Get current value of this register.
get_value(&self) -> T306     pub fn get_value(&self) -> T {
307         self.lock().value
308     }
309 
310     /// This function apply "write 1 to clear mask" and "guest writeable mask".
311     /// All write operations should go through this, the result of this function
312     /// is the new state of correspoding byte.
apply_write_masks_to_byte(&self, old_byte: u8, write_byte: u8, offset: usize) -> u8313     pub fn apply_write_masks_to_byte(&self, old_byte: u8, write_byte: u8, offset: usize) -> u8 {
314         let locked = self.lock();
315         let spec = &locked.spec;
316         let guest_write_1_to_clear_mask: u64 = spec.guest_write_1_to_clear_mask.into();
317         let guest_writeable_mask: u64 = spec.guest_writeable_mask.into();
318         // Mask with w1c mask.
319         let w1c_mask = (guest_write_1_to_clear_mask >> (offset * 8)) as u8;
320         let val = (!w1c_mask & write_byte) | (w1c_mask & old_byte & !write_byte);
321         // Mask with writable mask.
322         let w_mask = (guest_writeable_mask >> (offset * 8)) as u8;
323         (old_byte & (!w_mask)) | (val & w_mask)
324     }
325 
326     /// Set a callback. It will be invoked when write happens.
set_write_cb<C: 'static + Fn(T) -> T + Send>(&self, callback: C)327     pub fn set_write_cb<C: 'static + Fn(T) -> T + Send>(&self, callback: C) {
328         self.lock().write_cb = Some(Box::new(callback));
329     }
330 
331     /// Set value from device side. Callback won't be invoked.
set_value(&self, val: T)332     pub fn set_value(&self, val: T) {
333         self.lock().value = val;
334     }
335 
336     /// Set masked bits.
set_bits(&self, mask: T)337     pub fn set_bits(&self, mask: T) {
338         self.lock().value.set_bits(mask);
339     }
340 
341     /// Clear masked bits.
clear_bits(&self, mask: T)342     pub fn clear_bits(&self, mask: T) {
343         self.lock().value.clear_bits(mask);
344     }
345 }
346 
347 #[macro_export]
348 macro_rules! register {
349     (
350         name: $name:tt,
351         ty: $ty:ty,
352         offset: $offset:expr,
353         reset_value: $rv:expr,
354         guest_writeable_mask: $mask:expr,
355         guest_write_1_to_clear_mask: $w1tcm:expr,
356     ) => {{
357         use crate::register_space::*;
358         let spec: RegisterSpec<$ty> = RegisterSpec::<$ty> {
359             name: String::from($name),
360             offset: $offset,
361             reset_value: $rv,
362             guest_writeable_mask: $mask,
363             guest_write_1_to_clear_mask: $w1tcm,
364         };
365         Register::<$ty>::new(spec, $rv)
366     }};
367     (name: $name:tt, ty: $ty:ty,offset: $offset:expr,reset_value: $rv:expr,) => {{
368         use crate::register_space::*;
369         let spec: RegisterSpec<$ty> = RegisterSpec::<$ty> {
370             name: String::from($name),
371             offset: $offset,
372             reset_value: $rv,
373             guest_writeable_mask: !0,
374             guest_write_1_to_clear_mask: 0,
375         };
376         Register::<$ty>::new(spec, $rv)
377     }};
378 }
379 
380 #[macro_export]
381 macro_rules! register_array {
382     (
383         name: $name:tt,
384         ty:
385         $ty:ty,cnt:
386         $cnt:expr,base_offset:
387         $base_offset:expr,stride:
388         $stride:expr,reset_value:
389         $rv:expr,guest_writeable_mask:
390         $gwm:expr,guest_write_1_to_clear_mask:
391         $gw1tcm:expr,
392     ) => {{
393         use crate::register_space::*;
394         let mut v: Vec<Register<$ty>> = Vec::new();
395         for i in 0..$cnt {
396             let offset = $base_offset + ($stride * i) as RegisterOffset;
397             let spec: RegisterSpec<$ty> = RegisterSpec::<$ty> {
398                 name: format!("{}-{}", $name, i),
399                 offset,
400                 reset_value: $rv,
401                 guest_writeable_mask: $gwm,
402                 guest_write_1_to_clear_mask: $gw1tcm,
403             };
404             v.push(Register::<$ty>::new(spec, $rv));
405         }
406         v
407     }};
408 }
409 
410 #[cfg(test)]
411 mod tests {
412     use super::*;
413 
414     static REG_SPEC0: StaticRegisterSpec<u8> = StaticRegisterSpec::<u8> {
415         offset: 3,
416         value: 32,
417     };
418 
419     static REG_SPEC1: StaticRegisterSpec<u16> = StaticRegisterSpec::<u16> {
420         offset: 3,
421         value: 32,
422     };
423 
424     #[test]
static_register_basic_test_u8()425     fn static_register_basic_test_u8() {
426         let r = StaticRegister::<u8> { spec: &REG_SPEC0 };
427         let mut data: [u8; 4] = [0, 0, 0, 0];
428         assert_eq!(r.range().from, 3);
429         assert_eq!(r.range().to, 3);
430         r.read(0, &mut data);
431         assert_eq!(data, [0, 0, 0, 32]);
432         r.read(2, &mut data);
433         assert_eq!(data, [0, 32, 0, 32]);
434     }
435 
436     #[test]
static_register_basic_test_u16()437     fn static_register_basic_test_u16() {
438         let r = StaticRegister::<u16> { spec: &REG_SPEC1 };
439         let mut data: [u8; 4] = [0, 0, 0, 0];
440         assert_eq!(r.range().from, 3);
441         assert_eq!(r.range().to, 4);
442         r.read(0, &mut data);
443         assert_eq!(data, [0, 0, 0, 32]);
444         r.read(2, &mut data);
445         assert_eq!(data, [0, 32, 0, 32]);
446     }
447 
448     #[test]
static_register_interface_test()449     fn static_register_interface_test() {
450         let r: Box<dyn RegisterInterface> = Box::new(static_register! {
451             ty: u8,
452             offset: 3,
453             value: 32,
454         });
455         let mut data: [u8; 4] = [0, 0, 0, 0];
456         assert_eq!(r.range().from, 3);
457         assert_eq!(r.range().to, 3);
458         r.read(0, &mut data);
459         assert_eq!(data, [0, 0, 0, 32]);
460         r.read(2, &mut data);
461         assert_eq!(data, [0, 32, 0, 32]);
462     }
463 
464     #[test]
register_basic_rw_test()465     fn register_basic_rw_test() {
466         let r = register! {
467             name: "",
468             ty: u8,
469             offset: 3,
470             reset_value: 0xf1,
471             guest_writeable_mask: 0xff,
472             guest_write_1_to_clear_mask: 0x0,
473         };
474         let mut data: [u8; 4] = [0, 0, 0, 0];
475         assert_eq!(r.range().from, 3);
476         assert_eq!(r.range().to, 3);
477         r.read(0, &mut data);
478         assert_eq!(data, [0, 0, 0, 0xf1]);
479         r.read(2, &mut data);
480         assert_eq!(data, [0, 0xf1, 0, 0xf1]);
481         data = [0, 0, 0, 0xab];
482         r.write(0, &data);
483         assert_eq!(r.get_value(), 0xab);
484         r.reset();
485         assert_eq!(r.get_value(), 0xf1);
486         r.set_value(0xcc);
487         assert_eq!(r.get_value(), 0xcc);
488     }
489 
490     #[test]
register_basic_writeable_mask_test()491     fn register_basic_writeable_mask_test() {
492         let r = register! {
493             name: "",
494             ty: u8,
495             offset: 3,
496             reset_value: 0x0,
497             guest_writeable_mask: 0xf,
498             guest_write_1_to_clear_mask: 0x0,
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, 0]);
505         data = [0, 0, 0, 0xab];
506         r.write(0, &data);
507         assert_eq!(r.get_value(), 0x0b);
508         r.reset();
509         assert_eq!(r.get_value(), 0x0);
510         r.set_value(0xcc);
511         assert_eq!(r.get_value(), 0xcc);
512     }
513 
514     #[test]
register_basic_write_1_to_clear_mask_test()515     fn register_basic_write_1_to_clear_mask_test() {
516         let r = register! {
517             name: "",
518             ty: u8,
519             offset: 3,
520             reset_value: 0xf1,
521             guest_writeable_mask: 0xff,
522             guest_write_1_to_clear_mask: 0xf0,
523         };
524         let mut data: [u8; 4] = [0, 0, 0, 0];
525         assert_eq!(r.range().from, 3);
526         assert_eq!(r.range().to, 3);
527         r.read(0, &mut data);
528         assert_eq!(data, [0, 0, 0, 0xf1]);
529         data = [0, 0, 0, 0xfa];
530         r.write(0, &data);
531         assert_eq!(r.get_value(), 0x0a);
532         r.reset();
533         assert_eq!(r.get_value(), 0xf1);
534         r.set_value(0xcc);
535         assert_eq!(r.get_value(), 0xcc);
536     }
537 
538     #[test]
register_basic_write_1_to_clear_mask_test_u32()539     fn register_basic_write_1_to_clear_mask_test_u32() {
540         let r = register! {
541             name: "",
542             ty: u32,
543             offset: 0,
544             reset_value: 0xfff1,
545             guest_writeable_mask: 0xff,
546             guest_write_1_to_clear_mask: 0xf0,
547         };
548         let mut data: [u8; 4] = [0, 0, 0, 0];
549         assert_eq!(r.range().from, 0);
550         assert_eq!(r.range().to, 3);
551         r.read(0, &mut data);
552         assert_eq!(data, [0xf1, 0xff, 0, 0]);
553         data = [0xfa, 0, 0, 0];
554         r.write(0, &data);
555         assert_eq!(r.get_value(), 0xff0a);
556         r.reset();
557         assert_eq!(r.get_value(), 0xfff1);
558         r.set_value(0xcc);
559         assert_eq!(r.get_value(), 0xcc);
560     }
561 
562     #[test]
register_callback_test()563     fn register_callback_test() {
564         let state = Arc::new(Mutex::new(0u8));
565         let r = register! {
566             name: "",
567             ty: u8,
568             offset: 3,
569             reset_value: 0xf1,
570             guest_writeable_mask: 0xff,
571             guest_write_1_to_clear_mask: 0xf0,
572         };
573 
574         let s2 = state.clone();
575         r.set_write_cb(move |val: u8| {
576             *s2.lock() = val as u8;
577             val
578         });
579         let data: [u8; 4] = [0, 0, 0, 0xff];
580         r.write(0, &data);
581         assert_eq!(*state.lock(), 0xf);
582         r.set_value(0xab);
583         assert_eq!(*state.lock(), 0xf);
584         let data: [u8; 1] = [0xfc];
585         r.write(3, &data);
586         assert_eq!(*state.lock(), 0xc);
587     }
588 }
589