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