1#include <acpi/acpi.h>
2#include <acpi/cst.h>
3#include <acpi/hpet.h>
4#include <acpi/ioapic.h>
5#include <acpi/lapic.h>
6#include <acpi/uacpi_interface.h>
7#include <asm.h>
8#include <boot/gdt.h>
9#include <bootstage.h>
10#include <cmdline.h>
11#include <compiler.h>
12#include <console/printf.h>
13#include <console/term.h>
14#include <crypto/prng.h>
15#include <drivers/iommu/iommu.h>
16#include <drivers/mmio.h>
17#include <elf.h>
18#include <fs/vfs.h>
19#include <global.h>
20#include <irq/idt.h>
21#include <limine.h>
22#include <log.h>
23#include <logo.h>
24#include <mem/address_range.h>
25#include <mem/alloc.h>
26#include <mem/asan.h>
27#include <mem/buddy.h>
28#include <mem/domain.h>
29#include <mem/movealloc.h>
30#include <mem/page_alloc.h>
31#include <mem/pmm.h>
32#include <mem/slab.h>
33#include <mem/tlb.h>
34#include <mem/vmm.h>
35#include <ndjson.h>
36#include <nightmare/nightmare.h>
37#include <registry.h>
38#include <requests.h>
39#include <sch/domain.h>
40#include <sch/periodic_work.h>
41#include <sch/sched.h>
42#include <smp/core.h>
43#include <smp/domain.h>
44#include <smp/percpu.h>
45#include <smp/perdomain.h>
46#include <smp/pernode.h>
47#include <smp/smp.h>
48#include <stack_depot.h>
49#include <stdint.h>
50#include <sync/lock_chk.h>
51#include <sync/rcu.h>
52#include <sync/turnstile.h>
53#include <syscall.h>
54#include <test/test.h>
55#include <thread/dpc.h>
56#include <thread/reaper.h>
57#include <thread/thread.h>
58#include <thread/workqueue.h>
59#include <time/clock.h>
60#include <time/timekeeper.h>
61#include <time/timer.h>
62#include <watchdog.h>
63
64struct globals global = {0};
65
66#define BEHAVIOR /* avoids undefined behavior */
67
68__no_sanitize_address void k_main(void) {
69 disable_interrupts();
70 global.core_count = mp_request.response->cpu_count;
71 global.hhdm_offset = hhdm_request.response->offset;
72 global.pt_epoch = 1;
73
74 printf_init(fb: framebuffer_request.response->framebuffers[0]);
75 err_facilities_init();
76 crash_facilities_init();
77 ndjson_early_init();
78 bootstage_advance(new: BOOTSTAGE_EARLY_FB);
79
80 const char *cmdline =
81 cmdline_request.response ? cmdline_request.response->cmdline : "";
82
83 if (cmdline_wants_help(input: cmdline))
84 cmdline_dump_help();
85
86 pmm_early_init(m: memmap_request);
87 vmm_init(memmap: memmap_request.response, xa: xa_request.response);
88 pmm_mid_init();
89
90#ifdef DEBUG_ASAN
91 asan_init();
92#endif
93
94 address_ranges_init();
95 slab_allocator_init();
96 page_alloc_init();
97
98 stack_depot_init();
99 log_sites_init();
100 bootstage_advance(new: BOOTSTAGE_EARLY_ALLOCATORS);
101 gdt_install();
102 syscall_setup(syscall_entry);
103 smp_setup_bsp();
104
105 clocks_init();
106
107 mmio_init();
108 irq_init();
109 uacpi_init(rsdp: rsdp_request.response->address);
110 x2apic_init();
111 lapic_init();
112 hpet_init();
113 ioapic_init();
114 acpi_find_cst();
115 bootstage_advance(new: BOOTSTAGE_EARLY_DEVICES);
116
117 srat_init();
118 slit_init();
119 iommu_init();
120
121 domain_init();
122 pmm_late_init();
123 slab_domain_init();
124
125 percpu_obj_init();
126 watchdog_init();
127 smp_init();
128
129 domain_init_after_smp();
130 domain_buddies_init_after_smp();
131 thread_init_thread_ids();
132
133 scheduler_init();
134 turnstiles_init();
135
136 cmdline_parse(input: cmdline);
137 ndjson_init();
138 cmdline_debug_hook();
139
140 lapic_timer_init_bsp();
141 dpc_init_percpu();
142 smp_wake(mpr: mp_request.response);
143 timekeeper_init();
144 term_probe();
145
146 topology_init();
147 scheduler_domains_init();
148 bootstage_advance(new: BOOTSTAGE_MID_TOPOLOGY);
149
150 perdomain_obj_init();
151 pernode_obj_init();
152
153 lapic_clock_evdev_group_init();
154 timers_init();
155
156 scheduler_periodic_work_init();
157 movealloc_exec_all();
158 bootstage_advance(new: BOOTSTAGE_MID_ALLOCATORS);
159
160 scheduler_yield();
161}
162
163void k_sch_main(void *nop) {
164 (void) nop;
165 /* make sure everyone else is idle before we
166 * advance the bootstage here... */
167 smp_wait_for_others_to_idle();
168
169 /* we have to force everyone to disable their
170 * ticks because this prevents anyone from
171 * possibly entering an ISR since IRQL
172 * operations check bootstages and they can
173 * see the MID_ALLOCATORS bootstage (no-op) in
174 * an early `irql_raise` and the LATE_DEVICES
175 * bootstage later on (causing mis-raised IRQLs) */
176 smp_disable_all_ticks();
177
178 bootstage_advance(new: BOOTSTAGE_LATE);
179 lock_chk_init();
180
181 smp_enable_all_ticks();
182 watchdog_start();
183
184 rcu_init();
185 workqueues_permanent_init();
186 slab_domain_init_late();
187 domain_buddies_init_late();
188 reaper_init();
189
190 registry_setup();
191 nightmare_run();
192 tests_run();
193 bootstage_advance(new: BOOTSTAGE_COMPLETE);
194
195#ifdef TEST_ENABLED
196 return;
197#endif
198
199 thread_print(t: thread_get_current());
200
201 domain_buddy_dump();
202}
203