diff options
| -rw-r--r-- | src/_arch/arm/asm.rs | 35 | ||||
| -rw-r--r-- | src/bsp/raspberrypi/linker.ld | 6 | ||||
| -rw-r--r-- | src/cpu.rs | 2 | ||||
| -rw-r--r-- | src/kernel.rs | 1 | ||||
| -rw-r--r-- | 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.*); +	}  } @@ -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);  } | 
