1 /*
2  * Copyright (c) 2013-2015 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #include <lk/compiler.h>
11 #include <sys/types.h>
12 
13 __BEGIN_CDECLS
14 
15 /*
16  * LK's init system
17  */
18 
19 typedef void (*lk_init_hook)(uint level);
20 
21 enum lk_init_level {
22     LK_INIT_LEVEL_EARLIEST = 1,
23 
24     LK_INIT_LEVEL_ARCH_EARLY     = 0x1000,
25     LK_INIT_LEVEL_PLATFORM_EARLY = 0x2000,
26     LK_INIT_LEVEL_TARGET_EARLY   = 0x3000,
27     LK_INIT_LEVEL_HEAP           = 0x4000,
28     LK_INIT_LEVEL_VM             = 0x5000,
29     LK_INIT_LEVEL_KERNEL         = 0x6000,
30     LK_INIT_LEVEL_THREADING      = 0x7000,
31     LK_INIT_LEVEL_ARCH           = 0x8000,
32     LK_INIT_LEVEL_PLATFORM       = 0x9000,
33     LK_INIT_LEVEL_TARGET         = 0xa000,
34     LK_INIT_LEVEL_APPS           = 0xb000,
35 
36     LK_INIT_LEVEL_LAST = UINT16_MAX,
37 };
38 
39 enum lk_init_flags {
40     LK_INIT_FLAG_PRIMARY_CPU     = 0x1,
41     LK_INIT_FLAG_SECONDARY_CPUS  = 0x2,
42     LK_INIT_FLAG_ALL_CPUS        = LK_INIT_FLAG_PRIMARY_CPU | LK_INIT_FLAG_SECONDARY_CPUS,
43     LK_INIT_FLAG_CPU_SUSPEND     = 0x4,
44     LK_INIT_FLAG_CPU_RESUME      = 0x8,
45 };
46 
47 // Run init hooks between start_level (inclusive) and stop_level (exclusive) that match the required_flags.
48 void lk_init_level(enum lk_init_flags required_flags, uint16_t start_level, uint16_t stop_level);
49 
lk_primary_cpu_init_level(uint16_t start_level,uint16_t stop_level)50 static inline void lk_primary_cpu_init_level(uint16_t start_level, uint16_t stop_level) {
51     lk_init_level(LK_INIT_FLAG_PRIMARY_CPU, start_level, stop_level);
52 }
53 
lk_init_level_all(enum lk_init_flags flags)54 static inline void lk_init_level_all(enum lk_init_flags flags) {
55     lk_init_level(flags, LK_INIT_LEVEL_EARLIEST, LK_INIT_LEVEL_LAST);
56 }
57 
58 struct lk_init_struct {
59     uint16_t level;
60     uint16_t flags;
61     lk_init_hook hook;
62     const char *name;
63 };
64 
65 // Define an init hook with specific flags, level, and name.
66 #define LK_INIT_HOOK_FLAGS(_name, _hook, _level, _flags) \
67     static const struct lk_init_struct _init_struct_##_name __ALIGNED(sizeof(void *)) __SECTION("lk_init") = { \
68         .level = (_level), \
69         .flags = (_flags), \
70         .hook = (_hook), \
71         .name = #_name, \
72     };
73 
74 // Shortcut for defining an init hook with primary CPU flag.
75 #define LK_INIT_HOOK(_name, _hook, _level) \
76     LK_INIT_HOOK_FLAGS(_name, _hook, _level, LK_INIT_FLAG_PRIMARY_CPU)
77 
78 __END_CDECLS
79