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::*;
pub use self::context::*;
#[path = "context.rs"]
mod context;
pub fn init() {
unsafe {
// Set the exception vector address
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();
}
println!("interrupt: init end");
}
#[no_mangle]
@ -20,26 +39,10 @@ pub extern fn rust_trap(tf: &mut TrapFrame) {
}
fn timer() {
static mut TICK: usize = 0;
unsafe {
TICK += 1;
if TICK % 100 == 0 {
println!("timer");
}
}
::timer_interrupt();
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 {
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> {
alloc_frame()
}

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

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

@ -21,6 +21,10 @@ mod riscv {
pub const KERNEL_HEAP_SIZE: usize = 1 * 1024 * 1024;
pub const MEMORY_OFFSET: usize = 0x8000_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")]
@ -80,6 +84,7 @@ mod x86_64 {
/// Offset to user stack
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;
/// Size of user stack
pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB

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

@ -67,9 +67,9 @@ impl Process {
};
// 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 {
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),
};

@ -212,7 +212,12 @@ impl MutexSupport for Spin {
fn new() -> Self { Spin }
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 after_unlock(&self) {}
@ -237,7 +242,12 @@ impl MutexSupport for SpinNoIrq {
SpinNoIrq
}
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 {
FlagsGuard(unsafe { interrupt::disable_and_store() })

Loading…
Cancel
Save