sel4_runtime_common/start/
mod.rs

1//
2// Copyright 2025, Colias Group, LLC
3//
4// SPDX-License-Identifier: BSD-2-Clause
5//
6
7use core::arch::global_asm;
8
9use cfg_if::cfg_if;
10
11mod with_stack_init;
12
13#[macro_export]
14macro_rules! declare_entrypoint {
15    {
16        $f:ident($( $i:ident: $t:ty ),* $(,)?)
17     } => {
18        $crate::declare_entrypoint! {
19            $f($($i: $t,)*)
20            global_init if true
21        }
22    };
23    {
24        $f:ident($( $i:ident: $t:ty ),* $(,)?)
25        global_init if $global_init_cond:expr
26     } => {
27        const _: () = {
28            #[unsafe(no_mangle)]
29            unsafe extern "C" fn __sel4_runtime_common__rust_entrypoint($($i: $t,)*) -> ! {
30                $crate::_private::_run_entrypoint($global_init_cond, || {
31                    $f($($i,)*)
32                });
33            }
34        };
35
36        // TODO make this much prettier once #[feature(asm_cfg)] stabilizes
37        $crate::_private::cfg_if! {
38            if #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] {
39                $crate::_private::global_asm! {
40                    r#"
41                        .extern __sel4_runtime_common__call_rust_entrypoint
42
43                        .section .text
44
45                        .global _start
46                        _start:
47                            b __sel4_runtime_common__call_rust_entrypoint
48                    "#
49                }
50            } else if #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] {
51                $crate::_private::global_asm! {
52                    r#"
53                        .extern __sel4_runtime_common__call_rust_entrypoint
54
55                        .section .text
56
57                        .global _start
58                        _start:
59                            j __sel4_runtime_common__call_rust_entrypoint
60                    "#
61                }
62            } else if #[cfg(target_arch = "x86_64")] {
63                $crate::_private::global_asm! {
64                    r#"
65                        .extern __sel4_runtime_common__call_rust_entrypoint
66
67                        .section .text
68
69                        .global _start
70                        _start:
71                            jmp __sel4_runtime_common__call_rust_entrypoint
72                    "#
73                }
74            } else {
75                compile_error!("unsupported architecture");
76            }
77        }
78    };
79}
80
81macro_rules! common_asm_prefix {
82    () => {
83        r#"
84            .extern __sel4_runtime_common__rust_entrypoint
85
86            .section .text.__sel4_runtime_common__call_rust_entrypoint, "ax", %progbits
87
88            .global __sel4_runtime_common__call_rust_entrypoint
89            __sel4_runtime_common__call_rust_entrypoint:
90        "#
91    };
92}
93
94cfg_if! {
95    if #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] {
96        global_asm! {
97            common_asm_prefix!(),
98            r#"
99                    bl __sel4_runtime_common__rust_entrypoint
100                1:  b 1b
101            "#
102        }
103    } else if #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] {
104        global_asm! {
105            common_asm_prefix!(),
106            r#"
107                .option push
108                .option norelax
109                1:  auipc gp, %pcrel_hi(__global_pointer$)
110                    addi gp, gp, %pcrel_lo(1b)
111                .option pop
112                    jal __sel4_runtime_common__rust_entrypoint
113                1:  j 1b
114            "#
115        }
116    } else if #[cfg(target_arch = "x86_64")] {
117        global_asm! {
118            common_asm_prefix!(),
119            r#"
120                    call __sel4_runtime_common__rust_entrypoint
121                1:  jmp 1b
122            "#
123        }
124    } else {
125        compile_error!("unsupported architecture");
126    }
127}