polyhal/ctor.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
extern "Rust" {
/// The start symbol of the init section
pub fn __start_ph_init();
/// The stop symbol of the init section
pub fn __stop_ph_init();
}
/// Contructor Types
///
/// ## Executeion Flow:
///
/// ```plain
/// Primary Core:
/// Cpu -> Platform -> HALDriver -> (optional) Boot Other Core -> KernelService -> Normal -> jump to kernel
///
/// Secondary Core:
/// Cpu -> Waiting For Primary Core -> jump to kernel
/// ```
///
/// ## Note
///
/// If your kernel requires a specialized function, using [CtorType::Others] to manage it manually.
#[repr(u8)]
#[derive(PartialEq)]
pub enum CtorType {
/// Init function for the primary CPU, executed only once.
Primary,
/// CPU-related constructor, runs on all CPUs.
Cpu,
/// Platform-level constructor, executed only once on the primary CPU.
Platform,
/// HAL driver constructor (e.g., interrupt controller), executed only once on the primary CPU.
HALDriver,
/// Kernel service constructor, executed only once on the primary CPU.
KernelService,
/// General-purpose constructor, executed only once on the primary CPU.
Normal,
/// Custom constructor, not executed by HAL.
Others(u8),
}
/// PolyHAL's Initialize Wrapper
///
/// This struct contians' constructor function
/// and its priority.
/// The lower the priority, the earlier it will be called
pub struct PHInitWrap {
/// The priority of the init function
pub priority: CtorType,
/// The Initialize function
pub func: fn(),
}
/// Polyhal Constructor placeholder
#[used(linker)]
#[unsafe(link_section = "ph_init")]
static PH_INIT_ARR: [PHInitWrap; 0] = [];
/// Get a iterator of the polyhal init section.
///
/// The item of the iterator is function reference.
///
/// ## Demo
///
/// ```rust
/// // Call all initialize function.
/// ph_init_iter().for_each(|f| f());
/// ```
pub fn ph_init_iter<'a>(priority: CtorType) -> impl Iterator<Item = &'a PHInitWrap> {
let len = (__stop_ph_init as usize - __start_ph_init as usize) / size_of::<PHInitWrap>();
unsafe {
core::slice::from_raw_parts_mut(__start_ph_init as *mut PHInitWrap, len)
.iter()
.filter(move |x| x.priority == priority)
}
}
/// Definiation a constructer
///
/// This constructor will be called by polyhal when booting.
/// Please add `#![feature(used_with_arg)]` at the top of your `lib.rs` file.
///
/// ## Demo
///
/// ```rust
/// ph_ctor!(ctor_name, || {
/// // Ctor block
/// });
/// ```
#[macro_export]
macro_rules! ph_ctor {
($name:ident, $ty: expr, $f:expr) => {
#[used(linker)]
#[unsafe(no_mangle)]
#[unsafe(link_section = "ph_init")]
static $name: $crate::ctor::PHInitWrap = $crate::ctor::PHInitWrap {
priority: $ty,
func: $f,
};
};
}