parent
3386a793a5
commit
8c19499112
@ -1,62 +0,0 @@
|
||||
//! Trapframe and context definitions for aarch64.
|
||||
|
||||
/// TODO
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct TrapFrame {
|
||||
// TODO
|
||||
}
|
||||
|
||||
///TODO
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
// TODO
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// TODO
|
||||
#[inline(never)]
|
||||
pub unsafe extern fn switch(&mut self, target: &mut Self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn null() -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, cr3: usize) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, is32: bool, cr3: usize) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn enable() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn disable() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn disable_and_store() -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn restore(flags: usize) {
|
||||
unimplemented!()
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
//! TrapFrame and context definitions for aarch64.
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default, Debug, Copy, Clone)]
|
||||
pub struct TrapFrame {
|
||||
pub elr: u64,
|
||||
pub spsr: u64,
|
||||
pub sp: u64,
|
||||
pub tpidr: u64,
|
||||
// pub q0to31: [u128; 32], // disable SIMD/FP registers
|
||||
pub x1to29: [u64; 29],
|
||||
pub __reserved: u64,
|
||||
pub x30: u64, // lr
|
||||
pub x0: u64,
|
||||
}
|
||||
|
||||
///TODO
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
// TODO
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// TODO
|
||||
#[inline(never)]
|
||||
pub unsafe extern "C" fn switch(&mut self, target: &mut Self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn null() -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn new_kernel_thread(
|
||||
entry: extern "C" fn(usize) -> !,
|
||||
arg: usize,
|
||||
kstack_top: usize,
|
||||
cr3: usize,
|
||||
) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn new_user_thread(
|
||||
entry_addr: usize,
|
||||
ustack_top: usize,
|
||||
kstack_top: usize,
|
||||
is32: bool,
|
||||
cr3: usize,
|
||||
) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
//! Trap handler
|
||||
|
||||
use super::context::TrapFrame;
|
||||
use super::syndrome::Syndrome;
|
||||
|
||||
global_asm!(include_str!("trap.S"));
|
||||
global_asm!(include_str!("vector.S"));
|
||||
|
||||
#[repr(u16)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Kind {
|
||||
Synchronous = 0,
|
||||
Irq = 1,
|
||||
Fiq = 2,
|
||||
SError = 3,
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Source {
|
||||
CurrentSpEl0 = 0,
|
||||
CurrentSpElx = 1,
|
||||
LowerAArch64 = 2,
|
||||
LowerAArch32 = 3,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub struct Info {
|
||||
source: Source,
|
||||
kind: Kind,
|
||||
}
|
||||
|
||||
/// This function is called when an exception occurs. The `info` parameter
|
||||
/// specifies the source and kind of exception that has occurred. The `esr` is
|
||||
/// the value of the exception syndrome register. Finally, `tf` is a pointer to
|
||||
/// the trap frame for the exception.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_trap(info: Info, esr: u32, tf: &mut TrapFrame) {
|
||||
let syndrome = Syndrome::from(esr);
|
||||
trace!("Interrupt: {:?} from: {:?}", syndrome, info);
|
||||
match info.kind {
|
||||
Kind::Synchronous => {
|
||||
// syndrome is only valid with sync
|
||||
match syndrome {
|
||||
Syndrome::Brk(brk) => handle_break(brk, tf),
|
||||
Syndrome::Svc(syscall) => handle_syscall(syscall, tf),
|
||||
_ => ::trap::error(tf),
|
||||
}
|
||||
}
|
||||
Kind::Irq => {
|
||||
// TODO
|
||||
}
|
||||
_ => ::trap::error(tf),
|
||||
}
|
||||
::trap::before_return();
|
||||
trace!("Interrupt end");
|
||||
}
|
||||
|
||||
fn handle_break(num: u16, tf: &mut TrapFrame) {
|
||||
tf.elr += 4; // Skip the current brk instruction
|
||||
}
|
||||
|
||||
fn handle_syscall(num: u16, tf: &mut TrapFrame) {
|
||||
// svc instruction has been skipped in syscall
|
||||
println!("syscall {}", num);
|
||||
}
|
@ -1,14 +1,20 @@
|
||||
//! Interrupt handler implementation on raspi3.
|
||||
//! Interrupt and exception for aarch64.
|
||||
|
||||
pub use self::context::*;
|
||||
|
||||
#[path = "context.rs"]
|
||||
mod handler;
|
||||
mod context;
|
||||
mod syndrome;
|
||||
|
||||
/// Initialize the trap to enable the interrupt.
|
||||
pub use self::context::*;
|
||||
pub use self::handler::*;
|
||||
|
||||
/// Set the exception vector address
|
||||
pub fn init() {
|
||||
// TODO
|
||||
// info!("interrupt: init end");
|
||||
unsafe {
|
||||
asm!(
|
||||
"adr x0, __vectors;
|
||||
msr vbar_el1, x0"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable the interrupt.
|
@ -0,0 +1,108 @@
|
||||
//! Exception syndrome from ESR
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum Fault {
|
||||
AddressSize,
|
||||
Translation,
|
||||
AccessFlag,
|
||||
Permission,
|
||||
Alignment,
|
||||
TlbConflict,
|
||||
Other(u8),
|
||||
}
|
||||
|
||||
impl From<u32> for Fault {
|
||||
fn from(val: u32) -> Fault {
|
||||
use self::Fault::*;
|
||||
|
||||
// IFSC or DFSC bits (ref: D10.2.39, Page 2457~2464).
|
||||
match val & 0b111100 {
|
||||
0b000000 => AddressSize,
|
||||
0b000100 => Translation,
|
||||
0b001000 => AccessFlag,
|
||||
0b001100 => Permission,
|
||||
0b100000 => Alignment,
|
||||
0b110000 => TlbConflict,
|
||||
_ => Other((val & 0b111111) as u8),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum Syndrome {
|
||||
Unknown,
|
||||
WfiWfe,
|
||||
McrMrc,
|
||||
McrrMrrc,
|
||||
LdcStc,
|
||||
SimdFp,
|
||||
Vmrs,
|
||||
Mrrc,
|
||||
IllegalExecutionState,
|
||||
Svc(u16),
|
||||
Hvc(u16),
|
||||
Smc(u16),
|
||||
MsrMrsSystem,
|
||||
InstructionAbort { kind: Fault, level: u8 },
|
||||
PCAlignmentFault,
|
||||
DataAbort { kind: Fault, level: u8 },
|
||||
SpAlignmentFault,
|
||||
TrappedFpu,
|
||||
SError,
|
||||
Breakpoint,
|
||||
Step,
|
||||
Watchpoint,
|
||||
Brk(u16),
|
||||
Other(u32),
|
||||
}
|
||||
|
||||
/// Converts a raw syndrome value (ESR) into a `Syndrome` (ref: D1.10.4, D10.2.39).
|
||||
impl From<u32> for Syndrome {
|
||||
fn from(esr: u32) -> Syndrome {
|
||||
use self::Syndrome::*;
|
||||
|
||||
let ec = esr >> 26;
|
||||
let iss = esr & 0xFFFFFF;
|
||||
|
||||
match ec {
|
||||
0b000000 => Unknown,
|
||||
0b000001 => WfiWfe,
|
||||
0b000011 => McrMrc,
|
||||
0b000100 => McrrMrrc,
|
||||
0b000101 => McrMrc,
|
||||
0b000110 => LdcStc,
|
||||
0b000111 => SimdFp,
|
||||
0b001000 => Vmrs,
|
||||
0b001100 => Mrrc,
|
||||
0b001110 => IllegalExecutionState,
|
||||
0b010001 => Svc((iss & 0xFFFF) as u16),
|
||||
0b010010 => Hvc((iss & 0xFFFF) as u16),
|
||||
0b010011 => Smc((iss & 0xFFFF) as u16),
|
||||
0b010101 => Svc((iss & 0xFFFF) as u16),
|
||||
0b010110 => Hvc((iss & 0xFFFF) as u16),
|
||||
0b010111 => Smc((iss & 0xFFFF) as u16),
|
||||
0b011000 => MsrMrsSystem,
|
||||
0b100000 | 0b100001 => InstructionAbort {
|
||||
kind: Fault::from(iss),
|
||||
level: (iss & 0b11) as u8,
|
||||
},
|
||||
0b100010 => PCAlignmentFault,
|
||||
0b100100 | 0b100101 => DataAbort {
|
||||
kind: Fault::from(iss),
|
||||
level: (iss & 0b11) as u8,
|
||||
},
|
||||
0b100110 => SpAlignmentFault,
|
||||
0b101000 => TrappedFpu,
|
||||
0b101100 => TrappedFpu,
|
||||
0b101111 => SError,
|
||||
0b110000 => Breakpoint,
|
||||
0b110001 => Breakpoint,
|
||||
0b110010 => Step,
|
||||
0b110011 => Step,
|
||||
0b110100 => Watchpoint,
|
||||
0b110101 => Watchpoint,
|
||||
0b111100 => Brk((iss & 0xFFFF) as u16),
|
||||
other => Other(other),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
.section .text
|
||||
|
||||
.macro SAVE_ALL
|
||||
# lr, x0 is saved in HANDLER
|
||||
str x29, [sp, #-16]!
|
||||
stp x27, x28, [sp, #-16]!
|
||||
stp x25, x26, [sp, #-16]!
|
||||
stp x23, x24, [sp, #-16]!
|
||||
stp x21, x22, [sp, #-16]!
|
||||
stp x19, x20, [sp, #-16]!
|
||||
stp x17, x18, [sp, #-16]!
|
||||
stp x15, x16, [sp, #-16]!
|
||||
stp x13, x14, [sp, #-16]!
|
||||
stp x11, x12, [sp, #-16]!
|
||||
stp x9, x10, [sp, #-16]!
|
||||
stp x7, x8, [sp, #-16]!
|
||||
stp x5, x6, [sp, #-16]!
|
||||
stp x3, x4, [sp, #-16]!
|
||||
stp x1, x2, [sp, #-16]!
|
||||
|
||||
# stp q30, q31, [sp, #-32]!
|
||||
# stp q28, q29, [sp, #-32]!
|
||||
# stp q26, q27, [sp, #-32]!
|
||||
# stp q24, q25, [sp, #-32]!
|
||||
# stp q22, q23, [sp, #-32]!
|
||||
# stp q20, q21, [sp, #-32]!
|
||||
# stp q18, q19, [sp, #-32]!
|
||||
# stp q16, q17, [sp, #-32]!
|
||||
# stp q14, q15, [sp, #-32]!
|
||||
# stp q12, q13, [sp, #-32]!
|
||||
# stp q10, q11, [sp, #-32]!
|
||||
# stp q8, q9, [sp, #-32]!
|
||||
# stp q6, q7, [sp, #-32]!
|
||||
# stp q4, q5, [sp, #-32]!
|
||||
# stp q2, q3, [sp, #-32]!
|
||||
# stp q0, q1, [sp, #-32]!
|
||||
|
||||
mrs x2, tpidr_el0
|
||||
mrs x1, sp_el0
|
||||
stp x1, x2, [sp, #-16]!
|
||||
|
||||
mrs x2, spsr_el1
|
||||
mrs x1, elr_el1
|
||||
stp x1, x2, [sp, #-16]!
|
||||
.endm
|
||||
|
||||
.macro RESTORE_ALL
|
||||
ldp x1, x2, [sp], #16
|
||||
msr elr_el1, x1
|
||||
msr spsr_el1, x2
|
||||
|
||||
ldp x1, x2, [sp], #16
|
||||
msr sp_el0, x1
|
||||
msr tpidr_el0, x2
|
||||
|
||||
# ldp q0, q1, [sp], #32
|
||||
# ldp q2, q3, [sp], #32
|
||||
# ldp q4, q5, [sp], #32
|
||||
# ldp q6, q7, [sp], #32
|
||||
# ldp q8, q9, [sp], #32
|
||||
# ldp q10, q11, [sp], #32
|
||||
# ldp q12, q13, [sp], #32
|
||||
# ldp q14, q15, [sp], #32
|
||||
# ldp q16, q17, [sp], #32
|
||||
# ldp q18, q19, [sp], #32
|
||||
# ldp q20, q21, [sp], #32
|
||||
# ldp q22, q23, [sp], #32
|
||||
# ldp q24, q25, [sp], #32
|
||||
# ldp q26, q27, [sp], #32
|
||||
# ldp q28, q29, [sp], #32
|
||||
# ldp q30, q31, [sp], #32
|
||||
|
||||
ldp x1, x2, [sp], #16
|
||||
ldp x3, x4, [sp], #16
|
||||
ldp x5, x6, [sp], #16
|
||||
ldp x7, x8, [sp], #16
|
||||
ldp x9, x10, [sp], #16
|
||||
ldp x11, x12, [sp], #16
|
||||
ldp x13, x14, [sp], #16
|
||||
ldp x15, x16, [sp], #16
|
||||
ldp x17, x18, [sp], #16
|
||||
ldp x19, x20, [sp], #16
|
||||
ldp x21, x22, [sp], #16
|
||||
ldp x23, x24, [sp], #16
|
||||
ldp x25, x26, [sp], #16
|
||||
ldp x27, x28, [sp], #16
|
||||
ldr x29, [sp], #16
|
||||
ldp lr, x0, [sp], #16
|
||||
.endm
|
||||
|
||||
.global __alltraps
|
||||
__alltraps:
|
||||
SAVE_ALL
|
||||
|
||||
# x0 is set in HANDLER
|
||||
mrs x1, esr_el1
|
||||
mov x2, sp
|
||||
bl rust_trap
|
||||
|
||||
.global trap_ret
|
||||
trap_ret:
|
||||
RESTORE_ALL
|
||||
eret
|
@ -0,0 +1,29 @@
|
||||
.section .text
|
||||
|
||||
.macro HANDLER source kind
|
||||
.align 7
|
||||
stp lr, x0, [sp, #-16]!
|
||||
mov x0, #\source
|
||||
movk x0, #\kind, lsl #16
|
||||
b __alltraps
|
||||
.endm
|
||||
|
||||
.global __vectors
|
||||
.align 11
|
||||
__vectors:
|
||||
HANDLER 0 0
|
||||
HANDLER 0 1
|
||||
HANDLER 0 2
|
||||
HANDLER 0 3
|
||||
HANDLER 1 0
|
||||
HANDLER 1 1
|
||||
HANDLER 1 2
|
||||
HANDLER 1 3
|
||||
HANDLER 2 0
|
||||
HANDLER 2 1
|
||||
HANDLER 2 2
|
||||
HANDLER 2 3
|
||||
HANDLER 3 0
|
||||
HANDLER 3 1
|
||||
HANDLER 3 2
|
||||
HANDLER 3 3
|
Loading…
Reference in new issue