diff --git a/.gitignore b/.gitignore index a9e70705c..9981fa992 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ target/ # Ramdisk file src/ramdisk/initramfs/ src/ramdisk/build/ + +# qemu log file +qemu.log diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..e32426163 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "rust-analyzer.cargo.target" : "x86_64-unknown-none", + "rust-analyzer.check.extraArgs" : ["--target","x86_64-custom.json","-Zbuild-std=core,alloc,compiler_builtins","-Zbuild-std-features=compiler-builtins-mem"] +} \ No newline at end of file diff --git a/src/framework/jinux-frame/Cargo.toml b/src/framework/jinux-frame/Cargo.toml index 977e84ad4..2908c2d8b 100644 --- a/src/framework/jinux-frame/Cargo.toml +++ b/src/framework/jinux-frame/Cargo.toml @@ -22,6 +22,7 @@ intrusive-collections = "0.9.5" log = "0.4" limine = { version = "0.1.10", features = ["into-uuid"] } lazy_static = { version = "1.0", features = ["spin_no_std"] } +trapframe= "0.9.0" [features] default = ["serial_print"] diff --git a/src/framework/jinux-frame/src/cpu.rs b/src/framework/jinux-frame/src/cpu.rs index 4f7d4ad84..bebfbe519 100644 --- a/src/framework/jinux-frame/src/cpu.rs +++ b/src/framework/jinux-frame/src/cpu.rs @@ -4,8 +4,8 @@ use core::arch::x86_64::{_fxrstor, _fxsave}; use core::fmt::Debug; use core::mem::MaybeUninit; -use crate::trap::{CalleeRegs, CallerRegs, SyscallFrame, TrapFrame}; -use crate::x86_64_util::rdfsbase; +use trapframe::{GeneralRegs, UserContext}; + use log::debug; use pod::Pod; @@ -35,6 +35,7 @@ pub struct CpuContext { pub fp_regs: FpRegs, pub gp_regs: GpRegs, pub fs_base: u64, + pub gs_base: u64, /// trap information, this field is all zero when it is syscall pub trap_information: TrapInformation, } @@ -63,8 +64,6 @@ pub struct TrapInformation { pub cr2: u64, pub id: u64, pub err: u64, - pub cs: u64, - pub ss: u64, } /// The general-purpose registers of CPU. @@ -96,131 +95,68 @@ unsafe impl Pod for TrapInformation {} unsafe impl Pod for CpuContext {} unsafe impl Pod for FpRegs {} -impl From for CpuContext { - fn from(syscall: SyscallFrame) -> Self { +impl From for CpuContext { + fn from(value: UserContext) -> Self { Self { gp_regs: GpRegs { - r8: syscall.caller.r8, - r9: syscall.caller.r9, - r10: syscall.caller.r10, - r11: syscall.caller.r11, - r12: syscall.callee.r12, - r13: syscall.callee.r13, - r14: syscall.callee.r14, - r15: syscall.callee.r15, - rdi: syscall.caller.rdi, - rsi: syscall.caller.rsi, - rbp: syscall.callee.rbp, - rbx: syscall.callee.rbx, - rdx: syscall.caller.rdx, - rax: syscall.caller.rax, - rcx: syscall.caller.rcx, - rsp: syscall.callee.rsp, - rip: syscall.caller.rcx, - rflag: 0, + r8: value.general.r8 as u64, + r9: value.general.r9 as u64, + r10: value.general.r10 as u64, + r11: value.general.r11 as u64, + r12: value.general.r12 as u64, + r13: value.general.r13 as u64, + r14: value.general.r14 as u64, + r15: value.general.r15 as u64, + rdi: value.general.rdi as u64, + rsi: value.general.rsi as u64, + rbp: value.general.rbp as u64, + rbx: value.general.rbx as u64, + rdx: value.general.rdx as u64, + rax: value.general.rax as u64, + rcx: value.general.rcx as u64, + rsp: value.general.rsp as u64, + rip: value.general.rip as u64, + rflag: value.general.rflags as u64, }, - fs_base: 0, - fp_regs: FpRegs::default(), - trap_information: TrapInformation::default(), - } - } -} - -impl Into for CpuContext { - fn into(self) -> SyscallFrame { - SyscallFrame { - caller: CallerRegs { - rax: self.gp_regs.rax, - rcx: self.gp_regs.rcx, - rdx: self.gp_regs.rdx, - rsi: self.gp_regs.rsi, - rdi: self.gp_regs.rdi, - r8: self.gp_regs.r8, - r9: self.gp_regs.r9, - r10: self.gp_regs.r10, - r11: self.gp_regs.r11, - }, - callee: CalleeRegs { - rsp: self.gp_regs.rsp, - rbx: self.gp_regs.rbx, - rbp: self.gp_regs.rbp, - r12: self.gp_regs.r12, - r13: self.gp_regs.r13, - r14: self.gp_regs.r14, - r15: self.gp_regs.r15, - }, - } - } -} - -impl From for CpuContext { - fn from(trap: TrapFrame) -> Self { - Self { - gp_regs: GpRegs { - r8: trap.caller.r8, - r9: trap.caller.r9, - r10: trap.caller.r10, - r11: trap.caller.r11, - r12: trap.callee.r12, - r13: trap.callee.r13, - r14: trap.callee.r14, - r15: trap.callee.r15, - rdi: trap.caller.rdi, - rsi: trap.caller.rsi, - rbp: trap.callee.rbp, - rbx: trap.callee.rbx, - rdx: trap.caller.rdx, - rax: trap.caller.rax, - rcx: trap.caller.rcx, - rsp: trap.rsp, - rip: trap.rip, - rflag: trap.rflags, - }, - fs_base: rdfsbase(), + fs_base: value.general.fsbase as u64, fp_regs: FpRegs::default(), trap_information: TrapInformation { - cr2: trap.cr2, - id: trap.id, - err: trap.err, - cs: trap.cs, - ss: trap.ss, + cr2: x86_64::registers::control::Cr2::read_raw(), + id: value.trap_num as u64, + err: value.error_code as u64, }, + gs_base: value.general.gsbase as u64, } } } -impl Into for CpuContext { - fn into(self) -> TrapFrame { - let trap_information = self.trap_information; - TrapFrame { - caller: CallerRegs { - rax: self.gp_regs.rax, - rcx: self.gp_regs.rcx, - rdx: self.gp_regs.rdx, - rsi: self.gp_regs.rsi, - rdi: self.gp_regs.rdi, - r8: self.gp_regs.r8, - r9: self.gp_regs.r9, - r10: self.gp_regs.r10, - r11: self.gp_regs.r11, +impl Into for CpuContext { + fn into(self) -> UserContext { + UserContext { + trap_num: self.trap_information.id as usize, + error_code: self.trap_information.err as usize, + general: GeneralRegs { + rax: self.gp_regs.rax as usize, + rbx: self.gp_regs.rbx as usize, + rcx: self.gp_regs.rcx as usize, + rdx: self.gp_regs.rdx as usize, + rsi: self.gp_regs.rsi as usize, + rdi: self.gp_regs.rdi as usize, + rbp: self.gp_regs.rbp as usize, + rsp: self.gp_regs.rsp as usize, + r8: self.gp_regs.r8 as usize, + r9: self.gp_regs.r9 as usize, + r10: self.gp_regs.r10 as usize, + r11: self.gp_regs.r11 as usize, + r12: self.gp_regs.r12 as usize, + r13: self.gp_regs.r13 as usize, + r14: self.gp_regs.r14 as usize, + r15: self.gp_regs.r15 as usize, + rip: self.gp_regs.rip as usize, + rflags: self.gp_regs.rflag as usize, + fsbase: self.fs_base as usize, + gsbase: self.gs_base as usize, }, - callee: CalleeRegs { - rsp: self.gp_regs.rsp, - rbx: self.gp_regs.rbx, - rbp: self.gp_regs.rbp, - r12: self.gp_regs.r12, - r13: self.gp_regs.r13, - r14: self.gp_regs.r14, - r15: self.gp_regs.r15, - }, - id: trap_information.id, - err: trap_information.err, - cr2: trap_information.cr2, - rip: self.gp_regs.rip, - cs: trap_information.cs, - rflags: self.gp_regs.rflag, - rsp: self.gp_regs.rsp, - ss: trap_information.ss, } } } diff --git a/src/framework/jinux-frame/src/lib.rs b/src/framework/jinux-frame/src/lib.rs index 214362c4a..5403ebc1e 100644 --- a/src/framework/jinux-frame/src/lib.rs +++ b/src/framework/jinux-frame/src/lib.rs @@ -41,8 +41,9 @@ pub use device::serial::receive_char; pub use limine::LimineModuleRequest; pub use mm::address::{align_down, align_up, is_aligned, virt_to_phys}; pub use mm::page_table::translate_not_offset_virtual_address; -pub use trap::{allocate_irq, IrqAllocateHandle, TrapFrame}; +pub use trap::{allocate_irq, IrqAllocateHandle}; use trap::{IrqCallbackHandle, IrqLine}; +pub use trapframe::TrapFrame; pub use util::AlignExt; pub use x86_64::registers::rflags::read as get_rflags; pub use x86_64::registers::rflags::RFlags; diff --git a/src/framework/jinux-frame/src/mm/frame_allocator.rs b/src/framework/jinux-frame/src/mm/frame_allocator.rs index da43a3963..74c01cf79 100644 --- a/src/framework/jinux-frame/src/mm/frame_allocator.rs +++ b/src/framework/jinux-frame/src/mm/frame_allocator.rs @@ -8,8 +8,7 @@ use crate::{config::PAGE_SIZE, vm::Paddr}; use super::address::PhysAddr; -static FRAME_ALLOCATOR: Once> = Once::new(); - +static FRAME_ALLOCATOR: Once> = Once::new(); #[derive(Debug, Clone)] // #[repr(transparent)] @@ -28,23 +27,33 @@ impl PhysFrame { } pub fn alloc() -> Option { - FRAME_ALLOCATOR.get().unwrap().lock().alloc(1).map(|pa| Self { - frame_index: pa, - need_dealloc: true, - }) + FRAME_ALLOCATOR + .get() + .unwrap() + .lock() + .alloc(1) + .map(|pa| Self { + frame_index: pa, + need_dealloc: true, + }) } pub fn alloc_continuous_range(frame_count: usize) -> Option> { - FRAME_ALLOCATOR.get().unwrap().lock().alloc(frame_count).map(|start| { - let mut vector = Vec::new(); - for i in 0..frame_count { - vector.push(Self { - frame_index: start + i, - need_dealloc: true, - }) - } - vector - }) + FRAME_ALLOCATOR + .get() + .unwrap() + .lock() + .alloc(frame_count) + .map(|start| { + let mut vector = Vec::new(); + for i in 0..frame_count { + vector.push(Self { + frame_index: start + i, + need_dealloc: true, + }) + } + vector + }) } pub fn alloc_with_paddr(paddr: Paddr) -> Option { @@ -73,7 +82,11 @@ impl PhysFrame { impl Drop for PhysFrame { fn drop(&mut self) { if self.need_dealloc { - FRAME_ALLOCATOR.get().unwrap().lock().dealloc(self.frame_index, 1); + FRAME_ALLOCATOR + .get() + .unwrap() + .lock() + .dealloc(self.frame_index, 1); } } } @@ -94,5 +107,5 @@ pub(crate) fn init(regions: &Vec<&LimineMemmapEntry>) { ); } } - FRAME_ALLOCATOR.call_once(||Mutex::new(allocator)); -} \ No newline at end of file + FRAME_ALLOCATOR.call_once(|| Mutex::new(allocator)); +} diff --git a/src/framework/jinux-frame/src/task/mod.rs b/src/framework/jinux-frame/src/task/mod.rs index faad1c484..7cf2fde57 100644 --- a/src/framework/jinux-frame/src/task/mod.rs +++ b/src/framework/jinux-frame/src/task/mod.rs @@ -5,10 +5,6 @@ mod scheduler; #[allow(clippy::module_inception)] mod task; -pub(crate) use self::processor::get_idle_task_cx_ptr; pub use self::processor::schedule; pub use self::scheduler::{set_scheduler, Scheduler}; -pub(crate) use self::task::context_switch; -pub(crate) use self::task::TaskContext; -pub(crate) use self::task::SWITCH_TO_USER_SPACE_TASK; pub use self::task::{Task, TaskAdapter, TaskStatus}; diff --git a/src/framework/jinux-frame/src/task/task.rs b/src/framework/jinux-frame/src/task/task.rs index f40f7dcfe..d087f88ae 100644 --- a/src/framework/jinux-frame/src/task/task.rs +++ b/src/framework/jinux-frame/src/task/task.rs @@ -1,14 +1,9 @@ -use core::mem::size_of; - -use lazy_static::lazy_static; use spin::{Mutex, MutexGuard}; -use crate::cell::Cell; use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE}; use crate::prelude::*; use crate::task::processor::switch_to_task; -use crate::trap::{CalleeRegs, SyscallFrame, TrapFrame}; -use crate::user::{syscall_switch_to_user_space, trap_switch_to_user_space, UserSpace}; +use crate::user::UserSpace; use crate::vm::{VmAllocOptions, VmFrameVec}; use intrusive_collections::intrusive_adapter; @@ -17,6 +12,19 @@ use intrusive_collections::LinkedListAtomicLink; use super::processor::{current_task, schedule}; core::arch::global_asm!(include_str!("switch.S")); + +#[derive(Debug, Default, Clone, Copy)] +#[repr(C)] +pub struct CalleeRegs { + pub rsp: u64, + pub rbx: u64, + pub rbp: u64, + pub r12: u64, + pub r13: u64, + pub r14: u64, + pub r15: u64, +} + #[derive(Debug, Default, Clone, Copy)] #[repr(C)] pub(crate) struct TaskContext { @@ -28,56 +36,6 @@ extern "C" { pub(crate) fn context_switch(cur: *mut TaskContext, nxt: *const TaskContext); } -fn context_switch_to_user_space() { - let task = Task::current(); - let switch_space_task = SWITCH_TO_USER_SPACE_TASK.get(); - if task.inner_exclusive_access().is_from_trap { - *switch_space_task.trap_frame() = *task.trap_frame(); - unsafe { - trap_switch_to_user_space( - &task.user_space.as_ref().unwrap().cpu_ctx, - switch_space_task.trap_frame(), - ); - } - } else { - *switch_space_task.syscall_frame() = *task.syscall_frame(); - unsafe { - syscall_switch_to_user_space( - &task.user_space.as_ref().unwrap().cpu_ctx, - switch_space_task.syscall_frame(), - ); - } - } -} - -lazy_static! { - /// This variable is mean to switch to user space and then switch back in `UserMode.execute` - /// - /// When context switch to this task, there is no need to set the current task - pub(crate) static ref SWITCH_TO_USER_SPACE_TASK : Cell = - Cell::new({ - let task = Task{ - func: Box::new(context_switch_to_user_space), - data: Box::new(None::), - user_space: None, - task_inner: Mutex::new(TaskInner { - task_status: TaskStatus::Runnable, - ctx: TaskContext::default(), - is_from_trap:false, - }), - exit_code: usize::MAX, - kstack: KernelStack::new(), - link: LinkedListAtomicLink::new(), - }; - task.task_inner.lock().task_status = TaskStatus::Runnable; - task.task_inner.lock().ctx.rip = context_switch_to_user_space as usize; - task.task_inner.lock().ctx.regs.rsp = (task.kstack.frame.end_pa().unwrap().kvaddr().0 - - size_of::() - - size_of::()) as u64; - task - }); -} - pub struct KernelStack { frame: VmFrameVec, } @@ -85,8 +43,10 @@ pub struct KernelStack { impl KernelStack { pub fn new() -> Self { Self { - frame: VmFrameVec::allocate(&VmAllocOptions::new(KERNEL_STACK_SIZE / PAGE_SIZE)) - .expect("out of memory"), + frame: VmFrameVec::allocate( + &VmAllocOptions::new(KERNEL_STACK_SIZE / PAGE_SIZE).is_contiguous(true), + ) + .expect("out of memory"), } } } @@ -109,8 +69,6 @@ intrusive_adapter!(pub TaskAdapter = Arc: Task { link: LinkedListAtomicLin pub(crate) struct TaskInner { pub task_status: TaskStatus, pub ctx: TaskContext, - /// whether the task from trap. If it is Trap, then you should use read TrapFrame instead of SyscallFrame - pub is_from_trap: bool, } impl Task { @@ -166,7 +124,6 @@ impl Task { task_inner: Mutex::new(TaskInner { task_status: TaskStatus::Runnable, ctx: TaskContext::default(), - is_from_trap: false, }), exit_code: 0, kstack: KernelStack::new(), @@ -175,9 +132,8 @@ impl Task { result.task_inner.lock().task_status = TaskStatus::Runnable; result.task_inner.lock().ctx.rip = kernel_task_entry as usize; - result.task_inner.lock().ctx.regs.rsp = (result.kstack.frame.end_pa().unwrap().kvaddr().0 - - size_of::() - - size_of::()) as u64; + result.task_inner.lock().ctx.regs.rsp = + (result.kstack.frame.end_pa().unwrap().kvaddr().0) as u64; let arc_self = Arc::new(result); switch_to_task(arc_self.clone()); @@ -208,7 +164,6 @@ impl Task { task_inner: Mutex::new(TaskInner { task_status: TaskStatus::Runnable, ctx: TaskContext::default(), - is_from_trap: false, }), exit_code: 0, kstack: KernelStack::new(), @@ -217,9 +172,8 @@ impl Task { result.task_inner.lock().task_status = TaskStatus::Runnable; result.task_inner.lock().ctx.rip = kernel_task_entry as usize; - result.task_inner.lock().ctx.regs.rsp = (result.kstack.frame.end_pa().unwrap().kvaddr().0 - - size_of::() - - size_of::()) as u64; + result.task_inner.lock().ctx.regs.rsp = + (result.kstack.frame.end_pa().unwrap().kvaddr().0) as u64; Ok(Arc::new(result)) } @@ -228,32 +182,6 @@ impl Task { switch_to_task(self.clone()); } - pub(crate) fn syscall_frame(&self) -> &mut SyscallFrame { - unsafe { - &mut *(self - .kstack - .frame - .end_pa() - .unwrap() - .kvaddr() - .get_mut::() as *mut SyscallFrame) - .sub(1) - } - } - - pub(crate) fn trap_frame(&self) -> &mut TrapFrame { - unsafe { - &mut *(self - .kstack - .frame - .end_pa() - .unwrap() - .kvaddr() - .get_mut::() as *mut TrapFrame) - .sub(1) - } - } - /// Returns the task status. pub fn status(&self) -> TaskStatus { self.task_inner.lock().task_status diff --git a/src/framework/jinux-frame/src/trap/handler.rs b/src/framework/jinux-frame/src/trap/handler.rs index 2d5d0ca9e..9342a44a9 100644 --- a/src/framework/jinux-frame/src/trap/handler.rs +++ b/src/framework/jinux-frame/src/trap/handler.rs @@ -1,63 +1,27 @@ -use crate::task::{ - context_switch, get_idle_task_cx_ptr, Task, TaskContext, SWITCH_TO_USER_SPACE_TASK, -}; - use super::{irq::IRQ_LIST, *}; +use trapframe::TrapFrame; +/// Only from kernel #[no_mangle] -pub(crate) extern "C" fn syscall_handler(f: &mut SyscallFrame) -> isize { - let r = &f.caller; - let current = Task::current(); - current.inner_exclusive_access().is_from_trap = false; - *current.syscall_frame() = *SWITCH_TO_USER_SPACE_TASK.get().syscall_frame(); - unsafe { - context_switch( - get_idle_task_cx_ptr() as *mut TaskContext, - &Task::current().inner_ctx() as *const TaskContext, - ) +extern "sysv64" fn trap_handler(f: &mut TrapFrame) { + if is_cpu_fault(f) { + panic!("cannot handle kernel cpu fault now, information:{:#x?}", f); } - -1 + call_irq_callback_functions(f); } -#[no_mangle] -pub(crate) extern "C" fn trap_handler(f: &mut TrapFrame) { - if !is_from_kernel(f.cs) { - let current = Task::current(); - current.inner_exclusive_access().is_from_trap = true; - *current.trap_frame() = *SWITCH_TO_USER_SPACE_TASK.trap_frame(); - if is_cpu_fault(current.trap_frame()) { - // if is cpu fault, we will pass control to trap handler in jinux std - unsafe { - context_switch( - get_idle_task_cx_ptr() as *mut TaskContext, - &Task::current().inner_ctx() as *const TaskContext, - ) - } - } - } else { - if is_cpu_fault(f) { - panic!("cannot handle kernel cpu fault now, information:{:#x?}", f); - } - } - let irq_line = IRQ_LIST.get(f.id as usize).unwrap(); +pub(crate) fn call_irq_callback_functions(f: &mut TrapFrame) { + let irq_line = IRQ_LIST.get(f.trap_num as usize).unwrap(); let callback_functions = irq_line.callback_list(); for callback_function in callback_functions.iter() { callback_function.call(f); } - if f.id >= 0x20 { + if f.trap_num >= 0x20 { crate::driver::xapic_ack(); crate::driver::pic_ack(); } } -fn is_from_kernel(cs: u64) -> bool { - if cs & 0x3 == 0 { - true - } else { - false - } -} - /// As Osdev Wiki defines(https://wiki.osdev.org/Exceptions): /// CPU exceptions are classified as: @@ -68,7 +32,7 @@ fn is_from_kernel(cs: u64) -> bool { /// This function will determine a trap is a CPU faults. /// We will pass control to jinux-std if the trap is **faults**. pub fn is_cpu_fault(trap_frame: &TrapFrame) -> bool { - match trap_frame.id { + match trap_frame.trap_num as u64 { DIVIDE_BY_ZERO | DEBUG | BOUND_RANGE_EXCEEDED diff --git a/src/framework/jinux-frame/src/trap/irq.rs b/src/framework/jinux-frame/src/trap/irq.rs index 7482ea70c..af0a9f810 100644 --- a/src/framework/jinux-frame/src/trap/irq.rs +++ b/src/framework/jinux-frame/src/trap/irq.rs @@ -1,10 +1,10 @@ use crate::{prelude::*, Error}; -use super::TrapFrame; use crate::util::recycle_allocator::RecycleAllocator; use core::fmt::Debug; use lazy_static::lazy_static; use spin::{Mutex, MutexGuard}; +use trapframe::TrapFrame; lazy_static! { /// The IRQ numbers which are not using diff --git a/src/framework/jinux-frame/src/trap/mod.rs b/src/framework/jinux-frame/src/trap/mod.rs index 3caf392b5..7feca32ae 100644 --- a/src/framework/jinux-frame/src/trap/mod.rs +++ b/src/framework/jinux-frame/src/trap/mod.rs @@ -1,192 +1,13 @@ mod handler; mod irq; -use crate::cell::Cell; -use lazy_static::lazy_static; -use x86_64::{ - registers::{ - model_specific::{self, EferFlags}, - rflags::RFlags, - }, - structures::{gdt::*, tss::TaskStateSegment}, -}; - +pub(crate) use self::handler::call_irq_callback_functions; pub use self::irq::{allocate_irq, IrqAllocateHandle}; pub(crate) use self::irq::{allocate_target_irq, IrqCallbackHandle, IrqLine}; -use core::{fmt::Debug, mem::size_of_val}; - -use crate::{x86_64_util::*, *}; - -core::arch::global_asm!(include_str!("trap.S")); -core::arch::global_asm!(include_str!("vector.S")); - -#[derive(Default, Clone, Copy)] -#[repr(C)] -pub struct CallerRegs { - pub rax: u64, - pub rcx: u64, - pub rdx: u64, - pub rsi: u64, - pub rdi: u64, - pub r8: u64, - pub r9: u64, - pub r10: u64, - pub r11: u64, -} - -impl Debug for CallerRegs { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("rax: 0x{:x}, rcx: 0x{:x}, rdx: 0x{:x}, rsi: 0x{:x}, rdi: 0x{:x}, r8: 0x{:x}, r9: 0x{:x}, r10: 0x{:x}, r11: 0x{:x}", - self.rax, self.rcx, self.rdx, self.rsi, self.rdi, self.r8, self.r9, self.r10, self.r11))?; - Ok(()) - } -} - -#[derive(Default, Clone, Copy)] -#[repr(C)] -pub struct CalleeRegs { - pub rsp: u64, - pub rbx: u64, - pub rbp: u64, - pub r12: u64, - pub r13: u64, - pub r14: u64, - pub r15: u64, -} - -impl Debug for CalleeRegs { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("rsp: 0x{:x}, rbx: 0x{:x}, rbp: 0x{:x}, r12: 0x{:x}, r13: 0x{:x}, r14: 0x{:x}, r15: 0x{:x}", self.rsp, self.rbx, self.rbp, self.r12, self.r13, self.r14, self.r15))?; - Ok(()) - } -} - -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct SyscallFrame { - pub caller: CallerRegs, - pub callee: CalleeRegs, -} - -#[derive(Debug, Default, Clone, Copy)] -#[repr(C)] -pub struct TrapFrame { - pub cr2: u64, - pub caller: CallerRegs, - // do not use the rsp inside the callee, use another rsp instead - pub callee: CalleeRegs, - pub id: u64, - pub err: u64, - // Pushed by CPU - pub rip: u64, - pub cs: u64, - pub rflags: u64, - pub rsp: u64, - pub ss: u64, -} - -const TSS_SIZE: usize = 104; - -extern "C" { - /// TSS - static TSS: [u8; TSS_SIZE]; - /// 所有的中断向量push一个id后跳转到trao_entry - static __vectors: [usize; 256]; - fn syscall_entry(); -} - -lazy_static! { - static ref GDT: Cell = Cell::new(GlobalDescriptorTable::new()); -} - -#[repr(C, align(16))] -struct IDT { - /** - * The structure of all entries in IDT are shown below: - * related link: https://wiki.osdev.org/IDT#Structure_on_x86-64 - * Low 64 bits of entry: - * |0-------------------------------------15|16------------------------------31| - * | Low 16 bits of target address | Segment Selector | - * |32-34|35------39|40-------43|44|45-46|47|48------------------------------63| - * | IST | Reserved | Gate Type | 0| DPL |P | Middle 16 bits of target address | - * |---------------------------------------------------------------------------| - * High 64 bits of entry: - * |64-----------------------------------------------------------------------95| - * | High 32 bits of target address | - * |96----------------------------------------------------------------------127| - * | Reserved | - * |---------------------------------------------------------------------------| - */ - entries: [[usize; 2]; 256], -} - -impl IDT { - const fn default() -> Self { - Self { - entries: [[0; 2]; 256], - } - } -} - -static mut IDT: IDT = IDT::default(); pub(crate) fn init() { - // FIXME: use GDT in x86_64 crate in - - let tss = unsafe { &*(TSS.as_ptr() as *const TaskStateSegment) }; - - let gdt = GDT.get(); - let kcs = gdt.add_entry(Descriptor::kernel_code_segment()); - let kss = gdt.add_entry(Descriptor::kernel_data_segment()); - let uss = gdt.add_entry(Descriptor::user_data_segment()); - let ucs = gdt.add_entry(Descriptor::user_code_segment()); - let tss_load = gdt.add_entry(Descriptor::tss_segment(tss)); - - gdt.load(); - - x86_64_util::set_cs(kcs.0); - x86_64_util::set_ss(kss.0); - - load_tss(tss_load.0); - unsafe { - // enable syscall extensions - model_specific::Efer::update(|efer_flags| { - efer_flags.insert(EferFlags::SYSTEM_CALL_EXTENSIONS); - }); - } - - model_specific::Star::write(ucs, uss, kcs, kss) - .expect("error when configure star msr register"); - // set the syscall entry - model_specific::LStar::write(x86_64::VirtAddr::new(syscall_entry as u64)); - model_specific::SFMask::write( - RFlags::TRAP_FLAG - | RFlags::DIRECTION_FLAG - // | RFlags::INTERRUPT_FLAG - | RFlags::IOPL_LOW - | RFlags::IOPL_HIGH - | RFlags::NESTED_TASK - | RFlags::ALIGNMENT_CHECK, - ); - - // initialize the trap entry for all irq number - for i in 0..256 { - let p = unsafe { __vectors[i] }; - // set gate type to 1110: 64 bit Interrupt Gate, Present bit to 1, DPL to Ring 0 - let p_low = (((p >> 16) & 0xFFFF) << 48) | (p & 0xFFFF); - let trap_entry_option: usize = 0b1000_1110_0000_0000; - let low = (trap_entry_option << 32) | ((kcs.0 as usize) << 16) | p_low; - let high = p >> 32; - unsafe { - IDT.entries[i] = [low, high]; - } - } - unsafe { - lidt(&DescriptorTablePointer { - limit: size_of_val(&IDT) as u16 - 1, - base: &IDT as *const _ as _, - }) + trapframe::init(); } } diff --git a/src/framework/jinux-frame/src/trap/trap.S b/src/framework/jinux-frame/src/trap/trap.S deleted file mode 100644 index adb9b7b59..000000000 --- a/src/framework/jinux-frame/src/trap/trap.S +++ /dev/null @@ -1,126 +0,0 @@ -.data -.align 4 -TSS: - .space 104 - -.text - -.macro save - push r11 - push r10 - push r9 - push r8 - push rdi - push rsi - push rdx - push rcx - push rax -.endm - -.macro restore - pop rax - pop rcx - pop rdx - pop rsi - pop rdi - pop r8 - pop r9 - pop r10 - pop r11 -.endm - -.global __trap_entry -__trap_entry: - # 保存寄存器 - push r15 - push r14 - push r13 - push r12 - push rbp - push rbx - # mov rdi, 0 - push rdi - save - # save cr2 - mov rdi, cr2 - push rdi - # 将栈指针当成参数传入trap_handler - mov rdi, rsp - call trap_handler -__trap_return: - # judge whether the trap from kernel mode - mov rax, [rsp + 160] # 160 = offsetof(TrapFrame, cs) - and rax, 0x3 - jz __from_kernel - lea rax, [rsp + 192] # prepare new TSS.sp0, 192 = sizeof(TrapFrame) - mov [TSS + rip + 4], rax -__from_kernel: - add rsp, 8 # skip cr2 - restore - add rsp,8 # skip rsp in callee - pop rbx - pop rbp - pop r12 - pop r13 - pop r14 - pop r15 - - add rsp, 16 # skip TrapFrame.err and id - iretq - - - - -.global syscall_entry -syscall_entry: - # syscall instruction do: - # - load cs, ss from STAR MSR - # - r11 <- rflags, mask rflags from RFMASK MSR - # - rcx <- rip, load rip from LSTAR MSR - - # temporarily store user rsp into TSS.sp0 and load kernel rsp from it. - xchg rsp, [TSS + rip + 4] - push r15 - push r14 - push r13 - push r12 - push rbp - push rbx - push [TSS + rip + 4] # store user rsp into SyscallFrame.rsp - save - mov rdi, rsp - call syscall_handler - mov [rsp], rax # CallerRegs.rax is at offset 0 - jmp __syscall_return - -.global syscall_return -syscall_return: # (SyscallFrame *) - mov rsp, rdi -__syscall_return: - lea rax, [rsp + 128] # prepare new TSS.sp0, 128 = sizeof(SyscallFrame) - # store the rsp in TSS - mov [TSS + rip + 4], rax - restore - mov rbx, [rsp + 8] - mov rbp, [rsp + 16] - mov r12, [rsp + 24] - mov r13, [rsp + 32] - mov r14, [rsp + 40] - mov r15, [rsp + 48] - mov rsp, [rsp + 0] - sysretq - -.global syscall_switch_to_user_space -syscall_switch_to_user_space: # (cpu_context: *CpuContext,reg: *SyscallFrame) - # mov rflag, [rdi+136] - mov rdi, rsi - jmp syscall_return - -.global trap_switch_to_user_space -trap_switch_to_user_space: # (cpu_context: *CpuContext,reg: *TrapFrame) - # mov rflag, [rdi+136] - mov rdi, rsi - mov rsp, rdi - jmp __trap_return - - diff --git a/src/framework/jinux-frame/src/trap/vector.S b/src/framework/jinux-frame/src/trap/vector.S deleted file mode 100644 index d4fba75ef..000000000 --- a/src/framework/jinux-frame/src/trap/vector.S +++ /dev/null @@ -1,1278 +0,0 @@ -.section .text -vector0: - push 0 - push 0 - jmp __trap_entry -vector1: - push 0 - push 1 - jmp __trap_entry -vector2: - push 0 - push 2 - jmp __trap_entry -vector3: - push 0 - push 3 - jmp __trap_entry -vector4: - push 0 - push 4 - jmp __trap_entry -vector5: - push 0 - push 5 - jmp __trap_entry -vector6: - push 0 - push 6 - jmp __trap_entry -vector7: - push 0 - push 7 - jmp __trap_entry -vector8: - push 8 - jmp __trap_entry -vector9: - push 0 - push 9 - jmp __trap_entry -vector10: - push 10 - jmp __trap_entry -vector11: - push 11 - jmp __trap_entry -vector12: - push 12 - jmp __trap_entry -vector13: - push 13 - jmp __trap_entry -vector14: - push 14 - jmp __trap_entry -vector15: - push 0 - push 15 - jmp __trap_entry -vector16: - push 0 - push 16 - jmp __trap_entry -vector17: - push 17 - jmp __trap_entry -vector18: - push 0 - push 18 - jmp __trap_entry -vector19: - push 0 - push 19 - jmp __trap_entry -vector20: - push 0 - push 20 - jmp __trap_entry -vector21: - push 0 - push 21 - jmp __trap_entry -vector22: - push 0 - push 22 - jmp __trap_entry -vector23: - push 0 - push 23 - jmp __trap_entry -vector24: - push 0 - push 24 - jmp __trap_entry -vector25: - push 0 - push 25 - jmp __trap_entry -vector26: - push 0 - push 26 - jmp __trap_entry -vector27: - push 0 - push 27 - jmp __trap_entry -vector28: - push 0 - push 28 - jmp __trap_entry -vector29: - push 0 - push 29 - jmp __trap_entry -vector30: - push 0 - push 30 - jmp __trap_entry -vector31: - push 0 - push 31 - jmp __trap_entry -vector32: - push 0 - push 32 - jmp __trap_entry -vector33: - push 0 - push 33 - jmp __trap_entry -vector34: - push 0 - push 34 - jmp __trap_entry -vector35: - push 0 - push 35 - jmp __trap_entry -vector36: - push 0 - push 36 - jmp __trap_entry -vector37: - push 0 - push 37 - jmp __trap_entry -vector38: - push 0 - push 38 - jmp __trap_entry -vector39: - push 0 - push 39 - jmp __trap_entry -vector40: - push 0 - push 40 - jmp __trap_entry -vector41: - push 0 - push 41 - jmp __trap_entry -vector42: - push 0 - push 42 - jmp __trap_entry -vector43: - push 0 - push 43 - jmp __trap_entry -vector44: - push 0 - push 44 - jmp __trap_entry -vector45: - push 0 - push 45 - jmp __trap_entry -vector46: - push 0 - push 46 - jmp __trap_entry -vector47: - push 0 - push 47 - jmp __trap_entry -vector48: - push 0 - push 48 - jmp __trap_entry -vector49: - push 0 - push 49 - jmp __trap_entry -vector50: - push 0 - push 50 - jmp __trap_entry -vector51: - push 0 - push 51 - jmp __trap_entry -vector52: - push 0 - push 52 - jmp __trap_entry -vector53: - push 0 - push 53 - jmp __trap_entry -vector54: - push 0 - push 54 - jmp __trap_entry -vector55: - push 0 - push 55 - jmp __trap_entry -vector56: - push 0 - push 56 - jmp __trap_entry -vector57: - push 0 - push 57 - jmp __trap_entry -vector58: - push 0 - push 58 - jmp __trap_entry -vector59: - push 0 - push 59 - jmp __trap_entry -vector60: - push 0 - push 60 - jmp __trap_entry -vector61: - push 0 - push 61 - jmp __trap_entry -vector62: - push 0 - push 62 - jmp __trap_entry -vector63: - push 0 - push 63 - jmp __trap_entry -vector64: - push 0 - push 64 - jmp __trap_entry -vector65: - push 0 - push 65 - jmp __trap_entry -vector66: - push 0 - push 66 - jmp __trap_entry -vector67: - push 0 - push 67 - jmp __trap_entry -vector68: - push 0 - push 68 - jmp __trap_entry -vector69: - push 0 - push 69 - jmp __trap_entry -vector70: - push 0 - push 70 - jmp __trap_entry -vector71: - push 0 - push 71 - jmp __trap_entry -vector72: - push 0 - push 72 - jmp __trap_entry -vector73: - push 0 - push 73 - jmp __trap_entry -vector74: - push 0 - push 74 - jmp __trap_entry -vector75: - push 0 - push 75 - jmp __trap_entry -vector76: - push 0 - push 76 - jmp __trap_entry -vector77: - push 0 - push 77 - jmp __trap_entry -vector78: - push 0 - push 78 - jmp __trap_entry -vector79: - push 0 - push 79 - jmp __trap_entry -vector80: - push 0 - push 80 - jmp __trap_entry -vector81: - push 0 - push 81 - jmp __trap_entry -vector82: - push 0 - push 82 - jmp __trap_entry -vector83: - push 0 - push 83 - jmp __trap_entry -vector84: - push 0 - push 84 - jmp __trap_entry -vector85: - push 0 - push 85 - jmp __trap_entry -vector86: - push 0 - push 86 - jmp __trap_entry -vector87: - push 0 - push 87 - jmp __trap_entry -vector88: - push 0 - push 88 - jmp __trap_entry -vector89: - push 0 - push 89 - jmp __trap_entry -vector90: - push 0 - push 90 - jmp __trap_entry -vector91: - push 0 - push 91 - jmp __trap_entry -vector92: - push 0 - push 92 - jmp __trap_entry -vector93: - push 0 - push 93 - jmp __trap_entry -vector94: - push 0 - push 94 - jmp __trap_entry -vector95: - push 0 - push 95 - jmp __trap_entry -vector96: - push 0 - push 96 - jmp __trap_entry -vector97: - push 0 - push 97 - jmp __trap_entry -vector98: - push 0 - push 98 - jmp __trap_entry -vector99: - push 0 - push 99 - jmp __trap_entry -vector100: - push 0 - push 100 - jmp __trap_entry -vector101: - push 0 - push 101 - jmp __trap_entry -vector102: - push 0 - push 102 - jmp __trap_entry -vector103: - push 0 - push 103 - jmp __trap_entry -vector104: - push 0 - push 104 - jmp __trap_entry -vector105: - push 0 - push 105 - jmp __trap_entry -vector106: - push 0 - push 106 - jmp __trap_entry -vector107: - push 0 - push 107 - jmp __trap_entry -vector108: - push 0 - push 108 - jmp __trap_entry -vector109: - push 0 - push 109 - jmp __trap_entry -vector110: - push 0 - push 110 - jmp __trap_entry -vector111: - push 0 - push 111 - jmp __trap_entry -vector112: - push 0 - push 112 - jmp __trap_entry -vector113: - push 0 - push 113 - jmp __trap_entry -vector114: - push 0 - push 114 - jmp __trap_entry -vector115: - push 0 - push 115 - jmp __trap_entry -vector116: - push 0 - push 116 - jmp __trap_entry -vector117: - push 0 - push 117 - jmp __trap_entry -vector118: - push 0 - push 118 - jmp __trap_entry -vector119: - push 0 - push 119 - jmp __trap_entry -vector120: - push 0 - push 120 - jmp __trap_entry -vector121: - push 0 - push 121 - jmp __trap_entry -vector122: - push 0 - push 122 - jmp __trap_entry -vector123: - push 0 - push 123 - jmp __trap_entry -vector124: - push 0 - push 124 - jmp __trap_entry -vector125: - push 0 - push 125 - jmp __trap_entry -vector126: - push 0 - push 126 - jmp __trap_entry -vector127: - push 0 - push 127 - jmp __trap_entry -vector128: - push 0 - push 128 - jmp __trap_entry -vector129: - push 0 - push 129 - jmp __trap_entry -vector130: - push 0 - push 130 - jmp __trap_entry -vector131: - push 0 - push 131 - jmp __trap_entry -vector132: - push 0 - push 132 - jmp __trap_entry -vector133: - push 0 - push 133 - jmp __trap_entry -vector134: - push 0 - push 134 - jmp __trap_entry -vector135: - push 0 - push 135 - jmp __trap_entry -vector136: - push 0 - push 136 - jmp __trap_entry -vector137: - push 0 - push 137 - jmp __trap_entry -vector138: - push 0 - push 138 - jmp __trap_entry -vector139: - push 0 - push 139 - jmp __trap_entry -vector140: - push 0 - push 140 - jmp __trap_entry -vector141: - push 0 - push 141 - jmp __trap_entry -vector142: - push 0 - push 142 - jmp __trap_entry -vector143: - push 0 - push 143 - jmp __trap_entry -vector144: - push 0 - push 144 - jmp __trap_entry -vector145: - push 0 - push 145 - jmp __trap_entry -vector146: - push 0 - push 146 - jmp __trap_entry -vector147: - push 0 - push 147 - jmp __trap_entry -vector148: - push 0 - push 148 - jmp __trap_entry -vector149: - push 0 - push 149 - jmp __trap_entry -vector150: - push 0 - push 150 - jmp __trap_entry -vector151: - push 0 - push 151 - jmp __trap_entry -vector152: - push 0 - push 152 - jmp __trap_entry -vector153: - push 0 - push 153 - jmp __trap_entry -vector154: - push 0 - push 154 - jmp __trap_entry -vector155: - push 0 - push 155 - jmp __trap_entry -vector156: - push 0 - push 156 - jmp __trap_entry -vector157: - push 0 - push 157 - jmp __trap_entry -vector158: - push 0 - push 158 - jmp __trap_entry -vector159: - push 0 - push 159 - jmp __trap_entry -vector160: - push 0 - push 160 - jmp __trap_entry -vector161: - push 0 - push 161 - jmp __trap_entry -vector162: - push 0 - push 162 - jmp __trap_entry -vector163: - push 0 - push 163 - jmp __trap_entry -vector164: - push 0 - push 164 - jmp __trap_entry -vector165: - push 0 - push 165 - jmp __trap_entry -vector166: - push 0 - push 166 - jmp __trap_entry -vector167: - push 0 - push 167 - jmp __trap_entry -vector168: - push 0 - push 168 - jmp __trap_entry -vector169: - push 0 - push 169 - jmp __trap_entry -vector170: - push 0 - push 170 - jmp __trap_entry -vector171: - push 0 - push 171 - jmp __trap_entry -vector172: - push 0 - push 172 - jmp __trap_entry -vector173: - push 0 - push 173 - jmp __trap_entry -vector174: - push 0 - push 174 - jmp __trap_entry -vector175: - push 0 - push 175 - jmp __trap_entry -vector176: - push 0 - push 176 - jmp __trap_entry -vector177: - push 0 - push 177 - jmp __trap_entry -vector178: - push 0 - push 178 - jmp __trap_entry -vector179: - push 0 - push 179 - jmp __trap_entry -vector180: - push 0 - push 180 - jmp __trap_entry -vector181: - push 0 - push 181 - jmp __trap_entry -vector182: - push 0 - push 182 - jmp __trap_entry -vector183: - push 0 - push 183 - jmp __trap_entry -vector184: - push 0 - push 184 - jmp __trap_entry -vector185: - push 0 - push 185 - jmp __trap_entry -vector186: - push 0 - push 186 - jmp __trap_entry -vector187: - push 0 - push 187 - jmp __trap_entry -vector188: - push 0 - push 188 - jmp __trap_entry -vector189: - push 0 - push 189 - jmp __trap_entry -vector190: - push 0 - push 190 - jmp __trap_entry -vector191: - push 0 - push 191 - jmp __trap_entry -vector192: - push 0 - push 192 - jmp __trap_entry -vector193: - push 0 - push 193 - jmp __trap_entry -vector194: - push 0 - push 194 - jmp __trap_entry -vector195: - push 0 - push 195 - jmp __trap_entry -vector196: - push 0 - push 196 - jmp __trap_entry -vector197: - push 0 - push 197 - jmp __trap_entry -vector198: - push 0 - push 198 - jmp __trap_entry -vector199: - push 0 - push 199 - jmp __trap_entry -vector200: - push 0 - push 200 - jmp __trap_entry -vector201: - push 0 - push 201 - jmp __trap_entry -vector202: - push 0 - push 202 - jmp __trap_entry -vector203: - push 0 - push 203 - jmp __trap_entry -vector204: - push 0 - push 204 - jmp __trap_entry -vector205: - push 0 - push 205 - jmp __trap_entry -vector206: - push 0 - push 206 - jmp __trap_entry -vector207: - push 0 - push 207 - jmp __trap_entry -vector208: - push 0 - push 208 - jmp __trap_entry -vector209: - push 0 - push 209 - jmp __trap_entry -vector210: - push 0 - push 210 - jmp __trap_entry -vector211: - push 0 - push 211 - jmp __trap_entry -vector212: - push 0 - push 212 - jmp __trap_entry -vector213: - push 0 - push 213 - jmp __trap_entry -vector214: - push 0 - push 214 - jmp __trap_entry -vector215: - push 0 - push 215 - jmp __trap_entry -vector216: - push 0 - push 216 - jmp __trap_entry -vector217: - push 0 - push 217 - jmp __trap_entry -vector218: - push 0 - push 218 - jmp __trap_entry -vector219: - push 0 - push 219 - jmp __trap_entry -vector220: - push 0 - push 220 - jmp __trap_entry -vector221: - push 0 - push 221 - jmp __trap_entry -vector222: - push 0 - push 222 - jmp __trap_entry -vector223: - push 0 - push 223 - jmp __trap_entry -vector224: - push 0 - push 224 - jmp __trap_entry -vector225: - push 0 - push 225 - jmp __trap_entry -vector226: - push 0 - push 226 - jmp __trap_entry -vector227: - push 0 - push 227 - jmp __trap_entry -vector228: - push 0 - push 228 - jmp __trap_entry -vector229: - push 0 - push 229 - jmp __trap_entry -vector230: - push 0 - push 230 - jmp __trap_entry -vector231: - push 0 - push 231 - jmp __trap_entry -vector232: - push 0 - push 232 - jmp __trap_entry -vector233: - push 0 - push 233 - jmp __trap_entry -vector234: - push 0 - push 234 - jmp __trap_entry -vector235: - push 0 - push 235 - jmp __trap_entry -vector236: - push 0 - push 236 - jmp __trap_entry -vector237: - push 0 - push 237 - jmp __trap_entry -vector238: - push 0 - push 238 - jmp __trap_entry -vector239: - push 0 - push 239 - jmp __trap_entry -vector240: - push 0 - push 240 - jmp __trap_entry -vector241: - push 0 - push 241 - jmp __trap_entry -vector242: - push 0 - push 242 - jmp __trap_entry -vector243: - push 0 - push 243 - jmp __trap_entry -vector244: - push 0 - push 244 - jmp __trap_entry -vector245: - push 0 - push 245 - jmp __trap_entry -vector246: - push 0 - push 246 - jmp __trap_entry -vector247: - push 0 - push 247 - jmp __trap_entry -vector248: - push 0 - push 248 - jmp __trap_entry -vector249: - push 0 - push 249 - jmp __trap_entry -vector250: - push 0 - push 250 - jmp __trap_entry -vector251: - push 0 - push 251 - jmp __trap_entry -vector252: - push 0 - push 252 - jmp __trap_entry -vector253: - push 0 - push 253 - jmp __trap_entry -vector254: - push 0 - push 254 - jmp __trap_entry -vector255: - push 0 - push 255 - jmp __trap_entry - -.section .rodata -.global __vectors -__vectors: - .quad vector0 - .quad vector1 - .quad vector2 - .quad vector3 - .quad vector4 - .quad vector5 - .quad vector6 - .quad vector7 - .quad vector8 - .quad vector9 - .quad vector10 - .quad vector11 - .quad vector12 - .quad vector13 - .quad vector14 - .quad vector15 - .quad vector16 - .quad vector17 - .quad vector18 - .quad vector19 - .quad vector20 - .quad vector21 - .quad vector22 - .quad vector23 - .quad vector24 - .quad vector25 - .quad vector26 - .quad vector27 - .quad vector28 - .quad vector29 - .quad vector30 - .quad vector31 - .quad vector32 - .quad vector33 - .quad vector34 - .quad vector35 - .quad vector36 - .quad vector37 - .quad vector38 - .quad vector39 - .quad vector40 - .quad vector41 - .quad vector42 - .quad vector43 - .quad vector44 - .quad vector45 - .quad vector46 - .quad vector47 - .quad vector48 - .quad vector49 - .quad vector50 - .quad vector51 - .quad vector52 - .quad vector53 - .quad vector54 - .quad vector55 - .quad vector56 - .quad vector57 - .quad vector58 - .quad vector59 - .quad vector60 - .quad vector61 - .quad vector62 - .quad vector63 - .quad vector64 - .quad vector65 - .quad vector66 - .quad vector67 - .quad vector68 - .quad vector69 - .quad vector70 - .quad vector71 - .quad vector72 - .quad vector73 - .quad vector74 - .quad vector75 - .quad vector76 - .quad vector77 - .quad vector78 - .quad vector79 - .quad vector80 - .quad vector81 - .quad vector82 - .quad vector83 - .quad vector84 - .quad vector85 - .quad vector86 - .quad vector87 - .quad vector88 - .quad vector89 - .quad vector90 - .quad vector91 - .quad vector92 - .quad vector93 - .quad vector94 - .quad vector95 - .quad vector96 - .quad vector97 - .quad vector98 - .quad vector99 - .quad vector100 - .quad vector101 - .quad vector102 - .quad vector103 - .quad vector104 - .quad vector105 - .quad vector106 - .quad vector107 - .quad vector108 - .quad vector109 - .quad vector110 - .quad vector111 - .quad vector112 - .quad vector113 - .quad vector114 - .quad vector115 - .quad vector116 - .quad vector117 - .quad vector118 - .quad vector119 - .quad vector120 - .quad vector121 - .quad vector122 - .quad vector123 - .quad vector124 - .quad vector125 - .quad vector126 - .quad vector127 - .quad vector128 - .quad vector129 - .quad vector130 - .quad vector131 - .quad vector132 - .quad vector133 - .quad vector134 - .quad vector135 - .quad vector136 - .quad vector137 - .quad vector138 - .quad vector139 - .quad vector140 - .quad vector141 - .quad vector142 - .quad vector143 - .quad vector144 - .quad vector145 - .quad vector146 - .quad vector147 - .quad vector148 - .quad vector149 - .quad vector150 - .quad vector151 - .quad vector152 - .quad vector153 - .quad vector154 - .quad vector155 - .quad vector156 - .quad vector157 - .quad vector158 - .quad vector159 - .quad vector160 - .quad vector161 - .quad vector162 - .quad vector163 - .quad vector164 - .quad vector165 - .quad vector166 - .quad vector167 - .quad vector168 - .quad vector169 - .quad vector170 - .quad vector171 - .quad vector172 - .quad vector173 - .quad vector174 - .quad vector175 - .quad vector176 - .quad vector177 - .quad vector178 - .quad vector179 - .quad vector180 - .quad vector181 - .quad vector182 - .quad vector183 - .quad vector184 - .quad vector185 - .quad vector186 - .quad vector187 - .quad vector188 - .quad vector189 - .quad vector190 - .quad vector191 - .quad vector192 - .quad vector193 - .quad vector194 - .quad vector195 - .quad vector196 - .quad vector197 - .quad vector198 - .quad vector199 - .quad vector200 - .quad vector201 - .quad vector202 - .quad vector203 - .quad vector204 - .quad vector205 - .quad vector206 - .quad vector207 - .quad vector208 - .quad vector209 - .quad vector210 - .quad vector211 - .quad vector212 - .quad vector213 - .quad vector214 - .quad vector215 - .quad vector216 - .quad vector217 - .quad vector218 - .quad vector219 - .quad vector220 - .quad vector221 - .quad vector222 - .quad vector223 - .quad vector224 - .quad vector225 - .quad vector226 - .quad vector227 - .quad vector228 - .quad vector229 - .quad vector230 - .quad vector231 - .quad vector232 - .quad vector233 - .quad vector234 - .quad vector235 - .quad vector236 - .quad vector237 - .quad vector238 - .quad vector239 - .quad vector240 - .quad vector241 - .quad vector242 - .quad vector243 - .quad vector244 - .quad vector245 - .quad vector246 - .quad vector247 - .quad vector248 - .quad vector249 - .quad vector250 - .quad vector251 - .quad vector252 - .quad vector253 - .quad vector254 - .quad vector255 diff --git a/src/framework/jinux-frame/src/user.rs b/src/framework/jinux-frame/src/user.rs index 408771fc4..9e179d7ba 100644 --- a/src/framework/jinux-frame/src/user.rs +++ b/src/framework/jinux-frame/src/user.rs @@ -1,24 +1,16 @@ //! User space. -use crate::x86_64_util::{rdfsbase, wrfsbase}; +use crate::trap::call_irq_callback_functions; +use crate::x86_64_util::{self, rdfsbase, wrfsbase}; use log::debug; +use trapframe::{TrapFrame, UserContext}; use x86_64::registers::rflags::RFlags; use crate::cpu::CpuContext; use crate::prelude::*; -use crate::task::{context_switch, Task, TaskContext, SWITCH_TO_USER_SPACE_TASK}; -use crate::trap::{SyscallFrame, TrapFrame}; +use crate::task::Task; use crate::vm::VmSpace; -extern "C" { - pub(crate) fn syscall_switch_to_user_space( - cpu_context: &CpuContext, - syscall_frame: &SyscallFrame, - ); - /// cpu_context may delete in the future - pub(crate) fn trap_switch_to_user_space(cpu_context: &CpuContext, trap_frame: &TrapFrame); -} - /// A user space. /// /// Each user space has a VM address space and allows a task to execute in @@ -86,6 +78,7 @@ pub struct UserMode<'a> { current: Arc, user_space: &'a Arc, context: CpuContext, + user_context: UserContext, executed: bool, } @@ -99,6 +92,7 @@ impl<'a> UserMode<'a> { user_space, context: CpuContext::default(), executed: false, + user_context: UserContext::default(), } } @@ -116,12 +110,10 @@ impl<'a> UserMode<'a> { self.user_space.vm_space().activate(); } if !self.executed { - *self.current.syscall_frame() = self.user_space.cpu_ctx.into(); + self.context = self.user_space.cpu_ctx; if self.context.gp_regs.rflag == 0 { - self.context.gp_regs.rflag = (RFlags::INTERRUPT_FLAG | RFlags::ID).bits(); + self.context.gp_regs.rflag = (RFlags::INTERRUPT_FLAG | RFlags::ID).bits() | 0x2; } - self.current.syscall_frame().caller.r11 = self.context.gp_regs.rflag; - self.current.syscall_frame().caller.rcx = self.user_space.cpu_ctx.gp_regs.rip; // write fsbase wrfsbase(self.user_space.cpu_ctx.fs_base); let fp_regs = self.user_space.cpu_ctx.fp_regs; @@ -130,15 +122,6 @@ impl<'a> UserMode<'a> { } self.executed = true; } else { - if self.current.inner_exclusive_access().is_from_trap { - *self.current.trap_frame() = self.context.into(); - } else { - *self.current.syscall_frame() = self.context.into(); - self.context.gp_regs.rflag |= RFlags::INTERRUPT_FLAG.bits(); - self.current.syscall_frame().caller.r11 = self.context.gp_regs.rflag; - self.current.syscall_frame().caller.rcx = self.context.gp_regs.rip; - } - // write fsbase if rdfsbase() != self.context.fs_base { debug!("write fsbase: 0x{:x}", self.context.fs_base); @@ -151,26 +134,44 @@ impl<'a> UserMode<'a> { // fp_regs.restore(); // } } - - let mut current_task_inner = self.current.inner_exclusive_access(); - let binding = SWITCH_TO_USER_SPACE_TASK.get(); - let next_task_inner = binding.inner_exclusive_access(); - let current_ctx = &mut current_task_inner.ctx as *mut TaskContext; - let next_ctx = &next_task_inner.ctx as *const TaskContext; - drop(current_task_inner); - drop(next_task_inner); - drop(binding); - unsafe { - context_switch(current_ctx, next_ctx); - // switch_to_user_space(&self.user_space.cpu_ctx, self.current.syscall_frame()); + self.user_context = self.context.into(); + self.user_context.run(); + let mut trap_frame; + while self.user_context.trap_num >= 0x20 && self.user_context.trap_num < 0x100 { + trap_frame = TrapFrame { + rax: self.user_context.general.rax, + rbx: self.user_context.general.rbx, + rcx: self.user_context.general.rcx, + rdx: self.user_context.general.rdx, + rsi: self.user_context.general.rsi, + rdi: self.user_context.general.rdi, + rbp: self.user_context.general.rbp, + rsp: self.user_context.general.rsp, + r8: self.user_context.general.r8, + r9: self.user_context.general.r9, + r10: self.user_context.general.r10, + r11: self.user_context.general.r11, + r12: self.user_context.general.r12, + r13: self.user_context.general.r13, + r14: self.user_context.general.r14, + r15: self.user_context.general.r15, + _pad: 0, + trap_num: self.user_context.trap_num, + error_code: self.user_context.error_code, + rip: self.user_context.general.rip, + cs: 0, + rflags: self.user_context.general.rflags, + }; + call_irq_callback_functions(&mut trap_frame); + self.user_context.run(); } - if self.current.inner_exclusive_access().is_from_trap { - self.context = CpuContext::from(*self.current.trap_frame()); + x86_64::instructions::interrupts::enable(); + self.context = CpuContext::from(self.user_context); + if self.user_context.trap_num != 0x100 { self.context.fs_base = rdfsbase(); // self.context.fp_regs.save(); UserEvent::Exception } else { - self.context = CpuContext::from(*self.current.syscall_frame()); self.context.fs_base = rdfsbase(); // self.context.fp_regs.save(); // debug!("[kernel] syscall id:{}", self.context.gp_regs.rax); diff --git a/src/framework/jinux-frame/src/vm/frame.rs b/src/framework/jinux-frame/src/vm/frame.rs index c39648081..72b0e66a8 100644 --- a/src/framework/jinux-frame/src/vm/frame.rs +++ b/src/framework/jinux-frame/src/vm/frame.rs @@ -31,6 +31,16 @@ impl VmFrameVec { pub fn allocate(options: &VmAllocOptions) -> Result { let page_size = options.page_size; let mut frame_list = Vec::new(); + if options.is_contiguous { + if options.paddr.is_some() { + panic!("not support contiguous paddr"); + } + let frames = VmFrame::alloc_continuous(options.page_size); + if frames.is_none() { + return Err(Error::NoMemory); + } + return Ok(Self(frames.unwrap())); + } for i in 0..page_size { let vm_frame = if let Some(paddr) = options.paddr { VmFrame::alloc_with_paddr(paddr + i * PAGE_SIZE) @@ -204,6 +214,7 @@ impl<'a> Iterator for VmFrameVecIter<'a> { pub struct VmAllocOptions { page_size: usize, paddr: Option, + is_contiguous: bool, } impl VmAllocOptions { @@ -212,6 +223,7 @@ impl VmAllocOptions { Self { page_size: len, paddr: None, + is_contiguous: false, } } @@ -232,7 +244,8 @@ impl VmAllocOptions { /// /// The default value is `false`. pub fn is_contiguous(&mut self, is_contiguous: bool) -> &mut Self { - todo!() + self.is_contiguous = is_contiguous; + self } /// Sets whether the pages can be accessed by devices through @@ -291,6 +304,21 @@ impl VmFrame { }) } + /// Allocate contiguous VmFrame + pub(crate) fn alloc_continuous(frame_count: usize) -> Option> { + let phys = PhysFrame::alloc_continuous_range(frame_count); + if phys.is_none() { + return None; + } + let mut res = Vec::new(); + for i in phys.unwrap() { + res.push(Self { + physical_frame: Arc::new(i), + }) + } + Some(res) + } + /// Allocate a new VmFrame filled with zero pub(crate) fn alloc_zero() -> Option { let phys = PhysFrame::alloc_zero(); diff --git a/src/services/comps/input/src/virtio.rs b/src/services/comps/input/src/virtio.rs index 316a1c543..3ede9f669 100644 --- a/src/services/comps/input/src/virtio.rs +++ b/src/services/comps/input/src/virtio.rs @@ -46,7 +46,7 @@ impl VirtioInputDevice { fn handle_input(frame: &TrapFrame) { debug!("in handle input"); let input_component = crate::INPUT_COMPONENT.get().unwrap(); - input_component.call(frame.id as u8); + input_component.call(frame.trap_num as u8); } fn config_space_change(_: &TrapFrame) { debug!("input device config space change");