feat: syscall stub

This commit is contained in:
2021-10-21 12:16:24 +03:00
parent e745237130
commit 67d49f8f0e
16 changed files with 231 additions and 38 deletions
+8 -3
View File
@@ -3,6 +3,7 @@
use crate::arch::machine;
use crate::debug::Level;
use crate::dev::irq::{IntController, IrqContext};
use crate::syscall;
use cortex_a::registers::{ESR_EL1, FAR_EL1};
use tock_registers::interfaces::Readable;
@@ -18,7 +19,7 @@ pub const EC_SVC_AA64: u64 = 0b010101;
#[derive(Debug)]
#[repr(C)]
struct ExceptionFrame {
x: [u64; 32],
x: [usize; 32],
spsr_el1: u64,
elr_el1: u64,
sp_el0: u64,
@@ -81,8 +82,12 @@ extern "C" fn __aa64_exc_sync_handler(exc: &mut ExceptionFrame) {
dump_data_abort(Level::Error, esr, far);
}
EC_SVC_AA64 => {
infoln!("{:#x} {:#x}", exc.x[0], exc.x[1]);
exc.x[0] += 1;
unsafe {
match syscall::syscall(exc.x[8], &exc.x[..6]) {
Ok(val) => exc.x[0] = val,
Err(_) => exc.x[0] = usize::MAX,
}
}
return;
}
_ => {}
+2
View File
@@ -31,6 +31,8 @@ pub mod mem;
pub mod proc;
pub mod sync;
pub mod util;
#[allow(missing_docs)]
pub mod syscall;
#[panic_handler]
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
+8 -6
View File
@@ -57,13 +57,15 @@ pub unsafe fn enter(initrd: Option<(usize, usize)>) -> ! {
if let Some((start, end)) = initrd {
let initrd = Box::into_raw(Box::new((mem::virtualize(start), mem::virtualize(end))));
spawn!(fn (initrd_ptr: usize) {
debugln!("Running kernel init process");
for _ in 0..4 {
spawn!(fn (initrd_ptr: usize) {
debugln!("Running kernel init process");
let (start, _end) = unsafe { *(initrd_ptr as *const (usize, usize)) };
Process::execve(|space| elf::load_elf(space, start as *const u8), 0).unwrap();
panic!("This code should not run");
}, initrd as usize);
let (start, _end) = unsafe { *(initrd_ptr as *const (usize, usize)) };
Process::execve(|space| elf::load_elf(space, start as *const u8), 0).unwrap();
panic!("This code should not run");
}, initrd as usize);
}
}
SCHED.enter();
}
+7 -4
View File
@@ -125,6 +125,11 @@ impl Process {
const USTACK_VIRT_TOP: usize = 0x100000000;
const USTACK_PAGES: usize = 4;
/// Returns currently executing process
pub fn current() -> ProcessRef {
SCHED.current_process()
}
/// Schedules an initial thread for execution
///
/// # Safety
@@ -190,6 +195,7 @@ impl Process {
state: State::Ready,
}),
});
debugln!("New kernel process: {}", id);
assert!(PROCESSES.lock().insert(id, res.clone()).is_none());
Ok(res)
}
@@ -263,10 +269,7 @@ impl Process {
old_pid,
lock.id
);
assert!(
proc_lock.insert(lock.id, proc.clone()).is_none(),
"Failed to downgrade kernel process (add user pid)"
);
assert!(proc_lock.insert(lock.id, proc.clone()).is_none());
unsafe {
SCHED.hack_current_pid(lock.id);
}
+3 -3
View File
@@ -66,7 +66,7 @@ impl Scheduler {
PROCESSES.lock().get(&id).unwrap().clone()
};
asm!("msr daifclr, #2");
asm!("msr daifset, #2");
Process::enter(thread)
}
@@ -103,7 +103,7 @@ impl Scheduler {
let lock = PROCESSES.lock();
(
lock.get(&current).unwrap().clone(),
lock.get(&next).unwrap().clone(),
lock.get(&next).unwrap().clone()
)
};
@@ -112,7 +112,7 @@ impl Scheduler {
if !Rc::ptr_eq(&from, &to) {
unsafe {
asm!("msr daifclr, #2");
asm!("msr daifset, #2");
Process::switch(from, to, discard);
}
}
+60
View File
@@ -0,0 +1,60 @@
use crate::mem;
use error::Errno;
fn translate(virt: usize) -> Option<usize> {
let mut res: usize;
unsafe {
asm!("at s1e1r, {}; mrs {}, par_el1", in(reg) virt, out(reg) res);
}
if res & 1 == 0 {
Some(res & !(0xFFF | (0xFF << 56)))
} else {
None
}
}
fn validate_user_ptr(base: usize, len: usize) -> Result<(), Errno> {
if base > mem::KERNEL_OFFSET || base + len > mem::KERNEL_OFFSET {
warnln!("User region refers to kernel memory: base={:#x}, len={:#x}", base, len);
return Err(Errno::InvalidArgument);
}
for i in (base / mem::PAGE_SIZE)..((base + len + mem::PAGE_SIZE - 1) / mem::PAGE_SIZE) {
if translate(i * mem::PAGE_SIZE).is_none() {
warnln!(
"User region refers to unmapped memory: base={:#x}, len={:#x} (page {:#x})",
base,
len,
i * mem::PAGE_SIZE
);
return Err(Errno::InvalidArgument);
}
}
Ok(())
}
pub unsafe fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
match num {
// sys_exit
1 => {
use crate::proc::Process;
Process::current().exit(args[0] as i32);
unreachable!();
}
// sys_ex_debug_trace
120 => {
use crate::debug::Level;
validate_user_ptr(args[0], args[1])?;
let buf = core::slice::from_raw_parts(args[0] as *const u8, args[1]);
print!(Level::Debug, "[trace] ");
for &byte in buf.iter() {
print!(Level::Debug, "{}", byte as char);
}
println!(Level::Debug, "");
Ok(args[1])
}
_ => panic!("Undefined system call: {}", num),
}
}