diff --git a/crate/process/src/interrupt.rs b/crate/process/src/interrupt.rs new file mode 100644 index 0000000..f75102e --- /dev/null +++ b/crate/process/src/interrupt.rs @@ -0,0 +1,29 @@ +#[inline(always)] +#[cfg(target_arch = "x86_64")] +pub unsafe fn disable_and_store() -> usize { + let rflags: usize; + asm!("pushfq; popq $0; cli" : "=r"(rflags)); + rflags & (1 << 9) +} + +#[inline(always)] +#[cfg(target_arch = "riscv32")] +pub unsafe fn disable_and_store() -> usize { + let sstatus: usize; + asm!("csrrci $0, 0x100, 1" : "=r"(sstatus)); + sstatus & 1 +} + +#[inline(always)] +#[cfg(target_arch = "x86_64")] +pub unsafe fn restore(flags: usize) { + if flags != 0 { + asm!("sti"); + } +} + +#[inline(always)] +#[cfg(target_arch = "riscv32")] +pub unsafe fn restore(flags: usize) { + asm!("csrs 0x100, $0" :: "r"(flags)); +} \ No newline at end of file diff --git a/crate/process/src/lib.rs b/crate/process/src/lib.rs index 07c2e2c..feb5f63 100644 --- a/crate/process/src/lib.rs +++ b/crate/process/src/lib.rs @@ -4,6 +4,7 @@ #![feature(linkage)] #![feature(nll)] #![feature(vec_resize_default)] +#![feature(asm)] extern crate alloc; #[macro_use] @@ -20,6 +21,7 @@ mod processor; pub mod scheduler; pub mod thread; mod event_hub; +mod interrupt; pub use process_manager::*; pub use processor::Processor; diff --git a/crate/process/src/processor.rs b/crate/process/src/processor.rs index c1432ca..f0b3a4e 100644 --- a/crate/process/src/processor.rs +++ b/crate/process/src/processor.rs @@ -3,6 +3,7 @@ use alloc::sync::Arc; use spin::Mutex; use core::cell::UnsafeCell; use process_manager::*; +use interrupt; /// Process executor /// @@ -52,6 +53,7 @@ impl Processor { /// via switch back to the scheduler. pub fn run(&self) -> ! { let inner = self.inner(); + unsafe { interrupt::disable_and_store(); } loop { let proc = inner.manager.run(inner.id); trace!("CPU{} begin running process {}", inner.id, proc.0); @@ -70,7 +72,9 @@ impl Processor { pub fn yield_now(&self) { let inner = self.inner(); unsafe { + let flags = interrupt::disable_and_store(); inner.proc.as_mut().unwrap().1.switch_to(&mut *inner.loop_context); + interrupt::restore(flags); } }