#include "kernel.h" #include "log.h" #include "smp.h" #include #include "gdt.h" #include "mem.h" #include "vmem.h" #include "interrupts.h" #include "kmalloc.h" #include "spinlock.h" #include "asm_x86.h" #include "asm_pit.h" #include "asm_smp.h" #include "apic.h" #include "syscalls.h" // set cpu private value void smp_set(uint32_t offset, uint32_t value) { uint32_t *cpu_mem=VMEM_CPU_PRIVATE; cpu_mem[offset]=value; } // get cpu private value uint32_t smp_get(uint32_t offset) { uint32_t *cpu_mem=VMEM_CPU_PRIVATE; return cpu_mem[offset]; } void smp_main_generic(bool bsp) { if(!bsp) // for the bsp this was already done beforehand { struct pdirectory_struct *dir=vmem_kernel_dir(); x86_set_page_directory(dir); x86_paging_enable(); klog("Just setup Paging on CPU with lapic_id=0x%x",apic_id()); klog("Install Interrupt Vector Table (IVT) on CPU with lapic_id=0x%x ...",apic_id()); interrupts_install(); klog("Install Global Descriptor Table (GDT) on CPU with lapic_id=0x%x ...",apic_id()); gdt_init(); } // setup stack and jump to kernel_ap(); fixme("we hate iniline assembly!"); uint32_t ebp=VMEM_CPU_STACK_TOP; asm volatile("mov %0, %%ebp"::"r"(ebp)); asm volatile("mov %ebp, %esp"); asm volatile("jmp run_smp"); } void run_smp() { apic_enable(); klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); apic_init_timer(FOOLOS_APIC_FREQ);// freq x HZ klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id()); asm_smp_unlock(); smp_set(SMP_APIC_ID,apic_id()); smp_set(1000,'a'+apic_id()); smp_set(SMP_SCHEDULER_INIT,1); x86_sti(); while(1)asm("hlt"); // wait for scheduler to kick in } void smp_main() { smp_main_generic(false); } void smp_bsp() { smp_main_generic(true); }