feat: kernel/objects/tcb: support for endpoint

This commit is contained in:
Paul Pan 2024-09-03 19:38:01 +08:00
parent db7fa2ba58
commit 55547d336e
2 changed files with 60 additions and 31 deletions

View File

@ -1,10 +1,11 @@
use crate::arch::{layout::mmap_phys_to_virt, trap::TrapContext, vspace::*}; use crate::arch::{trap::TrapContext, vspace::*};
use crate::scheduler::SCHEDULER; use crate::scheduler::SCHEDULER;
use crate::syscall::handle_syscall; use crate::syscall::handle_syscall;
use crate::{objects::*, plat::trap::TrapContextOps, vspace::*}; use crate::{objects::*, plat::trap::TrapContextOps, vspace::*};
use core::fmt::Debug; use core::fmt::Debug;
use core::sync::atomic::{AtomicUsize, Ordering}; use core::sync::atomic::{AtomicUsize, Ordering};
use uapi::{cap::ObjectType, fault::*}; use uapi::cap::ObjectType;
use uapi::fault::Fault;
use utils::{ use utils::{
addr::*, addr::*,
linked_list::{Link, LinkHelper}, linked_list::{Link, LinkHelper},
@ -21,11 +22,13 @@ pub enum ThreadState {
Inactive, Inactive,
Running, Running,
Restart, Restart,
Blocked, Sending,
Receiving,
Idle, Idle,
} }
pub const SCHED_QUEUE_LINK_ID: usize = 1; pub const SCHED_QUEUE_LINK_ID: usize = 1;
pub const EP_QUEUE_LINK_ID: usize = 2;
#[repr(C)] #[repr(C)]
pub struct TcbObject { pub struct TcbObject {
@ -33,19 +36,22 @@ pub struct TcbObject {
cspace: CapEntry, cspace: CapEntry,
vspace: CapEntry, vspace: CapEntry,
notification: CapEntry,
buffer: CapEntry, // CapFrame // endpoint
badge: usize,
buffer: CapEntry,
fault: Fault, fault: Fault,
fault_handler: CapEntry,
state: ThreadState, state: ThreadState,
time_tick: usize, time_tick: usize,
tid: usize, tid: usize,
pub sched_queue: Link<Self, SCHED_QUEUE_LINK_ID>, pub sched_queue: Link<Self, SCHED_QUEUE_LINK_ID>,
pub ep_queue: Link<Self, EP_QUEUE_LINK_ID>,
} }
LinkHelperImpl!(TcbObject { sched_queue } => SCHED_QUEUE_LINK_ID); LinkHelperImpl!(TcbObject { sched_queue } => SCHED_QUEUE_LINK_ID);
LinkHelperImpl!(TcbObject { ep_queue } => EP_QUEUE_LINK_ID);
const_assert_eq!(ObjectType::TCB.size(0), ObjectType::TCB.size(0x42)); const_assert_eq!(ObjectType::TCB.size(0), ObjectType::TCB.size(0x42));
const_assert!(core::mem::size_of::<TcbObject>() <= ObjectType::TCB.size(0)); const_assert!(core::mem::size_of::<TcbObject>() <= ObjectType::TCB.size(0));
@ -56,19 +62,25 @@ impl TcbObject {
trapframe: TrapContext::default(), trapframe: TrapContext::default(),
cspace: CapEntry::new(NullCap::mint()), cspace: CapEntry::new(NullCap::mint()),
vspace: CapEntry::new(NullCap::mint()), vspace: CapEntry::new(NullCap::mint()),
notification: CapEntry::new(NullCap::mint()), badge: 0,
buffer: CapEntry::new(NullCap::mint()), buffer: CapEntry::new(NullCap::mint()),
fault: Fault::Null, fault: Fault::Null,
fault_handler: CapEntry::new(NullCap::mint()),
state: ThreadState::Inactive, state: ThreadState::Inactive,
time_tick: 0, time_tick: 0,
tid: TID_ALLOCATOR.fetch_add(1, Ordering::SeqCst), tid: TID_ALLOCATOR.fetch_add(1, Ordering::SeqCst),
sched_queue: Link::default(), sched_queue: Link::default(),
ep_queue: Link::default(),
} }
} }
pub fn cspace(&self) -> &CapEntry { pub fn configure_idle_thread(&mut self) {
&self.cspace self.trapframe.configure_idle_thread();
self.vspace = CapEntry::new(TableCap::mint(unsafe { get_current_pagetable().paddr() }));
self.state = ThreadState::Idle;
}
pub fn cspace(&self) -> SysResult<CNodeCap> {
CNodeCap::try_from(&self.cspace)
} }
pub fn set_cspace(&mut self, cspace: CapEntry) { pub fn set_cspace(&mut self, cspace: CapEntry) {
@ -84,20 +96,38 @@ impl TcbObject {
self.vspace = vspace; self.vspace = vspace;
} }
pub fn configure_idle_thread(&mut self) { pub fn badge(&self) -> usize {
self.trapframe.configure_idle_thread(); self.badge
self.vspace = CapEntry::new(TableCap::mint(unsafe { get_current_pagetable().paddr() }));
self.state = ThreadState::Idle;
} }
pub fn tid(&self) -> usize { pub fn set_badge(&mut self, badge: usize) {
self.tid self.badge = badge;
}
pub fn buffer(&self) -> SysResult<FrameCap> {
FrameCap::try_from(&self.buffer)
}
pub fn set_buffer(&mut self, buffer: CapEntry) {
self.buffer = buffer;
}
pub fn fault(&self) -> Fault {
self.fault
}
pub fn set_fault(&mut self, fault: Fault) {
self.fault = fault;
} }
pub fn state(&self) -> ThreadState { pub fn state(&self) -> ThreadState {
self.state self.state
} }
pub fn tid(&self) -> usize {
self.tid
}
pub fn schedulable(&self) -> bool { pub fn schedulable(&self) -> bool {
matches!(self.state, ThreadState::Idle | ThreadState::Running) matches!(self.state, ThreadState::Idle | ThreadState::Running)
} }
@ -163,10 +193,9 @@ impl Debug for TcbCap<'_> {
f.debug_struct("TcbCap") f.debug_struct("TcbCap")
.field("cspace", &obj.cspace) .field("cspace", &obj.cspace)
.field("vspace", &obj.vspace) .field("vspace", &obj.vspace)
.field("notification", &obj.notification) .field("badge", &obj.badge)
.field("buffer", &obj.buffer) .field("buffer", &obj.buffer)
.field("fault", &obj.fault) .field("fault", &obj.fault)
.field("fault_handler", &obj.fault_handler)
.field("state", &obj.state) .field("state", &obj.state)
.field("time_tick", &obj.time_tick) .field("time_tick", &obj.time_tick)
.finish() .finish()

View File

@ -29,7 +29,7 @@ pub fn handle_syscall(tcb: &mut TcbObject) -> SysResult {
_ => (), _ => (),
}; };
let cspace = CNodeCap::try_from(tcb.cspace())?; let cspace = tcb.cspace()?;
let cap_ptr = tcb.trapframe.get_reg(REG_CAP_PTR); let cap_ptr = tcb.trapframe.get_reg(REG_CAP_PTR);
let cap = cspace.resolve_address_bits(cap_ptr, info.bits()).map_err(SysError::from)?; let cap = cspace.resolve_address_bits(cap_ptr, info.bits()).map_err(SysError::from)?;