#include "kernel/kernel.h" // http://www.intel.com/content/dam/doc/specification-update/64-architecture-x2apic-specification.pdf // http://download.intel.com/design/chipsets/datashts/29056601.pdf // http://www.scs.stanford.edu/05au-cs240c/lab/ia32/IA32-3.pdf #include #include "smp.h" #include "mem.h" #include "spinlock.h" #include "asm_x86.h" #define FOOLOS_APIC_SPUR_INT 0x00f0 #define FOOLOS_APIC_INT_COMMAND_LOW 0x0300 #define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310 #define FOOLOS_APIC_ID 0x020 // some multiprocessor shit that should move away TODO uint32_t c1,c2,c3; volatile uint8_t proc; uint32_t cpu_counter[SMP_MAX_PROC]; uint32_t local_apic_addr; void smp_main() { // klog("local apic_addr:0x%08X",local_apic_addr); // // uint32_t *reg=local_apic_addr+FOOLOS_APIC_ID; //klog("local apic id: 0x%08X",(*reg)); // // // *reg=local_apic_addr+FOOLOS_APIC_SPUR_INT; // // // *reg|=0x100;//0xffffffff; // all bits 1 and interrupt 255 // *reg=0;//xffffffff; // all bits 1 and interrupt 255 int_install(); x86_sti(); while(1)__asm__("hlt"); // switch_to_user_mode(); // int x=1/0; while(1); uint32_t ebp=pmmngr_alloc_block()+4095; asm volatile("mov %0, %%ebp"::"r"(ebp)); asm volatile("mov %ebp, %esp"); asm volatile("jmp kernel_ap"); proc=c1=c2=c3=0; for(int i=0;iprocessors;i++) { klog("cpu %d, apic_id: 0x%X, bps: %s, apic_addr:0x%08X",i,procdata->local_apic_id[i],i==procdata->boot?"yes":"no",procdata->local_apic_address); } } // this will start all our application processors! void smp_start_aps(smp_processors *pros,char *path) { local_apic_addr=pros->local_apic_address; //bsp (boot processor) enables its local apic // uint32_t *reg=local_apic_addr+FOOLOS_APIC_SPUR_INT; // *reg=0xffffffff; // all bits 1 and interrupt 255 (is this not set anyway?) // *reg=0; uint32_t *reg=local_apic_addr+FOOLOS_APIC_ID; klog("local apic id: 0x%08X",(*reg)); for(int i=0;iprocessors;i++) { if(pros->boot==i)continue; uint8_t dest=pros->local_apic_id[i]; klog("starting cpu %d (dest: %d) ",i,dest); reg=local_apic_addr+FOOLOS_APIC_INT_COMMAND_HIGH; *reg=dest<<24; // destination apic. reg=local_apic_addr+FOOLOS_APIC_INT_COMMAND_LOW; *reg=(5<<8)|(1<<14); // 101 INIT // do we really neet this? // TODO!! // todo: use some real sleep (not implemented yet :( ) //sleep(30); // start proc 0x7 = 0x7000; *reg=(6<<8)|(1<<14)|0x7; // 110 SIPI } }