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