1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2018 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::btree_map::BTreeMap; 6*bb4ee6a4SAndroid Build Coastguard Worker 7*bb4ee6a4SAndroid Build Coastguard Worker #[macro_use] 8*bb4ee6a4SAndroid Build Coastguard Worker mod register; 9*bb4ee6a4SAndroid Build Coastguard Worker 10*bb4ee6a4SAndroid Build Coastguard Worker pub use self::register::*; 11*bb4ee6a4SAndroid Build Coastguard Worker 12*bb4ee6a4SAndroid Build Coastguard Worker /// Register space repesents a set of registers. It can handle read/write operations. 13*bb4ee6a4SAndroid Build Coastguard Worker pub struct RegisterSpace { 14*bb4ee6a4SAndroid Build Coastguard Worker regs: BTreeMap<RegisterRange, Box<dyn RegisterInterface>>, 15*bb4ee6a4SAndroid Build Coastguard Worker } 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker impl RegisterSpace { 18*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a new empty RegisterSpace. new() -> RegisterSpace19*bb4ee6a4SAndroid Build Coastguard Worker pub fn new() -> RegisterSpace { 20*bb4ee6a4SAndroid Build Coastguard Worker RegisterSpace { 21*bb4ee6a4SAndroid Build Coastguard Worker regs: BTreeMap::new(), 22*bb4ee6a4SAndroid Build Coastguard Worker } 23*bb4ee6a4SAndroid Build Coastguard Worker } 24*bb4ee6a4SAndroid Build Coastguard Worker 25*bb4ee6a4SAndroid Build Coastguard Worker /// Add a register to register space. add_register<T: RegisterInterface + 'static>(&mut self, reg: T)26*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_register<T: RegisterInterface + 'static>(&mut self, reg: T) { 27*bb4ee6a4SAndroid Build Coastguard Worker let range = reg.range(); 28*bb4ee6a4SAndroid Build Coastguard Worker debug_assert!(self.get_register(range.from).is_none()); 29*bb4ee6a4SAndroid Build Coastguard Worker if cfg!(debug_assertions) { 30*bb4ee6a4SAndroid Build Coastguard Worker if let Some(r) = self.first_before(range.to) { 31*bb4ee6a4SAndroid Build Coastguard Worker debug_assert!(r.range().to < range.to); 32*bb4ee6a4SAndroid Build Coastguard Worker } 33*bb4ee6a4SAndroid Build Coastguard Worker } 34*bb4ee6a4SAndroid Build Coastguard Worker 35*bb4ee6a4SAndroid Build Coastguard Worker let insert_result = self.regs.insert(range, Box::new(reg)).is_none(); 36*bb4ee6a4SAndroid Build Coastguard Worker debug_assert!(insert_result); 37*bb4ee6a4SAndroid Build Coastguard Worker } 38*bb4ee6a4SAndroid Build Coastguard Worker 39*bb4ee6a4SAndroid Build Coastguard Worker /// Add an array of registers. add_register_array<T: RegisterValue>(&mut self, regs: &[Register<T>])40*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_register_array<T: RegisterValue>(&mut self, regs: &[Register<T>]) { 41*bb4ee6a4SAndroid Build Coastguard Worker for r in regs { 42*bb4ee6a4SAndroid Build Coastguard Worker self.add_register(r.clone()); 43*bb4ee6a4SAndroid Build Coastguard Worker } 44*bb4ee6a4SAndroid Build Coastguard Worker } 45*bb4ee6a4SAndroid Build Coastguard Worker 46*bb4ee6a4SAndroid Build Coastguard Worker /// Read range. read(&self, addr: RegisterOffset, data: &mut [u8])47*bb4ee6a4SAndroid Build Coastguard Worker pub fn read(&self, addr: RegisterOffset, data: &mut [u8]) { 48*bb4ee6a4SAndroid Build Coastguard Worker let mut current_addr: RegisterOffset = addr; 49*bb4ee6a4SAndroid Build Coastguard Worker while current_addr < addr + data.len() as RegisterOffset { 50*bb4ee6a4SAndroid Build Coastguard Worker if let Some(r) = self.get_register(current_addr) { 51*bb4ee6a4SAndroid Build Coastguard Worker // Next addr to read is. 52*bb4ee6a4SAndroid Build Coastguard Worker current_addr = r.range().to + 1; 53*bb4ee6a4SAndroid Build Coastguard Worker r.read(addr, data); 54*bb4ee6a4SAndroid Build Coastguard Worker } else { 55*bb4ee6a4SAndroid Build Coastguard Worker // TODO(jkwang) Add logging for debug here. 56*bb4ee6a4SAndroid Build Coastguard Worker current_addr += 1; 57*bb4ee6a4SAndroid Build Coastguard Worker } 58*bb4ee6a4SAndroid Build Coastguard Worker } 59*bb4ee6a4SAndroid Build Coastguard Worker } 60*bb4ee6a4SAndroid Build Coastguard Worker 61*bb4ee6a4SAndroid Build Coastguard Worker /// Write range. If the targeted register has a callback, it will be invoked with the new 62*bb4ee6a4SAndroid Build Coastguard Worker /// value. write(&self, addr: RegisterOffset, data: &[u8])63*bb4ee6a4SAndroid Build Coastguard Worker pub fn write(&self, addr: RegisterOffset, data: &[u8]) { 64*bb4ee6a4SAndroid Build Coastguard Worker let mut current_addr: RegisterOffset = addr; 65*bb4ee6a4SAndroid Build Coastguard Worker while current_addr < addr + data.len() as RegisterOffset { 66*bb4ee6a4SAndroid Build Coastguard Worker if let Some(r) = self.get_register(current_addr) { 67*bb4ee6a4SAndroid Build Coastguard Worker // Next addr to read is, range is inclusive. 68*bb4ee6a4SAndroid Build Coastguard Worker current_addr = r.range().to + 1; 69*bb4ee6a4SAndroid Build Coastguard Worker r.write(addr, data); 70*bb4ee6a4SAndroid Build Coastguard Worker } else { 71*bb4ee6a4SAndroid Build Coastguard Worker current_addr += 1; 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker } 75*bb4ee6a4SAndroid Build Coastguard Worker 76*bb4ee6a4SAndroid Build Coastguard Worker /// Get first register before this addr. first_before(&self, addr: RegisterOffset) -> Option<&dyn RegisterInterface>77*bb4ee6a4SAndroid Build Coastguard Worker fn first_before(&self, addr: RegisterOffset) -> Option<&dyn RegisterInterface> { 78*bb4ee6a4SAndroid Build Coastguard Worker for (range, r) in self.regs.iter().rev() { 79*bb4ee6a4SAndroid Build Coastguard Worker if range.from <= addr { 80*bb4ee6a4SAndroid Build Coastguard Worker return Some(r.as_ref()); 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker } 83*bb4ee6a4SAndroid Build Coastguard Worker None 84*bb4ee6a4SAndroid Build Coastguard Worker } 85*bb4ee6a4SAndroid Build Coastguard Worker 86*bb4ee6a4SAndroid Build Coastguard Worker /// Get register at this addr. get_register(&self, addr: RegisterOffset) -> Option<&dyn RegisterInterface>87*bb4ee6a4SAndroid Build Coastguard Worker fn get_register(&self, addr: RegisterOffset) -> Option<&dyn RegisterInterface> { 88*bb4ee6a4SAndroid Build Coastguard Worker let r = self.first_before(addr)?; 89*bb4ee6a4SAndroid Build Coastguard Worker let range = r.range(); 90*bb4ee6a4SAndroid Build Coastguard Worker if addr <= range.to { 91*bb4ee6a4SAndroid Build Coastguard Worker Some(r) 92*bb4ee6a4SAndroid Build Coastguard Worker } else { 93*bb4ee6a4SAndroid Build Coastguard Worker None 94*bb4ee6a4SAndroid Build Coastguard Worker } 95*bb4ee6a4SAndroid Build Coastguard Worker } 96*bb4ee6a4SAndroid Build Coastguard Worker } 97*bb4ee6a4SAndroid Build Coastguard Worker 98*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)] 99*bb4ee6a4SAndroid Build Coastguard Worker mod tests { 100*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc; 101*bb4ee6a4SAndroid Build Coastguard Worker 102*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex; 103*bb4ee6a4SAndroid Build Coastguard Worker 104*bb4ee6a4SAndroid Build Coastguard Worker use super::*; 105*bb4ee6a4SAndroid Build Coastguard Worker 106*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_no_reg()107*bb4ee6a4SAndroid Build Coastguard Worker fn regs_no_reg() { 108*bb4ee6a4SAndroid Build Coastguard Worker let regs = RegisterSpace::new(); 109*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 4] = [4, 3, 2, 1]; 110*bb4ee6a4SAndroid Build Coastguard Worker // Read should be no op cause no register. 111*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 112*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([4, 3, 2, 1], data); 113*bb4ee6a4SAndroid Build Coastguard Worker // Write should be no op. 114*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0]); 115*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 116*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([4, 3, 2, 1], data); 117*bb4ee6a4SAndroid Build Coastguard Worker } 118*bb4ee6a4SAndroid Build Coastguard Worker 119*bb4ee6a4SAndroid Build Coastguard Worker #[test] 120*bb4ee6a4SAndroid Build Coastguard Worker #[should_panic] 121*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(debug_assertions)] regs_reg_overlap()122*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_overlap() { 123*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 124*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(static_register!( 125*bb4ee6a4SAndroid Build Coastguard Worker ty: u32, 126*bb4ee6a4SAndroid Build Coastguard Worker offset: 4, 127*bb4ee6a4SAndroid Build Coastguard Worker value: 11, 128*bb4ee6a4SAndroid Build Coastguard Worker )); 129*bb4ee6a4SAndroid Build Coastguard Worker 130*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(static_register!( 131*bb4ee6a4SAndroid Build Coastguard Worker ty: u16, 132*bb4ee6a4SAndroid Build Coastguard Worker offset: 7, 133*bb4ee6a4SAndroid Build Coastguard Worker value: 11, 134*bb4ee6a4SAndroid Build Coastguard Worker )); 135*bb4ee6a4SAndroid Build Coastguard Worker } 136*bb4ee6a4SAndroid Build Coastguard Worker 137*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_static_reg()138*bb4ee6a4SAndroid Build Coastguard Worker fn regs_static_reg() { 139*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 140*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(static_register!( 141*bb4ee6a4SAndroid Build Coastguard Worker ty: u8, 142*bb4ee6a4SAndroid Build Coastguard Worker offset: 0, 143*bb4ee6a4SAndroid Build Coastguard Worker value: 11, 144*bb4ee6a4SAndroid Build Coastguard Worker )); 145*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 4] = [4, 3, 2, 1]; 146*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 147*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([11, 3, 2, 1], data); 148*bb4ee6a4SAndroid Build Coastguard Worker // Write should be no op. 149*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0]); 150*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 4] = [4, 3, 2, 1]; 151*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 152*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([11, 3, 2, 1], data); 153*bb4ee6a4SAndroid Build Coastguard Worker } 154*bb4ee6a4SAndroid Build Coastguard Worker 155*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_static_reg_offset()156*bb4ee6a4SAndroid Build Coastguard Worker fn regs_static_reg_offset() { 157*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 158*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(static_register!( 159*bb4ee6a4SAndroid Build Coastguard Worker ty: u32, 160*bb4ee6a4SAndroid Build Coastguard Worker offset: 2, 161*bb4ee6a4SAndroid Build Coastguard Worker value: 0xaabbccdd, 162*bb4ee6a4SAndroid Build Coastguard Worker )); 163*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 164*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 165*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data); 166*bb4ee6a4SAndroid Build Coastguard Worker // Write should be no op. 167*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]); 168*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 169*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 170*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data); 171*bb4ee6a4SAndroid Build Coastguard Worker } 172*bb4ee6a4SAndroid Build Coastguard Worker 173*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_reg_write()174*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_write() { 175*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 176*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(register!( 177*bb4ee6a4SAndroid Build Coastguard Worker name: "", 178*bb4ee6a4SAndroid Build Coastguard Worker ty: u32, 179*bb4ee6a4SAndroid Build Coastguard Worker offset: 2, 180*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xaabbccdd, 181*bb4ee6a4SAndroid Build Coastguard Worker )); 182*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 183*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 184*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data); 185*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]); 186*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 187*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 188*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0, 0, 0, 0, 2, 1], data); 189*bb4ee6a4SAndroid Build Coastguard Worker } 190*bb4ee6a4SAndroid Build Coastguard Worker 191*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_reg_writeable()192*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_writeable() { 193*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 194*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(register!( 195*bb4ee6a4SAndroid Build Coastguard Worker name: "", 196*bb4ee6a4SAndroid Build Coastguard Worker ty: u32, 197*bb4ee6a4SAndroid Build Coastguard Worker offset: 2, 198*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xaabbccdd, 199*bb4ee6a4SAndroid Build Coastguard Worker guest_writeable_mask: 0x00f0000f, 200*bb4ee6a4SAndroid Build Coastguard Worker guest_write_1_to_clear_mask: 0, 201*bb4ee6a4SAndroid Build Coastguard Worker )); 202*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 203*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 204*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data); 205*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]); 206*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 207*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 208*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xd0, 0xcc, 0x0b, 0xaa, 2, 1], data); 209*bb4ee6a4SAndroid Build Coastguard Worker } 210*bb4ee6a4SAndroid Build Coastguard Worker 211*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_reg_writeable_callback()212*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_writeable_callback() { 213*bb4ee6a4SAndroid Build Coastguard Worker let state = Arc::new(Mutex::new(0u32)); 214*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 215*bb4ee6a4SAndroid Build Coastguard Worker let reg = register!( 216*bb4ee6a4SAndroid Build Coastguard Worker name: "", 217*bb4ee6a4SAndroid Build Coastguard Worker ty: u32, 218*bb4ee6a4SAndroid Build Coastguard Worker offset: 2, 219*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xaabbccdd, 220*bb4ee6a4SAndroid Build Coastguard Worker guest_writeable_mask: 0x00f0000f, 221*bb4ee6a4SAndroid Build Coastguard Worker guest_write_1_to_clear_mask: 0, 222*bb4ee6a4SAndroid Build Coastguard Worker ); 223*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(reg.clone()); 224*bb4ee6a4SAndroid Build Coastguard Worker let state_clone = state.clone(); 225*bb4ee6a4SAndroid Build Coastguard Worker reg.set_write_cb(move |val: u32| { 226*bb4ee6a4SAndroid Build Coastguard Worker *state_clone.lock() = val; 227*bb4ee6a4SAndroid Build Coastguard Worker val 228*bb4ee6a4SAndroid Build Coastguard Worker }); 229*bb4ee6a4SAndroid Build Coastguard Worker 230*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 231*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 232*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data); 233*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]); 234*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0xaa0bccd0, *state.lock()); 235*bb4ee6a4SAndroid Build Coastguard Worker } 236*bb4ee6a4SAndroid Build Coastguard Worker 237*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_reg_write_to_clear()238*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_write_to_clear() { 239*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 240*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register(register!( 241*bb4ee6a4SAndroid Build Coastguard Worker name: "", 242*bb4ee6a4SAndroid Build Coastguard Worker ty: u32, 243*bb4ee6a4SAndroid Build Coastguard Worker offset: 2, 244*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xaabbccdd, 245*bb4ee6a4SAndroid Build Coastguard Worker guest_writeable_mask: 0xfff0000f, 246*bb4ee6a4SAndroid Build Coastguard Worker guest_write_1_to_clear_mask: 0xf0000000, 247*bb4ee6a4SAndroid Build Coastguard Worker )); 248*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 249*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 250*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data); 251*bb4ee6a4SAndroid Build Coastguard Worker regs.write(0, &[0, 0, 0, 0, 0, 0xad, 0, 0]); 252*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1]; 253*bb4ee6a4SAndroid Build Coastguard Worker regs.read(0, &mut data); 254*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([8, 7, 0xd0, 0xcc, 0x0b, 0x0d, 2, 1], data); 255*bb4ee6a4SAndroid Build Coastguard Worker } 256*bb4ee6a4SAndroid Build Coastguard Worker 257*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_reg_array()258*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_array() { 259*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 260*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register_array(®ister_array!( 261*bb4ee6a4SAndroid Build Coastguard Worker name: "", 262*bb4ee6a4SAndroid Build Coastguard Worker ty: u8, 263*bb4ee6a4SAndroid Build Coastguard Worker cnt: 8, 264*bb4ee6a4SAndroid Build Coastguard Worker base_offset: 10, 265*bb4ee6a4SAndroid Build Coastguard Worker stride: 2, 266*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xff, 267*bb4ee6a4SAndroid Build Coastguard Worker guest_writeable_mask: !0, 268*bb4ee6a4SAndroid Build Coastguard Worker guest_write_1_to_clear_mask: 0, 269*bb4ee6a4SAndroid Build Coastguard Worker )); 270*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [0; 8]; 271*bb4ee6a4SAndroid Build Coastguard Worker regs.read(8, &mut data); 272*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([0, 0, 0xff, 0, 0xff, 0, 0xff, 0], data); 273*bb4ee6a4SAndroid Build Coastguard Worker } 274*bb4ee6a4SAndroid Build Coastguard Worker 275*bb4ee6a4SAndroid Build Coastguard Worker #[test] regs_reg_multi_array()276*bb4ee6a4SAndroid Build Coastguard Worker fn regs_reg_multi_array() { 277*bb4ee6a4SAndroid Build Coastguard Worker let mut regs = RegisterSpace::new(); 278*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register_array(®ister_array!( 279*bb4ee6a4SAndroid Build Coastguard Worker name: "", 280*bb4ee6a4SAndroid Build Coastguard Worker ty: u8, 281*bb4ee6a4SAndroid Build Coastguard Worker cnt: 8, 282*bb4ee6a4SAndroid Build Coastguard Worker base_offset: 10, 283*bb4ee6a4SAndroid Build Coastguard Worker stride: 2, 284*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xff, 285*bb4ee6a4SAndroid Build Coastguard Worker guest_writeable_mask: !0, 286*bb4ee6a4SAndroid Build Coastguard Worker guest_write_1_to_clear_mask: 0, 287*bb4ee6a4SAndroid Build Coastguard Worker )); 288*bb4ee6a4SAndroid Build Coastguard Worker regs.add_register_array(®ister_array!( 289*bb4ee6a4SAndroid Build Coastguard Worker name: "", 290*bb4ee6a4SAndroid Build Coastguard Worker ty: u8, 291*bb4ee6a4SAndroid Build Coastguard Worker cnt: 8, 292*bb4ee6a4SAndroid Build Coastguard Worker base_offset: 11, 293*bb4ee6a4SAndroid Build Coastguard Worker stride: 2, 294*bb4ee6a4SAndroid Build Coastguard Worker reset_value: 0xee, 295*bb4ee6a4SAndroid Build Coastguard Worker guest_writeable_mask: !0, 296*bb4ee6a4SAndroid Build Coastguard Worker guest_write_1_to_clear_mask: 0, 297*bb4ee6a4SAndroid Build Coastguard Worker )); 298*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 8] = [0; 8]; 299*bb4ee6a4SAndroid Build Coastguard Worker regs.read(8, &mut data); 300*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([0, 0, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee], data); 301*bb4ee6a4SAndroid Build Coastguard Worker } 302*bb4ee6a4SAndroid Build Coastguard Worker } 303