processes: start defining what a process is
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
649d1ba26b
commit
3a6c4f9a1c
70
src/definitions.rs
Normal file
70
src/definitions.rs
Normal 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,
|
||||
}
|
@ -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 --
|
||||
|
@ -9,4 +9,4 @@ extern crate xous_riscv;
|
||||
// }
|
||||
|
||||
// Allow consumers of this library to make syscalls
|
||||
pub mod syscalls;
|
||||
// pub mod syscalls;
|
||||
|
@ -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");
|
||||
|
57
src/mem.rs
57
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<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
26
src/processtable.rs
Normal 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
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user