1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
//! FFI shim around the inline assembly in `inline.rs`.
//!
//! We use this file to precompile some assembly stubs into the static libraries you can find in
//! `bin`. Apps using the `cortex-m` crate then link against those static libraries and don't need
//! to build this file themselves.
//!
//! Nowadays the assembly stubs are no longer actual assembly files, but actually just this small
//! Rust crate that uses unstable inline assembly, coupled with the `xtask` tool to invoke rustc
//! and build the files.
//!
//! Precompiling this to a static lib allows users to call assembly routines from stable Rust, but
//! also perform [linker plugin LTO] with the precompiled artifacts to completely inline the
//! assembly routines into their code, which brings the "outline assembly" on par with "real" inline
//! assembly.
//!
//! For developers and contributors to `cortex-m`, this setup means that they don't have to install
//! any binutils, assembler, or C compiler to hack on the crate. All they need is to run `cargo
//! xtask assemble` to rebuild the archives from this file.
//!
//! Cool, right?
//!
//! # Rust version management
//!
//! Since inline assembly is still unstable, and we want to ensure that the created blobs are
//! up-to-date in CI, we have to pin the nightly version we use for this. The nightly toolchain is
//! stored in `asm-toolchain`.
//!
//! The `cargo xtask` automation will automatically install the `asm-toolchain` as well as all
//! Cortex-M targets needed to generate the blobs.
//!
//! [linker plugin LTO]: https://doc.rust-lang.org/stable/rustc/linker-plugin-lto.html
#![feature(asm)]
#![no_std]
#![crate_type = "staticlib"]
#![deny(warnings)]
mod inline;
macro_rules! shims {
(
$( fn $name:ident( $($arg:ident: $argty:ty),* ) $(-> $ret:ty)?; )+
) => {
$(
#[no_mangle]
pub unsafe extern "C" fn $name(
$($arg: $argty),*
) $(-> $ret)? {
crate::inline::$name($($arg)*)
}
)+
};
}
shims! {
fn __bkpt();
fn __control_r() -> u32;
fn __control_w(w: u32);
fn __cpsid();
fn __cpsie();
fn __delay(cyc: u32);
fn __dmb();
fn __isb();
fn __msp_r() -> u32;
fn __msp_w(val: u32);
fn __nop();
fn __primask_r() -> u32;
fn __psp_r() -> u32;
fn __psp_w(val: u32);
fn __sev();
fn __udf();
fn __wfe();
fn __wfi();
}
// v7m *AND* v8m.main, but *NOT* v8m.base
#[cfg(any(armv7m, armv8m_main))]
shims! {
fn __basepri_max(val: u8);
fn __basepri_r() -> u8;
fn __basepri_w(val: u8);
fn __faultmask_r() -> u32;
fn __enable_icache();
fn __enable_dcache();
}
#[cfg(armv7em)]
shims! {
fn __basepri_max_cm7_r0p1(val: u8);
fn __basepri_w_cm7_r0p1(val: u8);
}
// Baseline and Mainline.
#[cfg(armv8m)]
shims! {
fn __tt(target: u32) -> u32;
fn __ttt(target: u32) -> u32;
fn __tta(target: u32) -> u32;
fn __ttat(target: u32) -> u32;
}
// Mainline only.
#[cfg(armv8m_main)]
shims! {
fn __msplim_r() -> u32;
fn __msplim_w(val: u32);
fn __psplim_r() -> u32;
fn __psplim_w(val: u32);
}
// All targets with FPU.
#[cfg(has_fpu)]
shims! {
fn __fpscr_r() -> u32;
fn __fpscr_w(val: u32);
}
/// We *must* define a panic handler here, even though nothing here should ever be able to panic.
///
/// We prove that nothing will ever panic by calling a function that doesn't exist. If the panic
/// handler gets linked in, this causes a linker error. We always build this file with optimizations
/// enabled, but even without them the panic handler should never be linked in.
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
extern "C" {
#[link_name = "cortex-m internal error: panic handler not optimized out, please file an \
issue at https://github.com/rust-embedded/cortex-m"]
fn __cortex_m_should_not_panic() -> !;
}
unsafe {
__cortex_m_should_not_panic();
}
}
|