mmu: first attempt to get it enabled
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
1ad0961c87
commit
b48271308c
26
asm.S
Normal file
26
asm.S
Normal file
@ -0,0 +1,26 @@
|
||||
#if __riscv_xlen == 64
|
||||
# define STORE sd
|
||||
# define LOAD ld
|
||||
# define LOG_REGBYTES 3
|
||||
#else
|
||||
# define STORE sw
|
||||
# define LOAD lw
|
||||
# define LOG_REGBYTES 2
|
||||
#endif
|
||||
#define REGBYTES (1 << LOG_REGBYTES)
|
||||
|
||||
.global start_kmain
|
||||
.text
|
||||
start_kmain:
|
||||
li t0, (1 << 11) | (1 << 5)
|
||||
csrw mstatus, t0
|
||||
csrw mepc, a0
|
||||
add a0, a1, zero
|
||||
add a1, a2, zero
|
||||
add a2, a3, zero
|
||||
add a3, a4, zero
|
||||
add a4, a5, zero
|
||||
add a5, a6, zero
|
||||
add a6, a7, zero
|
||||
add a7, zero, zero
|
||||
mret // Return to kmain
|
17
assemble.ps1
Normal file
17
assemble.ps1
Normal file
@ -0,0 +1,17 @@
|
||||
# remove existing blobs because otherwise this will append object files to the old blobs
|
||||
Remove-Item -Force bin/*.a
|
||||
|
||||
$crate = "xous-kernel"
|
||||
|
||||
riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32imac asm.S -o bin/$crate.o
|
||||
riscv64-unknown-elf-ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o
|
||||
riscv64-unknown-elf-ar crs bin/riscv32imc-unknown-none-elf.a bin/$crate.o
|
||||
|
||||
riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32i asm.S -DSKIP_MULTICORE -o bin/$crate.o
|
||||
riscv64-unknown-elf-ar crs bin/riscv32i-unknown-none-elf.a bin/$crate.o
|
||||
|
||||
riscv64-unknown-elf-gcc -ggdb3 -c -mabi=lp64 -march=rv64imac asm.S -o bin/$crate.o
|
||||
riscv64-unknown-elf-ar crs bin/riscv64imac-unknown-none-elf.a bin/$crate.o
|
||||
riscv64-unknown-elf-ar crs bin/riscv64gc-unknown-none-elf.a bin/$crate.o
|
||||
|
||||
Remove-Item bin/$crate.o
|
22
assemble.sh
Normal file
22
assemble.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
crate=xous-kernel
|
||||
|
||||
# remove existing blobs because otherwise this will append object files to the old blobs
|
||||
mkdir -p bin
|
||||
rm -f bin/*.a
|
||||
|
||||
riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32imac asm.S -o bin/$crate.o
|
||||
ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o
|
||||
ar crs bin/riscv32imc-unknown-none-elf.a bin/$crate.o
|
||||
|
||||
riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32i asm.S -DSKIP_MULTICORE -o bin/$crate.o
|
||||
ar crs bin/riscv32i-unknown-none-elf.a bin/$crate.o
|
||||
|
||||
riscv64-unknown-elf-gcc -ggdb3 -c -mabi=lp64 -march=rv64imac asm.S -o bin/$crate.o
|
||||
ar crs bin/riscv64imac-unknown-none-elf.a bin/$crate.o
|
||||
ar crs bin/riscv64gc-unknown-none-elf.a bin/$crate.o
|
||||
|
||||
rm bin/$crate.o
|
BIN
bin/riscv32i-unknown-none-elf.a
Normal file
BIN
bin/riscv32i-unknown-none-elf.a
Normal file
Binary file not shown.
BIN
bin/riscv32imac-unknown-none-elf.a
Normal file
BIN
bin/riscv32imac-unknown-none-elf.a
Normal file
Binary file not shown.
BIN
bin/riscv32imc-unknown-none-elf.a
Normal file
BIN
bin/riscv32imc-unknown-none-elf.a
Normal file
Binary file not shown.
BIN
bin/riscv64gc-unknown-none-elf.a
Normal file
BIN
bin/riscv64gc-unknown-none-elf.a
Normal file
Binary file not shown.
BIN
bin/riscv64imac-unknown-none-elf.a
Normal file
BIN
bin/riscv64imac-unknown-none-elf.a
Normal file
Binary file not shown.
12
build.rs
12
build.rs
@ -6,6 +6,18 @@ use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let name = env::var("CARGO_PKG_NAME").unwrap();
|
||||
|
||||
if target.starts_with("riscv") {
|
||||
fs::copy(
|
||||
format!("bin/{}.a", target),
|
||||
out_dir.join(format!("lib{}.a", name)),
|
||||
).unwrap();
|
||||
|
||||
println!("cargo:rustc-link-lib=static={}", name);
|
||||
println!("cargo:rustc-link-search={}", out_dir.display());
|
||||
}
|
||||
|
||||
// Put the linker script somewhere the linker can find it
|
||||
fs::File::create(out_dir.join("memory.x"))
|
||||
|
14
src/main.rs
14
src/main.rs
@ -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() };
|
||||
}
|
||||
}
|
||||
|
39
src/mem.rs
39
src/mem.rs
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -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
43
src/timer.rs
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user