sel4_reset/
lib.rs
1#![no_std]
8
9use core::arch::global_asm;
10use core::ptr;
11use core::slice;
12
13use cfg_if::cfg_if;
14
15use sel4_stack::{Stack, StackBottom};
16
17#[repr(C)]
20#[derive(Debug)]
21struct RegionMeta {
22 vaddr: usize,
23 offset: usize,
24 filesz: usize,
25 memsz: usize,
26}
27
28struct Regions<'a> {
29 meta: &'a [RegionMeta],
30 data: &'a [u8],
31}
32
33impl Regions<'_> {
34 unsafe fn reset_memory(&self) {
35 for meta in self.meta {
36 let dst = unsafe { slice::from_raw_parts_mut(meta.vaddr as *mut _, meta.memsz) };
37 let (dst_data, dst_zero) = dst.split_at_mut(meta.filesz);
38 let src_data = &self.data[meta.offset..][..meta.filesz];
39 dst_data.copy_from_slice(src_data);
40 ptr::write_bytes(dst_zero.as_mut_ptr(), 0, dst_zero.len());
41 }
42 }
43}
44
45const STACK_SIZE: usize = 4096;
48
49#[link_section = ".persistent"]
50static STACK: Stack<STACK_SIZE> = Stack::new();
51
52#[no_mangle]
53static __sel4_reset__stack_bottom: StackBottom = STACK.bottom();
54
55#[no_mangle]
58unsafe extern "C" fn __sel4_reset__reset_memory() {
59 unsafe {
60 get_regions().reset_memory();
61 }
62}
63
64unsafe fn get_regions() -> Regions<'static> {
65 Regions {
66 meta: slice::from_raw_parts(
67 (sel4_reset_regions_start + sel4_reset_regions_meta_offset) as *const _,
68 sel4_reset_regions_meta_count,
69 ),
70 data: slice::from_raw_parts(
71 (sel4_reset_regions_start + sel4_reset_regions_data_offset) as *const _,
72 sel4_reset_regions_data_size,
73 ),
74 }
75}
76
77macro_rules! rodata {
79 ($ident:ident) => {
80 extern "C" {
81 static $ident: usize;
82 }
83 global_asm! {
84 ".section .rodata",
85 concat!(".global ", stringify!($ident)),
86 concat!(stringify!($ident), ": ", asm_word_size!(), " 0"),
87 concat!(".size ", stringify!($ident), ", .-", stringify!($ident)),
88 }
89 };
90}
91
92cfg_if! {
93 if #[cfg(target_pointer_width = "64")] {
94 macro_rules! asm_word_size {
95 () => {
96 ".quad"
97 }
98 }
99 } else if #[cfg(target_pointer_width = "32")] {
100 macro_rules! asm_word_size {
101 () => {
102 ".word"
103 }
104 }
105 } else {
106 compile_error!("unsupported configuration");
107 }
108}
109
110rodata!(sel4_reset_regions_start);
111rodata!(sel4_reset_regions_meta_offset);
112rodata!(sel4_reset_regions_meta_count);
113rodata!(sel4_reset_regions_data_offset);
114rodata!(sel4_reset_regions_data_size);
115
116pub fn reset() -> ! {
119 unsafe {
120 _reset();
121 }
122 unreachable!()
123}
124
125extern "C" {
126 fn _reset();
127}
128
129macro_rules! common_asm_prefix {
130 () => {
131 r#"
132 .extern _start
133
134 .global _reset
135
136 .section .text
137
138 _reset:
139 "#
140 };
141}
142
143cfg_if::cfg_if! {
144 if #[cfg(target_arch = "aarch64")] {
145 global_asm! {
146 common_asm_prefix!(),
147 r#"
148 ldr x9, =__sel4_reset__stack_bottom
149 ldr x9, [x9]
150 mov sp, x9
151 bl __sel4_reset__reset_memory
152 b _start
153
154 1: b 1b
155 "#
156 }
157 } else {
158 compile_error!("unsupported architecture");
159 }
160}