Compile on aarch64.
This commit is contained in:
@@ -6,7 +6,6 @@ use crate::{
|
||||
memory::{ArchIntCtx, GenericPfFlags},
|
||||
syscall,
|
||||
syscall::flag::*,
|
||||
with_exception_stack,
|
||||
};
|
||||
|
||||
use super::InterruptStack;
|
||||
@@ -173,12 +172,12 @@ unsafe fn pf_inner(stack: &mut InterruptStack, ty: u8, from: &str) -> bool {
|
||||
|
||||
exception_stack!(synchronous_exception_at_el0, |stack| {
|
||||
match exception_code(stack.iret.esr_el1) {
|
||||
0b010101 => with_exception_stack!(|stack| {
|
||||
0b010101 => {
|
||||
let scratch = &stack.scratch;
|
||||
syscall::syscall(
|
||||
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, stack,
|
||||
)
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
ty => {
|
||||
if !pf_inner(stack, ty as u8, "sync_exc_el0") {
|
||||
|
||||
@@ -113,6 +113,22 @@ pub struct InterruptStack {
|
||||
}
|
||||
|
||||
impl InterruptStack {
|
||||
pub fn setup_minimal(&mut self, ip: usize, _singlestep: bool) {
|
||||
self.set_instr_pointer(ip);
|
||||
}
|
||||
pub fn set_stack_pointer(&mut self, sp: usize) {
|
||||
self.iret.sp_el0 = sp;
|
||||
}
|
||||
pub fn stack_pointer(&self) -> usize {
|
||||
self.iret.sp_el0
|
||||
}
|
||||
pub fn set_instr_pointer(&mut self, ip: usize) {
|
||||
self.iret.elr_el1 = ip;
|
||||
}
|
||||
// TODO: This can maybe be done in userspace?
|
||||
pub fn set_syscall_ret_reg(&mut self, ret: usize) {
|
||||
self.scratch.x0 = ret;
|
||||
}
|
||||
pub fn dump(&self) {
|
||||
self.iret.dump();
|
||||
self.scratch.dump();
|
||||
@@ -258,24 +274,6 @@ macro_rules! aarch64_asm {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! function {
|
||||
($name:ident => { $($body:expr,)+ }) => {
|
||||
aarch64_asm!(
|
||||
".global ", stringify!($name), "\n",
|
||||
".type ", stringify!($name), ", @function\n",
|
||||
".section .text.", stringify!($name), ", \"ax\", @progbits\n",
|
||||
stringify!($name), ":\n",
|
||||
$($body),+,
|
||||
".size ", stringify!($name), ", . - ", stringify!($name), "\n",
|
||||
".text\n",
|
||||
);
|
||||
extern "C" {
|
||||
pub fn $name();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! push_scratch {
|
||||
() => {
|
||||
@@ -377,21 +375,12 @@ macro_rules! pop_special {
|
||||
#[macro_export]
|
||||
macro_rules! exception_stack {
|
||||
($name:ident, |$stack:ident| $code:block) => {
|
||||
paste::item! {
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn [<__exception_ $name>](stack: *mut $crate::arch::aarch64::interrupt::InterruptStack) {
|
||||
// This inner function is needed because macros are buggy:
|
||||
// https://github.com/dtolnay/paste/issues/7
|
||||
#[inline(always)]
|
||||
unsafe fn inner($stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) {
|
||||
let _guard = $crate::ptrace::set_process_regs($stack);
|
||||
|
||||
$code
|
||||
}
|
||||
inner(&mut *stack);
|
||||
#[naked]
|
||||
unsafe extern "C" fn $name(stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) {
|
||||
unsafe extern "C" fn inner($stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) {
|
||||
$code
|
||||
}
|
||||
|
||||
function!($name => {
|
||||
core::arch::asm!(concat!(
|
||||
// Backup all userspace registers to stack
|
||||
push_preserved!(),
|
||||
push_scratch!(),
|
||||
@@ -400,7 +389,7 @@ macro_rules! exception_stack {
|
||||
// Call inner function with pointer to stack
|
||||
"mov x29, sp\n",
|
||||
"mov x0, sp\n",
|
||||
"bl __exception_", stringify!($name), "\n",
|
||||
"bl {}",
|
||||
|
||||
// Restore all userspace registers
|
||||
pop_special!(),
|
||||
@@ -408,7 +397,18 @@ macro_rules! exception_stack {
|
||||
pop_preserved!(),
|
||||
|
||||
"eret\n",
|
||||
});
|
||||
), sym inner, options(noreturn));
|
||||
}
|
||||
};
|
||||
}
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn enter_usermode() -> ! {
|
||||
core::arch::asm!(concat!(
|
||||
// Restore all userspace registers
|
||||
pop_special!(),
|
||||
pop_scratch!(),
|
||||
pop_preserved!(),
|
||||
|
||||
"eret\n",
|
||||
), options(noreturn));
|
||||
}
|
||||
|
||||
@@ -52,11 +52,4 @@ pub struct SyscallStack {
|
||||
pub x1: usize,
|
||||
pub x0: usize,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! with_exception_stack {
|
||||
(|$stack:ident| $code:block) => {{
|
||||
let $stack = &mut *$stack;
|
||||
(*$stack).scratch.x0 = $code;
|
||||
}};
|
||||
}
|
||||
pub use super::handler::enter_usermode;
|
||||
|
||||
@@ -23,6 +23,8 @@ pub static CONTEXT_SWITCH_LOCK: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
// 512 bytes for registers, extra bytes for fpcr and fpsr
|
||||
pub const KFX_ALIGN: usize = 16;
|
||||
pub const KSTACK_SIZE: usize = 65536;
|
||||
pub const KSTACK_ALIGN: usize = 16;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Context {
|
||||
|
||||
Reference in New Issue
Block a user