#include #include #include #include #include #include #include #include #include #include #include #include static uint32_t cpu_counter = 0; static spin_lock_t cpu_counter_lock = SPIN_LOCK_INIT; static struct cpu cpus[CPUS_MAX]; struct cpu* cpu_make (void) { spin_lock (&cpu_counter_lock); int id = cpu_counter++; spin_unlock (&cpu_counter_lock); struct cpu* cpu = &cpus[id]; memset (cpu, 0, sizeof (*cpu)); cpu->id = id; return cpu_get (id); } struct cpu* cpu_get (uint32_t id) { if (id >= CPUS_MAX) return NULL; return &cpus[id]; } uint32_t cpu_id (void) { return (uint32_t)amd64_rdmsr (MSR_GS_BASE); } void cpu_assign (uint32_t id) { amd64_wrmsr (MSR_GS_BASE, (uint64_t)id); } static void amd64_smp_bootstrap (struct limine_mp_info* mp_info) { amd64_load_kernel_cr3 (); struct cpu* cpu = cpu_make (); cpu_assign (cpu->id); amd64_init (cpu, true); /* gdt + idt */ thiscpu->lapic_ticks = amd64_lapic_init (2500); amd64_lapic_tick (thiscpu->lapic_ticks); DEBUG ("CPU %u is online!\n", thiscpu->id); __asm__ volatile ("sti"); for (;;) ; } void smp_init (void) { thiscpu->lapic_ticks = amd64_lapic_init (2500); struct limine_mp_response* mp = limine_mp_request.response; for (size_t i = 0; i < mp->cpu_count; i++) { if (mp->cpus[i]->lapic_id != thiscpu->id) { DEBUG ("Trying CPU %u\n", mp->cpus[i]->lapic_id); mp->cpus[i]->goto_address = &amd64_smp_bootstrap; } } }