diff --git a/kernel/src/arch/riscv/irq.rs b/kernel/src/arch/riscv/irq.rs index 40136fcb3..52c4d0849 100644 --- a/kernel/src/arch/riscv/irq.rs +++ b/kernel/src/arch/riscv/irq.rs @@ -5,6 +5,7 @@ use crate::arch::process::{Thread, RETURN_FROM_ISR}; use crate::mem::{MemoryManagerHandle, PAGE_SIZE}; use riscv::register::{scause, sepc, sie, sstatus, stval, vexriscv::sim, vexriscv::sip}; use xous::{SysCall, PID, TID}; +use crate::services::SystemServices; extern "Rust" { fn _xous_syscall_return_result(result: &xous::Result, context: &Thread) -> !; @@ -173,11 +174,10 @@ pub extern "C" fn trap_handler( previous_pid, previous_context ); // Switch to the previous process' address space. - { - let mut ss = SystemServicesHandle::get(); + SystemServices::with_mut(|ss| { ss.finish_callback_and_resume(previous_pid, previous_context) - .expect("unable to resume previous PID"); - } + .expect("unable to resume previous PID") + }); // Re-enable interrupts now that they're handled enable_all_irqs(); @@ -197,9 +197,9 @@ pub extern "C" fn trap_handler( // when this function runs. unsafe { if PREVIOUS_PAIR.is_none() { - let context_nr = SystemServicesHandle::get().current_context_nr(); - PREVIOUS_PAIR = Some((pid, context_nr)); - println!("ISR: Setting previous pair to ({}, {})", pid, context_nr); + let tid = crate::arch::process::current_tid(); + PREVIOUS_PAIR = Some((pid, tid)); + println!("ISR: Setting previous pair to ({}, {})", pid, tid); } else { println!("ISR: Previous pair is not None"); } diff --git a/kernel/src/arch/riscv/process.rs b/kernel/src/arch/riscv/process.rs index 32b2d799f..7c327f391 100644 --- a/kernel/src/arch/riscv/process.rs +++ b/kernel/src/arch/riscv/process.rs @@ -1,6 +1,6 @@ use core::mem; use core::cell::RefCell; -static mut PROCESS: *mut Process = 0xff80_1000 as *mut Process; +static mut PROCESS: *mut ProcessImpl = 0xff80_1000 as *mut ProcessImpl; pub const MAX_THREAD: TID = 31; pub const INITIAL_TID: TID = 1; use crate::arch::mem::PAGE_SIZE; @@ -21,6 +21,9 @@ pub const IRQ_CONTEXT: usize = 1; #[derive(Debug)] struct ProcessImpl { + /// Used by the interrupt handler to calculate offsets + scratch: usize, + /// Global parameters used by the operating system pub inner: ProcessInner, @@ -62,30 +65,16 @@ pub struct InitialProcess { pub satp: usize, /// Where execution begins - entrypoint: usize, + pub entrypoint: usize, /// Address of the top of the stack - sp: usize, + pub sp: usize, } #[repr(C)] #[derive(Debug)] pub struct Process { - /// Used by the interrupt handler to calculate offsets - scratch: usize, - - /// The index into the `contexts` list. This must never be 0. The interrupt - /// handler writes to this field, so it must not be moved. - thread_nr: TID, - - _hash: [usize; 8], - - /// Global parameters used by the operating system - pub inner: ProcessInner, - - /// The interrupt handler will save the current process to this Thread when - /// the trap handler is entered. - contexts: [Thread; MAX_THREAD], + pid: PID, } #[repr(C)] @@ -103,6 +92,10 @@ pub struct Thread { } impl Process { + pub fn current() -> Process { + Process { pid: unsafe { PROCESS_TABLE.borrow().current } } + } + /// Calls the provided function with the current inner process state. pub fn with_inner(f: F) -> R where @@ -123,8 +116,8 @@ impl Process { where F: FnOnce(&Process) -> R, { - let mut process = unsafe { &mut *PROCESS }; - f(process) + let process = Self::current(); + f(&process) } pub fn with_inner_mut(f: F) -> R @@ -141,35 +134,41 @@ impl Process { } pub fn current_thread(&mut self) -> &mut Thread { - assert!(self.thread_nr != 0, "thread number was 0"); - &mut self.contexts[self.thread_nr - 1] + let mut process = unsafe { &mut *PROCESS }; + assert!(process.current_thread != 0, "thread number was 0"); + &mut process.threads[process.current_thread - 1] } pub fn current_tid(&self) -> TID { - self.thread_nr + let mut process = unsafe { &mut *PROCESS }; + process.current_thread } /// Set the current thread number. - pub fn set_thread(&mut self, thread: TID) { + pub fn set_thread(&mut self, thread: TID) -> Result<(), xous::Error> { + let mut process = unsafe { &mut *PROCESS }; assert!( - thread > 0 && thread <= self.contexts.len(), + thread > 0 && thread <= process.threads.len(), "attempt to switch to an invalid thread {}", thread ); - self.thread_nr = thread; + process.current_thread = thread; + Ok(()) } - pub fn thread(&mut self, thread_nr: TID) -> &mut Thread { + pub fn thread(&mut self, thread: TID) -> &mut Thread { + let mut process = unsafe { &mut *PROCESS }; assert!( - thread_nr > 0 && thread_nr <= self.contexts.len(), + thread > 0 && thread <= process.threads.len(), "attempt to retrieve an invalid thread {}", - thread_nr + thread ); - &mut self.contexts[thread_nr - 1] + &mut process.threads[thread - 1] } - pub fn find_free_context_nr(&self) -> Option { - for (index, thread) in self.contexts.iter().enumerate() { + pub fn find_free_thread_nr(&self) -> Option { + let mut process = unsafe { &mut *PROCESS }; + for (index, thread) in process.threads.iter().enumerate() { if index != 0 && thread.sepc == 0 { return Some(index as TID + 1); } @@ -188,6 +187,7 @@ impl Process { /// Initialize this process thread with the given entrypoint and stack /// addresses. pub fn init(&mut self, entrypoint: usize, stack: usize, thread: usize) { + let mut process = unsafe { &mut *PROCESS }; assert!( mem::size_of::() == PAGE_SIZE, "Process size is {}, not PAGE_SIZE ({})", @@ -195,7 +195,7 @@ impl Process { PAGE_SIZE ); assert!( - thread + 1 < self.contexts.len(), + thread + 1 < process.threads.len(), "tried to init a thread that's out of range" ); assert!(thread != 1, "tried to init using the irq thread"); @@ -206,8 +206,8 @@ impl Process { ); // By convention, thread 0 is the trap thread. Therefore, thread 1 is // the first default thread. - self.thread_nr = thread; - for thread in self.contexts.iter_mut() { + process.current_thread = thread; + for thread in process.threads.iter_mut() { *thread = Default::default(); } @@ -217,7 +217,7 @@ impl Process { thread.sepc = entrypoint; thread.registers[1] = stack; - self.inner = Default::default(); + process.inner = Default::default(); } } @@ -247,6 +247,9 @@ pub fn current_pid() -> PID { unsafe { PROCESS_TABLE.borrow().current } } +pub fn current_tid() -> TID { + unsafe { (*PROCESS).current_thread } +} // pub struct ProcessHandle<'a> { // process: &'a mut Process, diff --git a/kernel/src/services.rs b/kernel/src/services.rs index 17e966eef..8b2302af9 100644 --- a/kernel/src/services.rs +++ b/kernel/src/services.rs @@ -28,7 +28,6 @@ macro_rules! thread_local { use std::thread_local; use crate::filled_array; -use crate::mem::PAGE_SIZE; use crate::server::Server; // use core::mem; use xous::{ @@ -320,7 +319,7 @@ impl SystemServices { // once a context switch _away_ from the kernel occurs, however we need // to make sure other fields such as "thread number" are all valid. // ProcessHandle::get().init(0, 0, INITIAL_TID); - self.processes[0].current_context = INITIAL_TID as u8; + // self.processes[0].current_thread = INITIAL_TID as u8; } /// Add a new entry to the process table. This results in a new address space @@ -991,7 +990,7 @@ impl SystemServices { // Locate an address to fit the new memory. dest_mapping.activate()?; let dest_virt = mm - .find_virtual_address(dest_virt, len, MemoryType::Messages) + .find_virtual_address(dest_virt, len, xous::MemoryType::Messages) .or_else(|e| { src_mapping.activate().expect("couldn't undo mapping"); Err(e) @@ -1004,7 +1003,7 @@ impl SystemServices { // Lend each subsequent page. for offset in - (0..(len / mem::size_of::())).step_by(PAGE_SIZE / mem::size_of::()) + (0..(len / core::mem::size_of::())).step_by(crate::mem::PAGE_SIZE / core::mem::size_of::()) { mm.move_page( &src_mapping, @@ -1084,7 +1083,7 @@ impl SystemServices { // Locate an address to fit the new memory. dest_mapping.activate(); let dest_virt = mm - .find_virtual_address(dest_virt, len, MemoryType::Messages) + .find_virtual_address(dest_virt, len, xous::MemoryType::Messages) .or_else(|e| { src_mapping.activate(); Err(e) @@ -1095,7 +1094,7 @@ impl SystemServices { // Lend each subsequent page. for offset in - (0..(len / mem::size_of::())).step_by(PAGE_SIZE / mem::size_of::()) + (0..(len / core::mem::size_of::())).step_by(crate::mem::PAGE_SIZE / core::mem::size_of::()) { mm.lend_page( &src_mapping, @@ -1165,7 +1164,7 @@ impl SystemServices { // Lend each subsequent page. for offset in - (0..(len / mem::size_of::())).step_by(PAGE_SIZE / mem::size_of::()) + (0..(len / core::mem::size_of::())).step_by(crate::mem::PAGE_SIZE / core::mem::size_of::()) { mm.unlend_page( &src_mapping,