sel4_runtime_common/start/
with_stack_init.rs

1//
2// Copyright 2023, 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
11#[macro_export]
12macro_rules! declare_stack {
13    ($size:expr) => {
14        const _: () = {
15            #[allow(non_upper_case_globals)]
16            #[unsafe(no_mangle)]
17            static __sel4_runtime_common__stack_bottom: $crate::_private::StackBottom = {
18                static STACK: $crate::_private::Stack<{ $size }> = $crate::_private::Stack::new();
19                STACK.bottom()
20            };
21        };
22    };
23}
24
25#[macro_export]
26macro_rules! declare_entrypoint_with_stack_init {
27    ($f:ident($( $i:ident: $t:ty ),* $(,)?)) => {
28        const _: () = {
29            #[unsafe(no_mangle)]
30            unsafe extern "C" fn __sel4_runtime_common__rust_entrypoint($($i: $t,)*) -> ! {
31                $crate::_private::_run_entrypoint(true, || {
32                    $f($($i,)*)
33                });
34            }
35        };
36
37        // TODO make this much prettier once #[feature(asm_cfg)] stabilizes
38        $crate::_private::cfg_if! {
39            if #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] {
40                $crate::_private::global_asm! {
41                    r#"
42                        .extern __sel4_runtime_common__stack_init
43
44                        .section .text
45
46                        .global _start
47                        _start:
48                            b __sel4_runtime_common__stack_init
49                    "#
50                }
51            } else if #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] {
52                $crate::_private::global_asm! {
53                    r#"
54                        .extern __sel4_runtime_common__stack_init
55
56                        .section .text
57
58                        .global _start
59                        _start:
60                            j __sel4_runtime_common__stack_init
61                    "#
62                }
63            } else if #[cfg(target_arch = "x86_64")] {
64                $crate::_private::global_asm! {
65                    r#"
66                        .extern __sel4_runtime_common__stack_init
67
68                        .section .text
69
70                        .global _start
71                        _start:
72                            jmp __sel4_runtime_common__stack_init
73                    "#
74                }
75            } else {
76                compile_error!("unsupported architecture");
77            }
78        }
79    };
80}
81
82macro_rules! common_asm_prefix {
83    () => {
84        r#"
85            .extern __sel4_runtime_common__stack_bottom
86            .extern __sel4_runtime_common__call_rust_entrypoint
87
88            .section .text.__sel4_runtime_common__stack_init, "ax", %progbits
89
90            .global __sel4_runtime_common__stack_init
91            __sel4_runtime_common__stack_init:
92        "#
93    };
94}
95
96cfg_if! {
97    if #[cfg(target_arch = "aarch64")] {
98        global_asm! {
99            common_asm_prefix!(),
100            r#"
101                    ldr x9, =__sel4_runtime_common__stack_bottom
102                    ldr x9, [x9]
103                    mov sp, x9
104                    b __sel4_runtime_common__rust_entrypoint
105            "#
106        }
107    } else if #[cfg(target_arch = "arm")] {
108        global_asm! {
109            common_asm_prefix!(),
110            r#"
111                    ldr r8, =__sel4_runtime_common__stack_bottom
112                    ldr r8, [r8]
113                    mov sp, r8
114                    b __sel4_runtime_common__rust_entrypoint
115            "#
116        }
117    } else if #[cfg(target_arch = "riscv64")] {
118        global_asm! {
119            common_asm_prefix!(),
120            r#"
121                    la sp, __sel4_runtime_common__stack_bottom
122                    ld sp, (sp)
123                    j __sel4_runtime_common__rust_entrypoint
124            "#
125        }
126    } else if #[cfg(target_arch = "riscv32")] {
127        global_asm! {
128            common_asm_prefix!(),
129            r#"
130                    la sp, __sel4_runtime_common__stack_bottom
131                    lw sp, (sp)
132                    j __sel4_runtime_common__rust_entrypoint
133            "#
134        }
135    } else if #[cfg(target_arch = "x86_64")] {
136        global_asm! {
137            common_asm_prefix!(),
138            r#"
139                    mov rsp, __sel4_runtime_common__stack_bottom
140                    mov rbp, rsp
141                    sub rsp, 0x8 // Stack must be 16-byte aligned before call
142                    push rbp
143                    call __sel4_runtime_common__rust_entrypoint
144                1:  jmp 1b
145            "#
146        }
147    } else {
148        compile_error!("unsupported architecture");
149    }
150}