mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
163 lines
3.8 KiB
Rust
163 lines
3.8 KiB
Rust
#![no_main]
|
|
#![no_std]
|
|
#![feature(asm_experimental_arch)]
|
|
#![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, EL0_ACCESSIBLE, LEVEL2_BLOCK_SIZE, 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
|
|
// TODO: Investigate why the size is off
|
|
allocate_memory_explicit(
|
|
0x3c100000,
|
|
1080 * 1920 * 4 + LEVEL2_BLOCK_SIZE + LEVEL2_BLOCK_SIZE,
|
|
0x3c100000,
|
|
NORMAL_MEM | PXN | UXN | WRITABLE | EL0_ACCESSIBLE,
|
|
)
|
|
.unwrap();
|
|
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();
|
|
|
|
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 0..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();
|
|
}
|