mmu: first attempt to get it enabled

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
2020-01-21 18:14:13 +08:00
parent 1ad0961c87
commit b48271308c
13 changed files with 173 additions and 18 deletions

View File

@ -12,6 +12,7 @@ mod macros;
mod mem;
mod processtable;
mod syscalls;
mod timer;
pub use irq::sys_interrupt_claim;
@ -39,6 +40,8 @@ fn xous_main() -> ! {
}
let uart = debug::DEFAULT_UART;
sys_interrupt_claim(0, timer::irq).unwrap();
timer::time_init();
// Enable "RX_EMPTY" interrupt
uart.enable_rx();
@ -50,10 +53,19 @@ fn xous_main() -> ! {
let mut mm = MemoryManager::new();
println!("Creating process table...");
let mut _pt = ProcessTable::new(&mut mm);
ProcessTable::new(mm, kmain);
panic!("fell off main");
}
fn kmain(mm: MemoryManager, pt: ProcessTable) -> ! {
println!("Entering main loop");
let mut last_time = timer::get_time();
loop {
let new_time = timer::get_time();
if new_time >= last_time + 1000 {
last_time = new_time;
println!("Uptime: {} ms", new_time);
}
// unsafe { vexriscv::asm::wfi() };
}
}

View File

@ -25,8 +25,8 @@ const IO_PAGE_COUNT: usize = IO_SIZE;
const LCD_PAGE_COUNT: usize = LCD_SIZE / PAGE_SIZE;
pub struct MemoryManager {
flash: [XousPid; FLASH_PAGE_COUNT],
ram: [XousPid; RAM_PAGE_COUNT],
flash: [XousPid; FLASH_PAGE_COUNT],
io: [XousPid; IO_PAGE_COUNT],
lcd: [XousPid; LCD_PAGE_COUNT],
}
@ -241,22 +241,25 @@ impl MemoryManager {
}
/// Create an identity mapping, copying the kernel to itself
pub fn create_identity(&mut self, process: &Process, pid: XousPid) -> Result<(), XousError> {
pub fn create_identity(&mut self, process: &Process) -> Result<(), XousError> {
let root_page = (process.satp & ((1 << 22) - 1)) << 9;
let pt = unsafe { &mut (*(root_page as *mut PageTable)) };
println!("SATP value: {:08x} Root page: {:08x} pt: {:p} pt: {:p}", process.satp, root_page, &pt, pt);
let flash_orig = self.flash.clone();
for (flash_idx, flash_pid) in flash_orig.iter().enumerate() {
if *flash_pid == pid {
// println!(
// "Flash addr {:08x} owned by PID {}, mapping it as ident",
// flash_idx * PAGE_SIZE + FLASH_START,
// pid
// );
let ranges = [
mem_range!(&_sbss, &_ebss),
mem_range!(&_sdata, &_edata),
mem_range!(&_estack, &_sstack), // NOTE: Stack is reversed
mem_range!(&_stext, &_etext),
];
for range in &ranges {
for region in range.clone() {
// mm.claim_page(region & !0xfff, 1)
// .expect("Unable to claim region for PID 1");
self.map_page(
pt,
flash_idx * PAGE_SIZE + FLASH_START,
flash_idx * PAGE_SIZE + FLASH_START,
region,
region,
)?;
print!("Entries mapped: >");
let mut i = 0;
@ -270,6 +273,18 @@ impl MemoryManager {
println!("");
}
}
// let flash_orig = self.flash.clone();
// for (flash_idx, flash_pid) in flash_orig.iter().enumerate() {
// if *flash_pid == pid {
// println!(
// "Flash addr {:08x} owned by PID {}, mapping it as ident",
// flash_idx * PAGE_SIZE + FLASH_START,
// pid
// );
// }
// }
// for (idx, page) in flash_orig.iter().enumerate() {
Ok(())
}

View File

@ -1,7 +1,7 @@
use crate::definitions::{MemoryAddress, XousError, XousPid};
use crate::mem::MemoryManager;
use crate::{filled_array, print, println};
use vexriscv::register::{satp, mstatus};
use vexriscv::register::{mstatus, satp};
const MAX_PROCESS_COUNT: usize = 256;
@ -26,8 +26,16 @@ pub struct ProcessTable {
processes: [Process; MAX_PROCESS_COUNT],
}
extern "Rust" {
fn start_kmain(
kmain: extern "Rust" fn(MemoryManager, ProcessTable) -> !,
mm: MemoryManager,
pt: ProcessTable,
) -> !;
}
impl ProcessTable {
pub fn new(mm: &mut MemoryManager) -> Self {
pub fn new(mut mm: MemoryManager, kmain: fn(MemoryManager, ProcessTable) -> !) -> ! {
let mut pt = ProcessTable {
processes: filled_array![Process { satp: 0 }; 256],
};
@ -36,7 +44,7 @@ impl ProcessTable {
// for "PID 1"
let root_page = mm.alloc_page(1).unwrap().get();
pt.processes[1].satp = (root_page >> 9) | (1 << 22);
mm.create_identity(&pt.processes[1], 1)
mm.create_identity(&pt.processes[1])
.expect("Unable to create identity mapping");
println!("PID 1: {:?} root page @ {:08x}", pt.processes[1], root_page);
println!("Enabling MMU...");
@ -51,7 +59,7 @@ impl ProcessTable {
// Switch to Supervisor mode
mstatus::set_mpp(mstatus::MPP::Supervisor);
};
println!("MMU enabled");
pt
println!("MMU enabled, jumping to kmain");
unsafe { start_kmain(kmain, mm, pt) }
}
}

43
src/timer.rs Normal file
View File

@ -0,0 +1,43 @@
static mut TIME_MS: u32 = 0;
pub fn irq(_irq_number: usize) {
let timer_base = 0xE0002800 as *mut u8;
unsafe {
TIME_MS = TIME_MS + 1;
timer_base.add(0x3c).write_volatile(1);
};
}
pub fn get_time() -> u32 {
unsafe { TIME_MS }
}
pub fn time_init() {
let timer_base = 0xE0002800 as *mut u8;
let period = 12_000_000 / 1000; // 12 MHz, 1 ms timer
unsafe {
// Disable, so we can update it
timer_base.add(0x20).write_volatile(0);
// Update "reload" register
timer_base.add(0x10).write_volatile((period >> 24) as u8);
timer_base.add(0x14).write_volatile((period >> 16) as u8);
timer_base.add(0x18).write_volatile((period >> 8) as u8);
timer_base.add(0x1c).write_volatile((period >> 0) as u8);
// Update "load" register
timer_base.add(0x00).write_volatile((period >> 24) as u8);
timer_base.add(0x04).write_volatile((period >> 16) as u8);
timer_base.add(0x08).write_volatile((period >> 8) as u8);
timer_base.add(0x0c).write_volatile((period >> 0) as u8);
// Enable ISR
timer_base.add(0x40).write_volatile(1);
// Set "pending" as well to clear it
timer_base.add(0x38).write_volatile(1);
// Finally, enable it
timer_base.add(0x20).write_volatile(1);
}
}