Skip to content

Commit

Permalink
Enable timer interrupt
Browse files Browse the repository at this point in the history
  • Loading branch information
田凯夫 committed Mar 11, 2023
1 parent e3687b7 commit 31c864d
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 155 deletions.
55 changes: 52 additions & 3 deletions crates/signal-defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,55 @@ pub use signo::*;
pub use sigpending::*;
pub use sigset::*;

pub fn sigmask(signo: SignalNo) -> u64 {
1 << (usize::from(signo) as u64 - 1)
}
#[inline(always)]
pub const fn sigmask(sig: usize) -> u64 {
1 << (sig as u64 - 1)
}

#[inline(always)]
pub const fn sigtest(sig: usize, mask: u64) -> bool {
sigmask(sig) & mask != 0
}

#[inline(always)]
pub const fn sigvalid(sig: usize) -> bool {
sig >= 1 && sig <= NSIG
}
pub const SIG_KERNEL_ONLY_MASK: u64 = sigmask(SIGKILL) | sigmask(SIGSTOP);

pub const SIG_KERNEL_STOP_MASK: u64 =
sigmask(SIGSTOP) | sigmask(SIGTSTP) | sigmask(SIGTTIN) | sigmask(SIGTTOU);

pub const SIG_KERNEL_COREDUMP_MASK: u64 = sigmask(SIGQUIT)
| sigmask(SIGILL)
| sigmask(SIGTRAP)
| sigmask(SIGABRT)
| sigmask(SIGFPE)
| sigmask(SIGSEGV)
| sigmask(SIGBUS)
| sigmask(SIGSYS)
| sigmask(SIGXCPU)
| sigmask(SIGXFSZ);

pub const SIG_KERNEL_IGNORE_MASK: u64 =
sigmask(SIGCONT) | sigmask(SIGCHLD) | sigmask(SIGWINCH) | sigmask(SIGURG);

#[inline(always)]
pub fn sig_kernel_only(sig: usize) -> bool {
sig == SIGKILL || sig == SIGSTOP
}

#[inline(always)]
pub fn sig_kernel_coredump(sig: usize) -> bool {
sigtest(sig, SIG_KERNEL_COREDUMP_MASK)
}

#[inline(always)]
pub fn sig_kernel_ignore(sig: usize) -> bool {
sigtest(sig, SIG_KERNEL_IGNORE_MASK)
}

#[inline(always)]
pub fn sig_kernel_stop(sig: usize) -> bool {
sigtest(sig, SIG_KERNEL_STOP_MASK)
}
45 changes: 1 addition & 44 deletions crates/signal-defs/src/sigaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,6 @@ impl SigAction {
Self::default()
}

/// Gets the programmer defined signal handler.
///
/// Returns None if `SA_SIGINFO` is set or default action is used or the signal is ignored.
pub fn get_handler(&self) -> Option<usize> {
if self.flags.contains(SigActionFlags::SA_SIGINFO)
|| self.handler == SIG_DFL
|| self.handler == SIG_IGN
{
None
} else {
Some(self.handler)
}
}

/// Returns if the signal will be ignored.
pub fn is_ignored(&self) -> bool {
!self.flags.contains(SigActionFlags::SA_SIGINFO) && self.handler == SIG_IGN
Expand Down Expand Up @@ -166,33 +152,4 @@ pub enum SigActionDefault {

pub const NSIG: usize = 64;

#[derive(Debug, Clone, Copy)]
pub struct SigActions(pub [Option<SigAction>; NSIG]);

impl SigActions {
/// Creates a new `SigActions`.
pub fn new() -> Self {
Self([None; NSIG])
}

/// Gets an immutable reference of the `SigAction` by `signum`.
pub fn get_ref(&mut self, signum: usize) -> &SigAction {
self.0[signum - 1] = Some(SigAction::new());
self.0[signum - 1].as_ref().unwrap()
}

/// Gets a mutable reference of the `SigAction` by `signum`.
pub fn get_mut(&mut self, signum: usize) -> &mut SigAction {
self.0[signum - 1] = Some(SigAction::new());
self.0[signum - 1].as_mut().unwrap()
}

/// Gets the programmer defined signal handler.
///
/// Returns None if `SA_SIGINFO` is set or default action is used or the signal is ignored.
pub fn get_handler(&self, signum: usize) -> Option<usize> {
self.0[signum - 1]
.as_ref()
.and_then(|action| action.get_handler())
}
}
pub type SigActions = [SigAction; NSIG];
139 changes: 64 additions & 75 deletions crates/signal-defs/src/signo.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,64 @@
numeric_enum_macro::numeric_enum! {
#[repr(usize)]
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum SignalNo {
ERR = 0,

/// The HUP signal is sent to a process when its controlling terminal is
/// closed. It was originally designed to notify a serial line drop (HUP
/// stands for "Hang Up"). In modern systems, this signal usually indicates
/// the controlling pseudo or virtual terminal is closed.
SIGHUP = 1,
SIGINT = 2,
SIGQUIT = 3,
SIGILL = 4,
SIGTRAP = 5,
SIGABRT = 6,
SIGBUS = 7,
SIGFPE = 8,
SIGKILL = 9,
SIGUSR1 = 10,
SIGSEGV = 11,
SIGUSR2 = 12,
SIGPIPE = 13,
SIGALRM = 14,
SIGTERM = 15,
SIGSTKFLT = 16,
SIGCHLD = 17,
SIGCONT = 18,
SIGSTOP = 19,
SIGTSTP = 20,
SIGTTIN = 21,
SIGTTOU = 22,
SIGURG = 23,
SIGXCPU = 24,
SIGXFSZ = 25,
SIGVTALRM = 26,
SIGPROF = 27,
SIGWINCH = 28,
SIGIO = 29,
SIGPWR = 30,
SIGSYS = 31,
SIGRTMIN = 32,
SIGRT1 = 33,
SIGRT2 = 34,
SIGRT3 = 35,
SIGRT4 = 36,
SIGRT5 = 37,
SIGRT6 = 38,
SIGRT7 = 39,
SIGRT8 = 40,
SIGRT9 = 41,
SIGRT10 = 42,
SIGRT11 = 43,
SIGRT12 = 44,
SIGRT13 = 45,
SIGRT14 = 46,
SIGRT15 = 47,
SIGRT16 = 48,
SIGRT17 = 49,
SIGRT18 = 50,
SIGRT19 = 51,
SIGRT20 = 52,
SIGRT21 = 53,
SIGRT22 = 54,
SIGRT23 = 55,
SIGRT24 = 56,
SIGRT25 = 57,
SIGRT26 = 58,
SIGRT27 = 59,
SIGRT28 = 60,
SIGRT29 = 61,
SIGRT30 = 62,
SIGRT31 = 63,
}
}
pub const SIGNONE: usize = 0;
pub const SIGHUP: usize = 1;
pub const SIGINT: usize = 2;
pub const SIGQUIT: usize = 3;
pub const SIGILL: usize = 4;
pub const SIGTRAP: usize = 5;
pub const SIGABRT: usize = 6;
pub const SIGBUS: usize = 7;
pub const SIGFPE: usize = 8;
pub const SIGKILL: usize = 9;
pub const SIGUSR1: usize = 10;
pub const SIGSEGV: usize = 11;
pub const SIGUSR2: usize = 12;
pub const SIGPIPE: usize = 13;
pub const SIGALRM: usize = 14;
pub const SIGTERM: usize = 15;
pub const SIGSTKFLT: usize = 16;
pub const SIGCHLD: usize = 17;
pub const SIGCONT: usize = 18;
pub const SIGSTOP: usize = 19;
pub const SIGTSTP: usize = 20;
pub const SIGTTIN: usize = 21;
pub const SIGTTOU: usize = 22;
pub const SIGURG: usize = 23;
pub const SIGXCPU: usize = 24;
pub const SIGXFSZ: usize = 25;
pub const SIGVTALRM: usize = 26;
pub const SIGPROF: usize = 27;
pub const SIGWINCH: usize = 28;
pub const SIGIO: usize = 29;
pub const SIGPWR: usize = 30;
pub const SIGSYS: usize = 31;
pub const SIGRTMIN: usize = 32;
pub const SIGRT1: usize = 33;
pub const SIGRT2: usize = 34;
pub const SIGRT3: usize = 35;
pub const SIGRT4: usize = 36;
pub const SIGRT5: usize = 37;
pub const SIGRT6: usize = 38;
pub const SIGRT7: usize = 39;
pub const SIGRT8: usize = 40;
pub const SIGRT9: usize = 41;
pub const SIGRT10: usize = 42;
pub const SIGRT11: usize = 43;
pub const SIGRT12: usize = 44;
pub const SIGRT13: usize = 45;
pub const SIGRT14: usize = 46;
pub const SIGRT15: usize = 47;
pub const SIGRT16: usize = 48;
pub const SIGRT17: usize = 49;
pub const SIGRT18: usize = 50;
pub const SIGRT19: usize = 51;
pub const SIGRT20: usize = 52;
pub const SIGRT21: usize = 53;
pub const SIGRT22: usize = 54;
pub const SIGRT23: usize = 55;
pub const SIGRT24: usize = 56;
pub const SIGRT25: usize = 57;
pub const SIGRT26: usize = 58;
pub const SIGRT27: usize = 59;
pub const SIGRT28: usize = 60;
pub const SIGRT29: usize = 61;
pub const SIGRT30: usize = 62;
pub const SIGRT31: usize = 63;
12 changes: 10 additions & 2 deletions crates/signal-defs/src/sigset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,21 @@ impl SigSet {
self.0 |= 1 << kth;
}

/// Sets bits in mask
pub fn set_mask(&mut self, mask: u64) {
self.0 |= mask;
}

/// Unsets the bit.
pub fn unset(&mut self, kth: usize) {
self.0 &= !(1 << kth);
}

/// Unsets bits in mask
pub fn unset_mask(&mut self, mask: u64) {
self.0 &= !mask;
}

/// Gets union.
pub fn union(&mut self, other: &SigSet) {
self.0 |= other.0;
Expand All @@ -47,8 +57,6 @@ impl SigSet {
pub fn difference(&mut self, other: &SigSet) {
self.0 &= !other.0;
}


}

impl From<u64> for SigSet {
Expand Down
30 changes: 30 additions & 0 deletions crates/syscall/src/comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ pub trait SyscallComm {
Ok(0)
}

/// The set of blocked signals is the union of the current set and the set argument.
const SIG_BLOCK: usize = 0;

/// The signals in set are removed from the current set of blocked signals. It is permissible
/// to attempt to unblock a signal which is not blocked.
const SIG_UNBLOCK: usize = 1;

/// The set of blocked signals is set to the argument set.
const SIG_SETMASK: usize = 2;

/// Sigprocmask() is used to fetch and/or change the signal mask of the calling
/// thread. The signal mask is the set of signals whose delivery is currently
/// blocked for the caller (see also signal(7) for more details).
Expand Down Expand Up @@ -73,4 +83,24 @@ pub trait SyscallComm {
fn sigpending(set: usize) -> SyscallResult {
Ok(0)
}


/// The sigtimedwait() function shall be equivalent to sigwaitinfo() except that if none of the signals
/// specified by set are pending, sigtimedwait() shall wait for the time interval specified in the timespec
/// structure referenced by timeout. If the timespec structure pointed to by timeout is zero-valued and if
/// none of the signals specified by set are pending, then sigtimedwait() shall return immediately with an error.
/// If timeout is the null pointer, the behavior is unspecified.
///
/// The sigwaitinfo() function selects the pending signal from the set specified by set. Should any of multiple
/// pending signals in the range SIGRTMIN to SIGRTMAX be selected, it shall be the lowest numbered one.
/// The selection order between realtime and non-realtime signals, or between multiple pending non-realtime signals,
/// is unspecified. If no signal in set is pending at the time of the call, the calling thread shall be suspended
/// until one or more signals in set become pending or until it is interrupted by an unblocked, caught signal.
///
/// # Return
/// Upon successful completion (that is, one of the signals specified by set is pending or is generated) sigwaitinfo()
/// and sigtimedwait() shall return the selected signal number.
fn sigtimedwait(set: usize, info: usize, timeout: usize) -> SyscallResult {
Ok(0)
}
}
6 changes: 6 additions & 0 deletions kernel/src/arch/riscv64/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ pub fn get_time_ms() -> usize {
pub fn get_time_us() -> usize {
time::read() / (CLOCK_FREQ / USEC_PER_SEC)
}

#[inline]
pub fn set_timer(stime_value: u64) {
sbi_rt::set_timer(stime_value);
}

16 changes: 15 additions & 1 deletion kernel/src/arch/riscv64/trap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use crate::{
println,
syscall::syscall,
task::do_exit,
task::{manager::curr_task, trapframe_base},
task::{do_yield, manager::curr_task, trapframe_base},
timer::set_next_trigger,
};

use self::trapframe::KernelTrapContext;
Expand All @@ -39,6 +40,12 @@ pub fn set_user_trap() {
unsafe { stvec::write(TRAMPOLINE_VA as usize, TrapMode::Direct) };
}

pub fn enable_timer_intr() {
unsafe {
sie::set_stimer();
}
}

/// User trap handler manages the task according to the cause:
///
/// 1. Calls syscall dispatcher and handler.
Expand Down Expand Up @@ -103,6 +110,13 @@ pub fn user_trap_handler() -> ! {
unsafe { do_exit(-1) };
}
}
Trap::Interrupt(Interrupt::SupervisorTimer) => {
trap_info();
set_next_trigger();
unsafe {
do_yield();
}
}
_ => {
let curr = curr_task().unwrap();
show_trapframe(curr.trapframe());
Expand Down
3 changes: 3 additions & 0 deletions kernel/src/config/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,6 @@ cfg_if::cfg_if! {
pub const TEST_UINTR: bool = false;
}
}

/// Timer interrupt per second
pub const INTR_PER_SEC: usize = 10;
2 changes: 1 addition & 1 deletion kernel/src/config/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub const USER_HEAP_SIZE: usize = 0x40_0000;
pub const USER_HEAP_PAGES: usize = USER_HEAP_SIZE >> PAGE_SIZE_BITS;

/// User stack size
pub const USER_STACK_SIZE: usize = 0x2_0000;
pub const USER_STACK_SIZE: usize = 0x20_0000;

/// User stack pages
pub const USER_STACK_PAGES: usize = USER_STACK_SIZE >> PAGE_SIZE_BITS;
Expand Down
Loading

0 comments on commit 31c864d

Please sign in to comment.