From 3c15bd68d3482726bd9a97e75d2178f5d2eb62fe Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Tue, 21 Jan 2020 20:05:39 +0800 Subject: [PATCH] mmu: almost have it working Just have major stack issues. Signed-off-by: Sean Cross --- asm.S | 6 +++ bin/riscv32i-unknown-none-elf.a | Bin 2244 -> 2378 bytes bin/riscv32imac-unknown-none-elf.a | Bin 2260 -> 2394 bytes bin/riscv32imc-unknown-none-elf.a | Bin 2260 -> 2394 bytes bin/riscv64gc-unknown-none-elf.a | Bin 3364 -> 3570 bytes bin/riscv64imac-unknown-none-elf.a | Bin 3364 -> 3570 bytes build.rs | 1 + src/main.rs | 7 +-- src/mem.rs | 81 +++++++++++++++-------------- src/processtable.rs | 6 ++- 10 files changed, 59 insertions(+), 42 deletions(-) diff --git a/asm.S b/asm.S index e3de3bd..21e470d 100644 --- a/asm.S +++ b/asm.S @@ -24,3 +24,9 @@ start_kmain: add a6, a7, zero add a7, zero, zero mret // Return to kmain + +.global read_satp +.text +read_satp: + csrr a0, satp + ret diff --git a/bin/riscv32i-unknown-none-elf.a b/bin/riscv32i-unknown-none-elf.a index 44d9ade270c640a403dbb5eca520551996052cdd..5bbf9fee39d0172a0f7a3f165c6cedd12af506e5 100644 GIT binary patch delta 609 zcmZva&o2W}5Xa~3_U)Dw+iLwNkw??5M6j*4NP6bdgNvJlCW;1C{gFsWint2RyGZm; z5Emj2+?*s1{1N^FSBaUoO$a8Ld7t^tym_0+KKY*m=R@^GDn2cQBglS6A*PZ_#IVv1 z02=xld8L{wSC==pbA=+5^SRaKO0HUhy`5TRd^2Az=C>wxCWVNnrf1X6-|2D3NvG37 zBoc9qqHz}0MvcbZTw5gyed~t+hmFr&P3LlzWp8fT0h24b$3KG)yT*VaWMovIWEr`r zUycPZPqwNSRVT8JfPcU8M)!nRy@t&rmV1NP?s9pbbpJQot)4pR^a>iW-Rd!rSwE=& zK6DmV2y~4FU8aMDT<#<8fq9h;Qqt=d1Tj_7)X;91e-DbZ2GP)1P+s#lT)~kMVI}!u z^vVarQWWDQY&emxMz{2t7Qfd4mgKM*;UB2mN?$T9Ey!ijw0Rg;7F6PuX)#AWnlWvI v%Xiae3$nu-GV3~lTXmFlIAyJPWa*r&K?mWQ+mD zao8+2nrD^E;zfNnw9rPQdEs=4~Q5W(hlVar#3y-v#T3%&bgQFA ztlFRoq$~v_hscEDdCf!5xaN_MK0)nsM@EXJgZbzuU7d3m%DBQM05f+4~iM`$>O)2u};ay S!PtbG78YZ7RR5Ry2BkkJPDj%K diff --git a/bin/riscv32imac-unknown-none-elf.a b/bin/riscv32imac-unknown-none-elf.a index 59fb560db4a70b8e963bcbec8f3001a960e735a7..39cbe4b00f1be0b72aeb7a787305f911701726d7 100644 GIT binary patch delta 606 zcmZuvO-sW-5Z!IMNfAHN54CD7i?t~tYEo@l{Q-Ir@dpUCUY&CWsm*= z54}}9iDwUb5l?~#|AOFAaAp%w)Pb3O^WN;+FyuM-61s>t(-|wvxydnpR?cVVBnf4` zixA?2+{CQb3YA)Zd$+LVkV>(zk*^kNWzs0st5e&>ic{Q~F3oUmWwP_O`PbbtP209P zPp4KpqN%Z*WsP(z$Q<&JGE1he4N<~@m2XpYO8h!Y7$-m#&3H$qLvkt>!x_bk$(dXg=Y#W~b%|2Ufq@h8riMjK)7ia3$eOUU1bYYGko=CO`^K3#)C?Adl|>|ZtLfAfk6Ma0 u#0S(>F&ap*W6&q0z827X+PHrB6MEr@i~Ya|YlD4E>g|Bet{5R_*nI(J`eo(- delta 446 zcmca5bVYE2T!^8eiJ^jmfdU91lL`t(5H3(Wfs28Gff0x!ic1oUO5(F~6EpJ|D)LK< zb+c28@=|m3^7R!I3{A}~%?v>1O>7WnGBlhxQ%=2&j3tu=84D-(F}iHNz}Uw) zxsF+d(PZ*s=GnpwdOijU49JEuY|dm6Wvnj-TBalbB!B?KR^taV8Q6dnqd0`k17b@+ z*dV2hLJ+nHh%F3ZgQOWj0ze=G#Eha~CW8WqEe2tO%@l;Nq2@qr0O?bP8U$ji3r%)m zy99K)IJ+`q#$;=Dbs(9{uFjePl&qNC&#uhcz|6p)GkH5u{=wwi?CMNwSSGV@s4=ol z*5*)WRG1tLBpD`G14)O;i-Ba(Y&CWsm*= z54}}9iDwUb5l?~#|AOFAaAp%w)Pb3O^WN;+FyuM-61s>t(-|wvxydnpR?cVVBnf4` zixA?2+{CQb3YA)Zd$+LVkV>(zk*^kNWzs0st5e&>ic{Q~F3oUmWwP_O`PbbtP209P zPp4KpqN%Z*WsP(z$Q<&JGE1he4N<~@m2XpYO8h!Y7$-m#&3H$qLvkt>!x_bk$(dXg=Y#W~b%|2Ufq@h8riMjK)7ia3$eOUU1bYYGko=CO`^K3#)C?Adl|>|ZtLfAfk6Ma0 u#0S(>F&ap*W6&q0z827X+PHrB6MEr@i~Ya|YlD4E>g|Bet{5R_*nI(J`eo(- delta 446 zcmca5bVYE2T!^8eiJ^jmfdU91lL`t(5H3(Wfs28Gff0x!ic1oUO5(F~6EpJ|D)LK< zb+c28@=|m3^7R!I3{A}~%?v>1O>7WnGBlhxQ%=2&j3tu=84D-(F}iHNz}Uw) zxsF+d(PZ*s=GnpwdOijU49JEuY|dm6Wvnj-TBalbB!B?KR^taV8Q6dnqd0`k17b@+ z*dV2hLJ+nHh%F3ZgQOWj0ze=G#Eha~CW8WqEe2tO%@l;Nq2@qr0O?bP8U$ji3r%)m zy99K)IJ+`q#$;=Dbs(9{uFjePl&qNC&#uhcz|6p)GkH5u{=wwi?CMNwSSGV@s4=ol z*5*)WRG1tLBpD`G14)O;i-Ba(!o+(8ebv3|iH z&|Go~UOWmOa`d3T;8hg6GZP7DLDhTx`gL`6-wl2Y-3%X2&xTE1H*^-=Ro7=CZIPBu zh2uCvbDL$clq{4s(wXE=mMf%^TN}k>X^-2_m5af2s*p|XPUS+n9-cMlqsHIvVZ(?< zqpZ6zM_bpfgJe~%HJ8NV7}tMtbcQmNi9^5=tk+u*Aoxlon8RnH!2;I6bIV64S>ZKY z=3fLi9jFh(ya)Y)TmGG<9uk5CD!3+UnF_VA7^m6WW>z`0`3ObVKRWaGb?K)zXMT2V zCptRwyYN`l1_nA?6jhr8#X-CmHSl6y@(AoVefTbF7?4yL#VgAEl=ZU?;OTOXww-y2 zoxGGj>Eq936RPwtG;GNMn|YOhT($4Iz(vKBIl)>s@LVwo0c1O>7WnHZnAuILm-(0>{KNUW^r!Wf@B+&tnYP{DD!6 zY4QO^mdSoBCX=~X#3s*Rxiq{W-)X z#gSxrplpyEB_`JcWrdJrC7^63AT2z3Jy2EzNmd2Q2I&=@e4j&{Q4C~0qaaRmKstmc z+jELD3QZ2@{LN@GIhf0wv1IZ_M)ApuxHO=wM_d}5B~Y_#CJS?$b1qZi=mn7LfM5s6 e4?w^N#4?lPd9^t^poR)fp3G~`$T0aduQ~uAcvM>e diff --git a/bin/riscv64imac-unknown-none-elf.a b/bin/riscv64imac-unknown-none-elf.a index 76192b186cf274e570f4b1c697c230254fb4e053..def0bcc359425cd254de13d7b9cbaef33f28a82f 100644 GIT binary patch delta 584 zcmZut$w~u35S{AGFiQqC8{-mW5SM_&Of+UxNOJNb3jTmgzz7nPm<>!o+(8ebv3|iH z&|Go~UOWmOa`d3T;8hg6GZP7DLDhTx`gL`6-wl2Y-3%X2&xTE1H*^-=Ro7=CZIPBu zh2uCvbDL$clq{4s(wXE=mMf%^TN}k>X^-2_m5af2s*p|XPUS+n9-cMlqsHIvVZ(?< zqpZ6zM_bpfgJe~%HJ8NV7}tMtbcQmNi9^5=tk+u*Aoxlon8RnH!2;I6bIV64S>ZKY z=3fLi9jFh(ya)Y)TmGG<9uk5CD!3+UnF_VA7^m6WW>z`0`3ObVKRWaGb?K)zXMT2V zCptRwyYN`l1_nA?6jhr8#X-CmHSl6y@(AoVefTbF7?4yL#VgAEl=ZU?;OTOXww-y2 zoxGGj>Eq936RPwtG;GNMn|YOhT($4Iz(vKBIl)>s@LVwo0c1O>7WnHZnAuILm-(0>{KNUW^r!Wf@B+&tnYP{DD!6 zY4QO^mdSoBCX=~X#3s*Rxiq{W-)X z#gSxrplpyEB_`JcWrdJrC7^63AT2z3Jy2EzNmd2Q2I&=@e4j&{Q4C~0qaaRmKstmc z+jELD3QZ2@{LN@GIhf0wv1IZ_M)ApuxHO=wM_d}5B~Y_#CJS?$b1qZi=mn7LfM5s6 e4?w^N#4?lPd9^t^poR)fp3G~`$T0aduQ~uAcvM>e diff --git a/build.rs b/build.rs index 4ecb4fa..03849de 100644 --- a/build.rs +++ b/build.rs @@ -17,6 +17,7 @@ fn main() { println!("cargo:rustc-link-lib=static={}", name); println!("cargo:rustc-link-search={}", out_dir.display()); + println!("cargo:rerun-if-changed=bin/{}.a", target); } // Put the linker script somewhere the linker can find it diff --git a/src/main.rs b/src/main.rs index b609553..4fe3c91 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ pub use irq::sys_interrupt_claim; use core::panic::PanicInfo; use mem::MemoryManager; use processtable::ProcessTable; -use vexriscv::register::{mcause, mie, mstatus, vmim, vmip}; +use vexriscv::register::{mcause, mepc, mie, mstatus, vmim, vmip}; use xous_kernel_riscv_rt::xous_kernel_entry; #[panic_handler] @@ -50,11 +50,10 @@ fn xous_main() -> ! { sys_interrupt_claim(2, debug::irq).unwrap(); println!("Creating memory manager..."); - let mut mm = MemoryManager::new(); + let mm = MemoryManager::new(); println!("Creating process table..."); ProcessTable::new(mm, kmain); - panic!("fell off main"); } fn kmain(mm: MemoryManager, pt: ProcessTable) -> ! { @@ -76,6 +75,8 @@ pub fn trap_handler() { let irqs_pending = vmip::read(); if mc.is_exception() { + println!("CPU Exception"); + println!("{:?} @ PC: {:08x}", mc.cause(), mepc::read()); unsafe { vexriscv::asm::ebreak() }; loop {} } diff --git a/src/mem.rs b/src/mem.rs index 93bc078..9715faf 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -134,14 +134,14 @@ impl MemoryManager { // the MMU unsafe { mstatus::clear_mie() }; - let ranges = [ + let mut 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() { + for range in &mut ranges { + for region in range { mm.claim_page(region & !0xfff, 1) .expect("Unable to claim region for PID 1"); } @@ -190,11 +190,12 @@ impl MemoryManager { phys: usize, virt: usize, ) -> Result<(), XousError> { - let ppn1 = (phys >> 20) & ((1 << 12) - 1); - let ppn0 = (phys >> 10) & ((1 << 10) - 1); + let ppn1 = (phys >> 22) & ((1 << 12) - 1); + let ppn0 = (phys >> 12) & ((1 << 10) - 1); let ppo = (phys >> 0) & ((1 << 12) - 1); + let vpn1 = (virt >> 22) & ((1 << 10) - 1); - let vpn0 = (virt >> 10) & ((1 << 10) - 1); + let vpn0 = (virt >> 12) & ((1 << 10) - 1); let vpo = (virt >> 0) & ((1 << 12) - 1); println!( @@ -213,7 +214,10 @@ impl MemoryManager { // Allocate a new level 1 pagetable entry if one doesn't exist. if l1_pt[vpn1] & 1 == 0 { - println!(" top-level VPN1 {:04x}: {:08x} (will allocate a new one)", vpn1, l1_pt[vpn1]); + println!( + " top-level VPN1 {:04x}: {:08x} (will allocate a new one)", + vpn1, l1_pt[vpn1] + ); // Allocate the page to the kernel (PID 1) let new_addr = self.alloc_page(1)?.get(); println!( @@ -223,64 +227,65 @@ impl MemoryManager { // Mark this entry as a leaf node (WRX as 0), and indicate // it is a valid page by setting "V". - l1_pt[vpn1] = (((new_addr >> 10) & ((1 << 22) - 1)) << 10) | 1; + let ppn = new_addr >> 12; + l1_pt[vpn1] = (ppn << 10) | 1; println!(" New top-level page entry: {:08x}", l1_pt[vpn1]); } - let mut l0_pt = unsafe { - let tmp = (l1_pt[vpn1] & ((1 << 10) - 1)) as *mut PageTable; - (*tmp).entries - }; + let l0_pt_idx = + unsafe { &mut (*(((l1_pt[vpn1] << 2) & !((1 << 12) - 1)) as *mut PageTable)) }; + let ref mut l0_pt = l0_pt_idx.entries; + println!(" l0_pt is at {:p} ({:p})", &l0_pt, &l0_pt[vpn0]); // Allocate a new level 0 pagetable entry if one doesn't exist. if l0_pt[vpn0] & 1 != 0 { - panic!("Page already allocated!"); + println!("Page already allocated!"); } - l0_pt[vpn0] = (ppn1 << 20) | (ppn0 << 10) | 1 | 0xe; + l0_pt[vpn0] = (ppn1 << 20) | (ppn0 << 10) | 1 | 0xe | 0xc0; Ok(()) } /// Create an identity mapping, copying the kernel to itself pub fn create_identity(&mut self, process: &Process) -> Result<(), XousError> { - let root_page = (process.satp & ((1 << 22) - 1)) << 9; + let root_page = (process.satp & ((1 << 22) - 1)) << 12; 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); + println!( + "SATP value: {:08x} Root page: {:08x} pt: {:p} pt: {:p}", + process.satp, root_page, &pt, pt + ); - let ranges = [ + let mut 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() { + for range in &mut ranges { + for region in range { // mm.claim_page(region & !0xfff, 1) // .expect("Unable to claim region for PID 1"); - self.map_page( - pt, - region, - region, - )?; - print!("Entries mapped: >"); - let mut i = 0; - for (entry_idx, entry) in pt.entries.iter().enumerate() { - i = i + 1; - if *entry != 0 { - print!(" {}:{:08x}", entry_idx, entry); - } - } - println!(" < ({})", i); + self.map_page(pt, region, region)?; + // print!("Entries mapped: >"); + // let mut i = 0; + // for (entry_idx, entry) in pt.entries.iter().enumerate() { + // i = i + 1; + // if *entry != 0 { + // print!(" {}:{:08x}", entry_idx, entry); + // } + // } + // println!(" < ({})", i); println!(""); } } + self.map_page(pt, 0xE000_1800, 0xE000_1800)?; // 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 - // ); + // println!( + // "Flash addr {:08x} owned by PID {}, mapping it as ident", + // flash_idx * PAGE_SIZE + FLASH_START, + // pid + // ); // } // } diff --git a/src/processtable.rs b/src/processtable.rs index 2f0d6d5..36219df 100644 --- a/src/processtable.rs +++ b/src/processtable.rs @@ -33,6 +33,9 @@ extern "Rust" { pt: ProcessTable, ) -> !; } +extern "C" { + fn read_satp() -> usize; +} impl ProcessTable { pub fn new(mut mm: MemoryManager, kmain: fn(MemoryManager, ProcessTable) -> !) -> ! { @@ -43,7 +46,7 @@ impl ProcessTable { // Allocate a root page table for PID 1. Also mark the "ASID" as "1" // for "PID 1" let root_page = mm.alloc_page(1).unwrap().get(); - pt.processes[1].satp = (root_page >> 9) | (1 << 22); + pt.processes[1].satp = (root_page >> 12) | (1 << 22); mm.create_identity(&pt.processes[1]) .expect("Unable to create identity mapping"); println!("PID 1: {:?} root page @ {:08x}", pt.processes[1], root_page); @@ -60,6 +63,7 @@ impl ProcessTable { mstatus::set_mpp(mstatus::MPP::Supervisor); }; println!("MMU enabled, jumping to kmain"); + println!("SATP: {:08x}", unsafe { read_satp() }); unsafe { start_kmain(kmain, mm, pt) } } }