From 3a6c4f9a1c17f11b34fc1bc85219eac8f761544d Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Wed, 25 Dec 2019 20:11:15 +0800 Subject: [PATCH] processes: start defining what a process is Signed-off-by: Sean Cross --- src/definitions.rs | 70 +++++++++++++++++++++++++++++++++++++ src/irq.rs | 8 ++--- src/lib.rs | 2 +- src/main.rs | 9 +++-- src/mem.rs | 57 +++++++++++++++++++++++++----- src/processtable.rs | 26 ++++++++++++++ src/syscalls.rs | 70 +------------------------------------ xous-kernel-riscv-rt/link.x | 1 + 8 files changed, 157 insertions(+), 86 deletions(-) create mode 100644 src/definitions.rs create mode 100644 src/processtable.rs diff --git a/src/definitions.rs b/src/definitions.rs new file mode 100644 index 0000000..f3830ab --- /dev/null +++ b/src/definitions.rs @@ -0,0 +1,70 @@ +use core::num::NonZeroUsize; + +#[allow(dead_code)] pub type MemoryAddress = NonZeroUsize; +#[allow(dead_code)] pub type MemorySize = NonZeroUsize; +#[allow(dead_code)] pub type StackPointer = usize; +#[allow(dead_code)] pub type MessageId = usize; + +#[allow(dead_code)] pub type XousPid = u8; +#[allow(dead_code)] pub type XousMessageSender = usize; +#[allow(dead_code)] pub type XousConnection = usize; + +/// Server ID +#[allow(dead_code)] pub type XousSid = usize; + +/// Equivalent to a RISC-V Hart ID +#[allow(dead_code)] pub type XousCpuId = usize; + +#[allow(dead_code)] +#[derive(Debug)] +pub enum XousError { + BadAlignment, + BadAddress, + OutOfMemory, + MemoryInUse, + InterruptNotFound, + InterruptInUse, + InvalidString, + ServerExists, + ServerNotFound, + ProcessNotFound, + ProcessNotChild, + ProcessTerminated, + Timeout, +} + +#[allow(dead_code)] +pub struct XousContext { + stack: StackPointer, + pid: XousPid, +} + +#[allow(dead_code)] +pub struct XousMemoryMessage { + id: MessageId, + in_buf: Option, + in_buf_size: Option, + out_buf: Option, + out_buf_size: Option, +} + +#[allow(dead_code)] +pub struct XousScalarMessage { + id: MessageId, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, +} + +#[allow(dead_code)] +pub enum XousMessage { + Memory(XousMemoryMessage), + Scalar(XousScalarMessage), +} + +#[allow(dead_code)] +pub struct XousMessageReceived { + sender: XousMessageSender, + message: XousMessage, +} diff --git a/src/irq.rs b/src/irq.rs index e271d82..22afc91 100644 --- a/src/irq.rs +++ b/src/irq.rs @@ -1,4 +1,4 @@ -use crate::syscalls; +use crate::definitions::XousError; use crate::filled_array; use xous_riscv::register::{mstatus, vmim}; @@ -28,15 +28,15 @@ pub fn handle(irqs_pending: usize) { } } -pub fn sys_interrupt_claim(irq: usize, f: fn(usize)) -> Result<(), syscalls::XousError> { +pub fn sys_interrupt_claim(irq: usize, f: fn(usize)) -> Result<(), XousError> { // Unsafe is required since we're accessing a static mut array. // However, we disable interrupts to prevent contention on this array. unsafe { mstatus::clear_mie(); let result = if irq > IRQ_HANDLERS.len() { - Err(syscalls::XousError::InterruptNotFound) + Err(XousError::InterruptNotFound) } else if IRQ_HANDLERS[irq].is_some() { - Err(syscalls::XousError::InterruptInUse) + Err(XousError::InterruptInUse) } else { IRQ_HANDLERS[irq] = Some(f); // Note that the vexriscv "IRQ Mask" register is inverse-logic -- diff --git a/src/lib.rs b/src/lib.rs index 3981b94..0842b67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,4 +9,4 @@ extern crate xous_riscv; // } // Allow consumers of this library to make syscalls -pub mod syscalls; +// pub mod syscalls; diff --git a/src/main.rs b/src/main.rs index a77c9ff..b794d05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,12 @@ #![no_main] extern crate xous_riscv; -mod syscalls; +mod definitions; mod irq; mod macros; mod mem; +mod processtable; +mod syscalls; pub use irq::sys_interrupt_claim; @@ -13,7 +15,7 @@ use core::panic::PanicInfo; use xous_kernel_riscv_rt::xous_kernel_entry; use xous_riscv::register::{mcause, mstatus, mie, vmim, vmip}; use mem::MemoryManager; - +use processtable::ProcessTable; #[panic_handler] fn handle_panic(_arg: &PanicInfo) -> ! { @@ -35,7 +37,8 @@ fn xous_main() -> ! { mie::set_mext(); mstatus::set_mie(); // Enable CPU interrupts } - let mm = MemoryManager::new(); + let mut mm = MemoryManager::new(); + let mut pt = ProcessTable::new(&mut mm); sys_interrupt_claim(2, |_| { let uart_ptr = 0xE000_1800 as *mut usize; print_str(uart_ptr, "hello, world!\r\n"); diff --git a/src/mem.rs b/src/mem.rs index c32f591..a9e9178 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -1,4 +1,5 @@ -use crate::syscalls::{XousError, XousPid}; +use crate::definitions::{XousError, XousPid, MemoryAddress}; +use core::num::NonZeroUsize; use xous_riscv::register::mstatus; const FLASH_START: usize = 0x20000000; @@ -21,10 +22,10 @@ const RAM_PAGE_COUNT: usize = RAM_SIZE / PAGE_SIZE; const IO_PAGE_COUNT: usize = IO_SIZE; const LCD_PAGE_COUNT: usize = LCD_SIZE / PAGE_SIZE; pub struct MemoryManager { - flash: [u8; FLASH_PAGE_COUNT], - ram: [u8; RAM_PAGE_COUNT], - io: [u8; IO_PAGE_COUNT], - lcd: [u8; LCD_PAGE_COUNT], + flash: [XousPid; FLASH_PAGE_COUNT], + ram: [XousPid; RAM_PAGE_COUNT], + io: [XousPid; IO_PAGE_COUNT], + lcd: [XousPid; LCD_PAGE_COUNT], } extern "C" { @@ -40,6 +41,10 @@ extern "C" { static mut _estack: usize; static mut _sstack: usize; + // Boundaries of the .text section + static mut _stext: usize; + static mut _etext: usize; + // Boundaries of the heap static _sheap: usize; static _eheap: usize; @@ -52,9 +57,9 @@ use core::mem::transmute; /// Initialzie the memory map. /// This will go through memory and map anything that the kernel is -/// using to process 0xff, then allocate a pagetable for this process -/// and place it at the usual offset. -/// Finally, it will enable the MMU. +/// using to process 1, then allocate a pagetable for this process +/// and place it at the usual offset. The MMU will not be enabled yet, +/// as the process entry has not yet been created. impl MemoryManager { pub fn new() -> MemoryManager { let mut mm = MemoryManager { @@ -80,6 +85,10 @@ impl MemoryManager { let end_stack = unsafe { transmute::<&usize, usize>(&_sstack) }; let stack_range = (start_stack..end_stack).step_by(PAGE_SIZE); + let start_text = unsafe { transmute::<&usize, usize>(&_stext) }; + let end_text = unsafe { transmute::<&usize, usize>(&_etext) }; + let text_range = (start_text..end_text).step_by(PAGE_SIZE); + for region in bss_range { mm.claim_page(region & !0xfff, 1).unwrap(); } @@ -92,10 +101,40 @@ impl MemoryManager { mm.claim_page(region & !0xfff, 1).unwrap(); } + for region in text_range { + mm.claim_page(region & !0xfff, 1).unwrap(); + } + unsafe { mstatus::set_mie() }; mm } + pub fn alloc_page(&mut self, pid: XousPid) -> Result { + // Go through all RAM pages looking for a free page. + // Optimization: start from the previous address. + for index in 0..RAM_PAGE_COUNT { + if self.ram[index] == 0 { + self.ram[index] = pid; + let page_addr = (index * PAGE_SIZE + RAM_START) as *mut u32; + // Zero-out the page + unsafe { + for i in 0..PAGE_SIZE/4 { + *page_addr.add(i) = 0; + } + } + let new_page = unsafe { transmute::<*mut u32, usize>(page_addr) }; + return Ok(NonZeroUsize::new(new_page).unwrap()); + } + } + Err(XousError::OutOfMemory) + } + + // Create an identity mapping, copying the kernel to itself. + pub fn create_identity(&mut self, satp: MemoryAddress, pid: XousPid) -> Result<(), XousError> { + + Err(XousError::OutOfMemory) + } + fn claim_page(&mut self, addr: usize, pid: XousPid) -> Result<(), XousError> { // Ensure the address lies on a page boundary if addr & 0xfff != 0 { @@ -119,7 +158,7 @@ impl MemoryManager { return Err(XousError::BadAddress); } if tbl[page] != 0 && tbl[page] != pid { - return Err(XousError::OutOfMemory); + return Err(XousError::MemoryInUse); } tbl[page] = pid; Ok(()) diff --git a/src/processtable.rs b/src/processtable.rs new file mode 100644 index 0000000..1d65343 --- /dev/null +++ b/src/processtable.rs @@ -0,0 +1,26 @@ +use crate::definitions::{XousError, XousPid, MemoryAddress}; +use crate::mem::MemoryManager; +use crate::filled_array; + +const MAX_PROCESS_COUNT: usize = 256; + +struct Process { + satp: Option, +} + +pub struct ProcessTable { + processes: [Process; MAX_PROCESS_COUNT], +} + +impl ProcessTable { + pub fn new(mm: &mut MemoryManager) -> Self { + let mut pt = ProcessTable { + processes: filled_array![Process { satp: None }; 256], + }; + + // Allocate a root page table for PID 1 + pt.processes[1].satp = Some(mm.alloc_page(1).unwrap()); + mm.create_identity(pt.processes[1].satp.unwrap(), 1); + pt + } +} diff --git a/src/syscalls.rs b/src/syscalls.rs index 687ba56..252da2a 100644 --- a/src/syscalls.rs +++ b/src/syscalls.rs @@ -1,72 +1,4 @@ -use core::num::NonZeroUsize; - -#[allow(dead_code)] pub type MemoryAddress = NonZeroUsize; -#[allow(dead_code)] pub type MemorySize = NonZeroUsize; -#[allow(dead_code)] pub type StackPointer = usize; -#[allow(dead_code)] pub type MessageId = usize; - -#[allow(dead_code)] pub type XousPid = u8; -#[allow(dead_code)] pub type XousMessageSender = usize; -#[allow(dead_code)] pub type XousConnection = usize; - -/// Server ID -#[allow(dead_code)] pub type XousSid = usize; - -/// Equivalent to a RISC-V Hart ID -#[allow(dead_code)] pub type XousCpuId = usize; - -#[allow(dead_code)] -#[derive(Debug)] -pub enum XousError { - BadAlignment, - BadAddress, - OutOfMemory, - InterruptNotFound, - InterruptInUse, - InvalidString, - ServerExists, - ServerNotFound, - ProcessNotFound, - ProcessNotChild, - ProcessTerminated, - Timeout, -} - -#[allow(dead_code)] -pub struct XousContext { - stack: StackPointer, - pid: XousPid, -} - -#[allow(dead_code)] -pub struct XousMemoryMessage { - id: MessageId, - in_buf: Option, - in_buf_size: Option, - out_buf: Option, - out_buf_size: Option, -} - -#[allow(dead_code)] -pub struct XousScalarMessage { - id: MessageId, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, -} - -#[allow(dead_code)] -pub enum XousMessage { - Memory(XousMemoryMessage), - Scalar(XousScalarMessage), -} - -#[allow(dead_code)] -pub struct XousMessageReceived { - sender: XousMessageSender, - message: XousMessage, -} +use super::definitions::*; extern "Rust" { /// Allocates kernel structures for a new process, and returns the new PID. diff --git a/xous-kernel-riscv-rt/link.x b/xous-kernel-riscv-rt/link.x index 4db8ef3..02d5aaf 100644 --- a/xous-kernel-riscv-rt/link.x +++ b/xous-kernel-riscv-rt/link.x @@ -52,6 +52,7 @@ SECTIONS This is required by LLD to ensure the LMA of the following .data section will have the correct alignment. */ . = ALIGN(4); + _etext = .; } > REGION_RODATA .data : ALIGN(4)