From 6f1e6acb1a9775eef4b0d8879c102df86e207687 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Thu, 18 Aug 2022 18:21:13 -0700 Subject: Assembly stuff --- src/_arch/arm/asm.rs | 35 ++++++++++++++++++++++++++- src/bsp/raspberrypi/linker.ld | 6 +++++ src/cpu.rs | 2 +- src/kernel.rs | 1 - src/uart.rs | 56 ++++++++++++++++++++++--------------------- 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/src/_arch/arm/asm.rs b/src/_arch/arm/asm.rs index c400f2f..c1af5b4 100644 --- a/src/_arch/arm/asm.rs +++ b/src/_arch/arm/asm.rs @@ -1,9 +1,42 @@ //! Wrapping ARMv7-A Instructions /// WFE -/// #[inline(always)] +#[inline(always)] pub fn wfe() { unsafe { core::arch::asm!("wfe", options(nomem, nostack)) } } + +/// NOP +#[inline(always)] +pub fn nop() { + unsafe { + core::arch::asm!("nop", options(nomem, nostack)) + } +} + +/// Store u32 to address +#[inline] +pub fn store32(addr: u32, value: u32) { + unsafe { + *(addr as *mut u32) = value; + } +} + +/// Read u32 value from address +#[inline] +pub fn load32(addr: u32) -> u32 { + unsafe { + *(addr as *mut u32) + } +} + +/// Wait for n cycles +#[inline] +pub fn spin_for_n_cycles(n: u32) { + unsafe { + core::arch::asm!("1: subs r1, #1 + bne 1b", in("r1") n); + } +} diff --git a/src/bsp/raspberrypi/linker.ld b/src/bsp/raspberrypi/linker.ld index aa60bbb..93ee267 100644 --- a/src/bsp/raspberrypi/linker.ld +++ b/src/bsp/raspberrypi/linker.ld @@ -37,4 +37,10 @@ SECTIONS . = ALIGN(4096); __bss_end = .; __end = .; + + /DISCARD/ : + { + *(.ARM.exidx); + *(.ARM.extab.*); + } } diff --git a/src/cpu.rs b/src/cpu.rs index 62fcf99..9f003f8 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -2,6 +2,6 @@ #[cfg(target_arch = "arm")] #[path = "_arch/arm/cpu.rs"] mod arch_cpu; -pub use arch_cpu::{wait_forever}; +pub use arch_cpu::{nop,wait_forever,spin_for_n_cycles,load32,store32}; mod boot; diff --git a/src/kernel.rs b/src/kernel.rs index 9697ca8..a194b14 100644 --- a/src/kernel.rs +++ b/src/kernel.rs @@ -23,7 +23,6 @@ unsafe fn kernel_init() -> ! { fn kernel_main() -> ! { write_char(b'a'); - write_char(b'b'); loop { } } diff --git a/src/uart.rs b/src/uart.rs index 7c048e0..a26bb2f 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -1,31 +1,33 @@ -pub unsafe fn uart_init() { - let UART0_CR = 0x3F201030 as *mut u32; - let UART0_ICR = 0x3F201044 as *mut u32; - let UART0_IBRD = 0x3F201024 as *mut u32; - let UART0_FBRD = 0x3F201028 as *mut u32; - let UART0_LCRH = 0x3F20102C as *mut u32; - let UART0_IMSC = 0x3F201038 as *mut u32; - let GPPUD = 0x3F200094 as *mut u32; - let GPPUDCLK0 = 0x3F200098 as *mut u32; - *UART0_CR = 0; - *GPPUD = 0; - for _ in 0..150 {core::arch::asm!("nop", options(nomem, nostack));} - *GPPUDCLK0 = (1 << 14) | (1 << 15); - for _ in 0..150 {core::arch::asm!("nop", options(nomem, nostack));} - *GPPUDCLK0 = 0; - *UART0_ICR = 0x7FF; - *UART0_IBRD = 9; - *UART0_FBRD = 49; - *UART0_LCRH = (1<<4)|(1<<5)|(1<<6); - *UART0_IMSC = (1<<1)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10); - *UART0_CR = (1<<0) | (1<<8) | (1<<9); +use crate::cpu::*; +const UART0_DR: u32 = 0x3F201000; +const UART0_FR: u32 = 0x3F201018; +const UART0_CR: u32 = 0x3F201030; +const UART0_ICR: u32 = 0x3F201044; +const UART0_IBRD: u32 = 0x3F201024; +const UART0_FBRD: u32 = 0x3F201028; +const UART0_LCRH: u32 = 0x3F20102C; +const UART0_IMSC: u32 = 0x3F201038; +const GPPUD: u32 = 0x3F200094; +const GPPUDCLK0: u32 = 0x3F200098; + +pub fn uart_init() { + store32(UART0_CR, 0); + store32(GPPUD, 0); + spin_for_n_cycles(150); + store32(GPPUDCLK0, (1 << 14) | (1 << 15)); + spin_for_n_cycles(150); + store32(GPPUDCLK0, 0); + store32(UART0_ICR, 0x7FF); + store32(UART0_IBRD, 9); + store32(UART0_FBRD, 49); + store32(UART0_LCRH, (1<<4) | (1<<5) | (1<<6)); + store32(UART0_IMSC, (1<<1) | (1<<4) | (1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<9) | (1<<10)); + store32(UART0_CR, (1<<0) | (1<<8) | (1<<9)); } pub fn write_char(ch: u8) { - let UART0_DR = 0x3F201000 as *mut u32; - let UART0_FR = 0x3F201018 as *mut u32; - unsafe { - while *UART0_FR & 0x20 != 0 {core::arch::asm!("nop", options(nomem, nostack));} - *UART0_DR = ch as u32; - } + while load32(UART0_FR) & 0x20 != 0 { + nop(); + } + store32(UART0_DR, ch as u32); } -- cgit v1.2.1