Skip to content

Commit

Permalink
add the some functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhiyuanSue committed Dec 4, 2024
1 parent 8913cd5 commit 35301e9
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 29 deletions.
131 changes: 125 additions & 6 deletions kernel/src/syscall/invocation/decode/decode_sched_invocation.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
use core::intrinsics::unlikely;

use log::debug;
use sel4_common::{
arch::MessageLabel,
arch::{usToTicks, MessageLabel},
platform::time_def::time_t,
println,
sel4_config::{seL4_IllegalOperation, seL4_RangeError, seL4_TruncatedMessage, TIME_ARG_SIZE},
structures::{exception_t, seL4_IPCBuffer},
structures_gen::{cap_sched_context_cap, cap_sched_control_cap},
utils::global_ops,
structures_gen::{cap, cap_sched_context_cap, cap_sched_control_cap, cap_tag},
utils::{convert_to_mut_type_ref, global_ops},
};
use sel4_cspace::interface::cte_t;
use sel4_task::{
get_currenct_thread,
sched_context::{
refill_absolute_max, sched_context, sched_context_t, MAX_PERIOD_US, MIN_BUDGET,
MIN_BUDGET_US, MIN_REFILLS,
},
set_thread_state, ThreadState,
};
use sel4_task::sched_context::sched_context;

use crate::kernel::boot::current_extra_caps;
use crate::{
kernel::boot::{current_extra_caps, current_syscall_error},
syscall::{get_syscall_arg, invocation::invoke_sched::invokeSchedControl_ConfigureFlags},
};

pub fn decode_sched_context_invocation(
inv_label: MessageLabel,
Expand All @@ -24,7 +39,111 @@ pub fn decode_sched_control_invocation(
capability: &cap_sched_control_cap,
buffer: &seL4_IPCBuffer,
) -> exception_t {
println!("go into decode sched control invocation");
match inv_label {
MessageLabel::SchedControlConfigureFlags => {
if global_ops!(current_extra_caps.excaprefs[0] == 0) {
debug!("SchedControl_ConfigureFlags: Truncated message.");
unsafe {
current_syscall_error._type = seL4_TruncatedMessage;
}
return exception_t::EXCEPTION_SYSCALL_ERROR;
}

if length < (TIME_ARG_SIZE * 2) + 3 {
debug!("SchedControl_configureFlags: truncated message.");
unsafe {
current_syscall_error._type = seL4_TruncatedMessage;
}
return exception_t::EXCEPTION_SYSCALL_ERROR;
}

let budget_us: time_t = get_syscall_arg(0, buffer);
let budget_ticks = usToTicks(budget_us);
let period_us = get_syscall_arg(TIME_ARG_SIZE, buffer);
let period_ticks = usToTicks(period_us);
let extra_refills = get_syscall_arg(TIME_ARG_SIZE * 2, buffer);
let badge = get_syscall_arg(TIME_ARG_SIZE * 2 + 1, buffer);
let flags = get_syscall_arg(TIME_ARG_SIZE * 2 + 2, buffer);

let targetCap =
&convert_to_mut_type_ref::<cte_t>(unsafe { current_extra_caps.excaprefs[0] })
.capability;
if unlikely(targetCap.get_tag() != cap_tag::cap_sched_context_cap) {
debug!("SchedControl_ConfigureFlags: budget out of range.");
unsafe {
current_syscall_error._type = seL4_RangeError;
current_syscall_error.rangeErrorMin = MIN_BUDGET_US();
current_syscall_error.rangeErrorMax = MAX_PERIOD_US();
return exception_t::EXCEPTION_SYSCALL_ERROR;
}
}
if budget_us > MAX_PERIOD_US() || budget_ticks < MIN_BUDGET() {
debug!("SchedControl_ConfigureFlags: budget out of range.");
unsafe {
current_syscall_error._type = seL4_RangeError;
current_syscall_error.rangeErrorMin = MIN_BUDGET_US();
current_syscall_error.rangeErrorMax = MAX_PERIOD_US();
}

return exception_t::EXCEPTION_SYSCALL_ERROR;
}

if period_us > MAX_PERIOD_US() || period_ticks < MIN_BUDGET() {
debug!("SchedControl_ConfigureFlags: period out of range.");
unsafe {
current_syscall_error._type = seL4_RangeError;
current_syscall_error.rangeErrorMin = MIN_BUDGET_US();
current_syscall_error.rangeErrorMax = MAX_PERIOD_US();
}

return exception_t::EXCEPTION_SYSCALL_ERROR;
}

if budget_ticks > period_ticks {
debug!("SchedControl_ConfigureFlags: budget must be <= period");
unsafe {
current_syscall_error._type = seL4_RangeError;
current_syscall_error.rangeErrorMin = MIN_BUDGET_US();
current_syscall_error.rangeErrorMax = period_us;
}
return exception_t::EXCEPTION_SYSCALL_ERROR;
}

if extra_refills + MIN_REFILLS
> refill_absolute_max(cap::cap_sched_context_cap(&targetCap))
{
unsafe {
current_syscall_error._type = seL4_RangeError;
current_syscall_error.rangeErrorMin = 0;
current_syscall_error.rangeErrorMax =
refill_absolute_max(cap::cap_sched_context_cap(&targetCap)) - MIN_REFILLS;
debug!(
"Max refills invalid, got {}, max {}",
extra_refills, current_syscall_error.rangeErrorMax
);
}
return exception_t::EXCEPTION_SYSCALL_ERROR;
}
set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart);
return invokeSchedControl_ConfigureFlags(
convert_to_mut_type_ref::<sched_context_t>(
cap::cap_sched_context_cap(&targetCap).get_capSCPtr() as usize,
),
capability.get_core() as usize,
budget_ticks,
period_ticks,
extra_refills + MIN_REFILLS,
badge,
flags,
);
}
_ => {
debug!("SchedControl invocation: Illegal operation attempted.");
unsafe {
current_syscall_error._type = seL4_IllegalOperation;
}
}
}
exception_t::EXCEPTION_NONE
}
pub fn decodeSchedContext_UnbindObject(sc: &mut sched_context) -> exception_t {
Expand Down
13 changes: 13 additions & 0 deletions kernel/src/syscall/invocation/invoke_sched.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use sel4_common::{
platform::time_def::ticks_t,
structures::exception_t,
structures_gen::{cap, cap_tag},
utils::convert_to_mut_type_ref,
Expand Down Expand Up @@ -36,3 +37,15 @@ pub fn invokeSchedContext_YieldTo(sc: &mut sched_context) -> exception_t {
// TODO: MCS
exception_t::EXCEPTION_NONE
}
pub fn invokeSchedControl_ConfigureFlags(
sc: &mut sched_context,
core: usize,
budget: ticks_t,
period: ticks_t,
max_refills: usize,
badge: usize,
flags: usize,
) -> exception_t {
// TODO: MCS
exception_t::EXCEPTION_NONE
}
2 changes: 2 additions & 0 deletions sel4_common/src/sel4_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,5 @@ pub const CONFIG_BOOT_THREAD_TIME_SLICE: usize = 5;
pub const minDom: usize = 0;
pub const maxDom: usize = CONFIG_NUM_DOMAINS - 1;
pub const numDomains: usize = CONFIG_NUM_DOMAINS;

pub const TIME_ARG_SIZE: usize = 1;
9 changes: 7 additions & 2 deletions sel4_task/src/sched_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use sel4_common::{
println,
sel4_config::{CONFIG_KERNEL_WCET_SCALE, UINT64_MAX},
shared_types_bf_gen::seL4_MessageInfo,
structures_gen::{notification, notification_t},
structures_gen::{cap_sched_context_cap, notification, notification_t},
utils::convert_to_mut_type_ref,
BIT,
};

use crate::{
Expand All @@ -40,7 +41,7 @@ pub struct sched_context {
pub scRefillTail: usize,
pub scSporadic: bool,
}
pub(crate) const MIN_REFILLS: usize = 2;
pub const MIN_REFILLS: usize = 2;
pub(crate) type refill_t = refill;
#[repr(C)]
#[derive(Debug, Clone)]
Expand All @@ -60,6 +61,10 @@ pub fn MAX_PERIOD_US() -> time_t {
pub fn MAX_RELEASE_TIME() -> time_t {
UINT64_MAX - 5 * usToTicks(MAX_PERIOD_US())
}
pub fn refill_absolute_max(sc_cap: &cap_sched_context_cap) -> usize {
return (BIT!(sc_cap.get_capSCSizeBits() as usize) - size_of::<sched_context_t>())
/ size_of::<refill_t>();
}

impl sched_context {
#[inline]
Expand Down
83 changes: 62 additions & 21 deletions sel4_task/src/tcb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,12 +936,72 @@ impl tcb_t {
#[inline]
#[cfg(feature = "KERNEL_MCS")]
pub fn Release_Remove(&mut self) {
unimplemented!("MCS");
use crate::ksReprogram;

if likely(self.tcbState.get_tcbInReleaseQueue() != 0) {
if self.tcbSchedPrev != 0 {
convert_to_mut_type_ref::<tcb_t>(self.tcbSchedPrev).tcbSchedNext =
self.tcbSchedNext;
} else {
unsafe {
ksReleaseHead = self.tcbSchedNext;
ksReprogram = true;
}
}

if self.tcbSchedNext != 0 {
convert_to_mut_type_ref::<tcb_t>(self.tcbSchedNext).tcbSchedPrev =
self.tcbSchedPrev;
}

self.tcbSchedNext = 0;
self.tcbSchedPrev = 0;
self.tcbState.set_tcbInReleaseQueue(0);
}
}
#[inline]
#[cfg(feature = "KERNEL_MCS")]
pub fn Release_Enqueue(&mut self) {
unimplemented!("MCS")
use crate::ksReprogram;

assert!(self.tcbState.get_tcbInReleaseQueue() == 0);
assert!(self.tcbState.get_tcbQueued() == 0);

unsafe {
let mut before_ptr: usize = 0;
let mut after_ptr: usize = ksReleaseHead;

/* find our place in the ordered queue */
while after_ptr != 0
&& (*convert_to_mut_type_ref::<sched_context_t>(self.tcbSchedContext).refill_head())
.rTime
>= (*convert_to_mut_type_ref::<sched_context_t>(
convert_to_mut_type_ref::<tcb_t>(after_ptr).tcbSchedContext,
)
.refill_head())
.rTime
{
before_ptr = after_ptr;
after_ptr = convert_to_mut_type_ref::<tcb_t>(after_ptr).tcbSchedNext;
}

if before_ptr == 0 {
/* insert at head */
ksReleaseHead = self.get_ptr();
ksReprogram = true;
} else {
convert_to_mut_type_ref::<tcb_t>(before_ptr).tcbSchedNext = self.get_ptr();
}

if after_ptr != 0 {
convert_to_mut_type_ref::<tcb_t>(after_ptr).tcbSchedPrev = self.get_ptr();
}

self.tcbSchedNext = after_ptr;
self.tcbSchedPrev = before_ptr;
}

self.tcbState.set_tcbInReleaseQueue(1);
}
#[inline]
#[cfg(feature = "KERNEL_MCS")]
Expand Down Expand Up @@ -985,25 +1045,6 @@ pub fn tcb_Release_Dequeue() -> *mut tcb_t {
assert!(ksReleaseHead != 0);
assert!(convert_to_mut_type_ref::<tcb_t>(ksReleaseHead).tcbSchedPrev != 0);

// tcb_t *detached_head = NODE_STATE(ksReleaseHead);
// NODE_STATE(ksReleaseHead) = NODE_STATE(ksReleaseHead)->tcbSchedNext;

// if (NODE_STATE(ksReleaseHead))
// {
// NODE_STATE(ksReleaseHead)->tcbSchedPrev = NULL;
// }

// if (detached_head->tcbSchedNext)
// {
// detached_head->tcbSchedNext->tcbSchedPrev = NULL;
// detached_head->tcbSchedNext = NULL;
// }

// thread_state_ptr_set_tcbInReleaseQueue(&detached_head->tcbState, false);
// NODE_STATE(ksReprogram) = true;

// return detached_head;

let detached_head = ksReleaseHead as *mut tcb_t;
ksReleaseHead = (*detached_head).tcbSchedNext;

Expand Down

0 comments on commit 35301e9

Please sign in to comment.