Use safe-mmio
Refactor driver to use safe-mmio for accessing register and handling
the ownership and lifetime of the peripheral.
Change-Id: I031c3ceb1e34978218188160a3e0ec345c2f4630
Signed-off-by: Imre Kis <imre.kis@arm.com>
diff --git a/Cargo.lock b/Cargo.lock
index eac2616..7758337 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,10 +7,76 @@
version = "0.1.0"
dependencies = [
"bitflags",
+ "safe-mmio",
+ "zerocopy",
]
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.94"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "safe-mmio"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3bc59a975d8faa0b4475145266e9f9eac01f0b3f393d0e5eecc8b88646ca2d29"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "zerocopy"
+version = "0.8.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/Cargo.toml b/Cargo.toml
index af86174..bec41bd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,4 +18,6 @@
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-bitflags = "2.6"
+bitflags = "2.9"
+safe-mmio = "0.2"
+zerocopy = "0.8"
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index cb0610b..b7567c5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,13 +9,22 @@
#![no_std]
use bitflags::bitflags;
-use core::ops::{DerefMut, Range};
+use core::ops::Range;
+use safe_mmio::{
+ field,
+ fields::{ReadOnly, ReadPure, ReadPureWrite, ReadWrite, WriteOnly},
+ UniqueMmioPointer,
+};
+use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
+
+#[repr(transparent)]
+#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
+
+struct DistributorControlRegister(u32);
bitflags! {
// Distributor Control Register
- #[repr(transparent)]
- #[derive(Copy, Clone)]
- struct DistributorControlRegister : u32 {
+ impl DistributorControlRegister : u32 {
/// Register Write Pending
const RWP = 1 << 31;
/// Enable 1 of N Wakeup Functionality
@@ -36,71 +45,135 @@
}
/// GIC Distributor register map
+#[derive(Clone, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
#[repr(C, align(4))]
pub struct GICDRegisters {
- 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
+ /// 0x0000
+ ctlr: ReadPureWrite<DistributorControlRegister>,
+ /// 0x0004
+ typer: ReadPure<u32>,
+ /// 0x0008
+ iidr: ReadPure<u32>,
+ /// 0x000c
+ typer2: ReadPure<u32>,
+ /// 0x0010
+ statusr: ReadPureWrite<u32>,
+ /// 0x0014-0x001c
+ reserved_0014: [u32; 3],
+ /// 0x0020-0x003c
+ imdef0: [ReadWrite<u32>; 8],
+ /// 0x0040
+ setspi_nsr: WriteOnly<u32>,
+ /// 0x0044
+ reserved_0044: u32,
+ /// 0x0048
+ clrspi_nsr: WriteOnly<u32>,
+ /// 0x004c
+ reserved_004c: u32,
+ /// 0x0050
+ setspi_sr: WriteOnly<u32>,
+ /// 0x0054
+ reserved_0054: u32,
+ /// 0x0058
+ clrspi_sr: WriteOnly<u32>,
+ /// 0x005c-0x007c
+ reserved_005c: [u32; 9],
+ /// 0x0080-0x00fc
+ igroupr: [ReadPureWrite<u32>; 32],
+ /// 0x0100-0x017c
+ isenabler: [ReadPureWrite<u32>; 32],
+ /// 0x0180-0x01fc
+ icenabler: [ReadPureWrite<u32>; 32],
+ // 0x0200-0x027c
+ ispendr: [ReadPureWrite<u32>; 32],
+ /// 0x0280-0x02fc
+ icpendr: [ReadPureWrite<u32>; 32],
+ /// 0x0300-0x037c
+ isactiver: [ReadPureWrite<u32>; 32],
+ /// 0x0380-0x03fc
+ icactiver: [ReadPureWrite<u32>; 32],
+ /// 0x0400-0x07f8
+ ipriorityr: [ReadPureWrite<u32>; 256],
+ /// 0x0800-0x0bfc
+ itargetsr: [ReadOnly<u32>; 256],
+ /// 0x0c00-0x0cfc
+ icfgr: [ReadPureWrite<u32>; 64],
+ /// 0x0d00-0x0d7c
+ igrpmodr: [ReadPureWrite<u32>; 32],
+ /// 0x0d80-0x0dfc
+ reserved_0d80: [u32; 32],
+ /// 0x0e00-0x0efc
+ nsacr: [ReadPureWrite<u32>; 64],
+ /// 0x0f00
+ sgir: WriteOnly<u32>,
+ /// 0x0f04-0x0f0c
+ reserved_0f04: [u32; 3],
+ /// 0x0f10-0x0f1c
+ cpendsgir: [ReadPureWrite<u32>; 4],
+ /// 0x0f20-0x0f2c
+ spendsgir: [ReadPureWrite<u32>; 4],
+ /// 0x0f30-0x0f7c
+ reserved_0f30: [u32; 20],
+ /// 0x0f80-0x0ffc
+ inmir: [ReadPureWrite<u32>; 32],
+ /// 0x1000-0x107c
+ igroupr_e: [ReadPureWrite<u32>; 32],
+ /// 0x1080-0x1fc
+ reserved_1080: [u32; 96],
+ /// 0x1200-0x127c
+ isenabler_e: [ReadPureWrite<u32>; 32],
+ /// 0x1280-0x13fc
+ reserved_1280: [u32; 96],
+ /// 0x1400-0x147c
+ icenabler_e: [ReadPureWrite<u32>; 32],
+ /// 0x1480-0x15fc
+ reserved_1480: [u32; 96],
+ /// 0x1600-0x167c
+ ispendr_e: [ReadPureWrite<u32>; 32],
+ /// 0x1680-0x17fc
+ reserved_1680: [u32; 96],
+ /// 0x1800-0x187c
+ icpendr_e: [ReadPureWrite<u32>; 32],
+ /// 0x1880-0x19fc
+ reserved_1880: [u32; 96],
+ /// 0x1a00-0x1a7c
+ isactive_e: [ReadPureWrite<u32>; 32],
+ /// 0x1a80-0x1bfc
+ reserved_1a80: [u32; 96],
+ /// 0x1c00-0x1c7c
+ icactive_e: [ReadPureWrite<u32>; 32],
+ /// 0x1c80-0x1ffc
+ reserved_1c80: [u32; 224],
+ /// 0x2000-0x23fc
+ ipriorityr_e: [ReadPureWrite<u32>; 256],
+ /// 0x2400-0x2ffc
+ reserved_2400: [u32; 768],
+ /// 0x3000-0x30fc
+ icfgr_e: [ReadPureWrite<u32>; 64],
+ /// 0x3100-0x33fc
+ reserved_3100: [u32; 192],
+ /// 0x3400-0x347c
+ igrpmodr_e: [ReadPureWrite<u32>; 32],
+ /// 0x3480-0x35fc
+ reserved_3480: [u32; 96],
+ /// 0x3600-0x367c
+ nsacr_e: [ReadPureWrite<u32>; 32],
+ /// 0x3680-0x3afc
+ reserved_3680: [u32; 256],
+ /// 0x3b00-0x3bfc
+ inmir_e: [ReadPureWrite<u32>; 64],
+ /// 0x3b80-0x60fc
+ reserved_3b80: [u32; 2400],
+ /// 0x6100-0x7fd8
+ irouter: [ReadPureWrite<u32>; 1975],
+ /// 0x7fdc-0x7ffc
+ reserved_7fdc: [u32; 9],
+ /// 0x8000-0x9ffc
+ irouter_e: [ReadPureWrite<u32>; 2048],
+ /// 0xa000-0xffcc
+ reserved_a000: [u32; 6132],
+ /// 0xffd0-0xfffc
+ id_registers: [ReadOnly<u32>; 12],
}
/// # GIC Distributor error type
@@ -113,28 +186,19 @@
///
/// The Distributor performs interrupt prioritization and distribution of SPIs and SGIs to the
/// Redistributors and CPU interfaces that are connected to the PEs in the system.
-pub struct GicDistributor<R>
-where
- R: DerefMut<Target = GICDRegisters>,
-{
- gicd: R,
+pub struct GicDistributor<'a> {
+ gicd: UniqueMmioPointer<'a, GICDRegisters>,
}
-impl<R> GicDistributor<R>
-where
- R: DerefMut<Target = GICDRegisters>,
-{
+impl<'a> GicDistributor<'a> {
const MAX_IT: usize = 32;
/// Create GIC Distributor instance
- pub fn new(mut gicd: R) -> Self {
- // SAFETY: gicd can be dereferenced as a valid GIC Distributor register block
- unsafe {
- for n in 0..Self::MAX_IT {
- (&raw mut gicd.icenabler[n]).write_volatile(0xffffffff);
- (&raw mut gicd.icpendr[n]).write_volatile(0xffffffff);
- (&raw mut gicd.igroupr[n]).write_volatile(0xffffffff);
- }
+ pub fn new(mut gicd: UniqueMmioPointer<'a, GICDRegisters>) -> Self {
+ for n in 0..Self::MAX_IT {
+ field!(gicd, icenabler).split()[n].write(0xffff_ffff);
+ field!(gicd, icpendr).split()[n].write(0xffff_ffff);
+ field!(gicd, igroupr).split()[n].write(0xffff_ffff);
}
Self { gicd }
@@ -142,32 +206,20 @@
/// Enable Group 0 interrupts
pub fn enable_group0(&mut self) {
- // SAFETY: self.gicd can be dereferenced as a valid GIC Distributor register block
- unsafe {
- let value = (&raw const self.gicd.ctlr).read_volatile();
- (&raw mut self.gicd.ctlr)
- .write_volatile(value | DistributorControlRegister::EnableGrp0.bits());
- }
+ let value = field!(self.gicd, ctlr).read();
+ field!(self.gicd, ctlr).write(value | DistributorControlRegister::EnableGrp0);
}
/// Enable Secure Group 1 interrupts
pub fn enable_secure_group1(&mut self) {
- // SAFETY: self.gicd can be dereferenced as a valid GIC Distributor register block
- unsafe {
- let value = (&raw const self.gicd.ctlr).read_volatile();
- (&raw mut self.gicd.ctlr)
- .write_volatile(value | DistributorControlRegister::EnableGrp1S.bits());
- }
+ let value = field!(self.gicd, ctlr).read();
+ field!(self.gicd, ctlr).write(value | DistributorControlRegister::EnableGrp1S);
}
/// Enable Non-secure Group 1 interrupts
pub fn enable_non_secure_group1(&mut self) {
- // SAFETY: self.gicd can be dereferenced as a valid GIC Distributor register block
- unsafe {
- let value = (&raw const self.gicd.ctlr).read_volatile();
- (&raw mut self.gicd.ctlr)
- .write_volatile(value | DistributorControlRegister::EnableGrp1NS.bits());
- }
+ let value = field!(self.gicd, ctlr).read();
+ field!(self.gicd, ctlr).write(value | DistributorControlRegister::EnableGrp1NS);
}
/// Select a range of interrupts for group 0
@@ -188,7 +240,7 @@
where
F: Fn(u32, u32) -> u32,
{
- let max_it_index: usize = self.gicd.igroupr.len() * 32;
+ let max_it_index: usize = field!(self.gicd, igroupr).split().len() * 32;
if range.start > max_it_index || range.end > max_it_index {
return Err(GicDistributorError::InvalidParameter);
@@ -197,10 +249,9 @@
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);
- // SAFETY: self.gicd can be dereferenced as a valid GIC Distributor register block
- let mut modify_igroupr = |index, mask| unsafe {
- let ptr: *mut u32 = (&raw mut self.gicd.igroupr[index]);
- ptr.write_volatile(f(ptr.read_volatile(), mask));
+ let mut modify_igroupr = |index: usize, mask| {
+ let value = field!(self.gicd, igroupr).split()[index].read();
+ field!(self.gicd, igroupr).split()[index].write(f(value, mask));
};
if start_reg == end_reg {
@@ -274,94 +325,84 @@
}
// SAFETY: It is safe to access GicDistributor from any core/thread.
-unsafe impl<R> Sync for GicDistributor<R> where R: DerefMut<Target = GICDRegisters> {}
+unsafe impl Sync for GicDistributor<'_> {}
-#[test]
-fn test_gicd_size() {
- assert_eq!(core::mem::size_of::<GICDRegisters>(), 0x1_0000);
-}
+#[cfg(test)]
+mod tests {
+ use super::*;
-#[test]
-fn test_bitmask() {
- assert_eq!(
- 0x0000_0000,
- GicDistributor::<&mut GICDRegisters>::create_mask(0..0)
- );
- assert_eq!(
- 0x0000_0001,
- GicDistributor::<&mut GICDRegisters>::create_mask(0..1)
- );
- assert_eq!(
- 0x8000_0000,
- GicDistributor::<&mut GICDRegisters>::create_mask(31..32)
- );
- assert_eq!(
- 0x0000_00ff,
- GicDistributor::<&mut GICDRegisters>::create_mask(0..8)
- );
- assert_eq!(
- 0xffff_ffff,
- GicDistributor::<&mut GICDRegisters>::create_mask(0..32)
- );
-}
+ #[test]
+ fn test_gicd_size() {
+ assert_eq!(core::mem::size_of::<GICDRegisters>(), 0x1_0000);
+ }
-#[test]
-fn test_gicd() {
- extern crate alloc;
- use alloc::vec::Vec;
+ #[test]
+ fn test_bitmask() {
+ assert_eq!(0x0000_0000, GicDistributor::create_mask(0..0));
+ assert_eq!(0x0000_0001, GicDistributor::create_mask(0..1));
+ assert_eq!(0x8000_0000, GicDistributor::create_mask(31..32));
+ assert_eq!(0x0000_00ff, GicDistributor::create_mask(0..8));
+ assert_eq!(0xffff_ffff, GicDistributor::create_mask(0..32));
+ }
- let area: [u32; 0x4000] = [0; 0x4000];
- let mut registers: GICDRegisters = unsafe { core::mem::transmute(area) };
+ fn check_igroup(expected: &[u32], mut registers: UniqueMmioPointer<GICDRegisters>) {
+ for (index, expected) in expected.iter().enumerate() {
+ let actual = field!(registers, igroupr).split()[index].read();
+ assert_eq!(*expected, actual);
+ }
+ }
- let mut gic_distributor = GicDistributor::new(&mut registers);
- gic_distributor.select_group0_range(8..16).unwrap();
- let result: Vec<u32> = registers.igroupr.to_vec();
- let mut expected = [0xffff_ffffu32; 32];
- expected[0] = 0xffff_00ff;
- assert_eq!(result.as_slice(), &expected);
+ #[test]
+ fn test_gicd() {
+ let area: [u32; 0x4000] = [0; 0x4000];
+ let mut registers: GICDRegisters = unsafe { core::mem::transmute(area) };
- let mut gic_distributor = GicDistributor::new(&mut registers);
- gic_distributor.select_group0_range(8..40).unwrap();
- let result: Vec<u32> = registers.igroupr.to_vec();
- let mut expected = [0xffff_ffffu32; 32];
- expected[0] = 0x0000_00ff;
- expected[1] = 0xffff_ff00;
- assert_eq!(result.as_slice(), &expected);
+ {
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ gic_distributor.select_group0_range(8..16).unwrap();
+ }
- let mut gic_distributor = GicDistributor::new(&mut registers);
- gic_distributor.select_group0_range(8..72).unwrap();
- let result: Vec<u32> = registers.igroupr.to_vec();
- 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 mut expected = [0xffff_ffffu32; 32];
+ expected[0] = 0xffff_00ff;
+ check_igroup(&expected, (&mut registers).into());
- let mut gic_distributor = GicDistributor::new(&mut registers);
- gic_distributor.select_group0_range(8..64).unwrap();
- let result: Vec<u32> = registers.igroupr.to_vec();
- let mut expected = [0xffff_ffffu32; 32];
- expected[0] = 0x0000_00ff;
- expected[1] = 0x0000_0000;
- assert_eq!(result.as_slice(), &expected);
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ gic_distributor.select_group0_range(8..40).unwrap();
+ let mut expected = [0xffff_ffffu32; 32];
+ expected[0] = 0x0000_00ff;
+ expected[1] = 0xffff_ff00;
+ check_igroup(&expected, (&mut registers).into());
- let mut gic_distributor = GicDistributor::new(&mut registers);
- gic_distributor.select_group0_range(1..1023).unwrap();
- let result: Vec<u32> = registers.igroupr.to_vec();
- let mut expected = [0x0000_0000u32; 32];
- expected[0] = 0x0000_0001;
- expected[31] = 0x8000_0000;
- assert_eq!(result.as_slice(), &expected);
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ gic_distributor.select_group0_range(8..72).unwrap();
+ let mut expected = [0xffff_ffffu32; 32];
+ expected[0] = 0x0000_00ff;
+ expected[1] = 0x0000_0000;
+ expected[2] = 0xffff_ff00;
+ check_igroup(&expected, (&mut registers).into());
- let mut gic_distributor = GicDistributor::new(&mut registers);
- gic_distributor.select_group0_range(0..1024).unwrap();
- let result: Vec<u32> = registers.igroupr.to_vec();
- let expected = [0x0000_0000u32; 32];
- assert_eq!(result.as_slice(), &expected);
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ gic_distributor.select_group0_range(8..64).unwrap();
+ let mut expected = [0xffff_ffffu32; 32];
+ expected[0] = 0x0000_00ff;
+ expected[1] = 0x0000_0000;
+ check_igroup(&expected, (&mut registers).into());
- let mut gic_distributor = GicDistributor::new(&mut registers);
- assert!(gic_distributor.select_group0_range(0..2048).is_err());
- let result: Vec<u32> = registers.igroupr.to_vec();
- let expected = [0xffff_ffffu32; 32];
- assert_eq!(result.as_slice(), &expected);
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ gic_distributor.select_group0_range(1..1023).unwrap();
+ let mut expected = [0x0000_0000u32; 32];
+ expected[0] = 0x0000_0001;
+ expected[31] = 0x8000_0000;
+ check_igroup(&expected, (&mut registers).into());
+
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ gic_distributor.select_group0_range(0..1024).unwrap();
+ let expected = [0x0000_0000u32; 32];
+ check_igroup(&expected, (&mut registers).into());
+
+ let mut gic_distributor = GicDistributor::new((&mut registers).into());
+ assert!(gic_distributor.select_group0_range(0..2048).is_err());
+ let expected = [0xffff_ffffu32; 32];
+ check_igroup(&expected, (&mut registers).into());
+ }
}