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(®_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: ®_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: ®_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