Files
novaOS/src/main.rs
2026-03-15 14:17:23 +01:00

165 lines
3.8 KiB
Rust

#![no_main]
#![no_std]
#![allow(static_mut_refs)]
#![allow(clippy::missing_safety_doc)]
use core::{
arch::{asm, global_asm},
ptr::write_volatile,
};
extern crate alloc;
use nova::{
aarch64::{
mmu::{
allocate_memory_explicit, sim_l3_access, EL0_ACCESSIBLE, NORMAL_MEM, PXN, UXN, WRITABLE,
},
registers::{daif, read_id_aa64mmfr0_el1},
},
configuration::mmu::initialize_mmu_translation_tables,
framebuffer::{FrameBuffer, BLUE, GREEN, RED},
get_current_el, init_heap,
interrupt_handlers::{enable_irq_source, IRQSource},
peripherals::{
gpio::{
blink_gpio, gpio_pull_up, set_falling_edge_detect, set_gpio_function, GPIOFunction,
SpecificGpio,
},
uart::uart_init,
},
pi3::mailbox,
println,
};
global_asm!(include_str!("vector.S"));
extern "C" {
fn el2_to_el1();
fn el1_to_el0();
fn configure_mmu_el1();
static mut __bss_start: u32;
static mut __bss_end: u32;
}
#[no_mangle]
#[cfg_attr(not(test), link_section = ".text._start")]
pub unsafe extern "C" fn _start() {
// Set the stack pointer
asm!(
"ldr x0, =__stack_end",
"mov sp, x0",
"b main",
options(noreturn)
);
}
#[no_mangle]
pub extern "C" fn main() -> ! {
unsafe {
zero_bss();
}
enable_uart();
// Set ACT Led to Outout
let _ = set_gpio_function(21, GPIOFunction::Output);
println!("Hello World!");
println!("Exception level: {}", get_current_el());
unsafe {
init_heap();
initialize_mmu_translation_tables();
// Frame Buffer memory range
// TODO: this is just temporary
allocate_memory_explicit(
0x3c100000,
1080 * 1920 * 4,
0x3c100000,
NORMAL_MEM | PXN | UXN | WRITABLE | EL0_ACCESSIBLE,
)
.unwrap();
sim_l3_access(0x3c100000);
configure_mmu_el1();
};
println!("AA64 {:064b}", read_id_aa64mmfr0_el1());
unsafe {
el2_to_el1();
}
#[allow(clippy::empty_loop)]
loop {}
}
unsafe fn zero_bss() {
let mut bss: *mut u32 = &raw mut __bss_start;
while bss < &raw mut __bss_end {
write_volatile(bss, 0);
bss = bss.add(1);
}
}
#[no_mangle]
pub extern "C" fn kernel_main() -> ! {
nova::initialize_kernel();
println!("Exception Level: {}", get_current_el());
daif::unmask_all();
let fb = FrameBuffer::default();
for i in 0..1080 {
fb.draw_pixel(50, i, RED);
}
unsafe {
el1_to_el0();
};
#[allow(clippy::empty_loop)]
loop {}
}
#[no_mangle]
pub extern "C" fn el0() -> ! {
println!("Jumped into EL0");
// Set GPIO 26 to Input
enable_irq_source(IRQSource::GpioInt0); //26 is on the first GPIO bank
let _ = set_gpio_function(26, GPIOFunction::Input);
gpio_pull_up(26);
set_falling_edge_detect(26, true);
enable_irq_source(IRQSource::UartInt);
let fb = FrameBuffer::default();
for i in 600..1080 {
fb.draw_pixel(50, i, RED);
}
fb.draw_square(500, 500, 600, 700, RED);
fb.draw_square_fill(800, 800, 900, 900, GREEN);
fb.draw_square_fill(1000, 800, 1200, 700, BLUE);
fb.draw_square_fill(900, 100, 800, 150, RED | BLUE);
fb.draw_string("Hello World! :D\nTest next Line", 500, 5, 3, BLUE);
fb.draw_function(cos, 0, 101, RED);
loop {
let temp = mailbox::read_soc_temp([0]).unwrap();
println!("{} °C", temp[1] / 1000);
blink_gpio(SpecificGpio::OnboardLed as u8, 500);
}
}
fn cos(x: u32) -> f64 {
libm::cos(x as f64 * 0.1) * 20.0
}
fn enable_uart() {
// Set GPIO Pins to UART
let _ = set_gpio_function(14, GPIOFunction::Alternative0);
let _ = set_gpio_function(15, GPIOFunction::Alternative0);
uart_init();
}