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

Commit 29e590b

Browse files
authored
Merge pull request #20 from japaric/fpu
enable the FPU before main if the target has an FPU
2 parents 032082d + f45f7d2 commit 29e590b

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ version = "0.3.0"
1313
r0 = "0.2.1"
1414

1515
[dependencies.cortex-m]
16-
optional = true
1716
version = "0.2.7"
1817

1918
[features]
2019
default = ["exceptions", "linker-script"]
2120
# service all exceptions using the default handler
22-
exceptions = ["cortex-m"]
21+
exceptions = []
2322
# generic linker script
2423
linker-script = []
2524
# provides a panic_fmt implementation that calls the abort instruction (`udf 0xfe`)
26-
abort-on-panic = []
25+
abort-on-panic = []

build.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::env;
2+
13
#[cfg(feature = "linker-script")]
24
mod imp {
35
use std::env;
@@ -6,6 +8,8 @@ mod imp {
68
use std::path::PathBuf;
79

810
pub fn main() {
11+
::has_fpu();
12+
913
// Put the linker script somewhere the linker can find it
1014
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
1115
File::create(out.join("link.x"))
@@ -21,7 +25,17 @@ mod imp {
2125

2226
#[cfg(not(feature = "linker-script"))]
2327
mod imp {
24-
pub fn main() {}
28+
pub fn main() {
29+
::has_fpu();
30+
}
31+
}
32+
33+
fn has_fpu() {
34+
let target = env::var("TARGET").unwrap();
35+
36+
if target.ends_with("eabihf") {
37+
println!("cargo:rustc-cfg=has_fpu");
38+
}
2539
}
2640

2741
fn main() {

src/lib.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@
155155
#![feature(used)]
156156
#![no_std]
157157

158-
#[cfg(feature = "exceptions")]
159158
extern crate cortex_m;
160159
extern crate compiler_builtins;
161160
extern crate r0;
@@ -189,9 +188,34 @@ unsafe extern "C" fn reset_handler() -> ! {
189188
r0::zero_bss(&mut _sbss, &mut _ebss);
190189
r0::init_data(&mut _sdata, &mut _edata, &_sidata);
191190

192-
// Neither `argc` or `argv` make sense in bare metal context so we just
193-
// stub them
194-
main(0, ::core::ptr::null());
191+
match () {
192+
#[cfg(not(has_fpu))]
193+
() => {
194+
// Neither `argc` or `argv` make sense in bare metal context so we just
195+
// stub them
196+
main(0, ::core::ptr::null());
197+
}
198+
#[cfg(has_fpu)]
199+
() => {
200+
// NOTE(safe) no exception / interrupt that also accesses the FPU
201+
// can occur here
202+
let scb = &*cortex_m::peripheral::SCB.get();
203+
scb.enable_fpu();
204+
205+
// Make sure the user main function never gets inlined into this
206+
// function as that may cause FPU related instructions like vpush to
207+
// be executed *before* enabling the FPU and that would generate an
208+
// exception
209+
#[inline(never)]
210+
fn main() {
211+
unsafe {
212+
::main(0, ::core::ptr::null());
213+
}
214+
}
215+
216+
main()
217+
}
218+
}
195219

196220
// If `main` returns, then we go into "reactive" mode and simply attend
197221
// interrupts as they occur.
@@ -210,6 +234,5 @@ static RESET_HANDLER: unsafe extern "C" fn() -> ! = reset_handler;
210234
#[cfg(feature = "exceptions")]
211235
#[link_section = ".rodata.exceptions"]
212236
#[used]
213-
static EXCEPTIONS: exception::Handlers = exception::Handlers {
214-
..exception::DEFAULT_HANDLERS
215-
};
237+
static EXCEPTIONS: exception::Handlers =
238+
exception::Handlers { ..exception::DEFAULT_HANDLERS };

0 commit comments

Comments
 (0)