diff --git a/src/stop.rs b/src/stop.rs index 7a9ac75..45b8d7d 100644 --- a/src/stop.rs +++ b/src/stop.rs @@ -1,6 +1,23 @@ use acpi; use syscall::io::{Io, Pio}; +#[no_mangle] +pub unsafe extern fn kreset() -> ! { + println!("kreset"); + + // 8042 reset + { + println!("Reset with 8042"); + let mut port = Pio::::new(0x64); + while port.readf(2) {} + port.write(0xFE); + } + + // TODO: Use triple fault to guarantee reset + + unreachable!(); +} + #[no_mangle] pub unsafe extern fn kstop() -> ! { println!("kstop"); @@ -22,7 +39,7 @@ pub unsafe extern fn kstop() -> ! { } } } - + println!("Shutdown with ACPI outw(0x{:X}, 0x{:X})", port, val); Pio::::new(port).write(val); } diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 9216c20..4b3f637 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -20,7 +20,7 @@ use scheme::{self, FileHandle}; use syscall; use syscall::data::{SigAction, Stat}; use syscall::error::*; -use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, O_CLOEXEC, SIG_DFL, WNOHANG}; +use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, O_CLOEXEC, SIG_DFL, SIGTERM, WNOHANG}; use syscall::validate::{validate_slice, validate_slice_mut}; pub fn brk(address: usize) -> Result { @@ -963,13 +963,18 @@ pub fn exit(status: usize) -> ! { } if pid == ContextId::from(1) { - println!("Main kernel thread exited with status {:X}, calling kstop", status); + println!("Main kernel thread exited with status {:X}", status); extern { + fn kreset() -> !; fn kstop() -> !; } - unsafe { kstop(); } + if status == SIGTERM { + unsafe { kreset(); } + } else { + unsafe { kstop(); } + } } }