Compare commits

...

2 Commits

Author SHA1 Message Date
683861b401 feat: elx_sp_el0 exception handling 2021-09-29 18:56:52 +03:00
2d31cfd3ca feat: enable FP instructions in EL0/1 2021-09-29 17:14:46 +03:00
8 changed files with 248 additions and 3 deletions

View File

@ -25,7 +25,7 @@ $(error TODO)
else
ifeq ($(MACH),qemu)
QEMU_OPTS+=-kernel $(O)/kernel.bin \
-M virt,virtualization=on \
-M virt,virtualization=off \
-cpu cortex-a72 \
-m 512 \
-serial chardev:serial0
@ -45,8 +45,8 @@ endif
clean:
cargo clean
qemu:
qemu: all
qemu-system-$(ARCH) $(QEMU_OPTS)
gdb:
gdb: all
$(GDB) -x etc/gdbrc $(O)/kernel

View File

@ -0,0 +1,48 @@
//! Assembly intrinsics for AArch64 platform
#![allow(missing_docs)]
use tock_registers::{
interfaces::{Readable, Writeable},
register_bitfields
};
register_bitfields! {
u64,
pub CPACR_EL1 [
FPEN OFFSET(20) NUMBITS(2) [
TrapAll = 0,
TrapEl0 = 1,
TrapNone = 3
]
]
}
pub struct Reg;
impl Readable for Reg {
type T = u64;
type R = CPACR_EL1::Register;
#[inline(always)]
fn get(&self) -> Self::T {
let mut tmp;
unsafe {
asm!("mrs {}, cpacr_el1", out(reg) tmp);
}
tmp
}
}
impl Writeable for Reg {
type T = u64;
type R = CPACR_EL1::Register;
#[inline(always)]
fn set(&self, value: Self::T) {
unsafe {
asm!("msr cpacr_el1, {}", in(reg) value);
}
}
}
pub const CPACR_EL1: Reg = Reg;

View File

@ -1,8 +1,22 @@
//! aarch64 common boot logic
use crate::arch::aarch64::asm::CPACR_EL1;
use cortex_a::registers::VBAR_EL1;
use tock_registers::interfaces::Writeable;
#[no_mangle]
fn __aa64_bsp_main() {
// Disable FP instruction trapping
CPACR_EL1.write(CPACR_EL1::FPEN::TrapNone);
extern "C" {
static aa64_el1_vectors: u8;
}
unsafe {
VBAR_EL1.set(&aa64_el1_vectors as *const _ as u64);
}
debugln!("Test");
use crate::arch::machine;
use crate::dev::{serial::SerialDevice, timer::TimestampSource, Device};

View File

@ -0,0 +1,87 @@
//! AArch64 exception handling
/// Trapped SIMD/FP functionality
pub const EC_FP_TRAP: u64 = 0b000111;
/// Data Abort at current EL
pub const EC_DATA_ABORT_ELX: u64 = 0b100101;
#[derive(Debug)]
#[repr(C)]
struct ExceptionFrame {
x0: u64,
x1: u64,
x2: u64,
x3: u64,
x4: u64,
x5: u64,
x6: u64,
x7: u64,
x8: u64,
x9: u64,
x10: u64,
x11: u64,
x12: u64,
x13: u64,
x14: u64,
x15: u64,
x16: u64,
x17: u64,
x18: u64,
x29: u64,
x30: u64,
elr: u64,
esr: u64,
far: u64,
}
#[inline(always)]
const fn data_abort_access_type(iss: u64) -> &'static str {
if iss & (1 << 6) != 0 {
"WRITE"
} else {
"READ"
}
}
#[inline(always)]
const fn data_abort_access_size(iss: u64) -> &'static str {
match (iss >> 22) & 0x3 {
0 => "BYTE",
1 => "HALFWORD",
2 => "WORD",
3 => "DOUBLEWORD",
_ => unreachable!(),
}
}
#[no_mangle]
extern "C" fn __aa64_exc_handler(exc: &mut ExceptionFrame) {
let err_code = exc.esr >> 26;
let iss = exc.esr & 0x1FFFFFF;
debugln!("Unhandled exception at ELR={:#018x}", exc.elr);
match err_code {
EC_DATA_ABORT_ELX => {
debugln!("Data Abort:");
debug!(" Illegal {}", data_abort_access_type(iss),);
if iss & (1 << 24) != 0 {
debug!(" of a {}", data_abort_access_size(iss));
}
if iss & (1 << 10) == 0 {
debug!(" at {:#018x}", exc.far);
} else {
debug!(" at UNKNOWN");
}
debugln!("");
}
_ => {}
}
debugln!("{:#018x?}", exc);
panic!("Unhandled exception");
}
global_asm!(include_str!("vectors.S"));

View File

@ -2,6 +2,8 @@
pub mod boot;
pub mod timer;
pub mod asm;
pub mod exception;
cfg_if! {
if #[cfg(feature = "mach_qemu")] {

View File

@ -0,0 +1,77 @@
.section .text
.global aa64_el1_vectors
.p2align 8
aa64_el1_vectors:
.el1_sp_el0_sync:
b .
.p2align 7
.el1_sp_el0_irq:
b .
.p2align 7
.el1_sp_el0_fiq:
b .
.p2align 7
.el1_sp_el0_serror:
b .
.p2align 7
.el1_sp_el1_sync:
sub sp, sp, #192
stp x0, x1, [sp, #0]
stp x2, x3, [sp, #16]
stp x4, x5, [sp, #32]
stp x6, x7, [sp, #48]
stp x8, x9, [sp, #64]
stp x10, x11, [sp, #80]
stp x12, x13, [sp, #96]
stp x14, x15, [sp, #112]
stp x16, x17, [sp, #128]
stp x18, x29, [sp, #144]
mrs x0, elr_el1
stp x30, x0, [sp, #160]
mrs x0, esr_el1
mrs x1, far_el1
stp x0, x1, [sp, #176]
mov x0, sp
bl __aa64_exc_handler
b .
.p2align 7
.el1_sp_el1_irq:
b .
.p2align 7
.el1_sp_el1_fiq:
b .
.p2align 7
.el1_sp_el1_serror:
b .
.p2align 7
.el0_aa64_sync:
b .
.p2align 7
.el0_aa64_irq:
b .
.p2align 7
.el0_aa64_fiq:
b .
.p2align 7
.el0_aa64_serror:
b .
.p2align 7
.el0_aa32_sync:
b .
.p2align 7
.el0_aa32_irq:
b .
.p2align 7
.el0_aa32_fiq:
b .
.p2align 7
.el0_aa32_serror:
b .

View File

@ -1,10 +1,12 @@
//! osdve5 crate (lol)
#![feature(
asm,
global_asm,
const_for,
const_mut_refs,
const_raw_ptr_deref,
const_fn_fn_ptr_basics,
const_panic,
panic_info_message
)]
#![no_std]

View File

@ -34,3 +34,18 @@ pub unsafe extern "C" fn memcmp(a: *mut u8, b: *mut u8, mut len: usize) -> isize
}
0
}
/// See memset(3p)
///
/// # Safety
///
/// Unsafe: writes to arbitrary memory locations, performs no pointer
/// validation.
#[no_mangle]
pub unsafe extern "C" fn memset(buf: *mut u8, val: u8, mut len: usize) -> *mut u8 {
while len != 0 {
len -= 1;
*buf.add(len) = val;
}
buf
}