Skip to content

Add bitflags for sysregs #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/gicv3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use self::registers::{Gicd, GicdCtlr, Gicr, GicrCtlr, Sgi, Waker};
use crate::sysreg::{
read_icc_iar1_el1, write_icc_ctlr_el1, write_icc_eoir1_el1, write_icc_igrpen0_el1,
write_icc_igrpen1_el1, write_icc_pmr_el1, write_icc_sgi1r_el1, write_icc_sre_el1,
write_icc_igrpen1_el1, write_icc_pmr_el1, write_icc_sgi1r_el1, write_icc_sre_el1, IccSre,
};
use crate::{IntId, Trigger};
use core::{hint::spin_loop, ptr::NonNull};
Expand Down Expand Up @@ -88,7 +88,7 @@
// SAFETY: Our caller promised that `gicd` is a valid and unique pointer to a GIC
// distributor.
gicd: unsafe { UniqueMmioPointer::new(NonNull::new(gicd).unwrap()) },
gicr_base: gicr_base,

Check warning on line 91 in src/gicv3.rs

View workflow job for this annotation

GitHub Actions / clippy

redundant field names in struct initialization

warning: redundant field names in struct initialization --> src/gicv3.rs:91:13 | 91 | gicr_base: gicr_base, | ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `gicr_base` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names = note: `#[warn(clippy::redundant_field_names)]` on by default
cpu_count,
gicr_stride,
}
Expand All @@ -106,7 +106,7 @@
/// for group 0 and group 1 interrupts separately.
pub fn init_cpu(&mut self, cpu: usize) {
// Enable system register access.
write_icc_sre_el1(0x01);
write_icc_sre_el1(IccSre::SRE);

// Ignore error in case core is already awake.
let _ = self.redistributor_mark_core_awake(cpu);
Expand Down Expand Up @@ -164,13 +164,13 @@
} else {
set_bit(field!(sgi, icenabler0).into(), intid.0 as usize);
}
} else {
if enable {
set_bit(field!(self.gicd, isenabler).into(), intid.0 as usize);
} else {
set_bit(field!(self.gicd, icenabler).into(), intid.0 as usize);
}
};

Check warning on line 173 in src/gicv3.rs

View workflow job for this annotation

GitHub Actions / clippy

this `else { if .. }` block can be collapsed

warning: this `else { if .. }` block can be collapsed --> src/gicv3.rs:167:16 | 167 | } else { | ________________^ 168 | | if enable { 169 | | set_bit(field!(self.gicd, isenabler).into(), intid.0 as usize); 170 | | } else { ... | 173 | | }; | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if = note: `#[warn(clippy::collapsible_else_if)]` on by default help: collapse nested if block | 167 ~ } else if enable { 168 + set_bit(field!(self.gicd, isenabler).into(), intid.0 as usize); 169 + } else { 170 + set_bit(field!(self.gicd, icenabler).into(), intid.0 as usize); 171 ~ }; |
}

/// Enables or disables all interrupts on all CPU cores.
Expand Down Expand Up @@ -266,20 +266,20 @@
set_bit(field!(sgi, igroupr0).into(), intid.0 as usize);
clear_bit(field!(sgi, igrpmodr0).into(), intid.0 as usize);
}
} else {
if let Group::Secure(sg) = group {
let igroupr = field!(self.gicd, igroupr);
clear_bit(igroupr.into(), intid.0 as usize);
let igrpmodr = field!(self.gicd, igrpmodr);
match sg {
SecureIntGroup::Group1S => set_bit(igrpmodr.into(), intid.0 as usize),
SecureIntGroup::Group0 => clear_bit(igrpmodr.into(), intid.0 as usize),
}
} else {
set_bit(field!(self.gicd, igroupr).into(), intid.0 as usize);
clear_bit(field!(self.gicd, igrpmodr).into(), intid.0 as usize);
}
};

Check warning on line 282 in src/gicv3.rs

View workflow job for this annotation

GitHub Actions / clippy

this `else { if .. }` block can be collapsed

warning: this `else { if .. }` block can be collapsed --> src/gicv3.rs:269:16 | 269 | } else { | ________________^ 270 | | if let Group::Secure(sg) = group { 271 | | let igroupr = field!(self.gicd, igroupr); 272 | | clear_bit(igroupr.into(), intid.0 as usize); ... | 282 | | }; | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if help: collapse nested if block | 269 ~ } else if let Group::Secure(sg) = group { 270 + let igroupr = field!(self.gicd, igroupr); 271 + clear_bit(igroupr.into(), intid.0 as usize); 272 + let igrpmodr = field!(self.gicd, igrpmodr); 273 + match sg { 274 + SecureIntGroup::Group1S => set_bit(igrpmodr.into(), intid.0 as usize), 275 + SecureIntGroup::Group0 => clear_bit(igrpmodr.into(), intid.0 as usize), 276 + } 277 + } else { 278 + set_bit(field!(self.gicd, igroupr).into(), intid.0 as usize); 279 + clear_bit(field!(self.gicd, igrpmodr).into(), intid.0 as usize); 280 ~ }; |
}

/// Sends a software-generated interrupt (SGI) to the given cores.
Expand Down
23 changes: 22 additions & 1 deletion src/sysreg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,33 @@
#[macro_use]
mod aarch32;

use bitflags::bitflags;

read_sysreg32!(icc_iar1_el1, 0, c12, c12, 0, read_icc_iar1_el1);

write_sysreg32!(icc_ctlr_el1, 0, c12, c12, 4, write_icc_ctlr_el1);
write_sysreg32!(icc_eoir1_el1, 0, c12, c12, 1, write_icc_eoir1_el1);
write_sysreg32!(icc_igrpen0_el1, 0, c12, c12, 6, write_icc_igrpen0_el1);
write_sysreg32!(icc_igrpen1_el1, 0, c12, c12, 7, write_icc_igrpen1_el1);
write_sysreg32!(icc_igrpen1_el3, 6, c12, c12, 7, write_icc_igrpen1_el3);

Check warning on line 25 in src/sysreg.rs

View workflow job for this annotation

GitHub Actions / clippy

function `write_icc_igrpen1_el3` is never used

warning: function `write_icc_igrpen1_el3` is never used --> src/sysreg.rs:25:50 | 25 | write_sysreg32!(icc_igrpen1_el3, 6, c12, c12, 7, write_icc_igrpen1_el3); | ^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(dead_code)]` on by default = note: this warning originates in the macro `write_sysreg32` (in Nightly builds, run with -Z macro-backtrace for more info)
write_sysreg32!(icc_pmr_el1, 0, c4, c6, 0, write_icc_pmr_el1);
write_sysreg64!(icc_sgi1r_el1, 0, c12, write_icc_sgi1r_el1);
write_sysreg32!(icc_sre_el1, 0, c12, c12, 5, write_icc_sre_el1);
write_sysreg32!(icc_sre_el1, 0, c12, c12, 5, write_icc_sre_el1, IccSre);

bitflags! {
/// Type for the `icc_sre_el2` and `icc_sre_el3` registers.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct IccSre: u32 {
/// System register enable.
///
/// Enables access to the GIC CPU interface system registers.
const SRE = 1 << 0;
/// Disable FIQ bypass.
const DFB = 1 << 1;
/// Disable IRQ bypass.
const DIB = 1 << 2;
// TODO: Should this be on a different type? Not all registers have it.
/// Enables lower EL access to ICC_SRE_ELn.
const ENABLE = 1 << 3;
}
}
28 changes: 26 additions & 2 deletions src/sysreg/aarch32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
///
/// This should only be used for system registers which are indeed safe to read.
macro_rules! read_sysreg32 {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2: literal, $function_name:ident) => {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2:literal, $function_name:ident) => {
#[inline]
#[doc = "Autogenerated function to read the 32-bit "]
#[doc = stringify!($sysreg)]
Expand Down Expand Up @@ -38,7 +38,7 @@ macro_rules! read_sysreg32 {
///
/// This should only be used for system registers which are indeed safe to write.
macro_rules! write_sysreg32 {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2: literal, $function_name:ident) => {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2:literal, $function_name:ident) => {
#[inline]
#[doc = "Autogenerated function to write the 32-bit "]
#[doc = stringify!($sysreg)]
Expand All @@ -62,6 +62,30 @@ macro_rules! write_sysreg32 {
}
}
};
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2:literal, $function_name:ident, $type:ty) => {
#[inline]
#[doc = "Autogenerated function to write the 32-bit "]
#[doc = stringify!($sysreg)]
#[doc = " system register"]
pub fn $function_name(value: $type) {
// SAFETY: The caller of the macro guarantees that this system register is safe to
// write.
unsafe {
core::arch::asm!(
concat!(
"mcr p15, ",
stringify!($opc1), ",",
"{value}, ",
stringify!($crm), ",",
stringify!($crn), ",",
stringify!($opc2)
),
options(nostack),
value = in(reg) value.bits(),
);
}
}
};
}

/// Generates a safe public function named `$function_name` to write to the 64-bit system register
Expand Down
21 changes: 19 additions & 2 deletions src/sysreg/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
///
/// This should only be used for system registers which are indeed safe to read.
macro_rules! read_sysreg32 {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2: literal, $function_name:ident) => {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2:literal, $function_name:ident) => {
#[inline]
#[doc = "Autogenerated function to read the 32-bit "]
#[doc = stringify!($sysreg)]
Expand All @@ -31,7 +31,7 @@ macro_rules! read_sysreg32 {
///
/// This should only be used for system registers which are indeed safe to write.
macro_rules! write_sysreg32 {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2: literal, $function_name:ident) => {
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2:literal, $function_name:ident) => {
#[inline]
#[doc = "Autogenerated function to write the 32-bit "]
#[doc = stringify!($sysreg)]
Expand All @@ -48,6 +48,23 @@ macro_rules! write_sysreg32 {
}
}
};
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2:literal, $function_name:ident, $type:ty) => {
#[inline]
#[doc = "Autogenerated function to write the 32-bit "]
#[doc = stringify!($sysreg)]
#[doc = " system register"]
pub fn $function_name(value: $type) {
// SAFETY: The caller of the macro guarantees that this system register is safe to
// write.
unsafe {
core::arch::asm!(
concat!("msr ", stringify!($sysreg), ", {value}"),
options(nostack),
value = in(reg) value.bits() as u64,
);
}
}
};
}

/// Generates a safe public function named `$function_name` to write to the 64-bit system register
Expand Down
10 changes: 8 additions & 2 deletions src/sysreg/fake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

//! Fake implementations of system register getters and setters for unit tests.

use super::IccSre;
use std::sync::Mutex;

/// Values of fake system registers.
Expand All @@ -19,7 +20,7 @@ pub struct SystemRegisters {
pub icc_igrpen1_el1: u32,
pub icc_pmr_el1: u32,
pub icc_sgi1r_el1: u64,
pub icc_sre_el1: u32,
pub icc_sre_el1: IccSre,
}

impl SystemRegisters {
Expand All @@ -32,7 +33,7 @@ impl SystemRegisters {
icc_igrpen1_el1: 0,
icc_pmr_el1: 0,
icc_sgi1r_el1: 0,
icc_sre_el1: 0,
icc_sre_el1: IccSre::empty(),
}
}
}
Expand All @@ -54,6 +55,11 @@ macro_rules! write_sysreg32 {
crate::sysreg::fake::SYSREGS.lock().unwrap().$sysreg = value;
}
};
($sysreg:ident, $opc1:literal, $crm:ident, $crn:ident, $opc2: literal, $function_name:ident, $type:ty) => {
pub fn $function_name(value: $type) {
crate::sysreg::fake::SYSREGS.lock().unwrap().$sysreg = value;
}
};
}

/// Generates a public function named `$function_name` to write to the fake system register
Expand Down
Loading