Fix address mask calculation
Replace left shift and subtract operator with unbounded_shl and
wrapping_sub so the overflow will not cause a panic if the implemented
address width is 64 bit.
Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: I6f642192a5eead9000cfac77f679064dfc33d0e7
diff --git a/src/lib.rs b/src/lib.rs
index b12ea45..ee0a747 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -419,7 +419,8 @@
let regions = field_shared!(self.regs, region_registers);
regions.get(idx).map(|regs| TzcRegion {
regs,
- address_width_mask: ((1 << config.address_width()) - 1),
+ address_width_mask: ((1_u64.unbounded_shl(config.address_width() as u32))
+ .wrapping_sub(1)),
})
} else {
None
@@ -436,7 +437,8 @@
regions.take(idx).map(|regs| TzcRegionMut {
regs,
addresses_writable: idx != 0,
- address_width_mask: ((1 << config.address_width()) - 1),
+ address_width_mask: ((1_u64.unbounded_shl(config.address_width() as u32))
+ .wrapping_sub(1)),
})
} else {
None
@@ -606,6 +608,24 @@
}
#[test]
+ fn build_config_64_bit_address_region() {
+ let mut regs = FakeTZCRegisters::new();
+
+ // Testing address mask calculation with 64 bit addresses.
+ regs.reg_write(0x000, 0b0000_0000_0000_0000_0011_1111_0000_1000);
+
+ let mut tzc = regs.tzc_for_test();
+
+ let region = tzc.region(1);
+ assert!(region.is_some());
+ assert_eq!(u64::MAX, region.unwrap().address_width_mask);
+
+ let region = tzc.region_mut(1);
+ assert!(region.is_some());
+ assert_eq!(u64::MAX, region.unwrap().address_width_mask);
+ }
+
+ #[test]
fn get_action() {
let mut regs = FakeTZCRegisters::new();