aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-08-17 22:14:15 -0700
committerChristian Cunningham <cc@localhost>2022-08-17 22:14:15 -0700
commit91d0ae783e51062f77b120b05c97cd352b9b86d5 (patch)
tree0270dfe976f91c11e62bb960420b366c08545d6f
Initial commit
-rw-r--r--.gitignore2
-rw-r--r--Cargo.toml18
-rw-r--r--Makefile29
-rw-r--r--src/_arch/arm/asm.rs9
-rw-r--r--src/_arch/arm/cpu.rs10
-rw-r--r--src/_arch/arm/cpu/boot.rs12
-rw-r--r--src/_arch/arm/cpu/boot.s84
-rw-r--r--src/bsp/raspberrypi/linker.ld40
-rw-r--r--src/cpu.rs7
-rw-r--r--src/cpu/boot.rs3
-rw-r--r--src/main.rs29
-rw-r--r--src/panic_wait.rs9
-rw-r--r--src/uart.rs31
13 files changed, 283 insertions, 0 deletions
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 <c@localhost>" ]
+
+[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;
+ }
+}