From 1ff752e3dd936841740a1a3c3f2e7771be652022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Neuh=C3=A4user?= Date: Sun, 8 Jun 2025 21:49:36 +0200 Subject: [PATCH 1/4] mailbox --- src/mailbox.rs | 57 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 13 ++++++++++ src/peripherals/gpio.rs | 34 ++++++++++++------------ 3 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 src/mailbox.rs diff --git a/src/mailbox.rs b/src/mailbox.rs new file mode 100644 index 0000000..cac50fa --- /dev/null +++ b/src/mailbox.rs @@ -0,0 +1,57 @@ +use crate::{mmio_read, mmio_write}; + +const MBOX_BASE: u32 = 0x3F00_B880; + +// MB0 +const MBOX_READ: u32 = MBOX_BASE + 0x00; +const MBOX_READ_STATUS: u32 = MBOX_BASE + 0x18; + +// MB1 +const MBOX_WRITE: u32 = MBOX_BASE + 0x20; +const MBOX_WRITE_STATUS: u32 = MBOX_BASE + 0x38; + +// Status +const MAIL_FULL: u32 = 0x80000000; +const MAIL_EMPTY: u32 = 0x40000000; + +#[repr(align(16))] +struct MailboxBuffer([u32; 36]); + +pub fn read_mailbox(channel: u32) -> u32 { + // Wait until mailbox is not empty + loop { + while (mmio_read(MBOX_READ_STATUS) & MAIL_EMPTY != 0) {} + let mut data = mmio_read(MBOX_READ); + let read_channel = data & 0xF; + + data >>= 4; + + if channel == read_channel { + return data; + } + } +} + +pub fn write_mailbox(channel: u32, data: u32) { + while (mmio_read(MBOX_WRITE_STATUS) & MAIL_FULL != 0) {} + mmio_write(MBOX_WRITE, data << 4 | (channel & 0xF)); +} + +pub fn read_soc_temp() -> u32 { + let mut mbox = MailboxBuffer([0; 36]); + + mbox.0[0] = 8 * 4; // Total size in bytes + mbox.0[1] = 0; // Request + mbox.0[2] = 0x00030006; // Tag: Get temperature + mbox.0[3] = 8; // Value buffer size (bytes) + mbox.0[4] = 4; // Request size (bytes) + mbox.0[5] = 0; // Temp ID: 0 = SoC + mbox.0[6] = 0; // Response will be written here + mbox.0[7] = 0; // End tag + + let addr = &mbox.0 as *const u32 as u32; + write_mailbox(8, addr); + let _ = read_mailbox(8); + let raw_temp = mbox.0[6]; + raw_temp / 1000 +} diff --git a/src/main.rs b/src/main.rs index 479f264..a5d19ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use core::{ use nova::{ irq_interrupt::enable_irq_source, + mailbox::read_soc_temp, peripherals::{ gpio::{ gpio_get_state, gpio_high, gpio_low, gpio_pull_up, set_falling_edge_detect, @@ -77,6 +78,9 @@ pub extern "C" fn kernel_main() -> ! { set_falling_edge_detect(26, true); loop { + //let temp = read_soc_temp(); + //u32_to_ascii(temp as u8); + let _ = gpio_high(29); sleep_ms(500); // 0.5s @@ -97,6 +101,15 @@ fn print_gpio_state() { print("\r\n"); } +fn u32_to_ascii(val: u8) { + let ascii_byte = b'0' + val; + let data = [ascii_byte]; + + let s = str::from_utf8(&data).unwrap(); + print(s); + print("C\r\n"); +} + pub fn get_current_el() -> u64 { let el: u64; unsafe { diff --git a/src/peripherals/gpio.rs b/src/peripherals/gpio.rs index 709277f..c283148 100644 --- a/src/peripherals/gpio.rs +++ b/src/peripherals/gpio.rs @@ -90,30 +90,28 @@ pub fn gpio_pull_down(gpio: u8) { } fn gpio_pull_up_down(gpio: u8, val: u32) { - unsafe { - // Determine GPPUDCLK Register - let register_addr = GPPUDCLK_BASE + 4 * (gpio as u32 / 32); - let register_offset = gpio % 32; + // Determine GPPUDCLK Register + let register_addr = GPPUDCLK_BASE + 4 * (gpio as u32 / 32); + let register_offset = gpio % 32; - // 1. Write Pull up - mmio_write(GPPUD, val); + // 1. Write Pull up + mmio_write(GPPUD, val); - // 2. Delay 150 cycles - delay_nops(150); + // 2. Delay 150 cycles + delay_nops(150); - // 3. Write to clock - let new_val = 0b1 << register_offset; - mmio_write(register_addr, new_val); + // 3. Write to clock + let new_val = 0b1 << register_offset; + mmio_write(register_addr, new_val); - // 4. Delay 150 cycles - delay_nops(150); + // 4. Delay 150 cycles + delay_nops(150); - // 5. reset GPPUD - mmio_write(GPPUD, 0); + // 5. reset GPPUD + mmio_write(GPPUD, 0); - // 6. reset clock - mmio_write(register_addr, 0); - } + // 6. reset clock + mmio_write(register_addr, 0); } /// Get the current status if falling edge detection is set From fe8e5e000a273d93cf7fd1d3c3d7e385ee0fdef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Neuh=C3=A4user?= Date: Wed, 25 Jun 2025 11:44:40 +0200 Subject: [PATCH 2/4] Trying to fix exception in el1 --- .vscode/launch.json | 41 +++++++++++++++------- .vscode/settings.json | 6 ++++ .vscode/tasks.json | 2 +- Cargo.toml | 2 ++ firmware_files/fixup.dat | Bin 0 -> 7321 bytes src/irq_interrupt.rs | 16 ++++++++- src/mailbox.rs | 61 +++++++++++++++++++++------------ src/main.rs | 54 ++++++++++++----------------- src/peripherals/gpio.rs | 10 +++++- src/peripherals/uart.rs | 29 ++++++++++++++-- src/vector.S | 9 +++-- tools/start_simulator_debug.sh | 3 +- 12 files changed, 159 insertions(+), 74 deletions(-) create mode 100644 .vscode/settings.json create mode 100755 firmware_files/fixup.dat diff --git a/.vscode/launch.json b/.vscode/launch.json index 941b38e..bffd237 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,5 +1,12 @@ { "version": "0.2.0", + "compounds": [ + { + "name": "Run QEMU + Attach LLDB", + "configurations": ["Attach LLDB"], + "preLaunchTask": "Run QEMU" + } + ], "configurations": [ { "name": "Attach to QEMU (AArch64)", @@ -12,19 +19,29 @@ "stopAtEntry": true, "externalConsole": false, "MIMode": "gdb", -"setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - }, - { - "description": "Show assembly on stop", - "text": "layout asm", - "ignoreFailures": true - } -], + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Show assembly on stop", + "text": "set disassemble-next-line on", + "ignoreFailures": true + } + ], "preLaunchTask": "Run QEMU" + }, + + { + "name": "Attach LLDB", + "type": "lldb", + "request": "attach", + "debugServer": 1234, + "program": "${workspaceFolder}/target/aarch64-unknown-none/debug/nova", + "stopOnEntry": true, + "processCreateCommands": ["gdb-remote localhost:1234"] } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a1c1a5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "always", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "commands" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9445da3..18998f4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -14,7 +14,7 @@ { "label": "Run QEMU", "type": "shell", - "command": "qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -serial stdio -sd sd.img -display none -kernel ${workspaceFolder}/target/aarch64-unknown-none/debug/kernel8.img -S -s", + "command": "qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -serial stdio -sd sd.img -display none -kernel ${workspaceFolder}/target/aarch64-unknown-none/debug/kernel8.img -S -s -m 1024", "isBackground": true, "dependsOn": ["Build"] } diff --git a/Cargo.toml b/Cargo.toml index 45aea39..c8de713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [profile.dev] panic = "abort" +debug = true +opt-level = 0 [profile.release] panic = "abort" diff --git a/firmware_files/fixup.dat b/firmware_files/fixup.dat new file mode 100755 index 0000000000000000000000000000000000000000..f83030049e9e53f8a82e5ce59d8ceaeeeadc9a79 GIT binary patch literal 7321 zcmeHLO=w+36rS&$Om1#pZ*E@F*U+@Du?g`t#;8SX2q8t0*hu{WDHhR+$--YstKuJ3 zRIHnJ<3@$5v{*NS8*yQAE9lDZ3SDSX3oazM?xyIOxifd>-gn<$e(DdN_wJiB=Wpho zIp@sGi-#!g@Pqdts14lJhTo38UkmhOg#^w(^lsjXqf(rH<%V{ODL)P*9v+8`0&JQT z+$4Z&I|N>e5&~WrFdVFm8PcU4Rv1^MMU8Ts25*(SQz)>9#kJeeW^qqX+sWX8&2420 z=IE2~MgLk&ICD7B+odu5wn}&5f{6h)dN&vbyPau(kyVd~-8N3UnPVc0ORLw_7I5Mn zmF`%mh@;}WABE@`|aaquZosSrh#E&*F)Qc?C-XR#L|o(2pTErm2|dNQ4213eJ`Uwm{UeSW5iG5_7{r=0j6VoFP(FAGcCPw7jg6Ib|k7D6ILee1kyK|X^;HFt!30yy45kfx5vHpb4yK95RZ@eN8#SG5;}yIt!^Ec| zx>udd$!yE@*U*(1AbtH0} zhU($a3`g~z>X~0Z^!}`=1Gf91Ma=8(vVFQe#fZi|+(Yquc3V@U#rF8_P*bjAi5vIIVfXy7AWSD-J0g>}jK#2Litv^Y5;JFF3AnZy=w zc|7$bmp}Z1mqMPWe`@qn0%ze)!keSf#{ zm0ZVQ-X~^%6(0&Jgx$}nQ}JBj4W8Q9mrA=src_4k+%2t0+48Pei)D3wKre5)|AgtR z%WI?GosX136J8zLF1nVmvP{-5;Ifg~@YJrp;Ed;D0;Tr1L#OOxGSUJ3h=wJfzIH)Cfp8~sN^Tw z(Dy7$ESK~@EE)HA*4buWj{i5Q;R%R*F4|!vFD_qIT7q{?Nz_KSUq=|)3vw)^VU;Mn^7_fS6gTl-WD2b3H?qx*-EOGR!l5!%bGrYLZrG4$iV*E-gr&oW zak)pRBb-{R^uc3W)dCI|EMR~qWhTS$O-aNQV3}0&ZO;D-&3*cYFN&Khe)+(Nt!chc z25)u(FejmmEN*Ks$MedF6n9w0h$WcS;XgM$c$1GxhcbYxqk;>g{Xm$6NW768L+RaQ zufd49JGd*OvyE3vBAjfVyewI`+6hqx80_=?>I`>=oogzFQqkVjRJ?&9>mNB9Zh_dI syIDJKf?3z=o{6emEgge>5aU`LJ4sYKhP^noLb&lH;mB7J?*0^i0T`S27XSbN literal 0 HcmV?d00001 diff --git a/src/irq_interrupt.rs b/src/irq_interrupt.rs index 27b2af8..6d1277f 100644 --- a/src/irq_interrupt.rs +++ b/src/irq_interrupt.rs @@ -3,7 +3,10 @@ use core::{ sync::atomic::{compiler_fence, Ordering}, }; -use crate::{mmio_read, mmio_write, peripherals::uart::print}; +use crate::{ + mmio_read, mmio_write, + peripherals::{gpio::blink_gpio, uart::print}, +}; const INTERRUPT_BASE: u32 = 0x3F00_B000; const IRQ_PENDING_BASE: u32 = INTERRUPT_BASE + 0x204; @@ -35,7 +38,18 @@ unsafe extern "C" fn irq_handler() { handle_gpio_interrupt(); } +#[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"); + } +} + fn handle_gpio_interrupt() { + print("Interrupt\r\n"); for i in 0..=53u32 { let val = read_gpio_event_detect_status(i); diff --git a/src/mailbox.rs b/src/mailbox.rs index cac50fa..5df8a89 100644 --- a/src/mailbox.rs +++ b/src/mailbox.rs @@ -1,26 +1,33 @@ -use crate::{mmio_read, mmio_write}; +use core::ptr::read_volatile; -const MBOX_BASE: u32 = 0x3F00_B880; +use crate::{ + mmio_read, mmio_write, + peripherals::uart::{print, print_u32}, +}; + +const MBOX_BASE: u32 = 0x3F00_0000 + 0xB880; // MB0 const MBOX_READ: u32 = MBOX_BASE + 0x00; -const MBOX_READ_STATUS: u32 = MBOX_BASE + 0x18; +const MBOX_STATUS: u32 = MBOX_BASE + 0x18; // MB1 const MBOX_WRITE: u32 = MBOX_BASE + 0x20; -const MBOX_WRITE_STATUS: u32 = MBOX_BASE + 0x38; // Status const MAIL_FULL: u32 = 0x80000000; const MAIL_EMPTY: u32 = 0x40000000; -#[repr(align(16))] +#[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 { - while (mmio_read(MBOX_READ_STATUS) & MAIL_EMPTY != 0) {} + while mmio_read(MBOX_STATUS) & MAIL_EMPTY != 0 {} let mut data = mmio_read(MBOX_READ); let read_channel = data & 0xF; @@ -33,25 +40,35 @@ pub fn read_mailbox(channel: u32) -> u32 { } pub fn write_mailbox(channel: u32, data: u32) { - while (mmio_read(MBOX_WRITE_STATUS) & MAIL_FULL != 0) {} - mmio_write(MBOX_WRITE, data << 4 | (channel & 0xF)); + while mmio_read(MBOX_STATUS) & MAIL_FULL != 0 {} + mmio_write(MBOX_WRITE, (data & !0xF) | (channel & 0xF)); } pub fn read_soc_temp() -> u32 { - let mut mbox = MailboxBuffer([0; 36]); + 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 - mbox.0[0] = 8 * 4; // Total size in bytes - mbox.0[1] = 0; // Request - mbox.0[2] = 0x00030006; // Tag: Get temperature - mbox.0[3] = 8; // Value buffer size (bytes) - mbox.0[4] = 4; // Request size (bytes) - mbox.0[5] = 0; // Temp ID: 0 = SoC - mbox.0[6] = 0; // Response will be written here - mbox.0[7] = 0; // End tag + print("Reading address\r\n"); + //let addr = core::ptr::addr_of!(MBOX.0[0]); - let addr = &mbox.0 as *const u32 as u32; - write_mailbox(8, addr); - let _ = read_mailbox(8); - let raw_temp = mbox.0[6]; - raw_temp / 1000 + print("Write address\r\n"); + + // write_mailbox(8, addr); + + let _ = read_mailbox(8); + + if MBOX.0[1] == 0 { + print("Failed\r\n"); + } + let raw_temp = MBOX.0[5]; + raw_temp + } } diff --git a/src/main.rs b/src/main.rs index a5d19ad..69d9316 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use core::{ arch::{asm, global_asm}, panic::PanicInfo, + ptr::write_volatile, }; use nova::{ @@ -12,18 +13,19 @@ use nova::{ mailbox::read_soc_temp, peripherals::{ gpio::{ - gpio_get_state, gpio_high, gpio_low, gpio_pull_up, set_falling_edge_detect, - set_gpio_function, GPIOFunction, + blink_gpio, gpio_pull_up, set_falling_edge_detect, set_gpio_function, GPIOFunction, }, - uart::{print, uart_init}, + uart::{print, print_u32, uart_init}, }, - timer::{delay_nops, sleep_ms, sleep_us}, + timer::{delay_nops, sleep_us}, }; global_asm!(include_str!("vector.S")); extern "C" { fn el2_to_el1(); + static mut __bss_start: u32; + static mut __bss_end: u32; } #[panic_handler] @@ -47,6 +49,9 @@ pub unsafe extern "C" fn _start() { #[no_mangle] pub extern "C" fn main() -> ! { + unsafe { + zero_bss(); + } enable_uart(); // Set ACT Led to Outout @@ -59,14 +64,24 @@ pub extern "C" fn main() -> ! { print("Hello World!\r\n"); unsafe { + asm!("mrs x0, SCTLR_EL1"); el2_to_el1(); } loop {} } +unsafe fn zero_bss() { + let mut bss: *mut u32 = &raw mut __bss_start as *mut u32; + while bss < &raw mut __bss_end as *mut u32 { + write_volatile(bss, 0); + bss = bss.add(1); + } +} + #[no_mangle] pub extern "C" fn kernel_main() -> ! { + print("AAA\r\n"); print_current_el_str(); sleep_us(500_000); @@ -78,38 +93,13 @@ pub extern "C" fn kernel_main() -> ! { set_falling_edge_detect(26, true); loop { - //let temp = read_soc_temp(); - //u32_to_ascii(temp as u8); + let temp = read_soc_temp(); + print_u32(temp); - let _ = gpio_high(29); - - sleep_ms(500); // 0.5s - let _ = gpio_low(29); - sleep_ms(500); // 0.5s - print_gpio_state(); + blink_gpio(29, 500); } } -fn print_gpio_state() { - let state = gpio_get_state(26); - - let ascii_byte = b'0' + state; - let data = [ascii_byte]; - - let s = str::from_utf8(&data).unwrap(); - print(s); - print("\r\n"); -} - -fn u32_to_ascii(val: u8) { - let ascii_byte = b'0' + val; - let data = [ascii_byte]; - - let s = str::from_utf8(&data).unwrap(); - print(s); - print("C\r\n"); -} - pub fn get_current_el() -> u64 { let el: u64; unsafe { diff --git a/src/peripherals/gpio.rs b/src/peripherals/gpio.rs index c283148..5e39716 100644 --- a/src/peripherals/gpio.rs +++ b/src/peripherals/gpio.rs @@ -1,7 +1,7 @@ use core::result::Result; use core::result::Result::Ok; -use crate::timer::delay_nops; +use crate::timer::{delay_nops, sleep_ms}; use crate::{mmio_read, mmio_write}; const GPFSEL_BASE: u32 = 0x3F20_0000; @@ -164,3 +164,11 @@ pub fn set_rising_edge_detect(gpio: u8, enable: bool) { mmio_write(register_addr, new_val); } + +pub fn blink_gpio(gpio: u8, duration_ms: u32) { + let _ = gpio_high(gpio); + + sleep_ms(duration_ms); + let _ = gpio_low(gpio); + sleep_ms(duration_ms); +} diff --git a/src/peripherals/uart.rs b/src/peripherals/uart.rs index 1ad0fd2..3fda269 100644 --- a/src/peripherals/uart.rs +++ b/src/peripherals/uart.rs @@ -1,3 +1,5 @@ +use core::{arch::asm, fmt}; + use crate::{mmio_read, mmio_write}; const BAUD: u32 = 115200; @@ -21,11 +23,34 @@ const UART0_LCRH_FEN: u32 = 1 << 4; /// Print `s` over UART pub fn print(s: &str) { for byte in s.bytes() { - while mmio_read(UART0_FR) & UART0_FR_TXFF != 0 {} + while (mmio_read(UART0_FR) & UART0_FR_TXFF) != 0 { + unsafe { asm!("nop") } + } mmio_write(UART0_DR, byte as u32); } // wait till uart is not busy anymore - while (mmio_read(UART0_FR) >> 3) & 0b1 != 0 {} + while ((mmio_read(UART0_FR) >> 3) & 0b1) != 0 {} +} + +pub fn print_u32(mut val: u32) { + let mut values = [0u32; 10]; + for c in &mut values { + if val == 0 { + break; + } + + *c = val % 10; + val /= 10; + } + + for c in values.iter().rev() { + let ascii_byte = b'0' + *c as u8; + let data = [ascii_byte]; + + let s = str::from_utf8(&data).unwrap(); + print(s); + } + print("\r\n"); } /// Initialize UART peripheral diff --git a/src/vector.S b/src/vector.S index 1e125a6..d8562db 100644 --- a/src/vector.S +++ b/src/vector.S @@ -14,8 +14,8 @@ vector_table: ventry . ventry . - ventry . - ventry irq_handler // IRQ(Interrupt Request) 0x280 + ventry synchronous_interrupt // Synchronous Exception 0x200 + ventry irq_handler // IRQ(Interrupt Request) 0x280 ventry . ventry . @@ -44,6 +44,11 @@ el2_to_el1: adr x0, vector_table msr VBAR_EL1, x0 + // Disable MMU + mrs x0, sctlr_el1 + bic x0, x0, #1 + msr sctlr_el1, x0 + isb // Return to EL1 diff --git a/tools/start_simulator_debug.sh b/tools/start_simulator_debug.sh index 5c75ea3..17e9660 100755 --- a/tools/start_simulator_debug.sh +++ b/tools/start_simulator_debug.sh @@ -10,4 +10,5 @@ qemu-system-aarch64 \ -serial stdio \ -sd ../sd.img \ -display none \ - -kernel ../target/aarch64-unknown-none/debug/kernel8.img + -kernel ../target/aarch64-unknown-none/debug/kernel8.img \ + -s -S From fbc2fcff729b4d2c0579d0edd1ef51d09321b95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Neuh=C3=A4user?= Date: Fri, 18 Jul 2025 14:41:19 +0200 Subject: [PATCH 3/4] Read SoC temp via mailboxes --- .gitignore | 1 + .vscode/settings.json | 6 ------ link.ld | 3 +-- src/configuration.rs | 15 +++++++++++++ src/irq_interrupt.rs | 36 +++++++++++++++++++++++++++---- src/lib.rs | 1 + src/mailbox.rs | 48 +++++++++++++++-------------------------- src/main.rs | 4 ++-- src/peripherals/gpio.rs | 5 +++++ src/peripherals/uart.rs | 13 ++++++++--- src/vector.S | 10 ++++++--- 11 files changed, 91 insertions(+), 51 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 src/configuration.rs 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 From 863f6000b0cc02047397752bf675e25eac2c3846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Neuh=C3=A4user?= Date: Fri, 18 Jul 2025 14:54:22 +0200 Subject: [PATCH 4/4] Remove unused import --- src/mailbox.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mailbox.rs b/src/mailbox.rs index 2317d2e..3f94599 100644 --- a/src/mailbox.rs +++ b/src/mailbox.rs @@ -1,5 +1,3 @@ -use core::ptr::read_volatile; - use crate::{mmio_read, mmio_write, peripherals::uart::print}; const MBOX_BASE: u32 = 0x3F00_0000 + 0xB880;