Split kernel/user trap handler && Fix user tests.

ch4-dev
Yifan Wu 4 years ago
parent f54573ae15
commit 8ee3671269

@ -3,6 +3,7 @@ use std::fs::{File, read_dir};
fn main() {
println!("cargo:rerun-if-changed=../user/src/");
println!("cargo:rerun-if-changed={}", TARGET_PATH);
insert_app_data().unwrap();
}

@ -1,8 +1,5 @@
pub const USER_STACK_SIZE: usize = 4096 * 2;
pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
pub const MAX_APP_NUM: usize = 4;
pub const APP_BASE_ADDRESS: usize = 0x80100000;
pub const APP_SIZE_LIMIT: usize = 0x20000;
pub const KERNEL_HEAP_SIZE: usize = 0x30_0000;
pub const MEMORY_END: usize = 0x80800000;
pub const PAGE_SIZE: usize = 0x1000;

@ -1,54 +1,3 @@
use crate::trap::TrapContext;
use crate::task::TaskContext;
use crate::config::*;
use xmas_elf::ElfFile;
/*
#[repr(align(4096))]
struct KernelStack {
data: [u8; KERNEL_STACK_SIZE],
}
#[repr(align(4096))]
struct UserStack {
data: [u8; USER_STACK_SIZE],
}
static KERNEL_STACK: [KernelStack; MAX_APP_NUM] = [
KernelStack { data: [0; KERNEL_STACK_SIZE], };
MAX_APP_NUM
];
static USER_STACK: [UserStack; MAX_APP_NUM] = [
UserStack { data: [0; USER_STACK_SIZE], };
MAX_APP_NUM
];
impl KernelStack {
fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + KERNEL_STACK_SIZE
}
pub fn push_context(&self, trap_cx: TrapContext, task_cx: TaskContext) -> &'static mut TaskContext {
unsafe {
let trap_cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
*trap_cx_ptr = trap_cx;
let task_cx_ptr = (trap_cx_ptr as usize - core::mem::size_of::<TaskContext>()) as *mut TaskContext;
*task_cx_ptr = task_cx;
task_cx_ptr.as_mut().unwrap()
}
}
}
impl UserStack {
fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + USER_STACK_SIZE
}
}
*/
fn get_base_i(app_id: usize) -> usize {
APP_BASE_ADDRESS + app_id * APP_SIZE_LIMIT
}
pub fn get_num_app() -> usize {
extern "C" { fn _num_app(); }
unsafe { (_num_app as usize as *const usize).read_volatile() }
@ -69,79 +18,3 @@ pub fn get_app_data(app_id: usize) -> &'static [u8] {
)
}
}
/*
fn debug_elf(start_addr: usize, end_addr: usize) {
let data_array = unsafe {
core::slice::from_raw_parts(start_addr as *const u8, end_addr - start_addr)
};
let elf = ElfFile::new(data_array).unwrap();
let elf_header = elf.header;
let magic = elf_header.pt1.magic;
assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
let ph_count = elf_header.pt2.ph_count();
println!("ph_count = {}", ph_count);
for i in 0..ph_count {
let ph = elf.program_header(i).unwrap();
if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
println!(
"offset={:#x},va={:#x},pa={:#x},filesz={:#x},memsz={:#x},align={:#x},flag={:?}",
ph.offset(),
ph.virtual_addr(),
ph.physical_addr(),
ph.file_size(),
ph.mem_size(),
ph.align(),
ph.flags(),
);
//println!("len={:?}", ph.get_data(&elf).unwrap());
}
}
}
pub fn load_apps() {
extern "C" { fn _num_app(); }
let num_app_ptr = _num_app as usize as *const usize;
let num_app = get_num_app();
let app_start = unsafe {
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1)
};
println!("num_app = {}", num_app);
for i in 0..num_app {
println!(
"app_{} [{:#x},{:#x}) size={:#x}",
i,
app_start[i],
app_start[i + 1],
app_start[i + 1] - app_start[i]
);
debug_elf(app_start[i], app_start[i + 1]);
}
loop {}
// clear i-cache first
unsafe { llvm_asm!("fence.i" :::: "volatile"); }
// load apps
for i in 0..num_app {
let base_i = get_base_i(i);
// clear region
(base_i..base_i + APP_SIZE_LIMIT).for_each(|addr| unsafe {
(addr as *mut u8).write_volatile(0)
});
// load app from data section to memory
let src = unsafe {
core::slice::from_raw_parts(app_start[i] as *const u8, app_start[i + 1] - app_start[i])
};
let dst = unsafe {
core::slice::from_raw_parts_mut(base_i as *mut u8, src.len())
};
dst.copy_from_slice(src);
}
}
pub fn init_app_cx(app_id: usize) -> &'static TaskContext {
KERNEL_STACK[app_id].push_context(
TrapContext::app_init_context(get_base_i(app_id), USER_STACK[app_id].get_sp()),
TaskContext::goto_restore(),
)
}
*/

@ -44,10 +44,9 @@ pub fn rust_main() -> ! {
println!("[kernel] back to world!");
mm::remap_test();
trap::init();
//loader::load_apps();
//trap::enable_interrupt();
//trap::enable_timer_interrupt();
//timer::set_next_trigger();
trap::enable_timer_interrupt();
timer::set_next_trigger();
task::run_first_task();
panic!("Unreachable in rust_main!");
}

@ -2,7 +2,6 @@ use super::{PageTable, PageTableEntry, PTEFlags};
use super::{VirtPageNum, VirtAddr, PhysPageNum, PhysAddr};
use super::{FrameTracker, frame_alloc};
use super::{VPNRange, StepByOne};
use core::ops::Range;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use riscv::register::satp;
@ -16,7 +15,6 @@ use crate::config::{
TRAP_CONTEXT,
USER_STACK_SIZE
};
use xmas_elf::ElfFile;
extern "C" {
fn stext();
@ -169,7 +167,7 @@ impl MemorySet {
}
// map user stack with U flags
//println!("mapping user stack!");
let mut max_end_va: VirtAddr = max_end_vpn.into();
let max_end_va: VirtAddr = max_end_vpn.into();
let mut user_stack_bottom: usize = max_end_va.into();
// guard page
user_stack_bottom += PAGE_SIZE;
@ -227,8 +225,7 @@ impl MapArea {
}
}
pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
let mut pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
let mut ppn = PhysPageNum(0);
let ppn: PhysPageNum;
match self.map_type {
MapType::Identical => {
ppn = PhysPageNum(vpn.0);
@ -239,8 +236,10 @@ impl MapArea {
self.data_frames.insert(vpn, frame);
}
}
let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
page_table.map(vpn, ppn, pte_flags);
}
#[allow(unused)]
pub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
match self.map_type {
MapType::Framed => {
@ -255,6 +254,7 @@ impl MapArea {
self.map_one(page_table, vpn);
}
}
#[allow(unused)]
pub fn unmap(&mut self, page_table: &mut PageTable) {
for vpn in self.vpn_range {
self.unmap_one(page_table, vpn);

@ -113,12 +113,14 @@ impl PageTable {
}
result
}
#[allow(unused)]
pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
//println!("mapping {:?} {:?}", vpn, ppn);
let pte = self.find_pte_create(vpn).unwrap();
assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
*pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
}
#[allow(unused)]
pub fn unmap(&mut self, vpn: VirtPageNum) {
let pte = self.find_pte_create(vpn).unwrap();
assert!(pte.is_valid(), "vpn {:?} is invalid before unmapping", vpn);

@ -2,7 +2,6 @@ mod context;
mod switch;
mod task;
use crate::config::MAX_APP_NUM;
use crate::loader::{get_num_app, get_app_data};
use crate::trap::TrapContext;
use core::cell::RefCell;

@ -71,7 +71,6 @@ impl TaskControlBlock {
#[derive(Copy, Clone, PartialEq)]
pub enum TaskStatus {
UnInit,
Ready,
Running,
Exited,

@ -21,11 +21,7 @@ impl TrapContext {
) -> Self {
let mut sstatus = sstatus::read();
sstatus.set_spp(SPP::User);
let mut temp_sstatus: usize;
unsafe {
llvm_asm!("csrr $0, sstatus" : "=r"(temp_sstatus) ::: "volatile");
}
println!("sstatus={:#x}", temp_sstatus);
sstatus.set_spie(true);
let mut cx = Self {
x: [0; 32],
sstatus,

@ -26,11 +26,22 @@ use crate::config::{TRAP_CONTEXT, TRAMPOLINE};
global_asm!(include_str!("trap.S"));
pub fn init() {
set_kernel_trap_entry();
}
fn set_kernel_trap_entry() {
unsafe {
stvec::write(TRAMPOLINE, TrapMode::Direct);
stvec::write(trap_from_kernel as usize, TrapMode::Direct);
}
}
fn set_user_trap_entry() {
unsafe {
stvec::write(TRAMPOLINE as usize, TrapMode::Direct);
}
}
#[allow(unused)]
pub fn enable_interrupt() {
unsafe { sstatus::set_sie(); }
}
@ -42,6 +53,7 @@ pub fn enable_timer_interrupt() {
#[no_mangle]
pub fn trap_handler() -> ! {
//println!("into trap_handler!");
set_kernel_trap_entry();
let cx = current_trap_cx();
let scause = scause::read();
let stval = stval::read();
@ -73,6 +85,7 @@ pub fn trap_handler() -> ! {
#[no_mangle]
pub fn trap_return() -> ! {
set_user_trap_entry();
//println!("into trap_return");
let trap_cx_ptr = TRAP_CONTEXT;
let user_satp = current_user_token();
@ -90,4 +103,9 @@ pub fn trap_return() -> ! {
panic!("Unreachable in back_to_user!");
}
#[no_mangle]
pub fn trap_from_kernel() -> ! {
panic!("a trap from kernel!");
}
pub use context::{TrapContext};

@ -6,24 +6,24 @@ extern crate user_lib;
const LEN: usize = 100;
static mut s: [u64; LEN] = [0u64; LEN];
static mut S: [u64; LEN] = [0u64; LEN];
#[no_mangle]
unsafe fn main() -> i32 {
let p = 3u64;
let m = 998244353u64;
let iter: usize = 100000;
let iter: usize = 300000;
let mut cur = 0usize;
s[cur] = 1;
S[cur] = 1;
for i in 1..=iter {
let next = if cur + 1 == LEN { 0 } else { cur + 1 };
s[next] = s[cur] * p % m;
S[next] = S[cur] * p % m;
cur = next;
if i % 10000 == 0 {
println!("power_3 [{}/{}]", i, iter);
}
}
println!("{}^{} = {}", p, iter, s[cur]);
println!("{}^{} = {}(mod {})", p, iter, S[cur], m);
println!("Test power_3 OK!");
0
}

@ -6,24 +6,24 @@ extern crate user_lib;
const LEN: usize = 100;
static mut s: [u64; LEN] = [0u64; LEN];
static mut S: [u64; LEN] = [0u64; LEN];
#[no_mangle]
unsafe fn main() -> i32 {
let p = 5u64;
let m = 998244353u64;
let iter: usize = 70000;
let iter: usize = 210000;
let mut cur = 0usize;
s[cur] = 1;
S[cur] = 1;
for i in 1..=iter {
let next = if cur + 1 == LEN { 0 } else { cur + 1 };
s[next] = s[cur] * p % m;
S[next] = S[cur] * p % m;
cur = next;
if i % 10000 == 0 {
println!("power_5 [{}/{}]", i, iter);
}
}
println!("{}^{} = {}", p, iter, s[cur]);
println!("{}^{} = {}(mod {})", p, iter, S[cur], m);
println!("Test power_5 OK!");
0
}

@ -6,24 +6,24 @@ extern crate user_lib;
const LEN: usize = 100;
static mut s: [u64; LEN] = [0u64; LEN];
static mut S: [u64; LEN] = [0u64; LEN];
#[no_mangle]
unsafe fn main() -> i32 {
let p = 7u64;
let m = 998244353u64;
let iter: usize = 80000;
let iter: usize = 240000;
let mut cur = 0usize;
s[cur] = 1;
S[cur] = 1;
for i in 1..=iter {
let next = if cur + 1 == LEN { 0 } else { cur + 1 };
s[next] = s[cur] * p % m;
S[next] = S[cur] * p % m;
cur = next;
if i % 10000 == 0 {
println!("power_7 [{}/{}]", i, iter);
}
}
println!("{}^{} = {}", p, iter, s[cur]);
println!("{}^{} = {}(mod {})", p, iter, S[cur], m);
println!("Test power_7 OK!");
0
}

Loading…
Cancel
Save