diff --git a/.gitignore b/.gitignore index a5adda7..a6534a8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ kernel8.img .env sd.img +settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7a1c1a5..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lldb.displayFormat": "auto", - "lldb.showDisassembly": "always", - "lldb.dereferencePointers": true, - "lldb.consoleMode": "commands" -} diff --git a/link.ld b/link.ld index 34c2072..f4ef72e 100644 --- a/link.ld +++ b/link.ld @@ -27,10 +27,9 @@ SECTIONS { KEEP(*(.vector_table)) } - .stack 0x8008000 : ALIGN(16) + .stack 0x8018000 : ALIGN(16) { __stack_start = .; - .+=0x10000; __stack_end = .; } diff --git a/src/configuration.rs b/src/configuration.rs new file mode 100644 index 0000000..59deccd --- /dev/null +++ b/src/configuration.rs @@ -0,0 +1,15 @@ +static SCTLR_EL1_MMU_DISABLED: u64 = 0 << 0; //M +static SCTLR_EL1_DATA_CACHE_DISABLED: u64 = 0 << 2; //C +static SCTLR_EL1_INSTRUCTION_CACHE_DISABLED: u64 = 0 << 12; //I +static SCTLR_EL1_LITTLE_ENDIAN_EL0: u64 = 0 << 24; //E0E +static SCTLR_EL1_LITTLE_ENDIAN_EL1: u64 = 0 << 25; //EE + +static SCTLR_EL1_RES: u64 = (0 << 6) | (1 << 11) | (0 << 17) | (1 << 20) | (1 << 22); //Res0 & Res1 + +#[no_mangle] +pub static SCTLR_EL1_CONF: u64 = SCTLR_EL1_MMU_DISABLED + | SCTLR_EL1_DATA_CACHE_DISABLED + | SCTLR_EL1_INSTRUCTION_CACHE_DISABLED + | SCTLR_EL1_LITTLE_ENDIAN_EL0 + | SCTLR_EL1_LITTLE_ENDIAN_EL1 + | SCTLR_EL1_RES; diff --git a/src/irq_interrupt.rs b/src/irq_interrupt.rs index 6d1277f..8e03285 100644 --- a/src/irq_interrupt.rs +++ b/src/irq_interrupt.rs @@ -5,7 +5,11 @@ use core::{ use crate::{ mmio_read, mmio_write, - peripherals::{gpio::blink_gpio, uart::print}, + peripherals::{ + gpio::{blink_gpio, SpecificGpio}, + uart::print, + }, + timer::{sleep_ms, sleep_s}, }; const INTERRUPT_BASE: u32 = 0x3F00_B000; @@ -41,10 +45,34 @@ unsafe extern "C" fn irq_handler() { #[no_mangle] unsafe extern "C" fn synchronous_interrupt() { loop { - let el: u64; - asm!("mrs x5, FAR_EL1"); - blink_gpio(29, 100); print("Sync Exception \r\n"); + blink_gpio(SpecificGpio::OnboardLed as u8, 100); + esr_uart_dump(); + sleep_s(200); + } +} + +fn esr_uart_dump() { + let esr: u32; + unsafe { + asm!( + "mrs {esr}, ESR_EL1", + esr = out(reg) esr + ); + } + for i in (0..32).rev() { + if ((esr >> i) & 1) == 0 { + print("0"); + } else { + print("1"); + } + if i % 4 == 0 && i > 0 { + print("_"); + } + + if i == 26 || i == 25 || i == 0 { + print("\n\r"); + } } } diff --git a/src/lib.rs b/src/lib.rs index 8d909e0..61a00be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ use core::ptr::{read_volatile, write_volatile}; pub mod peripherals; +pub mod configuration; pub mod irq_interrupt; pub mod mailbox; pub mod timer; diff --git a/src/mailbox.rs b/src/mailbox.rs index 5df8a89..2317d2e 100644 --- a/src/mailbox.rs +++ b/src/mailbox.rs @@ -1,9 +1,6 @@ use core::ptr::read_volatile; -use crate::{ - mmio_read, mmio_write, - peripherals::uart::{print, print_u32}, -}; +use crate::{mmio_read, mmio_write, peripherals::uart::print}; const MBOX_BASE: u32 = 0x3F00_0000 + 0xB880; @@ -18,12 +15,6 @@ const MBOX_WRITE: u32 = MBOX_BASE + 0x20; const MAIL_FULL: u32 = 0x80000000; const MAIL_EMPTY: u32 = 0x40000000; -#[repr(C, align(16))] -struct MailboxBuffer([u32; 36]); - -#[no_mangle] -static mut MBOX: MailboxBuffer = MailboxBuffer([0; 36]); - pub fn read_mailbox(channel: u32) -> u32 { // Wait until mailbox is not empty loop { @@ -45,30 +36,25 @@ pub fn write_mailbox(channel: u32, data: u32) { } pub fn read_soc_temp() -> u32 { - unsafe { - // MBOX.0[0] = 7 * 4; // Total size in bytes - // MBOX.0[1] = 0; // Request - // MBOX.0[2] = 0x00010002; // Tag - // MBOX.0[3] = 4; // Maximum buffer lenb - // MBOX.0[4] = 0; // Request length - // MBOX.0[5] = 0; // Value Buffer - // MBOX.0[6] = 0; // End - // core::arch::asm!("dsb sy"); // Ensure write reaches RAM - // core::arch::asm!("dmb sy"); // Memory barrier + let mut mailbox = [0; 36]; + mailbox[0] = 8 * 4; // Total size in bytes + mailbox[1] = 0; // Request + mailbox[2] = 0x00030006; // Tag + mailbox[3] = 8; // Maximum buffer len + mailbox[4] = 4; // Request length + mailbox[5] = 0; // Value Buffer + mailbox[6] = 0; // Value Buffer + mailbox[7] = 0; // End - print("Reading address\r\n"); - //let addr = core::ptr::addr_of!(MBOX.0[0]); + let addr = core::ptr::addr_of!(mailbox[0]) as u32; - print("Write address\r\n"); + write_mailbox(8, addr); - // write_mailbox(8, addr); + let _ = read_mailbox(8); - let _ = read_mailbox(8); - - if MBOX.0[1] == 0 { - print("Failed\r\n"); - } - let raw_temp = MBOX.0[5]; - raw_temp + if mailbox[1] == 0 { + print("Failed\r\n"); } + let raw_temp = mailbox[6] / 1000; + raw_temp } diff --git a/src/main.rs b/src/main.rs index 69d9316..81c3b16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use nova::{ peripherals::{ gpio::{ blink_gpio, gpio_pull_up, set_falling_edge_detect, set_gpio_function, GPIOFunction, + SpecificGpio, }, uart::{print, print_u32, uart_init}, }, @@ -81,7 +82,6 @@ unsafe fn zero_bss() { #[no_mangle] pub extern "C" fn kernel_main() -> ! { - print("AAA\r\n"); print_current_el_str(); sleep_us(500_000); @@ -96,7 +96,7 @@ pub extern "C" fn kernel_main() -> ! { let temp = read_soc_temp(); print_u32(temp); - blink_gpio(29, 500); + blink_gpio(SpecificGpio::OnboardLed as u8, 500); } } diff --git a/src/peripherals/gpio.rs b/src/peripherals/gpio.rs index 5e39716..dfe804b 100644 --- a/src/peripherals/gpio.rs +++ b/src/peripherals/gpio.rs @@ -13,6 +13,11 @@ const GPPUDCLK_BASE: u32 = 0x3F20_0098; const GPREN_BASE: u32 = 0x3F20_004C; const GPFEN_BASE: u32 = 0x3F20_0058; +#[repr(u8)] +pub enum SpecificGpio { + OnboardLed = 29, +} + #[repr(u32)] pub enum GPIOFunction { Input = 0b000, diff --git a/src/peripherals/uart.rs b/src/peripherals/uart.rs index 3fda269..30bd345 100644 --- a/src/peripherals/uart.rs +++ b/src/peripherals/uart.rs @@ -1,4 +1,4 @@ -use core::{arch::asm, fmt}; +use core::arch::asm; use crate::{mmio_read, mmio_write}; @@ -33,17 +33,24 @@ pub fn print(s: &str) { } pub fn print_u32(mut val: u32) { + let mut last_valid = 0; let mut values = [0u32; 10]; - for c in &mut values { + for (i, c) in (&mut values).iter_mut().enumerate() { if val == 0 { break; } *c = val % 10; val /= 10; + if *c != 0 { + last_valid = i; + } } - for c in values.iter().rev() { + for (i, c) in values.iter().enumerate().rev() { + if i > last_valid { + continue; + } let ascii_byte = b'0' + *c as u8; let data = [ascii_byte]; diff --git a/src/vector.S b/src/vector.S index d8562db..63d0b6a 100644 --- a/src/vector.S +++ b/src/vector.S @@ -21,7 +21,6 @@ vector_table: .align 4 -.extern main .global el2_to_el1 el2_to_el1: @@ -45,10 +44,15 @@ el2_to_el1: msr VBAR_EL1, x0 // Disable MMU - mrs x0, sctlr_el1 - bic x0, x0, #1 + ldr x0, =SCTLR_EL1_CONF msr sctlr_el1, x0 + // SIMD should not be trapped + mrs x0, CPACR_EL1 + mov x1, #(0b11<<20) + orr x0,x0, x1 + msr CPACR_EL1,x0 + isb // Return to EL1