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();