#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 "vesa.h" #include "syscalls.h" void run_smp(); // 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 { 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(); klog("Setup Paging on CPU with lapic_id=0x%x ...",apic_id()); struct pdirectory_struct *dir=vmem_kernel_dir(); x86_set_page_directory(dir); x86_paging_enable(); } // setup stack and jump to kernel_ap(); 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 smp_main() { smp_main_generic(false); } void run_smp() { apic_enable(); klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); apic_init_timer(1);// 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 } // this will start all our application processors! void smp_start_aps(acpi_information *pros) { /* for(int i=0;iprocessors;i++) { if(pros->boot==i)continue; // skib bsp uint8_t dest=pros->local_apic_id[i]; klog("starting cpu %d (destination apic id: 0x%x) ",i,dest); apic_sipi(dest,0x7); // start on 0x7000 } */ smp_main_generic(true); }