Recover `process` `thread` `sync` mod for RV32. Pass compile.

master
WangRunji 7 years ago
parent 0b5c9c0c68
commit 5530549a54

@ -1 +1 @@
Subproject commit 08d4a2e96399cef5985a85a035e1ac222f8d5bef Subproject commit b979c91db3bcfd9c9e9edabf45ef04e41dc4f659

@ -0,0 +1,155 @@
use super::super::riscv::register::*;
#[derive(Debug, Clone)]
#[repr(C)]
pub struct TrapFrame {
pub x: [usize; 32],
pub sstatus: sstatus::Sstatus,
pub sepc: usize,
pub sbadaddr: usize,
pub scause: scause::Scause,
}
/// 用于在内核栈中构造新线程的中断帧
impl TrapFrame {
fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, rsp: usize) -> Self {
use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() };
tf.x[10] = arg; // a0
tf.sepc = entry as usize;
tf
}
fn new_user_thread(entry_addr: usize, rsp: usize) -> Self {
unimplemented!()
}
pub fn is_user(&self) -> bool {
unimplemented!()
}
}
/// 新线程的内核栈初始内容
#[derive(Debug)]
#[repr(C)]
pub struct InitStack {
context: ContextData,
tf: TrapFrame,
}
impl InitStack {
unsafe fn push_at(self, stack_top: usize) -> Context {
let ptr = (stack_top as *mut Self).offset(-1);
*ptr = self;
Context(ptr as usize)
}
}
extern {
fn trap_ret();
}
/// The entry point of new thread
extern fn forkret() {
debug!("forkret");
// Will return to `trapret`
}
#[derive(Debug, Default)]
#[repr(C)]
struct ContextData {
ra: usize,
satp: usize,
s: [usize; 12],
}
impl ContextData {
fn new(satp: usize) -> Self {
ContextData { ra: forkret as usize, satp, ..ContextData::default() }
}
}
#[derive(Debug)]
pub struct Context(usize);
impl Context {
/// Switch to another kernel thread.
///
/// Defined in `trap.asm`.
///
/// Push all callee-saved registers at the current kernel stack.
/// Store current sp, switch to target.
/// Pop all callee-saved registers, then return to the target.
#[naked]
#[inline(never)]
pub unsafe extern fn switch(&mut self, target: &mut Self) {
asm!(
"
// save from's registers
sub sp, -14*4
sw sp, (a0)
sw ra, 0*4(sp)
sw s0, 2*4(sp)
sw s1, 3*4(sp)
sw s2, 4*4(sp)
sw s3, 5*4(sp)
sw s4, 6*4(sp)
sw s5, 7*4(sp)
sw s6, 8*4(sp)
sw s7, 9*4(sp)
sw s8, 10*4(sp)
sw s9, 11*4(sp)
sw s10, 12*4(sp)
sw s11, 13*4(sp)
csrrs s11, 0x180, x0 // satp
sw s11, 1*4(sp)
// restore to's registers
lw sp, (a1)
lw s11, 1*4(sp)
csrrw x0, 0x180, s11 // satp
lw ra, 0*4(sp)
lw s0, 2*4(sp)
lw s1, 3*4(sp)
lw s2, 4*4(sp)
lw s3, 5*4(sp)
lw s4, 6*4(sp)
lw s5, 7*4(sp)
lw s6, 8*4(sp)
lw s7, 9*4(sp)
lw s8, 10*4(sp)
lw s9, 11*4(sp)
lw s10, 12*4(sp)
lw s11, 13*4(sp)
add sp, 14*4
sw zero, (a1)
ret"
: : : : "intel" "volatile" )
}
pub unsafe fn null() -> Self {
Context(0)
}
pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, cr3: usize) -> Self {
InitStack {
context: ContextData::new(cr3),
tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top),
}.push_at(kstack_top)
}
pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, is32: bool, cr3: usize) -> Self {
InitStack {
context: ContextData::new(cr3),
tf: TrapFrame::new_user_thread(entry_addr, ustack_top),
}.push_at(kstack_top)
}
pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self {
InitStack {
context: ContextData::new(cr3),
tf: {
let mut tf = tf.clone();
tf.x[1] = 0; // ra
tf
},
}.push_at(kstack_top)
}
}

@ -1,13 +1,32 @@
use super::riscv::register::*; use super::riscv::register::*;
pub use self::context::*;
#[path = "context.rs"]
mod context;
pub fn init() { pub fn init() {
unsafe { unsafe {
// Set the exception vector address // Set the exception vector address
stvec::write(__alltraps as usize, stvec::TrapMode::Direct); stvec::write(__alltraps as usize, stvec::TrapMode::Direct);
// Enable interrupt }
info!("stvec: init end");
}
#[inline(always)]
pub unsafe fn enable() {
sstatus::set_sie();
}
#[inline(always)]
pub unsafe fn disable_and_store() -> usize {
sstatus::read().sie() as usize
}
#[inline(always)]
pub unsafe fn restore(flags: usize) {
if flags != 0 {
sstatus::set_sie(); sstatus::set_sie();
} }
println!("interrupt: init end");
} }
#[no_mangle] #[no_mangle]
@ -20,26 +39,10 @@ pub extern fn rust_trap(tf: &mut TrapFrame) {
} }
fn timer() { fn timer() {
static mut TICK: usize = 0; ::timer_interrupt();
unsafe {
TICK += 1;
if TICK % 100 == 0 {
println!("timer");
}
}
super::timer::set_next(); super::timer::set_next();
} }
#[derive(Debug, Clone)]
#[repr(C)]
pub struct TrapFrame {
x: [usize; 32],
sstatus: sstatus::Sstatus,
sepc: usize,
sbadaddr: usize,
scause: scause::Scause,
}
extern { extern {
fn __alltraps(); fn __alltraps();
} }

@ -198,6 +198,10 @@ impl InactivePageTable for InactivePageTable0 {
} }
} }
fn token(&self) -> usize {
self.p2_frame.number() | (1 << 31) // as satp
}
fn alloc_frame() -> Option<usize> { fn alloc_frame() -> Option<usize> {
alloc_frame() alloc_frame()
} }

@ -23,7 +23,7 @@ pub fn init() {
unsafe { sie::set_stimer(); } unsafe { sie::set_stimer(); }
set_next(); set_next();
println!("timer: init end"); info!("timer: init end");
} }
pub fn set_next() { pub fn set_next() {

@ -146,9 +146,7 @@ fn com2() {
} }
fn timer() { fn timer() {
use process::PROCESSOR; ::timer_interrupt();
let mut processor = PROCESSOR.try().unwrap().lock();
processor.tick();
} }
fn to_user(tf: &mut TrapFrame) { fn to_user(tf: &mut TrapFrame) {

@ -21,6 +21,10 @@ mod riscv {
pub const KERNEL_HEAP_SIZE: usize = 1 * 1024 * 1024; pub const KERNEL_HEAP_SIZE: usize = 1 * 1024 * 1024;
pub const MEMORY_OFFSET: usize = 0x8000_0000; pub const MEMORY_OFFSET: usize = 0x8000_0000;
pub const MEMORY_END: usize = 0x8080_0000; pub const MEMORY_END: usize = 0x8080_0000;
pub const USER_STACK_OFFSET: usize = 0x70000000;
pub const USER_STACK_SIZE: usize = 1024 * 1024;
// 1 MB
pub const USER32_STACK_OFFSET: usize = USER_STACK_OFFSET;
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
@ -80,6 +84,7 @@ mod x86_64 {
/// Offset to user stack /// Offset to user stack
pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE; pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE;
pub const USER32_STACK_OFFSET: usize = 0xB000_0000;
pub const USER_STACK_PML4: usize = (USER_STACK_OFFSET & PML4_MASK) / PML4_SIZE; pub const USER_STACK_PML4: usize = (USER_STACK_OFFSET & PML4_MASK) / PML4_SIZE;
/// Size of user stack /// Size of user stack
pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB

@ -71,15 +71,12 @@ mod memory;
mod lang; mod lang;
mod util; mod util;
mod consts; mod consts;
#[cfg(target_arch = "x86_64")]
mod process; mod process;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
mod syscall; mod syscall;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
mod fs; mod fs;
#[cfg(target_arch = "x86_64")]
mod thread; mod thread;
#[cfg(target_arch = "x86_64")]
mod sync; mod sync;
#[allow(dead_code)] #[allow(dead_code)]
@ -91,11 +88,19 @@ mod arch;
#[path = "arch/riscv32/mod.rs"] #[path = "arch/riscv32/mod.rs"]
mod arch; mod arch;
fn timer_interrupt() {
use process::PROCESSOR;
let mut processor = PROCESSOR.try().unwrap().lock();
processor.tick();
}
#[no_mangle] #[no_mangle]
#[cfg(target_arch = "riscv")] #[cfg(target_arch = "riscv")]
pub extern fn rust_main() -> ! { pub extern fn rust_main() -> ! {
arch::init(); arch::init();
println!("RISCV init end"); process::init();
info!("RISCV init end");
unsafe { arch::interrupt::enable(); }
loop {} loop {}
} }

@ -67,9 +67,9 @@ impl Process {
}; };
// User stack // User stack
use consts::{USER_STACK_OFFSET, USER_STACK_SIZE, USER_TCB_OFFSET}; use consts::{USER_STACK_OFFSET, USER_STACK_SIZE, USER32_STACK_OFFSET};
let (user_stack_buttom, user_stack_top) = match is32 { let (user_stack_buttom, user_stack_top) = match is32 {
true => (USER_TCB_OFFSET, USER_TCB_OFFSET + USER_STACK_SIZE), true => (USER32_STACK_OFFSET, USER32_STACK_OFFSET + USER_STACK_SIZE),
false => (USER_STACK_OFFSET, USER_STACK_OFFSET + USER_STACK_SIZE), false => (USER_STACK_OFFSET, USER_STACK_OFFSET + USER_STACK_SIZE),
}; };

@ -212,7 +212,12 @@ impl MutexSupport for Spin {
fn new() -> Self { Spin } fn new() -> Self { Spin }
fn cpu_relax(&self) { fn cpu_relax(&self) {
unsafe { asm!("pause" :::: "volatile"); } unsafe {
#[cfg(target_arch = "x86_64")]
asm!("pause" :::: "volatile");
#[cfg(target_arch = "riscv")]
asm!("nop" :::: "volatile");
}
} }
fn before_lock() -> Self::GuardData {} fn before_lock() -> Self::GuardData {}
fn after_unlock(&self) {} fn after_unlock(&self) {}
@ -237,7 +242,12 @@ impl MutexSupport for SpinNoIrq {
SpinNoIrq SpinNoIrq
} }
fn cpu_relax(&self) { fn cpu_relax(&self) {
unsafe { asm!("pause" :::: "volatile"); } unsafe {
#[cfg(target_arch = "x86_64")]
asm!("pause" :::: "volatile");
#[cfg(target_arch = "riscv")]
asm!("nop" :::: "volatile");
}
} }
fn before_lock() -> Self::GuardData { fn before_lock() -> Self::GuardData {
FlagsGuard(unsafe { interrupt::disable_and_store() }) FlagsGuard(unsafe { interrupt::disable_and_store() })

Loading…
Cancel
Save