sel4_runtime_common/
lib.rs1#![no_std]
8#![feature(cfg_target_thread_local)]
9#![feature(never_type)]
10#![feature(core_intrinsics)]
11#![feature(linkage)]
12#![allow(internal_features)]
13
14use core::sync::atomic::{AtomicBool, Ordering};
15
16use sel4_elf_header::{ElfHeader, ProgramHeader};
17use sel4_panicking_env::abort;
18
19mod abort;
20mod start;
21
22#[cfg(target_thread_local)]
23mod tls;
24
25#[cfg(panic = "unwind")]
26mod unwinding;
27
28#[cfg(not(any(
29 target_arch = "aarch64",
30 target_arch = "arm",
31 target_arch = "riscv64",
32 target_arch = "riscv32",
33 target_arch = "x86_64",
34)))]
35compile_error!("unsupported architecture");
36
37#[allow(clippy::missing_safety_doc)]
38pub unsafe fn with_local_init(f: impl FnOnce() -> !) -> ! {
39 cfg_if::cfg_if! {
40 if #[cfg(target_thread_local)] {
41 unsafe {
42 tls::with_tls(f)
43 }
44 } else {
45 f()
46 }
47 }
48}
49
50static GLOBAL_INIT_COMPLETE: AtomicBool = AtomicBool::new(false);
51
52unsafe fn global_init() {
53 #[cfg(panic = "unwind")]
54 {
55 unwinding::init_unwinding();
56 }
57
58 sel4_ctors_dtors::run_ctors().unwrap_or_else(|err| abort!("{err}"));
59
60 GLOBAL_INIT_COMPLETE.swap(true, Ordering::Release);
61}
62
63pub fn global_init_complete() -> bool {
64 GLOBAL_INIT_COMPLETE.load(Ordering::Acquire)
65}
66
67#[allow(dead_code)]
68fn locate_phdrs() -> &'static [ProgramHeader] {
69 unsafe extern "C" {
70 static __ehdr_start: ElfHeader;
71 }
72 unsafe {
73 if !__ehdr_start.is_magic_valid() {
74 abort!("ELF header magic mismatch")
75 }
76 __ehdr_start.locate_phdrs()
77 }
78}
79
80#[cfg(target_arch = "arm")]
81#[linkage = "weak"]
82#[unsafe(no_mangle)]
83extern "C" fn __aeabi_read_tp() -> usize {
84 let mut val: usize;
85 unsafe {
86 core::arch::asm!("mrc p15, 0, {val}, c13, c0, 2", val = out(reg) val); }
88 val
89}
90
91#[doc(hidden)]
92#[allow(unreachable_code)]
93pub unsafe fn _run_entrypoint(global_init_cond: bool, f: impl FnOnce() -> !) -> ! {
94 unsafe {
95 with_local_init(|| {
96 if global_init_cond {
97 global_init();
98 }
99 f()
100 });
101 }
102}
103
104#[doc(hidden)]
105pub mod _private {
106 pub use super::_run_entrypoint;
107 pub use cfg_if::cfg_if;
108 pub use core::arch::global_asm;
109 pub use sel4_stack::{Stack, StackBottom};
110}