1#![no_std]
8
9pub use paste::paste;
10
11#[repr(transparent)]
12#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
13pub struct LkInitLevel(pub u32);
14
15pub type LkInitHook = extern "C" fn(level: LkInitLevel);
16
17pub const LK_INIT_LEVEL_EARLIEST: LkInitLevel = LkInitLevel(1);
18
19pub const LK_INIT_LEVEL_ARCH_EARLY: LkInitLevel = LkInitLevel(0x10000);
25pub const LK_INIT_LEVEL_PLATFORM_EARLY: LkInitLevel = LkInitLevel(0x20000);
26
27pub const LK_INIT_LEVEL_ARCH_PREVM: LkInitLevel = LkInitLevel(0x30000);
32pub const LK_INIT_LEVEL_PLATFORM_PREVM: LkInitLevel = LkInitLevel(0x40000);
33
34pub const LK_INIT_LEVEL_VM_PREHEAP: LkInitLevel = LkInitLevel(0x50000);
36pub const LK_INIT_LEVEL_HEAP: LkInitLevel = LkInitLevel(0x60000);
37pub const LK_INIT_LEVEL_VM: LkInitLevel = LkInitLevel(0x70000);
38
39pub const LK_INIT_LEVEL_INTC: LkInitLevel = LkInitLevel(0x78000);
41
42pub const LK_INIT_LEVEL_TOPOLOGY: LkInitLevel = LkInitLevel(0x80000);
44pub const LK_INIT_LEVEL_KERNEL: LkInitLevel = LkInitLevel(0x90000);
45pub const LK_INIT_LEVEL_THREADING: LkInitLevel = LkInitLevel(0xa0000);
46
47pub const LK_INIT_LEVEL_ARCH: LkInitLevel = LkInitLevel(0xb0000);
52pub const LK_INIT_LEVEL_PLATFORM: LkInitLevel = LkInitLevel(0xc0000);
53pub const LK_INIT_LEVEL_ARCH_LATE: LkInitLevel = LkInitLevel(0xd0000);
54
55pub const LK_INIT_LEVEL_SMP_WAIT: LkInitLevel = LkInitLevel(0xd4000);
59
60pub const LK_INIT_LEVEL_SMP_READY: LkInitLevel = LkInitLevel(0xd8000);
62
63pub const LK_INIT_LEVEL_USER: LkInitLevel = LkInitLevel(0xe0000);
65pub const LK_INIT_LEVEL_LAST: LkInitLevel = LkInitLevel(u32::MAX);
66
67#[repr(u32)]
68#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
69pub enum LkInitFlags {
70 PrimaryCpu = 0x1,
71 SecondaryCpus = 0x2,
72 AllCpus = 0x3,
73}
74
75#[repr(C)]
76pub struct LkInitStruct {
77 pub level: LkInitLevel,
78 pub flags: LkInitFlags,
79 pub hook: LkInitHook,
80 pub name: *const core::ffi::c_char,
81}
82
83unsafe impl core::marker::Sync for LkInitStruct {}
86
87zr::static_assert!(core::mem::size_of::<LkInitStruct>() == 24);
89zr::static_assert!(core::mem::align_of::<LkInitStruct>() == 8);
90
91#[macro_export]
92macro_rules! lk_init_hook_flags {
93 ($var_name:ident, $hook:expr, $level:expr, $flags:expr) => {
94 $crate::paste! {
95 extern "C" fn [< _init_struct_fn_wrapper_ $var_name >](level: $crate::LkInitLevel) {
96 ($hook)(level)
97 }
98 #[used]
99 #[unsafe(link_section = ".data.rel.ro.lk_init")]
100 pub static [< _init_struct_ $var_name >]: $crate::LkInitStruct = $crate::LkInitStruct {
101 level: $level,
102 flags: $flags,
103 hook: [< _init_struct_fn_wrapper_ $var_name >],
104 name: core::concat!(core::stringify!($var_name), "\0").as_ptr()
105 as *const core::ffi::c_char,
106 };
107 }
108 };
109}
110
111#[macro_export]
112macro_rules! lk_init_hook {
113 ($var_name:ident, $hook:expr, $level:expr) => {
114 $crate::lk_init_hook_flags!($var_name, $hook, $level, $crate::LkInitFlags::PrimaryCpu);
115 };
116}