mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: kernel/objects/tcb: support for endpoint
This commit is contained in:
parent
db7fa2ba58
commit
55547d336e
@ -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,31 +22,36 @@ 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 {
|
||||||
pub trapframe: TrapContext, // must be the first field
|
pub trapframe: TrapContext, // must be the first field
|
||||||
|
|
||||||
cspace: CapEntry,
|
cspace: CapEntry,
|
||||||
vspace: CapEntry,
|
vspace: CapEntry,
|
||||||
notification: CapEntry,
|
|
||||||
buffer: CapEntry, // CapFrame
|
// endpoint
|
||||||
fault: Fault,
|
badge: usize,
|
||||||
fault_handler: CapEntry,
|
buffer: CapEntry,
|
||||||
|
fault: Fault,
|
||||||
|
|
||||||
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));
|
||||||
@ -53,22 +59,28 @@ const_assert!(core::mem::size_of::<TcbObject>() <= ObjectType::TCB.size(0));
|
|||||||
impl TcbObject {
|
impl TcbObject {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
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()
|
||||||
|
@ -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)?;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user