Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions crates/sel4-capdl-initializer/src/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use core::slice;

use rkyv::Archive;
use rkyv::ops::ArchivedRange;
use rkyv::option::ArchivedOption;

#[allow(unused_imports)]
use log::{debug, error, info, trace};
Expand Down Expand Up @@ -97,8 +98,10 @@ impl<'a> Initializer<'a> {

self.init_tcbs()?;
self.init_cspaces()?;
self.init_domain_schedule()?;
Comment thread
Kswin01 marked this conversation as resolved.

self.start_threads()?;
self.start_domain_schedule()?;

Ok(())
}
Expand Down Expand Up @@ -754,6 +757,15 @@ impl<'a> Initializer<'a> {
let max_prio = obj.extra.max_prio.into();
let prio = obj.extra.prio.into();

sel4::sel4_cfg_if! {
if #[sel4_cfg(not(NUM_DOMAINS = "1"))] {
if let ArchivedOption::Some(domain_id) = obj.extra.domain {
init_thread::slot::DOMAIN_SET.cap().domain_set_set(domain_id, tcb)
.unwrap_or_else(|err| panic!("Error setting domain of thread to {}: {:?}", domain_id, err));
}
}
}

#[allow(unused_variables)]
let affinity = obj.extra.affinity.to_sel4();

Expand Down Expand Up @@ -883,6 +895,53 @@ impl<'a> Initializer<'a> {
Ok(())
}

fn init_domain_schedule(&self) -> Result<()> {
if let ArchivedOption::Some(domain_schedule) = &self.spec.domain_schedule {
debug!("Initializing domain schedule");

let mut sched_index = self
.spec
.domain_idx_shift
.as_ref()
.map(ArchivedWord::to_sel4)
.unwrap_or(0);

// sched_index is used as a shift, and not an invariant for the loop.
#[allow(clippy::explicit_counter_loop)]
for ArchivedDomainSchedEntry { id, time } in domain_schedule.iter() {
let domain_time = *time;
init_thread::slot::DOMAIN_SET
.cap()
.domain_set_schedule_configure(sched_index, *id, domain_time.to_native())?;
sched_index += 1;
}
}
Ok(())
}

fn start_domain_schedule(&self) -> Result<()> {
if self.spec.domain_schedule.is_some() {
debug!("Starting domain schedule");

// The start index also needs to be shifted. This makes the shift
// an offset into the schedule rather than an absolute index.
let shift = self
.spec
.domain_idx_shift
.as_ref()
.map(ArchivedWord::to_sel4)
.unwrap_or(0);

// Only call set start if we have been given a start index
if let ArchivedOption::Some(start) = self.spec.domain_set_start {
init_thread::slot::DOMAIN_SET
.cap()
.domain_set_schedule_set_start(start.to_sel4() + shift)?;
}
}
Ok(())
}

fn start_threads(&self) -> Result<()> {
info!("Starting threads");
for (obj_id, obj) in self.filter_objects::<object::ArchivedTcb>() {
Expand Down Expand Up @@ -963,6 +1022,7 @@ impl<'a> Initializer<'a> {
}
}
}
ArchivedObject::DomainSet => init_thread::slot::DOMAIN_SET.upcast(),
ArchivedObject::Frame(object::ArchivedFrame {
init: ArchivedFrameInit::Embedded(embedded),
..
Expand Down
25 changes: 25 additions & 0 deletions crates/sel4-capdl-initializer/types/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ pub struct CapTableEntry {
pub struct Spec<D> {
pub objects: Vec<NamedObject<D>>,
pub irqs: Vec<IrqEntry>,
pub domain_schedule: Option<Vec<DomainSchedEntry>>,
pub domain_set_start: Option<Word>,
pub domain_idx_shift: Option<Word>,
pub asid_slots: Vec<AsidSlotEntry>,
pub root_objects: Range<ObjectId>,
pub untyped_covers: Vec<UntypedCover>,
Expand Down Expand Up @@ -140,6 +143,14 @@ pub struct IrqEntry {
pub handler: ObjectId,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
pub struct DomainSchedEntry {
pub id: u8,
pub time: u64,
}

pub type AsidSlotEntry = ObjectId;

#[derive(Debug, Clone, Eq, PartialEq)]
Expand Down Expand Up @@ -188,6 +199,7 @@ pub enum Object<D> {
SchedContext(object::SchedContext),
Reply,
ArmSmc,
DomainSet,
}

pub trait IsObject<D> {
Expand Down Expand Up @@ -275,6 +287,7 @@ pub enum Cap {
SchedContext(cap::SchedContext),
Reply(cap::Reply),
ArmSmc(cap::ArmSmc),
DomainSet(cap::DomainSet),
}

pub trait IsCap {
Expand Down Expand Up @@ -307,6 +320,7 @@ impl Cap {
Self::SchedContext(cap) => cap.object,
Self::Reply(cap) => cap.object,
Self::ArmSmc(cap) => cap.object,
Self::DomainSet(cap) => cap.object,
}
}

Expand All @@ -330,6 +344,7 @@ impl Cap {
Self::SchedContext(cap) => cap.object = object,
Self::Reply(cap) => cap.object = object,
Self::ArmSmc(cap) => cap.object = object,
Self::DomainSet(cap) => cap.object = object,
}
}
}
Expand Down Expand Up @@ -363,6 +378,7 @@ impl ArchivedCap {
Self::SchedContext(cap) => cap.object,
Self::Reply(cap) => cap.object,
Self::ArmSmc(cap) => cap.object,
Self::DomainSet(cap) => cap.object,
}
}
}
Expand Down Expand Up @@ -405,6 +421,8 @@ pub mod object {
pub max_prio: u8,
pub resume: bool,

pub domain: Option<u8>,

pub ip: Word,
pub sp: Word,
pub gprs: Vec<Word>,
Expand Down Expand Up @@ -692,6 +710,13 @@ pub mod cap {
pub struct ArmSmc {
pub object: ObjectId,
}

#[derive(Debug, Clone, Eq, PartialEq, IsCap)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
pub struct DomainSet {
pub object: ObjectId,
}
}

pub enum PageTableEntry<'a> {
Expand Down
4 changes: 4 additions & 0 deletions crates/sel4-capdl-initializer/types/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,15 @@ impl<D> Spec<D> {
Object::SchedContext(obj) => Object::SchedContext(obj.clone()),
Object::Reply => Object::Reply,
Object::ArmSmc => Object::ArmSmc,
Object::DomainSet => Object::DomainSet,
},
})
})
.collect::<Result<_, E>>()?,
irqs: self.irqs.clone(),
domain_schedule: self.domain_schedule.clone(),
domain_set_start: self.domain_set_start,
domain_idx_shift: self.domain_idx_shift,
asid_slots: self.asid_slots.clone(),
root_objects: self.root_objects.clone(),
untyped_covers: self.untyped_covers.clone(),
Expand Down
6 changes: 6 additions & 0 deletions crates/sel4/src/cptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ pub mod cap_type {
AsidPool
}

declare_cap_type! {
/// Corresponds to `seL4_DomainSet`
DomainSet
}

declare_cap_type! {
/// Corresponds to the null capability.
Null
Expand Down Expand Up @@ -286,6 +291,7 @@ pub mod cap {
declare_cap_alias!(CNode);
declare_cap_alias!(IrqControl);
declare_cap_alias!(IrqHandler);
declare_cap_alias!(DomainSet);
declare_cap_alias!(AsidControl);
declare_cap_alias!(AsidPool);

Expand Down
3 changes: 1 addition & 2 deletions crates/sel4/src/init_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ pub mod slot {
(IO_SPACE, Null, seL4_CapIOSpace),
(BOOT_INFO_FRAME, Granule, seL4_CapBootInfoFrame),
(IPC_BUFFER, Granule, seL4_CapInitThreadIPCBuffer),
#[cfg(false)] // TODO
(DOMAIN, Null, seL4_CapDomain),
(DOMAIN_SET, DomainSet, seL4_CapDomain),
#[cfg(false)] // TODO
(SMMU_SID_CONTROL, Null, seL4_CapSMMUSIDControl),
#[cfg(false)] // TODO
Expand Down
37 changes: 37 additions & 0 deletions crates/sel4/src/invocations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,43 @@ impl<C: InvocationContext> IrqHandler<C> {
}
}

impl<C: InvocationContext> DomainSet<C> {
/// Corresponds to `seL4_DomainSet_Set`.
pub fn domain_set_set(self, domain: u8, thread: Tcb) -> Result<()> {
Error::wrap(self.invoke(|cptr, ipc_buffer| {
ipc_buffer
.inner_mut()
.seL4_DomainSet_Set(cptr.bits(), domain, thread.bits())
}))
}

/// Corresponds to `seL4_DomainSet_ScheduleConfigure`
pub fn domain_set_schedule_configure(
self,
index: Word,
domain: u8,
duration: u64,
) -> Result<()> {
Error::wrap(self.invoke(|cptr, ipc_buffer| {
ipc_buffer.inner_mut().seL4_DomainSet_ScheduleConfigure(
cptr.bits(),
index,
domain,
duration,
)
}))
}

/// Corresponds to `seL4_DomainSet_ScheduleSetStart`
pub fn domain_set_schedule_set_start(self, index: Word) -> Result<()> {
Error::wrap(self.invoke(|cptr, ipc_buffer| {
ipc_buffer
.inner_mut()
.seL4_DomainSet_ScheduleSetStart(cptr.bits(), index)
}))
}
}

impl<C: InvocationContext> AbsoluteCPtr<C> {
/// Corresponds to `seL4_CNode_Revoke`.
pub fn revoke(self) -> Result<()> {
Expand Down
Loading