1#![doc = document_features::document_features!()]
5#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
6#![allow(asm_sub_register, named_asm_labels)]
7#![feature(asm_experimental_arch)]
8#![no_std]
9
10use core::{
11 arch::asm,
12 ptr::{addr_of, addr_of_mut},
13};
14
15pub use macros::{entry, exception, interrupt, pre_init};
16pub use r0::{init_data, zero_bss};
17pub use xtensa_lx;
18
19pub mod exception;
20pub mod interrupt;
21
22#[doc(hidden)]
23#[unsafe(no_mangle)]
24pub unsafe extern "C" fn DefaultPreInit() {}
25
26#[doc(hidden)]
27#[unsafe(no_mangle)]
28pub unsafe extern "C" fn Reset() -> ! {
29 unsafe {
30 unsafe extern "C" {
32 static mut _bss_start: u32;
33 static mut _bss_end: u32;
34
35 static mut _data_start: u32;
36 static mut _data_end: u32;
37 static _sidata: u32;
38
39 static mut _init_start: u32;
40
41 }
42
43 unsafe extern "Rust" {
44 fn main() -> !;
46
47 fn __pre_init();
49
50 fn __post_init();
51
52 fn __zero_bss() -> bool;
53
54 fn __init_data() -> bool;
55 }
56
57 __pre_init();
58
59 if __zero_bss() {
60 r0::zero_bss(addr_of_mut!(_bss_start), addr_of_mut!(_bss_end));
61 }
62
63 if __init_data() {
64 r0::init_data(addr_of_mut!(_data_start), addr_of_mut!(_data_end), &_sidata);
65 }
66
67 reset_internal_timers();
72
73 set_vecbase(addr_of!(_init_start));
75
76 __post_init();
77
78 main();
79 }
80}
81
82#[doc(hidden)]
83#[unsafe(no_mangle)]
84#[rustfmt::skip]
85pub unsafe extern "Rust" fn default_post_init() {}
86
87#[doc(hidden)]
90#[inline]
91unsafe fn reset_internal_timers() {
92 unsafe {
93 #[cfg(any(
94 XCHAL_HAVE_TIMER0,
95 XCHAL_HAVE_TIMER1,
96 XCHAL_HAVE_TIMER2,
97 XCHAL_HAVE_TIMER3
98 ))]
99 {
100 let value = 0;
101 cfg_asm!(
102 {
103 #[cfg(XCHAL_HAVE_TIMER0)]
104 "wsr.ccompare0 {0}",
105 #[cfg(XCHAL_HAVE_TIMER1)]
106 "wsr.ccompare1 {0}",
107 #[cfg(XCHAL_HAVE_TIMER2)]
108 "wsr.ccompare2 {0}",
109 #[cfg(XCHAL_HAVE_TIMER3)]
110 "wsr.ccompare3 {0}",
111 "isync",
112 }, in(reg) value, options(nostack));
113 }
114 }
115}
116
117unsafe extern "C" {
119 #[cfg(XCHAL_HAVE_TIMER0)]
120 pub fn Timer0(save_frame: &mut crate::exception::Context);
121 #[cfg(XCHAL_HAVE_TIMER1)]
122 pub fn Timer1(save_frame: &mut crate::exception::Context);
123 #[cfg(XCHAL_HAVE_TIMER2)]
124 pub fn Timer2(save_frame: &mut crate::exception::Context);
125 #[cfg(XCHAL_HAVE_TIMER3)]
126 pub fn Timer3(save_frame: &mut crate::exception::Context);
127
128 #[cfg(XCHAL_HAVE_PROFILING)]
129 pub fn Profiling(save_frame: &mut crate::exception::Context);
130
131 #[cfg(XCHAL_HAVE_SOFTWARE0)]
132 pub fn Software0(save_frame: &mut crate::exception::Context);
133 #[cfg(XCHAL_HAVE_SOFTWARE1)]
134 pub fn Software1(save_frame: &mut crate::exception::Context);
135
136 #[cfg(XCHAL_HAVE_NMI)]
137 pub fn NMI(save_frame: &mut crate::exception::Context);
138}
139
140#[doc(hidden)]
141#[inline]
142unsafe fn set_vecbase(base: *const u32) {
143 unsafe {
144 asm!("wsr.vecbase {0}", in(reg) base, options(nostack));
145 }
146}
147
148#[doc(hidden)]
149#[unsafe(no_mangle)]
150#[rustfmt::skip]
151pub extern "Rust" fn default_mem_hook() -> bool {
152 true }
154
155#[doc(hidden)]
156#[macro_export]
157macro_rules! cfg_asm {
158 (@inner, [$($x:tt)*], [$($opts:tt)*], ) => {
159 asm!($($x)* $($opts)*)
160 };
161 (@inner, [$($x:tt)*], [$($opts:tt)*], #[cfg($meta:meta)] $asm:literal, $($rest:tt)*) => {
162 #[cfg($meta)]
163 cfg_asm!(@inner, [$($x)* $asm,], [$($opts)*], $($rest)*);
164 #[cfg(not($meta))]
165 cfg_asm!(@inner, [$($x)*], [$($opts)*], $($rest)*)
166 };
167 (@inner, [$($x:tt)*], [$($opts:tt)*], $asm:literal, $($rest:tt)*) => {
168 cfg_asm!(@inner, [$($x)* $asm,], [$($opts)*], $($rest)*)
169 };
170 ({$($asms:tt)*}, $($opts:tt)*) => {
171 cfg_asm!(@inner, [], [$($opts)*], $($asms)*)
172 };
173}
174
175#[doc(hidden)]
176#[macro_export]
177macro_rules! cfg_global_asm {
178 {@inner, [$($x:tt)*], } => {
179 global_asm!{$($x)*}
180 };
181 (@inner, [$($x:tt)*], #[cfg($meta:meta)] $asm:literal, $($rest:tt)*) => {
182 #[cfg($meta)]
183 cfg_global_asm!{@inner, [$($x)* $asm,], $($rest)*}
184 #[cfg(not($meta))]
185 cfg_global_asm!{@inner, [$($x)*], $($rest)*}
186 };
187 {@inner, [$($x:tt)*], $asm:literal, $($rest:tt)*} => {
188 cfg_global_asm!{@inner, [$($x)* $asm,], $($rest)*}
189 };
190 {$($asms:tt)*} => {
191 cfg_global_asm!{@inner, [], $($asms)*}
192 };
193}