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 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 --
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
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;
|
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
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;
|
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.
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user