From 91d0ae783e51062f77b120b05c97cd352b9b86d5 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Wed, 17 Aug 2022 22:14:15 -0700 Subject: Initial commit --- .gitignore | 2 ++ Cargo.toml | 18 ++++++++++ Makefile | 29 +++++++++++++++ src/_arch/arm/asm.rs | 9 +++++ src/_arch/arm/cpu.rs | 10 ++++++ src/_arch/arm/cpu/boot.rs | 12 +++++++ src/_arch/arm/cpu/boot.s | 84 +++++++++++++++++++++++++++++++++++++++++++ src/bsp/raspberrypi/linker.ld | 40 +++++++++++++++++++++ src/cpu.rs | 7 ++++ src/cpu/boot.rs | 3 ++ src/main.rs | 29 +++++++++++++++ src/panic_wait.rs | 9 +++++ src/uart.rs | 31 ++++++++++++++++ 13 files changed, 283 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 Makefile create mode 100644 src/_arch/arm/asm.rs create mode 100644 src/_arch/arm/cpu.rs create mode 100644 src/_arch/arm/cpu/boot.rs create mode 100644 src/_arch/arm/cpu/boot.s create mode 100644 src/bsp/raspberrypi/linker.ld create mode 100644 src/cpu.rs create mode 100644 src/cpu/boot.rs create mode 100644 src/main.rs create mode 100644 src/panic_wait.rs create mode 100644 src/uart.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c3afac7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "ghOSt" +version = "0.1.0" +edition = "2021" +authors = [ "Sergey Bilovytskyy " ] + +[profile.release] +lto = true + +[features] +default = [] +bsp_rpi2 = [] + +[[bin]] +name = "kernel" +path = "src/main.rs" + +[dependencies] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9beb347 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +BSP ?= rpi2 +DEBUG ?= 0 +AUTO ?= 0 +DEV_SERIAL ?= /dev/ttyUSB0 +TARGET=armv7a-none-eabi +QEMU_BINARY=qemu-system-arm +QEMU_MACHINE_TYPE=raspi2b +QEMU_RELEASE_ARGS=-cpu=cortex-a7 -m 1G -display none +OBJDUMP_BINARY=arm-none-eabi-objdump +NM_BINARY=arm-none-eabi-nm +READELF_BINARY=arm-none-eabi-readelf +LINKER_FILE=src/bsp/raspberrypi/linker.ld +RUSTC_MISC_ARGS=-C target-cpu=cortex-a7 +QEMU_RELEASE_ARGS=-chardev stdio,id=char0,mux=on,logfile=serial.log,signal=on -serial chardev:char0 -mon chardev=char0 +KERNEL_ELF=target/$(TARGET)/release/kernel +RUSTFLAGS=-C link-arg=-T$(LINKER_FILE) $(RUSTC_MISC_ARGS) +RUSTFLAGS_PEDANTIC=$(RUSTFLAGS) -D warnings -D missing_docs +FEATURES=--features bsp_$(BSP) +COMPILER_ARGS=--target=$(TARGET) $(FEATURES) --release +RUSTC_CMD=cargo rustc $(COMPILER_ARGS) +export LINKER_FILE + +.PHONY: build clean + +build: + @RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(RUSTC_CMD) + +clean: + rm -rf target 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; + } +} -- cgit v1.2.1