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

Commit fc919a2

Browse files
bors[bot]jonas-schievinkadamgreig
authored
Merge #301
301: Initialize RAM in assembly r=adamgreig a=jonas-schievink Fixes #300 Co-authored-by: Jonas Schievink <[email protected]> Co-authored-by: Adam Greig <[email protected]>
2 parents 3a2ae35 + 599c58d commit fc919a2

14 files changed

+133
-163
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ autoexamples = true
1717
links = "cortex-m-rt" # Prevent multiple versions of cortex-m-rt being linked
1818

1919
[dependencies]
20-
r0 = "1.0"
2120
cortex-m-rt-macros = { path = "macros", version = "=0.6.11" }
2221
# Note: Do not depend on `cortex-m` here. This crate is used for testing `cortex-m`, so we need to
2322
# avoid pulling in multiple versions of `cortex-m`.

asm.S

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
.cfi_sections .debug_frame
2+
3+
# Notes for function attributes:
4+
# .type and .thumb_func are _both_ required, otherwise the Thumb mode bit
5+
# will not be set and an invalid vector table is generated.
6+
# LLD requires that section flags are set explicitly.
7+
8+
.section .HardFaultTrampoline, "ax"
9+
.global HardFaultTrampoline
10+
.type HardFaultTrampoline,%function
11+
.thumb_func
12+
.cfi_startproc
13+
# HardFault exceptions are bounced through this trampoline which grabs the
14+
# stack pointer at the time of the exception and passes it to the user's
15+
# HardFault handler in r0.
16+
HardFaultTrampoline:
17+
# Depending on the stack mode in EXC_RETURN, fetch stack pointer from
18+
# PSP or MSP.
19+
mov r0, lr
20+
mov r1, #4
21+
tst r0, r1
22+
bne 0f
23+
mrs r0, MSP
24+
b HardFault
25+
0:
26+
mrs r0, PSP
27+
b HardFault
28+
.cfi_endproc
29+
.size HardFaultTrampoline, . - HardFaultTrampoline
30+
31+
.section .Reset, "ax"
32+
.global Reset
33+
.type Reset,%function
34+
.thumb_func
35+
.cfi_startproc
36+
# Main entry point after reset. This jumps to the user __pre_init function,
37+
# which cannot be called from Rust code without invoking UB, then
38+
# initialises RAM. If the target has an FPU, it is enabled. Finally, jumps
39+
# to the user main function.
40+
Reset:
41+
# ARMv6-M does not initialise LR, but many tools expect it to be 0xFFFF_FFFF
42+
# when reaching the first call frame, so we set it at startup.
43+
# ARMv7-M and above initialise LR to 0xFFFF_FFFF at reset.
44+
ldr r4,=0xffffffff
45+
mov lr,r4
46+
47+
# Run user pre-init code, which must be executed immediately after startup,
48+
# before the potentially time-consuming memory initialisation takes place.
49+
# Example use cases include disabling default watchdogs or enabling RAM.
50+
bl __pre_init
51+
52+
# Restore LR after calling __pre_init (r4 is preserved by subroutines).
53+
mov lr,r4
54+
55+
# Initialise .bss memory. `__sbss` and `__ebss` come from the linker script.
56+
ldr r0,=__sbss
57+
ldr r1,=__ebss
58+
mov r2,#0
59+
0:
60+
cmp r1, r0
61+
beq 1f
62+
stm r0!, {r2}
63+
b 0b
64+
1:
65+
66+
# Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the
67+
# linker script. Copy from r2 into r0 until r0 reaches r1.
68+
ldr r0,=__sdata
69+
ldr r1,=__edata
70+
ldr r2,=__sidata
71+
2:
72+
cmp r1, r0
73+
beq 3f
74+
# load 1 word from r2 to r3, inc r2
75+
ldm r2!, {r3}
76+
# store 1 word from r3 to r0, inc r0
77+
stm r0!, {r3}
78+
b 2b
79+
3:
80+
81+
#ifdef HAS_FPU
82+
# Conditionally enable the FPU.
83+
# Address of SCB.CPACR.
84+
ldr r0, =0xE000ED88
85+
# Enable access to CP10 and CP11 from both privileged and unprivileged mode.
86+
ldr r1, =(0b1111 << 20)
87+
# RMW.
88+
ldr r2, [r0]
89+
orr r2, r2, r1
90+
str r2, [r0]
91+
# Barrier is required on some processors.
92+
dsb
93+
isb
94+
#endif
95+
96+
4:
97+
# Jump to user main function. We use bl for the extended range, but the
98+
# user main function may not return.
99+
bl main
100+
101+
# Trap on return.
102+
udf
103+
104+
.cfi_endproc
105+
.size Reset, . - Reset

asm.s

-67
This file was deleted.

assemble.sh

+9-5
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,25 @@ crate=cortex-m-rt
99
# remove existing blobs because otherwise this will append object files to the old blobs
1010
rm -f bin/*.a
1111

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

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

18-
arm-none-eabi-as -march=armv7e-m asm.s -o bin/$crate.o
18+
arm-none-eabi-gcc -c -march=armv7e-m asm.S -o bin/$crate.o
1919
ar crs bin/thumbv7em-none-eabi.a bin/$crate.o
20+
21+
arm-none-eabi-gcc -c -march=armv7e-m asm.S -DHAS_FPU -o bin/$crate.o
2022
ar crs bin/thumbv7em-none-eabihf.a bin/$crate.o
2123

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

25-
arm-none-eabi-as -march=armv8-m.main asm.s -o bin/$crate.o
27+
arm-none-eabi-gcc -c -march=armv8-m.main asm.S -o bin/$crate.o
2628
ar crs bin/thumbv8m.main-none-eabi.a bin/$crate.o
29+
30+
arm-none-eabi-gcc -c -march=armv8-m.main -DHAS_FPU asm.S -o bin/$crate.o
2731
ar crs bin/thumbv8m.main-none-eabihf.a bin/$crate.o
2832

2933
rm bin/$crate.o

bin/thumbv6m-none-eabi.a

128 Bytes
Binary file not shown.

bin/thumbv7em-none-eabi.a

164 Bytes
Binary file not shown.

bin/thumbv7em-none-eabihf.a

188 Bytes
Binary file not shown.

bin/thumbv7m-none-eabi.a

164 Bytes
Binary file not shown.

bin/thumbv8m.base-none-eabi.a

128 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabi.a

164 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabihf.a

188 Bytes
Binary file not shown.

build.rs

-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ fn main() {
1818

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

21-
has_fpu(&target);
22-
2321
if target.starts_with("thumbv") {
2422
fs::copy(
2523
format!("bin/{}.a", target),
@@ -92,9 +90,3 @@ handlers.");
9290
println!("cargo:rerun-if-changed=build.rs");
9391
println!("cargo:rerun-if-changed=link.x.in");
9492
}
95-
96-
fn has_fpu(target: &str) {
97-
if target.ends_with("eabihf") {
98-
println!("cargo:rustc-cfg=has_fpu");
99-
}
100-
}

link.x.in

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
INCLUDE memory.x
2424

2525
/* # Entry point = reset vector */
26+
EXTERN(__RESET_VECTOR);
27+
EXTERN(Reset);
2628
ENTRY(Reset);
27-
EXTERN(__RESET_VECTOR); /* depends on the `Reset` symbol */
2829

2930
/* # Exception vectors */
3031
/* This is effectively weak aliasing at the linker level */
@@ -85,13 +86,15 @@ SECTIONS
8586
/* ### .text */
8687
.text _stext :
8788
{
88-
/* place these 2 close to each other or the `b` instruction will fail to link */
89-
*(.PreResetTrampoline);
9089
*(.Reset);
9190

9291
*(.text .text.*);
92+
93+
/* The HardFaultTrampoline uses the `b` instruction to enter `HardFault`,
94+
so must be placed close to it. */
9395
*(.HardFaultTrampoline);
9496
*(.HardFault.*);
97+
9598
. = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */
9699
} > FLASH
97100
. = ALIGN(4); /* Ensure __etext is aligned if something unaligned is inserted after .text */

0 commit comments

Comments
 (0)