mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58:22 +00:00
smp: processor wakeup
This commit is contained in:
@@ -58,6 +58,7 @@ void kernel_entry() {
|
|||||||
timekeeper_init(arch_hpet_ticks, u);
|
timekeeper_init(arch_hpet_ticks, u);
|
||||||
arch_apic_timerinit();
|
arch_apic_timerinit();
|
||||||
sched_init();
|
sched_init();
|
||||||
|
arch_smp_wakeup();
|
||||||
vfs_init();
|
vfs_init();
|
||||||
tmpfs_init();
|
tmpfs_init();
|
||||||
devfs_init();
|
devfs_init();
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ void arch_mmu_switch(pagetableptr_t table) {
|
|||||||
asm volatile("mov %%rax, %%cr3" : : "a"(table));
|
asm volatile("mov %%rax, %%cr3" : : "a"(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
// hhdm pointer to template to be used for new mappings
|
// hhdm pointer to template to be used for new mappings and smp bootup
|
||||||
static pagetableptr_t template;
|
static pagetableptr_t template;
|
||||||
|
|
||||||
pagetableptr_t arch_mmu_newtable() {
|
pagetableptr_t arch_mmu_newtable() {
|
||||||
@@ -276,6 +276,10 @@ void arch_mmu_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arch_mmu_apswitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_mmu_apswitch() {
|
||||||
arch_mmu_switch(FROM_HHDM(template));
|
arch_mmu_switch(FROM_HHDM(template));
|
||||||
interrupt_register(14, pfisr, NULL, IPL_IGNORE);
|
interrupt_register(14, pfisr, NULL, IPL_IGNORE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#include <limine.h>
|
||||||
|
#include <logging.h>
|
||||||
|
#include <kernel/pmm.h>
|
||||||
|
#include <arch/cpu.h>
|
||||||
|
#include <arch/gdt.h>
|
||||||
|
#include <arch/idt.h>
|
||||||
|
#include <kernel/cmdline.h>
|
||||||
|
|
||||||
|
static volatile struct limine_smp_request smprequest = {
|
||||||
|
.id = LIMINE_SMP_REQUEST
|
||||||
|
};
|
||||||
|
|
||||||
|
// set to 1 because of the bsp
|
||||||
|
size_t cpusawake = 1;
|
||||||
|
|
||||||
|
static void cpuwakeup(struct limine_smp_info *info) {
|
||||||
|
cpu_set((cpu_t *)info->extra_argument);
|
||||||
|
|
||||||
|
arch_gdt_reload();
|
||||||
|
arch_idt_reload();
|
||||||
|
dpc_init();
|
||||||
|
arch_mmu_apswitch();
|
||||||
|
|
||||||
|
cpu_initstate();
|
||||||
|
arch_apic_timerinit();
|
||||||
|
|
||||||
|
__atomic_add_fetch(&cpusawake, 1, __ATOMIC_SEQ_CST);
|
||||||
|
// TODO let other processors run threads and applications
|
||||||
|
for (;;) CPU_HALT();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the nosmp argument is given to the kernel, this is what the APs will jump to
|
||||||
|
static void cpuwakeuphalt(struct limine_smp_info *info) {
|
||||||
|
for (;;) CPU_HALT();
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_smp_wakeup() {
|
||||||
|
struct limine_smp_response *response = smprequest.response;
|
||||||
|
if (response == NULL) {
|
||||||
|
// TODO try to detect the other processors manually
|
||||||
|
printf("smp: limine smp request response not present\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("smp: %d processor%s\n", response->cpu_count, response->cpu_count > 1 ? "s" : "");
|
||||||
|
|
||||||
|
// use physical pages so the other cpus have it on the hhdm
|
||||||
|
cpu_t *apcpu = pmm_alloc(ROUND_UP(sizeof(cpu_t) * response->cpu_count, PAGE_SIZE) / PAGE_SIZE, PMM_SECTION_DEFAULT);
|
||||||
|
__assert(apcpu);
|
||||||
|
apcpu = MAKE_HHDM(apcpu);
|
||||||
|
|
||||||
|
void (*wakeupfn)(struct limine_smp_info *) = cmdline_get("nosmp") ? cpuwakeuphalt : cpuwakeup;
|
||||||
|
|
||||||
|
// make the other processors jump to cpuwakeup()
|
||||||
|
for (int i = 0; i < response->cpu_count; ++i) {
|
||||||
|
// skip the bootstrap processor
|
||||||
|
if (response->cpus[i]->lapic_id == response->bsp_lapic_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
response->cpus[i]->extra_argument = (uint64_t)&apcpu[i];
|
||||||
|
|
||||||
|
__atomic_store_n(&response->cpus[i]->goto_address, wakeupfn, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for other cpus to boot up
|
||||||
|
if (wakeupfn == cpuwakeup)
|
||||||
|
while (__atomic_load_n(&cpusawake, __ATOMIC_SEQ_CST) != response->cpu_count) asm("pause");
|
||||||
|
|
||||||
|
printf("smp: awoke other processors\n");
|
||||||
|
}
|
||||||
@@ -34,5 +34,6 @@ bool arch_mmu_ispresent(pagetableptr_t table, void *vaddr);
|
|||||||
bool arch_mmu_iswritable(pagetableptr_t table, void *vaddr);
|
bool arch_mmu_iswritable(pagetableptr_t table, void *vaddr);
|
||||||
pagetableptr_t arch_mmu_newtable();
|
pagetableptr_t arch_mmu_newtable();
|
||||||
void arch_mmu_init();
|
void arch_mmu_init();
|
||||||
|
void arch_mmu_apswitch();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _SMP_H
|
||||||
|
#define _SMP_H
|
||||||
|
|
||||||
|
void arch_smp_wakeup();
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user