diff options
| author | Christian Cunningham <cc@localhost> | 2022-08-17 22:14:15 -0700 | 
|---|---|---|
| committer | Christian Cunningham <cc@localhost> | 2022-08-17 22:14:15 -0700 | 
| commit | 91d0ae783e51062f77b120b05c97cd352b9b86d5 (patch) | |
| tree | 0270dfe976f91c11e62bb960420b366c08545d6f /src | |
Initial commit
Diffstat (limited to 'src')
| -rw-r--r-- | src/_arch/arm/asm.rs | 9 | ||||
| -rw-r--r-- | src/_arch/arm/cpu.rs | 10 | ||||
| -rw-r--r-- | src/_arch/arm/cpu/boot.rs | 12 | ||||
| -rw-r--r-- | src/_arch/arm/cpu/boot.s | 84 | ||||
| -rw-r--r-- | src/bsp/raspberrypi/linker.ld | 40 | ||||
| -rw-r--r-- | src/cpu.rs | 7 | ||||
| -rw-r--r-- | src/cpu/boot.rs | 3 | ||||
| -rw-r--r-- | src/main.rs | 29 | ||||
| -rw-r--r-- | src/panic_wait.rs | 9 | ||||
| -rw-r--r-- | src/uart.rs | 31 | 
10 files changed, 234 insertions, 0 deletions
| diff --git a/src/_arch/arm/asm.rs b/src/_arch/arm/asm.rs new file mode 100644 index 0000000..c400f2f --- /dev/null +++ b/src/_arch/arm/asm.rs @@ -0,0 +1,9 @@ +//! Wrapping ARMv7-A Instructions + +/// WFE +/// #[inline(always)] +pub fn wfe() { +    unsafe { +        core::arch::asm!("wfe", options(nomem, nostack)) +    } +} diff --git a/src/_arch/arm/cpu.rs b/src/_arch/arm/cpu.rs new file mode 100644 index 0000000..1ca6fab --- /dev/null +++ b/src/_arch/arm/cpu.rs @@ -0,0 +1,10 @@ +//! Architectural processor code. +mod asm; +pub use asm::*; + +/// Pause execution +pub fn wait_forever() -> ! { +    loop { +        asm::wfe() +    } +} diff --git a/src/_arch/arm/cpu/boot.rs b/src/_arch/arm/cpu/boot.rs new file mode 100644 index 0000000..9ea2330 --- /dev/null +++ b/src/_arch/arm/cpu/boot.rs @@ -0,0 +1,12 @@ +//! Architectural boot code +//!  # Boot code for ARM +//!  crate::cpu::boot::arch_boot + +use core::arch::global_asm; +global_asm!(include_str!("boot.s")); + +/// The Rust entry of the `kernel` binary. +#[no_mangle] +pub unsafe fn _start_rust() -> ! { +    crate::kernel_init() +} diff --git a/src/_arch/arm/cpu/boot.s b/src/_arch/arm/cpu/boot.s new file mode 100644 index 0000000..fd2a652 --- /dev/null +++ b/src/_arch/arm/cpu/boot.s @@ -0,0 +1,84 @@ +.equ _core_id_mask, 0b11 +.section .text.boot + +.global _start +_start: +reset: +	cpsid aif +	mrc p15, #0, r1, c0, c0, #5 +	and r1, r1, #_core_id_mask +	cmp r1, #1 +	beq core1run +	cmp r1, #2 +	beq core2run +	cmp r1, #3 +	beq core3run + +	ldr r0, =vector +	mcr p15, 0, r0, c12, c0, 0 +	cps #0x12 +	ldr sp, =core0_irq_stack +	cps #0x11 +	ldr sp, =core0_fiq_stack +	cps #0x1B +	ldr sp, =core0_undefined_stack +	cps #0x17 +	ldr sp, =core0_data_stack +	cps #0x1f +	ldr sp, =core0_sys_stack +	cps #0x13 +	ldr sp, =core0_svc_stack + +	ldr r4, =__bss_start +	ldr r9, =__bss_end +	mov r5, #0 +	mov r6, #0 +	mov r7, #0 +	mov r8, #0 +	b 2f +1: +	stmia r4!, {{r5-r8}} +2: +	cmp r4, r9 +	blo 1b + +	ldr r3, =_start_rust +	blx r3 + +core1run: +core2run: +core3run: +.global io_halt +undefined: +io_halt: +	wfi +	b io_halt + +.align 5 +vector: +	ldr pc, reset_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler +	ldr pc, undefined_handler + +reset_handler: .word reset +undefined_handler: .word undefined + +.section .bss.sysstacks +.align 4 +	.space 4096 +core0_undefined_stack: +	.space 4096 +core0_svc_stack: +	.space 4096 +core0_data_stack: +	.space 4096 +core0_irq_stack: +	.space 4096 +core0_fiq_stack: +	.space 4096 +core0_sys_stack: diff --git a/src/bsp/raspberrypi/linker.ld b/src/bsp/raspberrypi/linker.ld new file mode 100644 index 0000000..aa60bbb --- /dev/null +++ b/src/bsp/raspberrypi/linker.ld @@ -0,0 +1,40 @@ +ENTRY(_start) + +SECTIONS +{ +	. = 0x8000; +	__start = .; +	__text_start = .; +	.text : +	{ +		KEEP(*(.text.boot)) +		KEEP(*(.text.exceptions)) +		KEEP(*(.text.kernel)) +		*(.text*) +	} +	. = 0x208000; +	__text_end = .; + +	__data_start = .; +	.data : +	{ +		*(.data*) +		__stacks_start = .; +		KEEP(*(.data.stacks)) +	} +	. = ALIGN(4096); +	__data_end = .; + +	__bss_start = .; +	.bss : +	{ +		bss = .; +		. = ALIGN(4096); +		KEEP(*(.bss.sysstacks)) +		*(.bss) +		*(.bss*) +	} +	. = ALIGN(4096); +	__bss_end = .; +	__end = .; +} diff --git a/src/cpu.rs b/src/cpu.rs new file mode 100644 index 0000000..62fcf99 --- /dev/null +++ b/src/cpu.rs @@ -0,0 +1,7 @@ +//! Processor code. +#[cfg(target_arch = "arm")] +#[path = "_arch/arm/cpu.rs"] +mod arch_cpu; +pub use arch_cpu::{wait_forever}; + +mod boot; diff --git a/src/cpu/boot.rs b/src/cpu/boot.rs new file mode 100644 index 0000000..9ef25bd --- /dev/null +++ b/src/cpu/boot.rs @@ -0,0 +1,3 @@ +//! Boot code +#[path = "../_arch/arm/cpu/boot.rs"] +mod arch_boot; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9697ca8 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,29 @@ +//! Kernel Code + +#![allow(non_snake_case)] +#![allow(clippy::upper_case_acronyms,dead_code)] +#![feature(format_args_nl)] +#![feature(panic_info_message)] +#![feature(trait_alias)] +#![feature(exclusive_range_pattern)] +#![no_main] +#![no_std] + +mod cpu; +mod panic_wait; +mod uart; +use crate::uart::*; + +/// Initialization Code +unsafe fn kernel_init() -> ! { +    uart_init(); + +    kernel_main() +} + +fn kernel_main() -> ! { +    write_char(b'a'); +    write_char(b'b'); +    loop { +    } +} diff --git a/src/panic_wait.rs b/src/panic_wait.rs new file mode 100644 index 0000000..33097d8 --- /dev/null +++ b/src/panic_wait.rs @@ -0,0 +1,9 @@ +//! A panic handler that infinitely waits + +use core::panic::PanicInfo; + +/// Panic handler +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { +    unimplemented!() +} diff --git a/src/uart.rs b/src/uart.rs new file mode 100644 index 0000000..7c048e0 --- /dev/null +++ b/src/uart.rs @@ -0,0 +1,31 @@ +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); +} + +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; +    } +} | 
