1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#define pr_fmt(fmt) "ap_entry: " fmt
4
5#include "mos/x86/cpu/ap_entry.h"
6
7#include "mos/platform/platform.h"
8#include "mos/syslog/printk.h"
9#include "mos/tasks/schedule.h"
10#include "mos/x86/cpu/cpu.h"
11#include "mos/x86/descriptors/descriptors.h"
12#include "mos/x86/interrupt/apic.h"
13#include "mos/x86/x86_platform.h"
14
15static bool aps_blocked = true;
16
17void x86_unblock_aps(void)
18{
19 MOS_ASSERT(aps_blocked);
20 aps_blocked = false;
21}
22
23void platform_ap_entry(u64 arg)
24{
25 MOS_UNUSED(arg);
26
27#if !MOS_CONFIG(MOS_SMP)
28 pr_info("SMP not enabled, halting AP");
29 platform_halt_cpu();
30#endif
31
32 while (aps_blocked)
33 __asm__ volatile("pause");
34
35 x86_init_percpu_gdt();
36 x86_init_percpu_tss();
37 x86_init_percpu_idt();
38
39 // enable paging
40 platform_switch_mm(new_mm: platform_info->kernel_mm);
41
42 x86_cpu_initialise_caps();
43 x86_cpu_setup_xsave_area();
44 lapic_enable();
45
46 const u8 processor_id = platform_current_cpu_id();
47 pr_dinfo2(x86_startup, "AP %u started", processor_id);
48
49 const u8 lapic_id = lapic_get_id();
50 if (lapic_id != processor_id)
51 pr_warn("LAPIC ID mismatch: LAPIC_ID: %u != PROCESSOR_ID: %u", lapic_id, processor_id);
52
53 current_cpu->mm_context = platform_info->kernel_mm;
54 current_cpu->id = lapic_id;
55
56 x86_setup_lapic_timer();
57 enter_scheduler();
58}
59