From b48271308cfcd61c450a73dc8a4207e6cc247bb8 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Tue, 21 Jan 2020 18:14:13 +0800 Subject: [PATCH] mmu: first attempt to get it enabled Signed-off-by: Sean Cross --- asm.S | 26 +++++++++++++++++ assemble.ps1 | 17 ++++++++++++ assemble.sh | 22 +++++++++++++++ bin/riscv32i-unknown-none-elf.a | Bin 0 -> 2244 bytes bin/riscv32imac-unknown-none-elf.a | Bin 0 -> 2260 bytes bin/riscv32imc-unknown-none-elf.a | Bin 0 -> 2260 bytes bin/riscv64gc-unknown-none-elf.a | Bin 0 -> 3364 bytes bin/riscv64imac-unknown-none-elf.a | Bin 0 -> 3364 bytes build.rs | 12 ++++++++ src/main.rs | 14 +++++++++- src/mem.rs | 39 ++++++++++++++++++-------- src/processtable.rs | 18 ++++++++---- src/timer.rs | 43 +++++++++++++++++++++++++++++ 13 files changed, 173 insertions(+), 18 deletions(-) create mode 100644 asm.S create mode 100644 assemble.ps1 create mode 100644 assemble.sh create mode 100644 bin/riscv32i-unknown-none-elf.a create mode 100644 bin/riscv32imac-unknown-none-elf.a create mode 100644 bin/riscv32imc-unknown-none-elf.a create mode 100644 bin/riscv64gc-unknown-none-elf.a create mode 100644 bin/riscv64imac-unknown-none-elf.a create mode 100644 src/timer.rs diff --git a/asm.S b/asm.S new file mode 100644 index 0000000..e3de3bd --- /dev/null +++ b/asm.S @@ -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 diff --git a/assemble.ps1 b/assemble.ps1 new file mode 100644 index 0000000..1058229 --- /dev/null +++ b/assemble.ps1 @@ -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 diff --git a/assemble.sh b/assemble.sh new file mode 100644 index 0000000..7d9d444 --- /dev/null +++ b/assemble.sh @@ -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 diff --git a/bin/riscv32i-unknown-none-elf.a b/bin/riscv32i-unknown-none-elf.a new file mode 100644 index 0000000000000000000000000000000000000000..44d9ade270c640a403dbb5eca520551996052cdd GIT binary patch literal 2244 zcmbtVO>Y!O5Uuuj*Ty!>+CV;V4#N`0AUTu$aEu%UVuA<V7gt~E2Z z9OV#%6v!cwkht;vrD2VN=e=Qs_J!B_jGm7>2IQBW9!n? zm;SIczPhloTyHd%8opo8UB%w_n^uMA!IX#?w0mh5CE5Dpov7QBgZ^In#p5{X#oJ*Y z!T%{-WZ0oV&soJfzw}?ELzHkb5fOK@@7ut<5H*? zT0Obc`ne>BrLwf1mF2KJA+6^VayT(5tzRbPa8e`{zn)>fC!e7==FiGe^m$SwHWH;f z;Vqk{G{(`Z7|$Gm>;Lqak1RFxc}y7}Y?3(&VxE{;sg`HWobf92m9v%Ox@mB@Vx3=@ zF@SdMSH5oFN#i7Kr#l--zkQ{@8Mp7@RND4bsCH+0t1 zKs=cqC_tXfV1)yzGJCjI_oaAKMb3j_G;|BNrlm$4sC|WY4MrR&=Udt*&_Rd; z>GFvK1%4wS>~nUB#y7}{ttl4|e&55h- z(=d?dsbk9#bfk~6fX4FqH(moAHwRD{?|?wX`S=cS4XbM3Mc_p^St_)%@yx$Nb8`UY zEm}aJ;(QmO7vsHxavL_r<2P{eZUDPEfKrCS^LFBV5eyE~=R@%cRP-uI8+tMCJ1Bh9 zn3vbe<=q8lJo+fBP?{FzJ$-CHqTy4Jo=XDbDW_m0hr+S=2ly3+-_dxbSo_RdMdKRW anE^^0iYsmEE*`H$k>}&h`Hch>$NLK=`klo9 literal 0 HcmV?d00001 diff --git a/bin/riscv32imac-unknown-none-elf.a b/bin/riscv32imac-unknown-none-elf.a new file mode 100644 index 0000000000000000000000000000000000000000..59fb560db4a70b8e963bcbec8f3001a960e735a7 GIT binary patch literal 2260 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 ! { } 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() }; } } diff --git a/src/mem.rs b/src/mem.rs index b043cf4..93bc078 100644 --- a/src/mem.rs +++ b/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(()) } diff --git a/src/processtable.rs b/src/processtable.rs index 3432ffd..2f0d6d5 100644 --- a/src/processtable.rs +++ b/src/processtable.rs @@ -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) } } } diff --git a/src/timer.rs b/src/timer.rs new file mode 100644 index 0000000..6ecd091 --- /dev/null +++ b/src/timer.rs @@ -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); + } +}