mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-05-24 08:55:20 -04:00
libkernel: CpuOps: make interrupt flags a associated type
Rather than hard-coding the interrupt flags as a `usize`. Allow each CPU architecture to define it's own interrupt flags type via an associated type.
This commit is contained in:
committed by
Ashwin Naren
parent
20c17b69c5
commit
370aae9697
@@ -83,6 +83,7 @@ extern crate alloc;
|
||||
/// struct MockCpu;
|
||||
///
|
||||
/// impl CpuOps for MockCpu {
|
||||
/// type InterruptFlags = usize;
|
||||
/// fn id() -> usize { 0 }
|
||||
/// fn halt() -> ! { loop { core::hint::spin_loop() } }
|
||||
/// fn disable_interrupts() -> usize { 0 }
|
||||
@@ -91,6 +92,9 @@ extern crate alloc;
|
||||
/// }
|
||||
/// ```
|
||||
pub trait CpuOps: 'static {
|
||||
/// The type of the register that contains the interrupt flag enable state.
|
||||
type InterruptFlags: Clone + Copy;
|
||||
|
||||
/// Returns the ID of the currently executing core.
|
||||
fn id() -> usize;
|
||||
|
||||
@@ -99,10 +103,10 @@ pub trait CpuOps: 'static {
|
||||
|
||||
/// Disables all maskable interrupts on the current CPU core, returning the
|
||||
/// previous state prior to masking.
|
||||
fn disable_interrupts() -> usize;
|
||||
fn disable_interrupts() -> Self::InterruptFlags;
|
||||
|
||||
/// Restore the previous interrupt state obtained from `disable_interrupts`.
|
||||
fn restore_interrupt_state(flags: usize);
|
||||
fn restore_interrupt_state(flags: Self::InterruptFlags);
|
||||
|
||||
/// Explicitly enables maskable interrupts on the current CPU core.
|
||||
fn enable_interrupts();
|
||||
@@ -119,6 +123,8 @@ pub mod test {
|
||||
pub struct MockCpuOps {}
|
||||
|
||||
impl CpuOps for MockCpuOps {
|
||||
type InterruptFlags = usize;
|
||||
|
||||
fn id() -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ use crate::CpuOps;
|
||||
/// A wrapper for a RefCell guard (G) that restores interrupts on drop.
|
||||
pub struct IrqGuard<G, CPU: CpuOps> {
|
||||
guard: ManuallyDrop<G>,
|
||||
flags: usize,
|
||||
flags: CPU::InterruptFlags,
|
||||
_phantom: PhantomData<CPU>,
|
||||
}
|
||||
|
||||
impl<G, CPU: CpuOps> IrqGuard<G, CPU> {
|
||||
fn new(guard: G, flags: usize) -> Self {
|
||||
fn new(guard: G, flags: CPU::InterruptFlags) -> Self {
|
||||
Self {
|
||||
guard: ManuallyDrop::new(guard),
|
||||
flags,
|
||||
@@ -68,7 +68,7 @@ where
|
||||
/// A mutable borrow of per-CPU data that restores interrupts on drop.
|
||||
pub struct IrqSafeRefMut<'a, T, CPU: CpuOps> {
|
||||
borrow: ManuallyDrop<RefMut<'a, T>>,
|
||||
flags: usize,
|
||||
flags: CPU::InterruptFlags,
|
||||
_phantom: PhantomData<CPU>,
|
||||
}
|
||||
|
||||
@@ -316,6 +316,8 @@ mod tests {
|
||||
struct MockArch;
|
||||
|
||||
impl CpuOps for MockArch {
|
||||
type InterruptFlags = usize;
|
||||
|
||||
fn id() -> usize {
|
||||
MOCK_CPU_ID.with(|id| id.get())
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ impl<T: ?Sized, CPU: CpuOps> SpinLockIrq<T, CPU> {
|
||||
#[must_use]
|
||||
pub struct SpinLockIrqGuard<'a, T: ?Sized + 'a, CPU: CpuOps> {
|
||||
lock: &'a SpinLockIrq<T, CPU>,
|
||||
irq_flags: usize, // The saved DAIF register state
|
||||
irq_flags: CPU::InterruptFlags,
|
||||
_marker: PhantomData<*const ()>, // !Send
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use core::arch::asm;
|
||||
|
||||
/// Returns the current state of the interrupt flags (DAIF register) and disables IRQs.
|
||||
#[inline(always)]
|
||||
pub fn local_irq_save() -> usize {
|
||||
pub fn local_irq_save() -> u64 {
|
||||
let flags: u64;
|
||||
unsafe {
|
||||
asm!(
|
||||
@@ -12,16 +12,16 @@ pub fn local_irq_save() -> usize {
|
||||
options(nomem, nostack)
|
||||
);
|
||||
}
|
||||
flags as _
|
||||
flags
|
||||
}
|
||||
|
||||
/// Restores the interrupt flags to a previously saved state.
|
||||
#[inline(always)]
|
||||
pub fn local_irq_restore(flags: usize) {
|
||||
pub fn local_irq_restore(flags: u64) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"msr daif, {0}", // Write flags back to DAIF
|
||||
in(reg) flags as u64,
|
||||
in(reg) flags,
|
||||
options(nomem, nostack)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ impl SlabGetter<ArchImpl, PgAllocGetter, PageOffsetTranslator> for StaticSlabGet
|
||||
}
|
||||
|
||||
pub struct PerCpuCache {
|
||||
flags: usize,
|
||||
flags: u64,
|
||||
}
|
||||
|
||||
impl PerCpuCache {
|
||||
|
||||
@@ -48,6 +48,8 @@ pub mod ptrace;
|
||||
pub struct Aarch64 {}
|
||||
|
||||
impl CpuOps for Aarch64 {
|
||||
type InterruptFlags = u64;
|
||||
|
||||
fn id() -> usize {
|
||||
MPIDR_EL1.read(MPIDR_EL1::Aff0) as _
|
||||
}
|
||||
@@ -58,11 +60,11 @@ impl CpuOps for Aarch64 {
|
||||
}
|
||||
}
|
||||
|
||||
fn disable_interrupts() -> usize {
|
||||
fn disable_interrupts() -> Self::InterruptFlags {
|
||||
local_irq_save()
|
||||
}
|
||||
|
||||
fn restore_interrupt_state(state: usize) {
|
||||
fn restore_interrupt_state(state: Self::InterruptFlags) {
|
||||
local_irq_restore(state);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user