aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/_arch/arm/asm.rs35
-rw-r--r--src/bsp/raspberrypi/linker.ld6
-rw-r--r--src/cpu.rs2
-rw-r--r--src/kernel.rs1
-rw-r--r--src/uart.rs56
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);
}