Skip to content

Commit d53d096

Browse files
Merge #291
291: Avoid depending on `cortex-m` r=adamgreig a=jonas-schievink I'd like to use `cortex-m-rt` to write test executables for `cortex-m`. This would pull in multiple versions of `cortex-m` when c-m-rt depends on it, which does not work. Replace the Rust FPU trampoline with one written in asm to get rid of the cortex-m dependency. Co-authored-by: Jonas Schievink <[email protected]>
2 parents b9afdec + e9eae4d commit d53d096

11 files changed

+45
-33
lines changed

cortex-m-rt/.cargo/config

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
[target.thumbv6m-none-eabi]
2+
runner = "qemu-system-arm -cpu cortex-m0 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
3+
14
[target.thumbv7m-none-eabi]
2-
# uncomment this to make `cargo run` execute programs on QEMU
35
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
46

5-
[target.thumbv6m-none-eabi]
6-
# uncomment this to make `cargo run` execute programs on QEMU
7-
# For now, we use cortex-m3 instead of cortex-m0 which are not supported by QEMU
8-
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
7+
[target.thumbv7em-none-eabi]
8+
runner = "qemu-system-arm -cpu cortex-m4 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
9+
10+
[target.thumbv7em-none-eabihf]
11+
runner = "qemu-system-arm -cpu cortex-m4 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
912

1013
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
1114
# uncomment ONE of these three option to make `cargo run` start a GDB session
@@ -28,4 +31,4 @@ rustflags = [
2831
# "-C", "linker=arm-none-eabi-gcc",
2932
# "-C", "link-arg=-Wl,-Tlink.x",
3033
# "-C", "link-arg=-nostartfiles",
31-
]
34+
]

cortex-m-rt/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ links = "cortex-m-rt" # Prevent multiple versions of cortex-m-rt being linked
1919
[dependencies]
2020
r0 = "1.0"
2121
cortex-m-rt-macros = { path = "macros", version = "=0.6.11" }
22-
cortex-m = "0.6"
22+
# Note: Do not depend on `cortex-m` here. This crate is used for testing `cortex-m`, so we need to
23+
# avoid pulling in multiple versions of `cortex-m`.
2324

2425
[dev-dependencies]
26+
cortex-m = "0.6"
2527
panic-halt = "0.2.0"
2628
cortex-m-semihosting = "0.3"
2729

cortex-m-rt/asm.s

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,26 @@ HardFaultTrampoline:
1717
0:
1818
mrs r0, PSP
1919
b HardFault
20+
21+
.section .text.FpuTrampoline, "ax"
22+
.global FpuTrampoline
23+
# .type and .thumb_func are both required; otherwise its Thumb bit does not
24+
# get set and an invalid vector table is generated
25+
.type FpuTrampoline,%function
26+
.thumb_func
27+
# This enables the FPU and jumps to the main function.
28+
FpuTrampoline:
29+
# Address of SCB.CPACR.
30+
ldr r0, =0xE000ED88
31+
# Enable access to CP10 and CP11 from both privileged and unprivileged mode.
32+
ldr r1, =(0b1111 << 20)
33+
# RMW.
34+
ldr r2, [r0]
35+
orr r2, r2, r1
36+
str r2, [r0]
37+
# Barrier is required on some processors.
38+
dsb
39+
isb
40+
# Hand execution over to `main`.
41+
bl main
42+
# Note: `main` must not return. `bl` is used only because it has a wider range than `b`.

cortex-m-rt/bin/thumbv6m-none-eabi.a

278 Bytes
Binary file not shown.

cortex-m-rt/bin/thumbv7em-none-eabi.a

258 Bytes
Binary file not shown.
258 Bytes
Binary file not shown.

cortex-m-rt/bin/thumbv7m-none-eabi.a

258 Bytes
Binary file not shown.
278 Bytes
Binary file not shown.
258 Bytes
Binary file not shown.
258 Bytes
Binary file not shown.

cortex-m-rt/src/lib.rs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -937,9 +937,6 @@ pub unsafe extern "C" fn Reset() -> ! {
937937
static mut __sdata: u32;
938938
static mut __edata: u32;
939939
static __sidata: u32;
940-
941-
// This symbol will be provided by the user via `#[entry]`
942-
fn main() -> !;
943940
}
944941

945942
extern "Rust" {
@@ -956,33 +953,20 @@ pub unsafe extern "C" fn Reset() -> ! {
956953
#[allow(clippy::match_single_binding)]
957954
match () {
958955
#[cfg(not(has_fpu))]
959-
() => main(),
956+
() => {
957+
extern "C" {
958+
// This symbol will be provided by the user via `#[entry]`
959+
fn main() -> !;
960+
}
961+
main()
962+
}
960963
#[cfg(has_fpu)]
961964
() => {
962-
const SCB_CPACR: *mut u32 = 0xE000_ED88 as *mut u32;
963-
const SCB_CPACR_FPU_ENABLE: u32 = 0b01_01 << 20;
964-
const SCB_CPACR_FPU_USER: u32 = 0b10_10 << 20;
965-
966-
// enable the FPU
967-
core::ptr::write_volatile(
968-
SCB_CPACR,
969-
*SCB_CPACR | SCB_CPACR_FPU_ENABLE | SCB_CPACR_FPU_USER,
970-
);
971-
972-
cortex_m::asm::dsb();
973-
cortex_m::asm::isb();
974-
975-
// this is used to prevent the compiler from inlining the user `main` into the reset
976-
// handler. Inlining can cause the FPU instructions in the user `main` to be executed
977-
// before enabling the FPU, and that would produce a hard to diagnose hard fault at
978-
// runtime.
979-
#[inline(never)]
980-
#[export_name = "ResetTrampoline"]
981-
fn trampoline() -> ! {
982-
unsafe { main() }
965+
extern "C" {
966+
fn FpuTrampoline() -> !;
983967
}
984968

985-
trampoline()
969+
FpuTrampoline()
986970
}
987971
}
988972
}

0 commit comments

Comments
 (0)