1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 16:16:16 +04:00

Use trapframe-rs

This commit is contained in:
Jiajie Chen 2020-06-15 19:48:17 +08:00
parent a73fdde6ac
commit 4cfead4c73
11 changed files with 86 additions and 338 deletions

View File

@ -74,12 +74,12 @@ use bitflags::*;
use log::*;
use x86_64::registers::control::Cr2;
global_asm!(include_str!("trap.asm"));
global_asm!(include_str!("vector.asm"));
//global_asm!(include_str!("trap.asm"));
//global_asm!(include_str!("vector.asm"));
#[allow(non_upper_case_globals)]
#[no_mangle]
pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
trace!(
"Interrupt: {:#x} @ CPU{}",
tf.trap_num,
@ -234,12 +234,14 @@ fn invalid_opcode(tf: &mut TrapFrame) {
tf.rip += 2; // must before syscall
syscall(tf);
} else {
crate::trap::error(tf);
todo!()
//crate::trap::error(tf);
}
}
fn error(tf: &TrapFrame) {
crate::trap::error(tf);
todo!()
//crate::trap::error(tf);
}
#[no_mangle]

View File

@ -1,10 +1,9 @@
pub mod consts;
pub mod fast_syscall;
mod handler;
mod trapframe;
pub use self::handler::*;
pub use self::trapframe::*;
pub use trapframe::TrapFrame;
use crate::memory::phys_to_virt;
use apic::*;

View File

@ -1,278 +0,0 @@
use crate::arch::signal::MachineContext;
use core::default::Default;
use core::fmt;
#[derive(Clone)]
#[repr(C)]
pub struct FpState([u8; 16 + 512]);
impl fmt::Debug for FpState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "fpstate")
}
}
impl Default for FpState {
fn default() -> Self {
FpState([0u8; 16 + 512])
}
}
#[derive(Debug, Clone, Default)]
#[repr(C)]
pub struct TrapFrame {
// fpstate needs to be 16-byte aligned
// so we reserve some space here and save the offset
// the read fpstate begin from fpstate[offset]
pub fpstate_offset: usize,
pub fpstate: FpState,
// Pushed by __alltraps at 'trap.asm'
pub fsbase: usize,
pub mxcsr: usize,
pub r15: usize,
pub r14: usize,
pub r13: usize,
pub r12: usize,
pub rbp: usize,
pub rbx: usize,
pub r11: usize,
pub r10: usize,
pub r9: usize,
pub r8: usize,
pub rsi: usize,
pub rdi: usize,
pub rdx: usize,
pub rcx: usize,
pub rax: usize,
// Pushed by vector{i} at 'vector.asm'
pub trap_num: usize,
pub error_code: usize,
// Pushed by CPU
pub rip: usize,
pub cs: usize,
pub rflags: usize,
// Pushed by CPU when Ring3->0
pub rsp: usize,
pub ss: usize,
}
/// 用于在内核栈中构造新线程的中断帧
impl TrapFrame {
fn new_kernel_thread(entry: extern "C" fn(usize) -> !, arg: usize, rsp: usize) -> Self {
use crate::arch::gdt;
let mut tf = TrapFrame::default();
tf.rdi = arg;
tf.cs = gdt::KCODE_SELECTOR.0 as usize;
tf.rip = entry as usize;
tf.ss = gdt::KDATA_SELECTOR.0 as usize;
tf.rsp = rsp;
tf.rflags = 0x282;
tf.fpstate_offset = 16; // skip restoring for first time
tf.mxcsr = 0x1f80;
tf
}
pub fn new_user_thread(entry_addr: usize, rsp: usize) -> Self {
use crate::arch::gdt;
let mut tf = TrapFrame::default();
tf.cs = gdt::UCODE_SELECTOR.0 as usize;
tf.rip = entry_addr;
tf.ss = gdt::UDATA32_SELECTOR.0 as usize;
tf.rsp = rsp;
tf.rflags = 0x282;
tf.fpstate_offset = 16; // skip restoring for first time
tf.mxcsr = 0x1f80;
tf
}
pub fn get_sp(&self) -> usize {
self.rsp
}
pub fn from_mcontext(mc: &MachineContext) -> Self {
// FIXME: missing fields
TrapFrame {
fpstate_offset: 16,
fpstate: Default::default(),
fsbase: mc.fs as usize,
mxcsr: 0x1f80,
r15: mc.r15,
r14: mc.r14,
r13: mc.r13,
r12: mc.r12,
rbp: mc.rbp,
rbx: mc.rbx,
r11: mc.r11,
r10: mc.r10,
r9: mc.r9,
r8: mc.r8,
rsi: mc.rsi,
rdi: mc.rdi,
rdx: mc.rdx,
rcx: mc.rcx,
rax: mc.rax,
trap_num: 0,
error_code: 0,
rip: mc.rip,
cs: mc.cs as usize,
rflags: 0,
rsp: mc.rsp,
ss: 0,
}
}
}
#[derive(Debug, Default)]
#[repr(C)]
struct ContextData {
cr3: usize,
r15: usize,
r14: usize,
r13: usize,
r12: usize,
rbp: usize,
rbx: usize,
rip: usize,
}
impl ContextData {
fn new(cr3: usize) -> Self {
ContextData {
rip: trap_ret as usize,
cr3,
..ContextData::default()
}
}
}
/// 新线程的内核栈初始内容
#[derive(Debug)]
#[repr(C)]
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 "C" {
fn trap_ret();
}
#[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 rsp, switch to target.
/// Pop all callee-saved registers, then return to the target.
#[naked]
#[inline(never)]
pub unsafe extern "C" fn switch(&mut self, _target: &mut Self) {
llvm_asm!(
"
// push rip (by caller)
// Save old callee-save registers
push rbx
push rbp
push r12
push r13
push r14
push r15
// save page table
mov r15, cr3
push r15
// Switch stacks
mov [rdi], rsp // rdi = from_rsp
mov rsp, [rsi] // rsi = to_rsp
// restore page table
pop r15
mov cr3, r15
// restore old callee-save registers
pop r15
pop r14
pop r13
pop r12
pop rbp
pop rbx
": : : : "intel" "volatile");
}
pub unsafe fn null() -> Self {
Context(0)
}
pub unsafe fn new_kernel_thread(
entry: extern "C" 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,
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.rax = 0;
tf
},
}
.push_at(kstack_top)
}
pub unsafe fn new_clone(
tf: &TrapFrame,
ustack_top: usize,
kstack_top: usize,
cr3: usize,
tls: usize,
) -> Self {
InitStack {
context: ContextData::new(cr3),
tf: {
let mut tf = tf.clone();
tf.rsp = ustack_top;
tf.fsbase = tls;
tf.rax = 0;
tf
},
}
.push_at(kstack_top)
}
}

View File

@ -52,12 +52,17 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! {
// Init physical memory management
memory::init(boot_info);
// Init trap handler
unsafe {
trapframe::init();
}
// Init GDT
gdt::init();
//gdt::init();
// Init trap handling
// WARN: IDT must be initialized after GDT.
// Because x86_64::IDT will use current CS segment in IDT entry.
idt::init();
//idt::init();
// Init virtual space
memory::init_kernel_kseg2_map();
// get local apic id of cpu

View File

@ -15,7 +15,8 @@ use xmas_elf::{
ElfFile,
};
use crate::arch::interrupt::{Context, TrapFrame};
use crate::arch::interrupt::TrapFrame;
use trapframe::UserContext;
use crate::fs::{FileHandle, FileLike, OpenOptions, FOLLOW_MAX_DEPTH};
use crate::ipc::SemProc;
use crate::memory::{
@ -34,7 +35,7 @@ use rcore_thread::std_thread::yield_now;
#[allow(dead_code)]
pub struct Thread {
context: Context,
context: UserContext,
kstack: KernelStack,
/// Kernel performs futex wake when thread exits.
/// Ref: [http://man7.org/linux/man-pages/man2/set_tid_address.2.html]
@ -136,7 +137,8 @@ impl rcore_thread::Context for Thread {
unsafe fn switch_to(&mut self, target: &mut dyn rcore_thread::Context) {
use core::mem::transmute;
let (target, _): (&mut Thread, *const ()) = transmute(target);
self.context.switch(&mut target.context);
todo!();
//self.context.switch(&mut target.context);
}
fn set_tid(&mut self, tid: Tid) {
@ -151,7 +153,7 @@ impl Thread {
pub unsafe fn new_init() -> Box<Thread> {
let zero = MaybeUninit::<Thread>::zeroed();
Box::new(Thread {
context: Context::null(),
context: UserContext::default(),
// safety: other fields will never be used
..zero.assume_init()
})
@ -164,7 +166,8 @@ impl Thread {
let vm = Arc::new(Mutex::new(vm));
let kstack = KernelStack::new();
Box::new(Thread {
context: unsafe { Context::new_kernel_thread(entry, arg, kstack.top(), vm_token) },
//context: unsafe { Context::new_kernel_thread(entry, arg, kstack.top(), vm_token) },
context: todo!(),
kstack,
clear_child_tid: 0,
vm: vm.clone(),
@ -360,9 +363,10 @@ impl Thread {
);
Box::new(Thread {
context: unsafe {
Context::new_user_thread(entry_addr, ustack_top, kstack.top(), vm_token)
},
//context: unsafe {
//Context::new_user_thread(entry_addr, ustack_top, kstack.top(), vm_token)
//},
context: todo!(),
kstack,
clear_child_tid: 0,
vm: vm.clone(),
@ -397,7 +401,8 @@ impl Thread {
let vm = self.vm.lock().clone();
let vm_token = vm.token();
let vm = Arc::new(Mutex::new(vm));
let context = unsafe { Context::new_fork(tf, kstack.top(), vm_token) };
//let context = unsafe { Context::new_fork(tf, kstack.top(), vm_token) };
let context = todo!();
let mut proc = self.proc.lock();
@ -451,7 +456,8 @@ impl Thread {
let kstack = KernelStack::new();
let vm_token = self.vm.lock().token();
Box::new(Thread {
context: unsafe { Context::new_clone(tf, stack_top, kstack.top(), vm_token, tls) },
//context: unsafe { Context::new_clone(tf, stack_top, kstack.top(), vm_token, tls) },
context: todo!(),
kstack,
clear_child_tid,
vm: self.vm.clone(),

View File

@ -114,7 +114,7 @@ pub fn send_signal(process: Arc<Mutex<Process>>, tid: isize, info: Siginfo) {
#[repr(C)]
#[derive(Clone)]
pub struct UserContext {
pub struct SignalUserContext {
pub flags: usize,
pub link: usize,
pub stack: SignalStack,
@ -129,7 +129,7 @@ pub struct SignalFrame {
pub ret_code_addr: usize, // point to ret_code
pub tf: TrapFrame,
pub info: Siginfo,
pub ucontext: UserContext, // adapt interface, a little bit waste
pub ucontext: SignalUserContext, // adapt interface, a little bit waste
pub ret_code: [u8; 7], // call sys_sigreturn
}
@ -215,12 +215,13 @@ pub fn do_signal(tf: &mut TrapFrame) {
if action_flags.contains(SignalActionFlags::ONSTACK) {
let stack_flags = SignalStackFlags::from_bits_truncate(stack.flags);
if stack_flags.contains(SignalStackFlags::DISABLE) {
tf.get_sp()
todo!()
} else {
stack.sp + stack.size
}
} else {
tf.get_sp()
todo!()
//tf.get_sp()
}
} - core::mem::size_of::<SignalFrame>();
let frame = if let Ok(frame) = unsafe {
@ -235,7 +236,7 @@ pub fn do_signal(tf: &mut TrapFrame) {
};
frame.tf = tf.clone();
frame.info = info;
frame.ucontext = UserContext {
frame.ucontext = SignalUserContext {
flags: 0,
link: 0,
stack,
@ -266,7 +267,7 @@ pub fn do_signal(tf: &mut TrapFrame) {
tf.rdi = info.signo as usize;
tf.rsi = &frame.info as *const Siginfo as usize;
// TODO: complete context
tf.rdx = &frame.ucontext as *const UserContext as usize;
tf.rdx = &frame.ucontext as *const SignalUserContext as usize;
}
return;
}

View File

@ -15,7 +15,7 @@ impl Syscall<'_> {
match code {
ARCH_SET_FS => {
info!("sys_arch_prctl: set FSBASE to {:#x}", addr);
self.tf.fsbase = addr;
self.tf.general.fsbase = addr;
Ok(0)
}
_ => Err(SysError::EINVAL),

View File

@ -41,12 +41,13 @@ mod proc;
mod signal;
mod time;
use crate::signal::{Signal, SignalAction, SignalFrame, SignalStack, Sigset};
use crate::signal::{Signal, SignalAction, SignalFrame, SignalStack, Sigset, SignalUserContext};
#[cfg(feature = "profile")]
use alloc::collections::BTreeMap;
use rcore_thread::std_thread::yield_now;
#[cfg(feature = "profile")]
use spin::Mutex;
use trapframe::UserContext;
#[cfg(feature = "profile")]
lazy_static! {
@ -56,15 +57,17 @@ lazy_static! {
/// System call dispatcher
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
let thread = unsafe { current_thread() };
let mut syscall = Syscall { thread, tf };
let ret = syscall.syscall(id, args);
ret
todo!();
//let mut syscall = Syscall { thread, tf };
//let ret = syscall.syscall(id, args);
//ret
0
}
/// All context needed for syscall
struct Syscall<'a> {
thread: &'a mut Thread,
tf: &'a mut TrapFrame,
tf: &'a mut UserContext,
}
impl Syscall<'_> {

View File

@ -5,11 +5,13 @@ use crate::fs::FileLike;
use crate::signal::{has_signal_to_do, send_signal, Signal};
use crate::syscall::SysError::{EINTR, ESRCH};
use alloc::sync::Weak;
use alloc::boxed::Box;
impl Syscall<'_> {
/// Fork the current process. Return the child's PID.
pub fn sys_fork(&mut self) -> SysResult {
let new_thread = self.thread.fork(self.tf);
//let new_thread = self.thread.fork(self.tf);
let new_thread: Box<Thread> = todo!();
let pid = new_thread.proc.lock().pid.get();
let tid = thread_manager().add(new_thread);
thread_manager().detach(tid);
@ -56,13 +58,15 @@ impl Syscall<'_> {
let parent_tid_ref = unsafe { self.vm().check_write_ptr(parent_tid)? };
// child_tid buffer should not be set because CLONE_CHILD_SETTID flag is not specified in the current implementation
// let child_tid_ref = unsafe { self.vm().check_write_ptr(child_tid)? };
let mut new_thread = self
.thread
.clone(self.tf, newsp, newtls, child_tid as usize);
todo!();
//let mut new_thread = self
//.thread
//.clone(self.tf, newsp, newtls, child_tid as usize);
if clone_flags.contains(CloneFlags::CHILD_CLEARTID) {
new_thread.clear_child_tid = child_tid as usize;
//new_thread.clear_child_tid = child_tid as usize;
}
let tid = thread_manager().add(new_thread);
//let tid = thread_manager().add(new_thread);
let tid: usize = todo!();
thread_manager().detach(tid);
info!("clone: {} -> {}", thread::current().id(), tid);
*parent_tid_ref = tid as u32;
@ -228,7 +232,8 @@ impl Syscall<'_> {
drop(proc);
// Modify the TrapFrame
*self.tf = TrapFrame::new_user_thread(entry_addr, ustack_top);
todo!();
//*self.tf = TrapFrame::new_user_thread(entry_addr, ustack_top);
info!("exec:END: path: {:?}", path);
Ok(0)

View File

@ -49,7 +49,8 @@ impl Syscall<'_> {
pub fn sys_rt_sigreturn(&mut self) -> SysResult {
info!("rt_sigreturn");
// FIXME: adapt arch
let frame = unsafe { &*((self.tf.get_sp() - 8) as *mut SignalFrame) };
//let frame = unsafe { &*((self.tf.get_sp() - 8) as *mut SignalFrame) };
let frame: SignalFrame = todo!();
// frame.info.signo
{
let mut process = self.process();
@ -58,27 +59,30 @@ impl Syscall<'_> {
}
// *self.tf = TrapFrame::from_mcontext(&frame.ucontext.mcontext);
*self.tf = frame.tf.clone();
todo!();
//*self.tf = frame.tf.clone();
/*
let mc = &frame.ucontext.mcontext;
self.tf.r15 = mc.r15;
self.tf.r14 = mc.r14;
self.tf.r13 = mc.r13;
self.tf.r12 = mc.r12;
self.tf.rbp = mc.rbp;
self.tf.rbx = mc.rbx;
self.tf.r11 = mc.r11;
self.tf.r10 = mc.r10;
self.tf.r9 = mc.r9;
self.tf.r8 = mc.r8;
self.tf.rsi = mc.rsi;
self.tf.rdi = mc.rdi;
self.tf.rdx = mc.rdx;
self.tf.rcx = mc.rcx;
self.tf.rax = mc.rax;
self.tf.rip = mc.rip;
self.tf.rsp = mc.rsp;
self.tf.general.r15 = mc.r15;
self.tf.general.r14 = mc.r14;
self.tf.general.r13 = mc.r13;
self.tf.general.r12 = mc.r12;
self.tf.general.rbp = mc.rbp;
self.tf.general.rbx = mc.rbx;
self.tf.general.r11 = mc.r11;
self.tf.general.r10 = mc.r10;
self.tf.general.r9 = mc.r9;
self.tf.general.r8 = mc.r8;
self.tf.general.rsi = mc.rsi;
self.tf.general.rdi = mc.rdi;
self.tf.general.rdx = mc.rdx;
self.tf.general.rcx = mc.rcx;
self.tf.general.rax = mc.rax;
self.tf.general.rip = mc.rip;
self.tf.general.rsp = mc.rsp;
*/
let ret = self.tf.rax as isize;
let ret = self.tf.general.rax as isize;
if ret >= 0 {
Ok(ret as usize)
} else {

View File

@ -2,12 +2,13 @@ use crate::arch::cpu;
use crate::arch::interrupt::{syscall, TrapFrame};
use crate::consts::INFORM_PER_MSEC;
use crate::process::*;
use crate::sync::Condvar;
use crate::{signal::SignalUserContext, sync::Condvar};
use rcore_thread::std_thread as thread;
use rcore_thread::std_thread::current;
use naive_timer::Timer;
use core::time::Duration;
use spin::Mutex;
use trapframe::UserContext;
pub static mut TICK: usize = 0;
@ -29,7 +30,7 @@ pub fn timer() {
NAIVE_TIMER.lock().expire(now);
}
pub fn error(tf: &TrapFrame) -> ! {
pub fn error(tf: &UserContext) -> ! {
error!("{:#x?}", tf);
unsafe {
let mut proc = current_thread().proc.lock();