Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Commit

Permalink
Merge #301
Browse files Browse the repository at this point in the history
301: Initialize RAM in assembly r=adamgreig a=jonas-schievink

Fixes #300 

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
Co-authored-by: Adam Greig <adam@adamgreig.com>
  • Loading branch information
3 people authored Jan 21, 2021
2 parents 3a2ae35 + 599c58d commit fc919a2
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 163 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ autoexamples = true
links = "cortex-m-rt" # Prevent multiple versions of cortex-m-rt being linked

[dependencies]
r0 = "1.0"
cortex-m-rt-macros = { path = "macros", version = "=0.6.11" }
# Note: Do not depend on `cortex-m` here. This crate is used for testing `cortex-m`, so we need to
# avoid pulling in multiple versions of `cortex-m`.
Expand Down
105 changes: 105 additions & 0 deletions asm.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
.cfi_sections .debug_frame

# Notes for function attributes:
# .type and .thumb_func are _both_ required, otherwise the Thumb mode bit
# will not be set and an invalid vector table is generated.
# LLD requires that section flags are set explicitly.

.section .HardFaultTrampoline, "ax"
.global HardFaultTrampoline
.type HardFaultTrampoline,%function
.thumb_func
.cfi_startproc
# HardFault exceptions are bounced through this trampoline which grabs the
# stack pointer at the time of the exception and passes it to the user's
# HardFault handler in r0.
HardFaultTrampoline:
# Depending on the stack mode in EXC_RETURN, fetch stack pointer from
# PSP or MSP.
mov r0, lr
mov r1, #4
tst r0, r1
bne 0f
mrs r0, MSP
b HardFault
0:
mrs r0, PSP
b HardFault
.cfi_endproc
.size HardFaultTrampoline, . - HardFaultTrampoline

.section .Reset, "ax"
.global Reset
.type Reset,%function
.thumb_func
.cfi_startproc
# Main entry point after reset. This jumps to the user __pre_init function,
# which cannot be called from Rust code without invoking UB, then
# initialises RAM. If the target has an FPU, it is enabled. Finally, jumps
# to the user main function.
Reset:
# ARMv6-M does not initialise LR, but many tools expect it to be 0xFFFF_FFFF
# when reaching the first call frame, so we set it at startup.
# ARMv7-M and above initialise LR to 0xFFFF_FFFF at reset.
ldr r4,=0xffffffff
mov lr,r4

# Run user pre-init code, which must be executed immediately after startup,
# before the potentially time-consuming memory initialisation takes place.
# Example use cases include disabling default watchdogs or enabling RAM.
bl __pre_init

# Restore LR after calling __pre_init (r4 is preserved by subroutines).
mov lr,r4

# Initialise .bss memory. `__sbss` and `__ebss` come from the linker script.
ldr r0,=__sbss
ldr r1,=__ebss
mov r2,#0
0:
cmp r1, r0
beq 1f
stm r0!, {r2}
b 0b
1:

# Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the
# linker script. Copy from r2 into r0 until r0 reaches r1.
ldr r0,=__sdata
ldr r1,=__edata
ldr r2,=__sidata
2:
cmp r1, r0
beq 3f
# load 1 word from r2 to r3, inc r2
ldm r2!, {r3}
# store 1 word from r3 to r0, inc r0
stm r0!, {r3}
b 2b
3:

#ifdef HAS_FPU
# Conditionally enable the FPU.
# Address of SCB.CPACR.
ldr r0, =0xE000ED88
# Enable access to CP10 and CP11 from both privileged and unprivileged mode.
ldr r1, =(0b1111 << 20)
# RMW.
ldr r2, [r0]
orr r2, r2, r1
str r2, [r0]
# Barrier is required on some processors.
dsb
isb
#endif

4:
# Jump to user main function. We use bl for the extended range, but the
# user main function may not return.
bl main

# Trap on return.
udf

.cfi_endproc
.size Reset, . - Reset
67 changes: 0 additions & 67 deletions asm.s

This file was deleted.

14 changes: 9 additions & 5 deletions assemble.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ crate=cortex-m-rt
# remove existing blobs because otherwise this will append object files to the old blobs
rm -f bin/*.a

arm-none-eabi-as -march=armv6s-m asm.s -o bin/$crate.o
arm-none-eabi-gcc -c -march=armv6s-m asm.S -o bin/$crate.o
ar crs bin/thumbv6m-none-eabi.a bin/$crate.o

arm-none-eabi-as -march=armv7-m asm.s -o bin/$crate.o
arm-none-eabi-gcc -c -march=armv7-m asm.S -o bin/$crate.o
ar crs bin/thumbv7m-none-eabi.a bin/$crate.o

arm-none-eabi-as -march=armv7e-m asm.s -o bin/$crate.o
arm-none-eabi-gcc -c -march=armv7e-m asm.S -o bin/$crate.o
ar crs bin/thumbv7em-none-eabi.a bin/$crate.o

arm-none-eabi-gcc -c -march=armv7e-m asm.S -DHAS_FPU -o bin/$crate.o
ar crs bin/thumbv7em-none-eabihf.a bin/$crate.o

arm-none-eabi-as -march=armv8-m.base asm.s -o bin/$crate.o
arm-none-eabi-gcc -c -march=armv8-m.base asm.S -o bin/$crate.o
ar crs bin/thumbv8m.base-none-eabi.a bin/$crate.o

arm-none-eabi-as -march=armv8-m.main asm.s -o bin/$crate.o
arm-none-eabi-gcc -c -march=armv8-m.main asm.S -o bin/$crate.o
ar crs bin/thumbv8m.main-none-eabi.a bin/$crate.o

arm-none-eabi-gcc -c -march=armv8-m.main -DHAS_FPU asm.S -o bin/$crate.o
ar crs bin/thumbv8m.main-none-eabihf.a bin/$crate.o

rm bin/$crate.o
Binary file modified bin/thumbv6m-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabihf.a
Binary file not shown.
Binary file modified bin/thumbv7m-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.base-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabihf.a
Binary file not shown.
8 changes: 0 additions & 8 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ fn main() {

let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

has_fpu(&target);

if target.starts_with("thumbv") {
fs::copy(
format!("bin/{}.a", target),
Expand Down Expand Up @@ -92,9 +90,3 @@ handlers.");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=link.x.in");
}

fn has_fpu(target: &str) {
if target.ends_with("eabihf") {
println!("cargo:rustc-cfg=has_fpu");
}
}
9 changes: 6 additions & 3 deletions link.x.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
INCLUDE memory.x

/* # Entry point = reset vector */
EXTERN(__RESET_VECTOR);
EXTERN(Reset);
ENTRY(Reset);
EXTERN(__RESET_VECTOR); /* depends on the `Reset` symbol */

/* # Exception vectors */
/* This is effectively weak aliasing at the linker level */
Expand Down Expand Up @@ -85,13 +86,15 @@ SECTIONS
/* ### .text */
.text _stext :
{
/* place these 2 close to each other or the `b` instruction will fail to link */
*(.PreResetTrampoline);
*(.Reset);

*(.text .text.*);

/* The HardFaultTrampoline uses the `b` instruction to enter `HardFault`,
so must be placed close to it. */
*(.HardFaultTrampoline);
*(.HardFault.*);

. = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */
} > FLASH
. = ALIGN(4); /* Ensure __etext is aligned if something unaligned is inserted after .text */
Expand Down
Loading

0 comments on commit fc919a2

Please sign in to comment.