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 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 --

View File

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

View File

@ -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");

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;
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<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> {
// 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(())

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;
#[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,
}
use super::definitions::*;
extern "Rust" {
/// 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
section will have the correct alignment. */
. = ALIGN(4);
_etext = .;
} > REGION_RODATA
.data : ALIGN(4)