Compare commits
2 Commits
3e4d9a6a4e
...
683861b401
Author | SHA1 | Date | |
---|---|---|---|
683861b401 | |||
2d31cfd3ca |
6
Makefile
6
Makefile
@ -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
|
||||
|
48
kernel/src/arch/aarch64/asm.rs
Normal file
48
kernel/src/arch/aarch64/asm.rs
Normal 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;
|
@ -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};
|
||||
|
||||
|
87
kernel/src/arch/aarch64/exception.rs
Normal file
87
kernel/src/arch/aarch64/exception.rs
Normal 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"));
|
@ -2,6 +2,8 @@
|
||||
|
||||
pub mod boot;
|
||||
pub mod timer;
|
||||
pub mod asm;
|
||||
pub mod exception;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "mach_qemu")] {
|
||||
|
77
kernel/src/arch/aarch64/vectors.S
Normal file
77
kernel/src/arch/aarch64/vectors.S
Normal 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 .
|
@ -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]
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user