diff --git a/kernel/src/arch/aarch64/exception.rs b/kernel/src/arch/aarch64/exception.rs index be29151..d2a54dd 100644 --- a/kernel/src/arch/aarch64/exception.rs +++ b/kernel/src/arch/aarch64/exception.rs @@ -2,7 +2,6 @@ use crate::arch::aarch64::consts::ARMDataAbort; use crate::arch::aarch64::consts::ARMPrefetchAbort; use crate::compatibility::lookupIPCBuffer; use crate::halt; -use crate::kernel::boot::current_fault; use crate::object::lookupCapAndSlot; use crate::strnlen; use crate::syscall::handle_fault; @@ -15,6 +14,7 @@ use aarch64_cpu::registers::Readable; use aarch64_cpu::registers::TTBR0_EL1; use log::debug; use sel4_common::arch::ArchReg::*; +use sel4_common::ffi::current_fault; use sel4_common::platform::timer; use sel4_common::platform::Timer_func; use sel4_common::print; diff --git a/kernel/src/arch/riscv/exception.rs b/kernel/src/arch/riscv/exception.rs index f920263..0beb7c4 100644 --- a/kernel/src/arch/riscv/exception.rs +++ b/kernel/src/arch/riscv/exception.rs @@ -2,7 +2,6 @@ use super::read_stval; use crate::compatibility::lookupIPCBuffer; use crate::config::*; use crate::halt; -use crate::kernel::boot::current_fault; use crate::object::lookupCapAndSlot; use crate::strnlen; use crate::syscall::handle_fault; @@ -12,6 +11,7 @@ use crate::syscall::{ }; use log::debug; use sel4_common::arch::ArchReg::*; +use sel4_common::ffi::current_fault; use sel4_common::platform::read_time; use sel4_common::print; use sel4_common::sel4_config::seL4_MsgMaxLength; diff --git a/kernel/src/kernel/boot.rs b/kernel/src/kernel/boot.rs index 073ac92..3a78c5a 100644 --- a/kernel/src/kernel/boot.rs +++ b/kernel/src/kernel/boot.rs @@ -14,12 +14,6 @@ use crate::structures::{extra_caps_t, syscall_error_t}; // #[link_section = ".boot.bss"] pub static mut current_lookup_fault: lookup_fault = lookup_fault(Bitfield { arr: [0; 2] }); -#[no_mangle] -// #[link_section = ".boot.bss"] -pub static mut current_fault: seL4_Fault = seL4_Fault { - 0: Bitfield { arr: [0; 2usize] }, -}; - #[no_mangle] // #[link_section = ".boot.bss"] pub static mut current_syscall_error: syscall_error_t = syscall_error_t { diff --git a/kernel/src/syscall/invocation/decode/decode_sched_invocation.rs b/kernel/src/syscall/invocation/decode/decode_sched_invocation.rs index 8747a88..25b08b3 100644 --- a/kernel/src/syscall/invocation/decode/decode_sched_invocation.rs +++ b/kernel/src/syscall/invocation/decode/decode_sched_invocation.rs @@ -1,13 +1,24 @@ use log::debug; -use sel4_common::{structures::exception_t, utils::global_ops}; +use sel4_common::{arch::MessageLabel, println, structures::{exception_t, seL4_IPCBuffer}, structures_gen::{cap_sched_context_cap, cap_sched_control_cap}, utils::global_ops}; use sel4_task::sched_context::sched_context; use crate::kernel::boot::current_extra_caps; -pub fn decode_sched_context_invocation() -> exception_t { +pub fn decode_sched_context_invocation( + inv_label: MessageLabel, + capability: &cap_sched_context_cap, + buffer: &seL4_IPCBuffer, +) -> exception_t { + println!("go into decode sched context invocation"); exception_t::EXCEPTION_NONE } -pub fn decode_sched_control_invocation() -> exception_t { +pub fn decode_sched_control_invocation( + inv_label: MessageLabel, + length: usize, + capability: &cap_sched_control_cap, + buffer: &seL4_IPCBuffer, +) -> exception_t { + println!("go into decode sched control invocation"); exception_t::EXCEPTION_NONE } pub fn decodeSchedContext_UnbindObject(sc: &mut sched_context) -> exception_t { diff --git a/kernel/src/syscall/invocation/decode/mod.rs b/kernel/src/syscall/invocation/decode/mod.rs index 50950de..74bf2a3 100644 --- a/kernel/src/syscall/invocation/decode/mod.rs +++ b/kernel/src/syscall/invocation/decode/mod.rs @@ -104,29 +104,21 @@ pub fn decode_invocation( } cap_Splayed::reply_cap(data) => { - #[cfg(feature = "KERNEL_MCS")] - { - // TODO: MCS - exception_t::EXCEPTION_NONE - } - #[cfg(not(feature = "KERNEL_MCS"))] - { - if unlikely(data.get_capReplyMaster() != 0) { - debug!("Attempted to invoke an invalid reply cap {}.", cap_index); - unsafe { - current_syscall_error._type = seL4_InvalidCapability; - current_syscall_error.invalidCapNumber = 0; - return exception_t::EXCEPTION_SYSCALL_ERROR; - } + if unlikely(data.get_capReplyMaster() != 0) { + debug!("Attempted to invoke an invalid reply cap {}.", cap_index); + unsafe { + current_syscall_error._type = seL4_InvalidCapability; + current_syscall_error.invalidCapNumber = 0; + return exception_t::EXCEPTION_SYSCALL_ERROR; } - set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); - get_currenct_thread().do_reply( - convert_to_mut_type_ref::(data.get_capTCBPtr() as usize), - slot, - data.get_capReplyCanGrant() != 0, - ); - exception_t::EXCEPTION_NONE } + set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); + get_currenct_thread().do_reply( + convert_to_mut_type_ref::(data.get_capTCBPtr() as usize), + slot, + data.get_capReplyCanGrant() != 0, + ); + exception_t::EXCEPTION_NONE } cap_Splayed::thread_cap(data) => { decode_tcb_invocation(label, length, &data, slot, call, buffer) @@ -161,6 +153,8 @@ pub fn decode_invocation( // TODO: MCS , in this function, there's lot's of mcs codes // println!("decode invocation {}",capability.get_tag()); + use sel4_task::reply::reply_t; + match capability.clone().splay() { cap_Splayed::null_cap(_) | cap_Splayed::zombie_cap(_) => { debug!( @@ -219,29 +213,12 @@ pub fn decode_invocation( } cap_Splayed::reply_cap(data) => { - #[cfg(feature = "KERNEL_MCS")] - { - // TODO: MCS - exception_t::EXCEPTION_NONE - } - #[cfg(not(feature = "KERNEL_MCS"))] - { - if unlikely(data.get_capReplyMaster() != 0) { - debug!("Attempted to invoke an invalid reply cap {}.", cap_index); - unsafe { - current_syscall_error._type = seL4_InvalidCapability; - current_syscall_error.invalidCapNumber = 0; - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - } - set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); - get_currenct_thread().do_reply( - convert_to_mut_type_ref::(data.get_capTCBPtr() as usize), - slot, - data.get_capReplyCanGrant() != 0, - ); - exception_t::EXCEPTION_NONE - } + set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); + get_currenct_thread().do_reply( + convert_to_mut_type_ref::(data.get_capReplyPtr() as usize), + data.get_capReplyCanGrant() != 0, + ); + exception_t::EXCEPTION_NONE } cap_Splayed::thread_cap(data) => { if unlikely(firstPhase) { @@ -275,7 +252,7 @@ pub fn decode_invocation( cap_Splayed::irq_handler_cap(data) => { decode_irq_handler_invocation(label, data.get_capIRQ() as usize) } - cap_Splayed::sched_control_cap(_) => { + cap_Splayed::sched_control_cap(data) => { if unlikely(firstPhase) { debug!( "Cannot invoke sched control capabilities in the first phase of an invocation" @@ -286,9 +263,9 @@ pub fn decode_invocation( } return exception_t::EXCEPTION_NONE; } - decode_sched_control_invocation() + decode_sched_control_invocation(label,length,&data,buffer) } - cap_Splayed::sched_context_cap(_) => { + cap_Splayed::sched_context_cap(data) => { if unlikely(firstPhase) { debug!( "Cannot invoke sched context capabilities in the first phase of an invocation" @@ -299,7 +276,7 @@ pub fn decode_invocation( } return exception_t::EXCEPTION_NONE; } - decode_sched_context_invocation() + decode_sched_context_invocation(label,&data,buffer) } _ => decode_mmu_invocation(label, length, slot, call, buffer), } diff --git a/kernel/src/syscall/invocation/mod.rs b/kernel/src/syscall/invocation/mod.rs index 862b045..60b74b9 100644 --- a/kernel/src/syscall/invocation/mod.rs +++ b/kernel/src/syscall/invocation/mod.rs @@ -18,10 +18,10 @@ use sel4_common::structures::exception_t; use sel4_common::structures_gen::seL4_Fault_CapFault; use sel4_task::{get_currenct_thread, set_thread_state, ThreadState}; -use crate::kernel::boot::current_fault; use crate::syscall::invocation::decode::decode_invocation; use crate::syscall::syscall_reply::{reply_error_from_kernel, reply_success_from_kernel}; use crate::syscall::{handle_fault, lookup_extra_caps_with_buf}; +use sel4_common::ffi::current_fault; #[no_mangle] #[cfg(not(feature = "KERNEL_MCS"))] diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 14a409b..26887b3 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -77,8 +77,9 @@ pub use utils::*; use crate::arch::restore_user_context; use crate::interrupt::handler::handleInterrupt; -use crate::kernel::boot::{current_fault, current_lookup_fault}; +use crate::kernel::boot::current_lookup_fault; use crate::{config::irqInvalid, interrupt::getActiveIRQ}; +use sel4_common::ffi::current_fault; use self::invocation::handleInvocation; @@ -335,6 +336,7 @@ pub fn handle_fault(thread: &mut tcb_t) { } #[inline] #[cfg(feature = "KERNEL_MCS")] +#[no_mangle] pub fn handleTimeout(tptr: &mut tcb_t) { use sel4_common::sel4_config::tcbTimeoutHandler; diff --git a/kernel/src/syscall/utils.rs b/kernel/src/syscall/utils.rs index e2c6c24..5f6a0aa 100644 --- a/kernel/src/syscall/utils.rs +++ b/kernel/src/syscall/utils.rs @@ -1,6 +1,6 @@ use core::intrinsics::unlikely; -use crate::kernel::boot::{current_extra_caps, current_fault}; +use crate::kernel::boot::current_extra_caps; use crate::{ config::seL4_MinPrio, kernel::boot::{current_lookup_fault, current_syscall_error}, @@ -8,6 +8,7 @@ use crate::{ }; use log::debug; use sel4_common::arch::{maskVMRights, msgRegisterNum, ArchReg}; +use sel4_common::ffi::current_fault; use sel4_common::sel4_config::seL4_MinUntypedBits; use sel4_common::shared_types_bf_gen::seL4_CapRights; use sel4_common::structures_gen::{ diff --git a/sel4_common/src/ffi.rs b/sel4_common/src/ffi.rs index 1f1b6f0..6032d11 100644 --- a/sel4_common/src/ffi.rs +++ b/sel4_common/src/ffi.rs @@ -1,4 +1,6 @@ +use crate::sel4_bitfield_types::Bitfield; use crate::sel4_config::{CONFIG_KERNEL_STACK_BITS, CONFIG_MAX_NUM_NODES}; +use crate::structures_gen::seL4_Fault; use crate::BIT; #[repr(align(4096))] pub struct kernel_stack_alloc_data { @@ -13,3 +15,9 @@ pub static mut kernel_stack_alloc: kernel_stack_alloc_data = kernel_stack_alloc_ extern "C" { pub fn coreMap(); } + +#[no_mangle] +// #[link_section = ".boot.bss"] +pub static mut current_fault: seL4_Fault = seL4_Fault { + 0: Bitfield { arr: [0; 2usize] }, +}; diff --git a/sel4_ipc/src/transfer.rs b/sel4_ipc/src/transfer.rs index 4c8fe4a..f1e3530 100644 --- a/sel4_ipc/src/transfer.rs +++ b/sel4_ipc/src/transfer.rs @@ -19,6 +19,8 @@ use sel4_common::structures_gen::seL4_Fault_NullFault; use sel4_common::structures_gen::seL4_Fault_tag; use sel4_common::utils::*; use sel4_cspace::interface::*; +#[cfg(feature = "KERNEL_MCS")] +use sel4_task::reply::reply_t; use sel4_task::{possible_switch_to, set_thread_state, tcb_t, ThreadState}; use sel4_vspace::pptr_t; @@ -62,7 +64,9 @@ pub trait Transfer { badge: usize, grant: bool, ); - + #[cfg(feature = "KERNEL_MCS")] + fn do_reply(&mut self, reply: &mut reply_t, grant: bool); + #[cfg(not(feature = "KERNEL_MCS"))] fn do_reply(&mut self, receiver: &mut tcb_t, slot: &mut cte_t, grant: bool); } @@ -326,7 +330,61 @@ impl Transfer for tcb_t { self.do_fault_transfer(receiver, badge) } } + #[cfg(feature = "KERNEL_MCS")] + fn do_reply(&mut self, reply: &mut reply_t, grant: bool) { + use sel4_common::{ffi::current_fault, structures_gen::seL4_Fault_Timeout}; + use sel4_task::{handleTimeout, ksCurSC, sched_context::sched_context_t}; + + if reply.replyTCB == 0 + || convert_to_mut_type_ref::(reply.replyTCB) + .tcbState + .get_tsType() + != ThreadState::ThreadStateBlockedOnReply as u64 + { + /* nothing to do */ + return; + } + + let receiver = convert_to_mut_type_ref::(reply.replyTCB); + reply.remove(receiver); + assert!(receiver.tcbState.get_replyObject() == 0); + assert!(reply.replyTCB == 0); + + let sc = convert_to_mut_type_ref::(receiver.tcbSchedContext); + if sc.sc_sporadic() && sc.get_ptr() != unsafe { ksCurSC } { + sc.refill_unblock_check(); + } + assert_eq!(receiver.get_state(), ThreadState::ThreadStateBlockedOnReply); + let fault_type = receiver.tcbFault.get_tag(); + if likely(fault_type == seL4_Fault_tag::seL4_Fault_NullFault) { + self.do_ipc_transfer(receiver, None, 0, grant); + set_thread_state(receiver, ThreadState::ThreadStateRunning); + } else { + if self.do_fault_reply_transfer(receiver) { + set_thread_state(receiver, ThreadState::ThreadStateRestart); + } else { + set_thread_state(receiver, ThreadState::ThreadStateInactive); + } + } + if receiver.tcbSchedContext != 0 && receiver.is_runnable() { + if sc.refill_ready() && sc.refill_sufficient(0) { + possible_switch_to(receiver); + } else { + if receiver.validTimeoutHandler() + && fault_type != seL4_Fault_tag::seL4_Fault_Timeout as u64 + { + unsafe { + current_fault = seL4_Fault_Timeout::new(sc.scBadge as u64).unsplay(); + handleTimeout(receiver) + }; + } else { + sc.postpone(); + } + } + } + } + #[cfg(not(feature = "KERNEL_MCS"))] fn do_reply(&mut self, receiver: &mut tcb_t, slot: &mut cte_t, grant: bool) { assert_eq!(receiver.get_state(), ThreadState::ThreadStateBlockedOnReply); let fault_type = receiver.tcbFault.get_tag(); diff --git a/sel4_task/src/ffi.rs b/sel4_task/src/ffi.rs index 85c5bb1..eafd1ee 100644 --- a/sel4_task/src/ffi.rs +++ b/sel4_task/src/ffi.rs @@ -42,4 +42,5 @@ extern "C" { pub fn reorder_EP(ep: &mut endpoint, thread: &mut tcb_t); pub fn reorder_NTFN(ntfn: &mut notification, thread: &mut tcb_t); pub fn endTimeslice(can_timeout_fault: bool); + pub fn handleTimeout(tptr: &mut tcb_t); }