This commit is contained in:
Jeremy Soller 2016-08-25 17:03:01 -06:00
parent c2a95c96d5
commit 6715d5c534
29 changed files with 385 additions and 21 deletions

8
arch/arm/Cargo.toml Normal file
View file

@ -0,0 +1,8 @@
[package]
name = "arch_arm"
version = "0.1.0"
[dependencies]
bitflags = "*"
hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
spin = "*"

9
arch/arm/src/context.rs Normal file
View file

@ -0,0 +1,9 @@
#[derive(Debug)]
pub struct Context;
impl Context {
pub fn new() -> Self {
Context
}
}

70
arch/arm/src/externs.rs Normal file
View file

@ -0,0 +1,70 @@
/// Memcpy
///
/// Copy N bytes of memory from one location to another.
#[no_mangle]
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
n: usize) -> *mut u8 {
let mut i = 0;
while i < n {
*dest.offset(i as isize) = *src.offset(i as isize);
i += 1;
}
dest
}
/// Memmove
///
/// Copy N bytes of memory from src to dest. The memory areas may overlap.
#[no_mangle]
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
n: usize) -> *mut u8 {
if src < dest as *const u8 {
let mut i = n;
while i != 0 {
i -= 1;
*dest.offset(i as isize) = *src.offset(i as isize);
}
} else {
let mut i = 0;
while i < n {
*dest.offset(i as isize) = *src.offset(i as isize);
i += 1;
}
}
dest
}
/// Memset
///
/// Fill a block of memory with a specified value.
#[no_mangle]
pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
let mut i = 0;
while i < n {
*s.offset(i as isize) = c as u8;
i += 1;
}
s
}
/// Memcmp
///
/// Compare two blocks of memory.
#[no_mangle]
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
let mut i = 0;
while i < n {
let a = *s1.offset(i as isize);
let b = *s2.offset(i as isize);
if a != b {
return a as i32 - b as i32
}
i += 1;
}
0
}

30
arch/arm/src/interrupt.rs Normal file
View file

@ -0,0 +1,30 @@
//! Interrupt instructions
/// Clear interrupts
#[inline(always)]
pub unsafe fn disable() {
}
/// Set interrupts
#[inline(always)]
pub unsafe fn enable() {
}
/// Set interrupts and halt
#[inline(always)]
pub unsafe fn enable_and_halt() {
halt();
}
/// Halt instruction
#[inline(always)]
pub unsafe fn halt() {
//asm!("wfi" : : : : "volatile");
asm!("nop" : : : : "volatile");
}
/// Get a stack trace
//TODO: Check for stack being mapped before dereferencing
#[inline(never)]
pub unsafe fn stack_trace() {
}

39
arch/arm/src/lib.rs Normal file
View file

@ -0,0 +1,39 @@
//! Architecture support for ARM
#![feature(asm)]
#![feature(lang_items)]
#![feature(naked_functions)]
#![no_std]
extern crate hole_list_allocator as allocator;
#[macro_use]
extern crate bitflags;
extern crate spin;
/// Print to console
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ({});
}
/// Print with new line to console
#[macro_export]
macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
/// Context switching
pub mod context;
/// Memset, memcpy, etc.
pub mod externs;
/// Interrupt handling
pub mod interrupt;
/// Panic support
pub mod panic;
/// Initialization function
pub mod start;

60
arch/arm/src/linker.ld Normal file
View file

@ -0,0 +1,60 @@
ENTRY(kstart)
OUTPUT_ARCH(arm)
OUTPUT_FORMAT(elf32-littlearm)
KERNEL_OFFSET = 0;
SECTIONS {
. = KERNEL_OFFSET;
.text : AT(ADDR(.text) - KERNEL_OFFSET) {
__text_start = .;
*(.text*)
. = ALIGN(4096);
__text_end = .;
}
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
__rodata_start = .;
*(.rodata*)
. = ALIGN(4096);
__rodata_end = .;
}
.data : AT(ADDR(.data) - KERNEL_OFFSET) {
__data_start = .;
*(.data*)
. = ALIGN(4096);
__data_end = .;
}
.tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
__tdata_start = .;
*(.tdata*)
. = ALIGN(4096);
__tdata_end = .;
__tbss_start = .;
*(.tbss*)
. += 8;
. = ALIGN(4096);
__tbss_end = .;
}
.bss : AT(ADDR(.bss) - KERNEL_OFFSET) {
__bss_start = .;
*(.bss*)
. = ALIGN(4096);
__bss_end = .;
}
__end = .;
/DISCARD/ : {
*(.comment*)
*(.debug*)
*(.eh_frame*)
*(.gcc_except_table*)
*(.note*)
*(.rel.eh_frame*)
}
}

38
arch/arm/src/panic.rs Normal file
View file

@ -0,0 +1,38 @@
//! Intrinsics for panic handling
use interrupt;
#[cfg(not(test))]
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
#[cfg(not(test))]
/// Required to handle panics
#[lang = "panic_fmt"]
extern "C" fn panic_fmt(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
println!("PANIC: {}", fmt);
println!("FILE: {}", file);
println!("LINE: {}", line);
unsafe { interrupt::stack_trace(); }
println!("HALT");
loop {
unsafe { interrupt::halt(); }
}
}
#[allow(non_snake_case)]
#[no_mangle]
/// Required to handle panics
pub extern "C" fn _Unwind_Resume() -> ! {
loop {
unsafe { interrupt::halt(); }
}
}
/// Required for linker
#[no_mangle]
pub extern "C" fn __aeabi_unwind_cpp_pr0() {
loop {}
}

27
arch/arm/src/start.rs Normal file
View file

@ -0,0 +1,27 @@
const SERIAL_BASE: *mut u8 = 0x16000000 as *mut u8;
const SERIAL_FLAG_REGISTER: *const u8 = 0x16000018 as *const u8;
const SERIAL_BUFFER_FULL: u8 = (1 << 5);
unsafe fn putc (c: u8)
{
/* Wait until the serial buffer is empty */
while *SERIAL_FLAG_REGISTER & SERIAL_BUFFER_FULL == SERIAL_BUFFER_FULL {}
/* Put our character, c, into the serial buffer */
*SERIAL_BASE = c;
}
unsafe fn puts(string: &str)
{
for b in string.bytes() {
putc(b);
}
}
#[no_mangle]
#[naked]
pub unsafe extern fn kstart() -> ! {
asm!("mov sp, 0x18000" : : : : "volatile");
puts("TEST\r\n");
loop {}
}