Eliminate the use of volatile-register crate

See related issue
https://github.com/rust-embedded/volatile-register/issues/10

Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: I395de4a119d5471297f0d39480e390f506e575b0
diff --git a/Cargo.lock b/Cargo.lock
index a8dccba..eac2616 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,7 +7,6 @@
 version = "0.1.0"
 dependencies = [
  "bitflags",
- "volatile-register",
 ]
 
 [[package]]
@@ -15,18 +14,3 @@
 version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
-
-[[package]]
-name = "vcell"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
-
-[[package]]
-name = "volatile-register"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
-dependencies = [
- "vcell",
-]
diff --git a/Cargo.toml b/Cargo.toml
index 1a359e3..db5bdf0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,4 +18,3 @@
 
 [dependencies]
 bitflags = "2.6"
-volatile-register = "0.2"
diff --git a/src/lib.rs b/src/lib.rs
index fa3e661..21bc595 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,8 +9,10 @@
 #![no_std]
 
 use bitflags::bitflags;
-use core::ops::{Deref, Range};
-use volatile_register::{RO, RW, WO};
+use core::{
+    ops::{DerefMut, Range},
+    ptr::{addr_of, addr_of_mut},
+};
 
 bitflags! {
     // Distributor Control Register
@@ -39,69 +41,69 @@
 /// GIC Distributor register map
 #[repr(C, align(4))]
 pub struct GICDRegisters {
-    ctlr: RW<u32>,                // 0x0000
-    typer: RO<u32>,               // 0x0004
-    iidr: RO<u32>,                // 0x0008
-    typer2: RO<u32>,              // 0x000c
-    statusr: RW<u32>,             // 0x0010
-    reserved_0014: [u32; 3],      // 0x0014-0x001c
-    imdef0: [u32; 8],             // 0x0020-0x003c
-    setspi_nsr: WO<u32>,          // 0x0040
-    reserved_0044: u32,           // 0x0044
-    clrspi_nsr: WO<u32>,          // 0x0048
-    reserved_004c: u32,           // 0x004c
-    setspi_sr: WO<u32>,           // 0x0050
-    reserved_0054: u32,           // 0x0054
-    clrspi_sr: WO<u32>,           // 0x0058
-    reserved_005c: [u32; 9],      // 0x005c-0x007c
-    igroupr: [RW<u32>; 32],       // 0x0080-0x00fc
-    isenabler: [RW<u32>; 32],     // 0x0100-0x017c
-    icenabler: [RW<u32>; 32],     // 0x0180-0x01fc
-    ispendr: [RW<u32>; 32],       // 0x0200-0x027c
-    icpendr: [RW<u32>; 32],       // 0x0280-0x02fc
-    isactiver: [RW<u32>; 32],     // 0x0300-0x037c
-    icactiver: [RW<u32>; 32],     // 0x0380-0x03fc
-    ipriorityr: [RW<u32>; 256],   // 0x0400-0x07f8
-    itargetsr: [RW<u32>; 256],    // 0x0800-0x0bfc
-    icfgr: [RW<u32>; 64],         // 0x0c00-0x0cfc
-    igrpmodr: [RW<u32>; 32],      // 0x0d00-0x0d7c
-    reserved_0d80: [u32; 32],     // 0x0d80-0x0dfc
-    nsacr: [RW<u32>; 64],         // 0x0e00-0x0efc
-    sgir: WO<u32>,                // 0x0f00
-    reserved_0f04: [u32; 3],      // 0x0f04-0x0f0c
-    cpendsgir: [RW<u32>; 4],      // 0x0f10-0x0f1c
-    spendsgir: [RW<u32>; 4],      // 0x0f20-0x0f2c
-    reserved_0f30: [u32; 20],     // 0x0f30-0x0f7c
-    inmir: [RW<u32>; 32],         // 0x0f80-0x0ffc
-    igroupr_e: [RW<u32>; 32],     // 0x1000-0x107c
-    reserved_1080: [u32; 96],     // 0x1080-0x1fc
-    isenabler_e: [RW<u32>; 32],   // 0x1200-0x127c
-    reserved_1280: [u32; 96],     // 0x1280-0x13fc
-    icenabler_e: [RW<u32>; 32],   // 0x1400-0x147c
-    reserved_1480: [u32; 96],     // 0x1480-0x15fc
-    ispendr_e: [RW<u32>; 32],     // 0x1600-0x167c
-    reserved_1680: [u32; 96],     // 0x1680-0x17fc
-    icpendr_e: [RW<u32>; 32],     // 0x1800-0x187c
-    reserved_1880: [u32; 96],     // 0x1880-0x19fc
-    isactive_e: [RW<u32>; 32],    // 0x1a00-0x1a7c
-    reserved_1a80: [u32; 96],     // 0x1a80-0x1bfc
-    icactive_e: [RW<u32>; 32],    // 0x1c00-0x1c7c
-    reserved_1c80: [u32; 224],    // 0x1c80-0x1ffc
-    ipriorityr_e: [RW<u32>; 256], // 0x2000-0x23fc
-    reserved_2400: [u32; 768],    // 0x2400-0x2ffc
-    icfgr_e: [RW<u32>; 64],       // 0x3000-0x30fc
-    reserved_3100: [u32; 192],    // 0x3100-0x33fc
-    igrpmodr_e: [RW<u32>; 32],    // 0x3400-0x347c
-    reserved_3480: [u32; 96],     // 0x3480-0x35fc
-    nsacr_e: [RW<u32>; 32],       // 0x3600-0x367c
-    reserved_3680: [u32; 256],    // 0x3680-0x3afc
-    inmir_e: [RW<u32>; 64],       // 0x3b00-0x3bfc
-    reserved_3b80: [u32; 2400],   // 0x3b80-0x60fc
-    irouter: [RW<u32>; 1975],     // 0x6100-0x7fd8
-    reserved_7fdc: [u32; 9],      // 0x7fdc-0x7ffc
-    irouter_e: [RW<u32>; 2048],   // 0x8000-0x9ffc
-    reserved_a000: [u32; 6132],   // 0xa000-0xffcc
-    id_registers: [RW<u32>; 12],  // 0xffd0-0xfffc
+    ctlr: u32,                  // 0x0000
+    typer: u32,                 // 0x0004
+    iidr: u32,                  // 0x0008
+    typer2: u32,                // 0x000c
+    statusr: u32,               // 0x0010
+    reserved_0014: [u32; 3],    // 0x0014-0x001c
+    imdef0: [u32; 8],           // 0x0020-0x003c
+    setspi_nsr: u32,            // 0x0040
+    reserved_0044: u32,         // 0x0044
+    clrspi_nsr: u32,            // 0x0048
+    reserved_004c: u32,         // 0x004c
+    setspi_sr: u32,             // 0x0050
+    reserved_0054: u32,         // 0x0054
+    clrspi_sr: u32,             // 0x0058
+    reserved_005c: [u32; 9],    // 0x005c-0x007c
+    igroupr: [u32; 32],         // 0x0080-0x00fc
+    isenabler: [u32; 32],       // 0x0100-0x017c
+    icenabler: [u32; 32],       // 0x0180-0x01fc
+    ispendr: [u32; 32],         // 0x0200-0x027c
+    icpendr: [u32; 32],         // 0x0280-0x02fc
+    isactiver: [u32; 32],       // 0x0300-0x037c
+    icactiver: [u32; 32],       // 0x0380-0x03fc
+    ipriorityr: [u32; 256],     // 0x0400-0x07f8
+    itargetsr: [u32; 256],      // 0x0800-0x0bfc
+    icfgr: [u32; 64],           // 0x0c00-0x0cfc
+    igrpmodr: [u32; 32],        // 0x0d00-0x0d7c
+    reserved_0d80: [u32; 32],   // 0x0d80-0x0dfc
+    nsacr: [u32; 64],           // 0x0e00-0x0efc
+    sgir: u32,                  // 0x0f00
+    reserved_0f04: [u32; 3],    // 0x0f04-0x0f0c
+    cpendsgir: [u32; 4],        // 0x0f10-0x0f1c
+    spendsgir: [u32; 4],        // 0x0f20-0x0f2c
+    reserved_0f30: [u32; 20],   // 0x0f30-0x0f7c
+    inmir: [u32; 32],           // 0x0f80-0x0ffc
+    igroupr_e: [u32; 32],       // 0x1000-0x107c
+    reserved_1080: [u32; 96],   // 0x1080-0x1fc
+    isenabler_e: [u32; 32],     // 0x1200-0x127c
+    reserved_1280: [u32; 96],   // 0x1280-0x13fc
+    icenabler_e: [u32; 32],     // 0x1400-0x147c
+    reserved_1480: [u32; 96],   // 0x1480-0x15fc
+    ispendr_e: [u32; 32],       // 0x1600-0x167c
+    reserved_1680: [u32; 96],   // 0x1680-0x17fc
+    icpendr_e: [u32; 32],       // 0x1800-0x187c
+    reserved_1880: [u32; 96],   // 0x1880-0x19fc
+    isactive_e: [u32; 32],      // 0x1a00-0x1a7c
+    reserved_1a80: [u32; 96],   // 0x1a80-0x1bfc
+    icactive_e: [u32; 32],      // 0x1c00-0x1c7c
+    reserved_1c80: [u32; 224],  // 0x1c80-0x1ffc
+    ipriorityr_e: [u32; 256],   // 0x2000-0x23fc
+    reserved_2400: [u32; 768],  // 0x2400-0x2ffc
+    icfgr_e: [u32; 64],         // 0x3000-0x30fc
+    reserved_3100: [u32; 192],  // 0x3100-0x33fc
+    igrpmodr_e: [u32; 32],      // 0x3400-0x347c
+    reserved_3480: [u32; 96],   // 0x3480-0x35fc
+    nsacr_e: [u32; 32],         // 0x3600-0x367c
+    reserved_3680: [u32; 256],  // 0x3680-0x3afc
+    inmir_e: [u32; 64],         // 0x3b00-0x3bfc
+    reserved_3b80: [u32; 2400], // 0x3b80-0x60fc
+    irouter: [u32; 1975],       // 0x6100-0x7fd8
+    reserved_7fdc: [u32; 9],    // 0x7fdc-0x7ffc
+    irouter_e: [u32; 2048],     // 0x8000-0x9ffc
+    reserved_a000: [u32; 6132], // 0xa000-0xffcc
+    id_registers: [u32; 12],    // 0xffd0-0xfffc
 }
 
 /// # GIC Distributor error type
@@ -116,24 +118,24 @@
 /// Redistributors and CPU interfaces that are connected to the PEs in the system.
 pub struct GicDistributor<R>
 where
-    R: Deref<Target = GICDRegisters>,
+    R: DerefMut<Target = GICDRegisters>,
 {
     gicd: R,
 }
 
 impl<R> GicDistributor<R>
 where
-    R: Deref<Target = GICDRegisters>,
+    R: DerefMut<Target = GICDRegisters>,
 {
     const MAX_IT: usize = 32;
 
     /// Create GIC Distributor instance
-    pub fn new(gicd: R) -> Self {
+    pub fn new(mut gicd: R) -> Self {
         unsafe {
             for n in 0..Self::MAX_IT {
-                gicd.icenabler[n].write(0xffffffff);
-                gicd.icpendr[n].write(0xffffffff);
-                gicd.igroupr[n].write(0xffffffff);
+                addr_of_mut!(gicd.icenabler[n]).write_volatile(0xffffffff);
+                addr_of_mut!(gicd.icpendr[n]).write_volatile(0xffffffff);
+                addr_of_mut!(gicd.igroupr[n]).write_volatile(0xffffffff);
             }
         }
 
@@ -141,43 +143,47 @@
     }
 
     /// Enable Group 0 interrupts
-    pub fn enable_group0(&self) {
+    pub fn enable_group0(&mut self) {
         unsafe {
-            self.gicd
-                .ctlr
-                .modify(|v| v | DistributorControlRegister::EnableGrp0.bits());
+            let value = addr_of!(self.gicd.ctlr).read_volatile();
+            addr_of_mut!(self.gicd.ctlr)
+                .write_volatile(value | DistributorControlRegister::EnableGrp0.bits());
         }
     }
 
     /// Enable Secure Group 1 interrupts
-    pub fn enable_secure_group1(&self) {
+    pub fn enable_secure_group1(&mut self) {
         unsafe {
-            self.gicd
-                .ctlr
-                .modify(|v| v | DistributorControlRegister::EnableGrp1S.bits());
+            let value = addr_of!(self.gicd.ctlr).read_volatile();
+            addr_of_mut!(self.gicd.ctlr)
+                .write_volatile(value | DistributorControlRegister::EnableGrp1S.bits());
         }
     }
 
     /// Enable Non-secure Group 1 interrupts
-    pub fn enable_non_secure_group1(&self) {
+    pub fn enable_non_secure_group1(&mut self) {
         unsafe {
-            self.gicd
-                .ctlr
-                .modify(|v| v | DistributorControlRegister::EnableGrp1NS.bits());
+            let value = addr_of!(self.gicd.ctlr).read_volatile();
+            addr_of_mut!(self.gicd.ctlr)
+                .write_volatile(value | DistributorControlRegister::EnableGrp1NS.bits());
         }
     }
 
     /// Select a range of interrupts for group 0
-    pub fn select_group0_range(&self, range: Range<usize>) -> Result<(), GicDistributorError> {
+    pub fn select_group0_range(&mut self, range: Range<usize>) -> Result<(), GicDistributorError> {
         self.modify_group_range(range, |v, mask| v & !mask)
     }
 
     /// Select a range of interrupts for group 1
-    pub fn select_group1_range(&self, range: Range<usize>) -> Result<(), GicDistributorError> {
+    pub fn select_group1_range(&mut self, range: Range<usize>) -> Result<(), GicDistributorError> {
         self.modify_group_range(range, |v, mask| v | mask)
     }
 
-    fn modify_group_range<F>(&self, range: Range<usize>, f: F) -> Result<(), GicDistributorError>
+    fn modify_group_range<F>(
+        &mut self,
+        range: Range<usize>,
+        f: F,
+    ) -> Result<(), GicDistributorError>
     where
         F: Fn(u32, u32) -> u32,
     {
@@ -190,28 +196,25 @@
         let (start_reg, start_bit) = Self::index_to_reg_and_bit(range.start);
         let (end_reg, end_bit) = Self::index_to_reg_and_bit(range.end);
 
+        let mut modify_igroupr = |index, mask| unsafe {
+            let ptr: *mut u32 = addr_of_mut!(self.gicd.igroupr[index]);
+            ptr.write_volatile(f(ptr.read_volatile(), mask));
+        };
+
         if start_reg == end_reg {
             let mask = Self::create_mask(start_bit..end_bit);
-            unsafe {
-                self.gicd.igroupr[start_reg].modify(|v| f(v, mask));
-            }
+            modify_igroupr(start_reg, mask);
         } else {
             let start_mask = Self::create_mask(start_bit..32);
-            unsafe {
-                self.gicd.igroupr[start_reg].modify(|v| f(v, start_mask));
-            }
+            modify_igroupr(start_reg, start_mask);
 
             for reg_index in (start_reg + 1)..end_reg {
-                unsafe {
-                    self.gicd.igroupr[reg_index].modify(|v| f(v, 0xffff_ffff));
-                }
+                modify_igroupr(reg_index, 0xffff_ffff);
             }
 
             if end_reg < Self::MAX_IT {
                 let end_mask = Self::create_mask(0..end_bit);
-                unsafe {
-                    self.gicd.igroupr[end_reg].modify(|v| f(v, end_mask));
-                }
+                modify_igroupr(end_reg, end_mask);
             }
         }
 
@@ -265,7 +268,7 @@
     }
 }
 
-unsafe impl<R> Sync for GicDistributor<R> where R: Deref<Target = GICDRegisters> {}
+unsafe impl<R> Sync for GicDistributor<R> where R: DerefMut<Target = GICDRegisters> {}
 
 #[test]
 fn test_gicd_size() {
@@ -276,23 +279,23 @@
 fn test_bitmask() {
     assert_eq!(
         0x0000_0000,
-        GicDistributor::<&GICDRegisters>::create_mask(0..0)
+        GicDistributor::<&mut GICDRegisters>::create_mask(0..0)
     );
     assert_eq!(
         0x0000_0001,
-        GicDistributor::<&GICDRegisters>::create_mask(0..1)
+        GicDistributor::<&mut GICDRegisters>::create_mask(0..1)
     );
     assert_eq!(
         0x8000_0000,
-        GicDistributor::<&GICDRegisters>::create_mask(31..32)
+        GicDistributor::<&mut GICDRegisters>::create_mask(31..32)
     );
     assert_eq!(
         0x0000_00ff,
-        GicDistributor::<&GICDRegisters>::create_mask(0..8)
+        GicDistributor::<&mut GICDRegisters>::create_mask(0..8)
     );
     assert_eq!(
         0xffff_ffff,
-        GicDistributor::<&GICDRegisters>::create_mask(0..32)
+        GicDistributor::<&mut GICDRegisters>::create_mask(0..32)
     );
 }
 
@@ -302,57 +305,57 @@
     use alloc::vec::Vec;
 
     let area: [u32; 0x4000] = [0; 0x4000];
-    let registers: GICDRegisters = unsafe { core::mem::transmute(area) };
+    let mut registers: GICDRegisters = unsafe { core::mem::transmute(area) };
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     gic_distributor.select_group0_range(8..16).unwrap();
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let mut expected = [0xffff_ffffu32; 32];
     expected[0] = 0xffff_00ff;
     assert_eq!(result.as_slice(), &expected);
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     gic_distributor.select_group0_range(8..40).unwrap();
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let mut expected = [0xffff_ffffu32; 32];
     expected[0] = 0x0000_00ff;
     expected[1] = 0xffff_ff00;
     assert_eq!(result.as_slice(), &expected);
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     gic_distributor.select_group0_range(8..72).unwrap();
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let mut expected = [0xffff_ffffu32; 32];
     expected[0] = 0x0000_00ff;
     expected[1] = 0x0000_0000;
     expected[2] = 0xffff_ff00;
     assert_eq!(result.as_slice(), &expected);
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     gic_distributor.select_group0_range(8..64).unwrap();
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let mut expected = [0xffff_ffffu32; 32];
     expected[0] = 0x0000_00ff;
     expected[1] = 0x0000_0000;
     assert_eq!(result.as_slice(), &expected);
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     gic_distributor.select_group0_range(1..1023).unwrap();
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let mut expected = [0x0000_0000u32; 32];
     expected[0] = 0x0000_0001;
     expected[31] = 0x8000_0000;
     assert_eq!(result.as_slice(), &expected);
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     gic_distributor.select_group0_range(0..1024).unwrap();
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let expected = [0x0000_0000u32; 32];
     assert_eq!(result.as_slice(), &expected);
 
-    let gic_distributor = GicDistributor::new(&registers);
+    let mut gic_distributor = GicDistributor::new(&mut registers);
     assert!(gic_distributor.select_group0_range(0..2048).is_err());
-    let result: Vec<u32> = registers.igroupr.iter().map(|r| r.read()).collect();
+    let result: Vec<u32> = registers.igroupr.iter().map(|r| *r).collect();
     let expected = [0xffff_ffffu32; 32];
     assert_eq!(result.as_slice(), &expected);
 }