#![no_std] #![allow(clippy::missing_safety_doc)] extern crate alloc; use alloc::boxed::Box; use core::{ arch::asm, panic::PanicInfo, ptr::{read_volatile, write_volatile}, }; use heap::Heap; use crate::{ aarch64::mmu::{ allocate_memory, PhysSource, KERNEL_VIRTUAL_MEM_SPACE, LEVEL2_BLOCK_SIZE, NORMAL_MEM, UXN, WRITABLE, }, interrupt_handlers::initialize_interrupt_handler, logger::DefaultLogger, pi3::timer::sleep_s, }; static PERIPHERAL_BASE: usize = 0x3F00_0000; unsafe extern "C" { unsafe static mut __kernel_end: u8; } #[global_allocator] pub static mut GLOBAL_ALLOCATOR: Heap = Heap::empty(); pub unsafe fn init_kernel_heap() { let start = core::ptr::addr_of_mut!(__kernel_end) as usize | KERNEL_VIRTUAL_MEM_SPACE; let size = LEVEL2_BLOCK_SIZE * 2; allocate_memory(start, size, PhysSource::Any, NORMAL_MEM | UXN | WRITABLE).unwrap(); let heap = core::ptr::addr_of_mut!(GLOBAL_ALLOCATOR); (*heap).init(start, start + size); } #[panic_handler] fn panic(_panic: &PanicInfo) -> ! { loop { println!("Panic: {}", _panic.message()); sleep_s(1); } } pub mod peripherals; pub mod aarch64; pub mod configuration; pub mod framebuffer; pub mod interrupt_handlers; pub mod logger; pub mod pi3; #[inline(always)] pub unsafe fn read_address(address: u32) -> u32 { unsafe { read_volatile(address as *const u32) } } #[inline(always)] pub unsafe fn write_address(address: u32, data: u32) { unsafe { write_volatile(address as *mut u32, data) } } pub fn get_current_el() -> u64 { let el: u64; unsafe { asm!( "mrs {el}, CurrentEL", el = out(reg) el, options(nomem, nostack, preserves_flags) ); } el >> 2 } static mut KERNEL_INITIALIZED: bool = false; pub fn initialize_kernel() { if unsafe { KERNEL_INITIALIZED } { return; } unsafe { init_kernel_heap() }; logger::set_logger(Box::new(DefaultLogger)); initialize_interrupt_handler(); unsafe { KERNEL_INITIALIZED = true }; }