Implement first basic interrupt handler

This commit is contained in:
2025-05-29 18:21:42 +02:00
parent 18233ec722
commit 20808a7992
16 changed files with 283 additions and 32 deletions

View File

@@ -2,20 +2,33 @@
#![no_std]
#![feature(asm_experimental_arch)]
use core::{arch::asm, panic::PanicInfo};
use core::{
arch::{asm, global_asm},
panic::PanicInfo,
};
use gpio::{gpio_get_state, gpio_high, gpio_low, gpio_pull_up, set_gpio_state};
use gpio::{
gpio_enable_low_detect, gpio_get_state, gpio_high, gpio_low, gpio_pull_up, set_gpio_state,
};
use interrupt::enable_iqr_source;
use timer::{delay_nops, sleep};
use uart::print;
mod gpio;
mod interrupt;
mod timer;
mod uart;
global_asm!(include_str!("vector.S"));
extern "C" {
fn el2_to_el1();
}
#[panic_handler]
fn panic(_panic: &PanicInfo) -> ! {
loop {
uart::print("Panic");
uart::print("Panic\r\n");
}
}
@@ -23,13 +36,17 @@ fn panic(_panic: &PanicInfo) -> ! {
#[link_section = ".text._start"]
pub unsafe extern "C" fn _start() {
// Set the stack pointer
asm!("ldr x0, =0x8004000", "mov sp, x0");
main();
asm!(
"ldr x0, =0x8008000",
"mov sp, x0",
"b main",
options(noreturn)
);
}
#[no_mangle]
extern "C" fn main() {
uart::configure_uart();
pub extern "C" fn main() -> ! {
uart::uart_init();
// Set ACT Led to Outout
let _ = set_gpio_state(21, gpio::GPIOState::Output);
@@ -37,16 +54,32 @@ extern "C" fn main() {
let _ = set_gpio_state(14, gpio::GPIOState::Alternative0);
let _ = set_gpio_state(15, gpio::GPIOState::Alternative0);
// Set GPIO 21 to Input
let _ = set_gpio_state(21, gpio::GPIOState::Input);
gpio_pull_up(21);
print_current_el_str();
// Delay so clock speed can stabilize
delay_nops(50000);
uart::print("Hello World!\r\n");
unsafe {
el2_to_el1();
}
loop {}
}
#[no_mangle]
pub extern "C" fn kernel_main() -> ! {
let el = get_current_el();
print_current_el_str();
sleep(500_000);
// Set GPIO 21 to Input
enable_iqr_source(49); //21 is on the first GPIO bank
let _ = set_gpio_state(21, gpio::GPIOState::Input);
gpio_pull_up(21);
gpio_enable_low_detect(21, true);
loop {
let _ = gpio_high(29);
@@ -67,3 +100,29 @@ fn print_gpio_state() {
print(s);
print("\r\n");
}
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
}
fn print_current_el_str() {
let el = get_current_el();
let el_str = match el {
0b11 => "Level 3",
0b10 => "Level 2",
0b01 => "Level 1",
0b00 => "Level 0",
_ => "Unknown EL",
};
print(el_str);
print("\r\n");
}