use crate::mmu::Mmu;
use crate::registers::{set_vbar_el1, sctlr_el1_read, sctlr_el1_write};
use crate::VECTOR_ALIGNMENT;
extern "C" {
static mut __bss_start: u8;
static mut __bss_end: u8;
}
extern "C" {
static exception_vectors: u8;
}
#[no_mangle]
pub unsafe extern "C" fn early_init() -> ! {
unsafe {
init_bss();
init_mmu();
init_exception_vectors();
enable_mmu();
}
kernel_main()
}
unsafe fn init_bss() {
let start = unsafe { core::ptr::addr_of_mut!(__bss_start) };
let end = unsafe { core::ptr::addr_of_mut!(__bss_end) };
let len = (end as usize).wrapping_sub(start as usize);
unsafe {
core::ptr::write_bytes(start, 0, len);
}
}
unsafe fn init_mmu() {
let mut mmu = Mmu::new();
unsafe {
mmu.init();
}
}
unsafe fn init_exception_vectors() {
let vbar = unsafe { core::ptr::addr_of!(exception_vectors) } as usize;
assert_eq!(
vbar & (VECTOR_ALIGNMENT - 1),
0,
"Exception vectors must be {VECTOR_ALIGNMENT}-byte aligned"
);
unsafe {
set_vbar_el1(vbar);
}
}
unsafe fn enable_mmu() {
let mut sctlr = unsafe { sctlr_el1_read() };
sctlr |= (1 << 0) | (1 << 2) | (1 << 12) | (1 << 1);
unsafe {
sctlr_el1_write(sctlr);
}
unsafe {
core::arch::asm!("isb", options(nostack, preserves_flags));
}
}
#[no_mangle]
pub extern "C" fn kernel_main() -> ! {
loop {
unsafe {
core::arch::asm!("wfi", options(nostack, nomem, preserves_flags));
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vector_alignment() {
assert_eq!(VECTOR_ALIGNMENT.count_ones(), 1);
assert_eq!(VECTOR_ALIGNMENT, 0x800);
}
}