processes: start defining what a process is

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2019-12-25 20:11:15 +08:00
parent 649d1ba26b
commit 3a6c4f9a1c
8 changed files with 157 additions and 86 deletions

70
src/definitions.rs Normal file
View File

@ -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<MemoryAddress>,
in_buf_size: Option<MemorySize>,
out_buf: Option<MemoryAddress>,
out_buf_size: Option<MemorySize>,
}
#[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,
}

View File

@ -1,4 +1,4 @@
use crate::syscalls; use crate::definitions::XousError;
use crate::filled_array; use crate::filled_array;
use xous_riscv::register::{mstatus, vmim}; 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. // Unsafe is required since we're accessing a static mut array.
// However, we disable interrupts to prevent contention on this array. // However, we disable interrupts to prevent contention on this array.
unsafe { unsafe {
mstatus::clear_mie(); mstatus::clear_mie();
let result = if irq > IRQ_HANDLERS.len() { let result = if irq > IRQ_HANDLERS.len() {
Err(syscalls::XousError::InterruptNotFound) Err(XousError::InterruptNotFound)
} else if IRQ_HANDLERS[irq].is_some() { } else if IRQ_HANDLERS[irq].is_some() {
Err(syscalls::XousError::InterruptInUse) Err(XousError::InterruptInUse)
} else { } else {
IRQ_HANDLERS[irq] = Some(f); IRQ_HANDLERS[irq] = Some(f);
// Note that the vexriscv "IRQ Mask" register is inverse-logic -- // Note that the vexriscv "IRQ Mask" register is inverse-logic --

View File

@ -9,4 +9,4 @@ extern crate xous_riscv;
// } // }
// Allow consumers of this library to make syscalls // Allow consumers of this library to make syscalls
pub mod syscalls; // pub mod syscalls;

View File

@ -2,10 +2,12 @@
#![no_main] #![no_main]
extern crate xous_riscv; extern crate xous_riscv;
mod syscalls; mod definitions;
mod irq; mod irq;
mod macros; mod macros;
mod mem; mod mem;
mod processtable;
mod syscalls;
pub use irq::sys_interrupt_claim; pub use irq::sys_interrupt_claim;
@ -13,7 +15,7 @@ use core::panic::PanicInfo;
use xous_kernel_riscv_rt::xous_kernel_entry; use xous_kernel_riscv_rt::xous_kernel_entry;
use xous_riscv::register::{mcause, mstatus, mie, vmim, vmip}; use xous_riscv::register::{mcause, mstatus, mie, vmim, vmip};
use mem::MemoryManager; use mem::MemoryManager;
use processtable::ProcessTable;
#[panic_handler] #[panic_handler]
fn handle_panic(_arg: &PanicInfo) -> ! { fn handle_panic(_arg: &PanicInfo) -> ! {
@ -35,7 +37,8 @@ fn xous_main() -> ! {
mie::set_mext(); mie::set_mext();
mstatus::set_mie(); // Enable CPU interrupts 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, |_| { sys_interrupt_claim(2, |_| {
let uart_ptr = 0xE000_1800 as *mut usize; let uart_ptr = 0xE000_1800 as *mut usize;
print_str(uart_ptr, "hello, world!\r\n"); print_str(uart_ptr, "hello, world!\r\n");

View File

@ -1,4 +1,5 @@
use crate::syscalls::{XousError, XousPid}; use crate::definitions::{XousError, XousPid, MemoryAddress};
use core::num::NonZeroUsize;
use xous_riscv::register::mstatus; use xous_riscv::register::mstatus;
const FLASH_START: usize = 0x20000000; 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 IO_PAGE_COUNT: usize = IO_SIZE;
const LCD_PAGE_COUNT: usize = LCD_SIZE / PAGE_SIZE; const LCD_PAGE_COUNT: usize = LCD_SIZE / PAGE_SIZE;
pub struct MemoryManager { pub struct MemoryManager {
flash: [u8; FLASH_PAGE_COUNT], flash: [XousPid; FLASH_PAGE_COUNT],
ram: [u8; RAM_PAGE_COUNT], ram: [XousPid; RAM_PAGE_COUNT],
io: [u8; IO_PAGE_COUNT], io: [XousPid; IO_PAGE_COUNT],
lcd: [u8; LCD_PAGE_COUNT], lcd: [XousPid; LCD_PAGE_COUNT],
} }
extern "C" { extern "C" {
@ -40,6 +41,10 @@ extern "C" {
static mut _estack: usize; static mut _estack: usize;
static mut _sstack: usize; static mut _sstack: usize;
// Boundaries of the .text section
static mut _stext: usize;
static mut _etext: usize;
// Boundaries of the heap // Boundaries of the heap
static _sheap: usize; static _sheap: usize;
static _eheap: usize; static _eheap: usize;
@ -52,9 +57,9 @@ use core::mem::transmute;
/// Initialzie the memory map. /// Initialzie the memory map.
/// This will go through memory and map anything that the kernel is /// This will go through memory and map anything that the kernel is
/// using to process 0xff, then allocate a pagetable for this process /// using to process 1, then allocate a pagetable for this process
/// and place it at the usual offset. /// and place it at the usual offset. The MMU will not be enabled yet,
/// Finally, it will enable the MMU. /// as the process entry has not yet been created.
impl MemoryManager { impl MemoryManager {
pub fn new() -> MemoryManager { pub fn new() -> MemoryManager {
let mut mm = MemoryManager { let mut mm = MemoryManager {
@ -80,6 +85,10 @@ impl MemoryManager {
let end_stack = unsafe { transmute::<&usize, usize>(&_sstack) }; let end_stack = unsafe { transmute::<&usize, usize>(&_sstack) };
let stack_range = (start_stack..end_stack).step_by(PAGE_SIZE); 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 { for region in bss_range {
mm.claim_page(region & !0xfff, 1).unwrap(); mm.claim_page(region & !0xfff, 1).unwrap();
} }
@ -92,10 +101,40 @@ impl MemoryManager {
mm.claim_page(region & !0xfff, 1).unwrap(); mm.claim_page(region & !0xfff, 1).unwrap();
} }
for region in text_range {
mm.claim_page(region & !0xfff, 1).unwrap();
}
unsafe { mstatus::set_mie() }; unsafe { mstatus::set_mie() };
mm mm
} }
pub fn alloc_page(&mut self, pid: XousPid) -> Result<MemoryAddress, XousError> {
// 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> { fn claim_page(&mut self, addr: usize, pid: XousPid) -> Result<(), XousError> {
// Ensure the address lies on a page boundary // Ensure the address lies on a page boundary
if addr & 0xfff != 0 { if addr & 0xfff != 0 {
@ -119,7 +158,7 @@ impl MemoryManager {
return Err(XousError::BadAddress); return Err(XousError::BadAddress);
} }
if tbl[page] != 0 && tbl[page] != pid { if tbl[page] != 0 && tbl[page] != pid {
return Err(XousError::OutOfMemory); return Err(XousError::MemoryInUse);
} }
tbl[page] = pid; tbl[page] = pid;
Ok(()) Ok(())

26
src/processtable.rs Normal file
View File

@ -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<MemoryAddress>,
}
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
}
}

View File

@ -1,72 +1,4 @@
use core::num::NonZeroUsize; use super::definitions::*;
#[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<MemoryAddress>,
in_buf_size: Option<MemorySize>,
out_buf: Option<MemoryAddress>,
out_buf_size: Option<MemorySize>,
}
#[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,
}
extern "Rust" { extern "Rust" {
/// Allocates kernel structures for a new process, and returns the new PID. /// Allocates kernel structures for a new process, and returns the new PID.

View File

@ -52,6 +52,7 @@ SECTIONS
This is required by LLD to ensure the LMA of the following .data This is required by LLD to ensure the LMA of the following .data
section will have the correct alignment. */ section will have the correct alignment. */
. = ALIGN(4); . = ALIGN(4);
_etext = .;
} > REGION_RODATA } > REGION_RODATA
.data : ALIGN(4) .data : ALIGN(4)