+
+#ifdef XNU_KERNEL_PRIVATE
+
+#ifndef _KERN_STARTUP_H_
+#define _KERN_STARTUP_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <libkern/section_keywords.h>
+
+__BEGIN_DECLS
+
+#pragma GCC visibility push(hidden)
+
+/*!
+ * @enum startup_subsystem_id_t
+ *
+ * @abstract
+ * Represents a stage of kernel intialization, ubnd allows for subsystems
+ * to register initializers for a specific stage.
+ *
+ * @discussion
+ * Documentation of each subsystem initialization sequence exists in
+ * @file doc/startup.md.
+ */
+__enum_decl(startup_subsystem_id_t, uint32_t, {
+ STARTUP_SUB_NONE = 0, /**< reserved for the startup subsystem */
+
+ STARTUP_SUB_TUNABLES, /**< support for the tunables subsystem */
+ STARTUP_SUB_LOCKS_EARLY, /**< early locking, before zalloc */
+ STARTUP_SUB_KPRINTF, /**< kprintf initialization */
+
+ STARTUP_SUB_PMAP_STEAL, /**< to perform various pmap carveouts */
+ STARTUP_SUB_VM_KERNEL, /**< once the kernel VM is ready */
+ STARTUP_SUB_KMEM, /**< once kmem is ready */
+ STARTUP_SUB_KMEM_ALLOC, /**< once kmem_alloc is ready */
+ STARTUP_SUB_ZALLOC, /**< initialize zalloc and kalloc */
+ STARTUP_SUB_PERCPU, /**< initialize the percpu subsystem */
+ STARTUP_SUB_LOCKS, /**< various subsystem locks */
+
+ STARTUP_SUB_CODESIGNING, /**< codesigning subsystem */
+ STARTUP_SUB_OSLOG, /**< oslog and kernel loggging */
+ STARTUP_SUB_MACH_IPC, /**< Mach IPC */
+ STARTUP_SUB_SYSCTL, /**< registers sysctls */
+ STARTUP_SUB_EARLY_BOOT, /**< interrupts/premption are turned on */
+
+ STARTUP_SUB_LOCKDOWN = ~0u, /**< reserved for the startup subsystem */
+});
+
+/*!
+ * Stores the last subsystem to have been fully initialized;
+ */
+extern startup_subsystem_id_t startup_phase;
+
+/*!
+ * @enum startup_debug_t
+ *
+ * @abstract
+ * Flags set in the @c startup_debug global to configure startup debugging.
+ */
+__options_decl(startup_debug_t, uint32_t, {
+ STARTUP_DEBUG_NONE = 0x00000000,
+ STARTUP_DEBUG_VERBOSE = 0x00000001,
+});
+
+#if DEBUG || DEVELOPMENT
+extern startup_debug_t startup_debug;
+#else
+#define startup_debug STARTUP_DEBUG_NONE
+#endif
+
+/*!
+ * @enum startup_rank
+ *
+ * @abstract
+ * Specifies in which rank a given initializer runs within a given section
+ * to register initializers for a specific rank within the subsystem.
+ *
+ * @description
+ * A startup function, declared with @c STARTUP or @c STARTUP_ARG, can specify
+ * an rank within the subsystem they initialize.
+ *
+ * @c STARTUP_RANK_NTH(n) will let callbacks be run at stage @c n (0-based).
+ *
+ * @c STARTUP_RANK_FIRST, @c STARTUP_RANK_SECOND, @c STARTUP_RANK_THIRD and
+ * @c STARTUP_RANK_FOURTH are given as conveniency names for these.
+ *
+ * @c STARTUP_RANK_MIDDLE is a reserved value that will let startup functions
+ * run after all the @c STARTUP_RANK_NTH(n) ones have.
+ *
+ * @c STARTUP_RANK_NTH_LATE_NTH(n) will let callbacks be run then in @c n rank
+ * after the @c STARTUP_RANK_MIDDLE ones (0-based).
+ *
+ * @c STARTUP_RANK_LAST callbacks will run absolutely last after everything
+ * else did for this subsystem.
+ */
+__enum_decl(startup_rank_t, uint32_t, {
+#define STARTUP_RANK_NTH(n) \
+ (enum startup_rank)(n)
+ STARTUP_RANK_FIRST = 0,
+ STARTUP_RANK_SECOND = 1,
+ STARTUP_RANK_THIRD = 2,
+ STARTUP_RANK_FOURTH = 3,
+
+ STARTUP_RANK_MIDDLE = 0x7fffffff,
+
+#define STARTUP_RANK_LATE_NTH(n) \
+ (enum startup_rank)(STARTUP_RANK_MIDDLE + 1 + (n))
+
+ STARTUP_RANK_LAST = 0xffffffff,
+});
+
+#if KASAN