Skip to content

Commit

Permalink
monolithic: add syscall handler
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Jun 19, 2024
1 parent 22da826 commit afa8ddd
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 18 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions modules/axhal/src/arch/x86_64/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,36 @@ pub struct TrapFrame {
}

impl TrapFrame {
/// Gets the 0th syscall argument.
pub const fn arg0(&self) -> usize {
self.rdi as _
}

/// Gets the 1st syscall argument.
pub const fn arg1(&self) -> usize {
self.rsi as _
}

/// Gets the 2nd syscall argument.
pub const fn arg2(&self) -> usize {
self.rdx as _
}

/// Gets the 3rd syscall argument.
pub const fn arg3(&self) -> usize {
self.r10 as _
}

/// Gets the 4th syscall argument.
pub const fn arg4(&self) -> usize {
self.r8 as _
}

/// Gets the 5th syscall argument.
pub const fn arg5(&self) -> usize {
self.r9 as _
}

/// Whether the trap is from userspace.
pub const fn is_user(&self) -> bool {
self.cs & 0b11 == 3
Expand Down
5 changes: 1 addition & 4 deletions modules/axhal/src/arch/x86_64/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ core::arch::global_asm!(

#[no_mangle]
pub(super) fn x86_syscall_handler(tf: &mut TrapFrame) {
info!(
"syscall @ {:#x}: {} [{}, {}, {}, {}]",
tf.rip, tf.rax, tf.rdi, tf.rsi, tf.rdx, tf.rdx,
);
tf.rax = crate::trap::handle_syscall(tf, tf.rax as usize) as u64;
}

/// Initializes syscall support and setups the syscall handler.
Expand Down
16 changes: 16 additions & 0 deletions modules/axhal/src/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
use crate_interface::{call_interface, def_interface};

use crate::arch::TrapFrame;

/// Syscall handler interface.
#[def_interface]
pub trait SyscallHandler {
/// Handles a system call with the given number, arguments are stored in
/// [`TrapFrame`].
fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize;
}

/// Trap handler interface.
///
/// This trait is defined with the [`#[def_interface]`][1] attribute. Users
Expand All @@ -21,3 +31,9 @@ pub trait TrapHandler {
pub(crate) fn handle_irq_extern(irq_num: usize) {
call_interface!(TrapHandler::handle_irq, irq_num);
}

/// Call the external syscall handler.
#[allow(dead_code)]
pub(crate) fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
call_interface!(SyscallHandler::handle_syscall, tf, syscall_num)
}
5 changes: 5 additions & 0 deletions variants/monolithic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ edition = "2021"

[dependencies]
axstd = { path = "../../ulib/axstd", features = ["paging"] }
arceos_posix_api = { path = "../../api/arceos_posix_api" }

axhal = { path = "../../modules/axhal", features = ["uspace"] }
axlog = { path = "../../modules/axlog" }
axconfig = { path = "../../modules/axconfig" }
axtask = { path = "../../modules/axtask" }
axruntime = { path = "../../modules/axruntime", features = ["multitask"] }

axerrno = { path = "../../crates/axerrno" }
memory_addr = { path = "../../crates/memory_addr" }
crate_interface = { path = "../../crates/crate_interface" }
20 changes: 6 additions & 14 deletions variants/monolithic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ extern crate axlog;
extern crate alloc;
extern crate axstd;

mod syscall;
mod task;

use memory_addr::{PhysAddr, VirtAddr};

use axhal::arch::{TrapFrame, UspaceContext};
use axhal::arch::UspaceContext;
use axhal::mem::virt_to_phys;
use axhal::paging::MappingFlags;
use axruntime::KERNEL_PAGE_TABLE;
Expand All @@ -24,14 +25,14 @@ fn app_main(arg0: usize) {
core::arch::asm!(
"2:",
"int3",
"mov rax, r12",
"syscall",
"add rax, 1",
"add r12, 1",
"jmp 2b",
in("rax") arg0,
in("r12") arg0,
in("rdi") 2,
in("rsi") 3,
in("rdx") 3,
in("rcx") 3,
options(nostack, nomem)
)
}
Expand Down Expand Up @@ -59,15 +60,6 @@ fn spawn_user_task(page_table_root: PhysAddr, uctx: UspaceContext) -> AxTaskRef
axtask::spawn_task(task)
}

fn sys_clone(tf: &TrapFrame, newsp: usize) -> usize {
let page_table_root = axtask::current().task_ext().page_table_root;
let mut uctx = UspaceContext::from(tf);
uctx.set_sp(newsp);
uctx.set_ret_reg(0);
let new_task = spawn_user_task(page_table_root, uctx);
new_task.id().as_u64() as usize
}

fn run_apps() -> ! {
let entry = VirtAddr::from(app_main as usize);
let entry_paddr_align = virt_to_phys(entry.align_down_4k());
Expand Down Expand Up @@ -98,7 +90,7 @@ fn run_apps() -> ! {
ustack_vaddr,
ustack_paddr,
4096,
MappingFlags::READ | MappingFlags::EXECUTE | MappingFlags::USER,
MappingFlags::READ | MappingFlags::WRITE | MappingFlags::USER,
false,
)
.unwrap();
Expand Down
44 changes: 44 additions & 0 deletions variants/monolithic/src/syscall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#![allow(dead_code)]

use arceos_posix_api as api;
use axerrno::LinuxError;
use axhal::arch::{TrapFrame, UspaceContext};
use axhal::trap::SyscallHandler;
use axtask::TaskExtRef;

const SYS_READ: usize = 0;
const SYS_WRITE: usize = 1;
const SYS_SCHED_YIELD: usize = 24;
const SYS_GETPID: usize = 39;
const SYS_CLONE: usize = 56;
const SYS_FORK: usize = 57;
const SYS_EXECVE: usize = 59;
const SYS_EXIT: usize = 60;

fn sys_clone(tf: &TrapFrame, newsp: usize) -> usize {
let page_table_root = axtask::current().task_ext().page_table_root;
let mut uctx = UspaceContext::from(tf);
uctx.set_sp(newsp);
uctx.set_ret_reg(0);
let new_task = super::spawn_user_task(page_table_root, uctx);
new_task.id().as_u64() as usize
}

struct SyscallHandlerImpl;

#[crate_interface::impl_interface]
impl SyscallHandler for SyscallHandlerImpl {
fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
let ret = match syscall_num {
SYS_READ => api::sys_read(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _),
SYS_WRITE => api::sys_write(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _),
SYS_SCHED_YIELD => api::sys_sched_yield() as isize,
SYS_GETPID => api::sys_getpid() as isize,
_ => {
warn!("Unimplemented syscall: {}", syscall_num);
-LinuxError::ENOSYS.code() as _
}
};
ret
}
}

0 comments on commit afa8ddd

Please sign in to comment.