#define FOOLOS_MODULE_NAME "smp" #include "lib/logger/log.h" #include "lib/int/stdint.h" #include "smp.h" #define FOOLOS_APIC_SPUR_INT 0x00f0 #define FOOLOS_APIC_INT_COMMAND_LOW 0x0300 #define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310 void smp_log_procdata(smp_processors *procdata) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"---- smp -----"); for(int i=0;iprocessors;i++) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"cpu %d : local_apic_id: 0x%X bps: %s local_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,uint8_t *start_sel) { //lets copy the code to the bootsector ! uint8_t *dest=0x7000; for(int i=0;i<0x100;i++) { dest[i]=start_sel[i]; } //bsp (boot processor) enables its local apic uint32_t *reg=pros->local_apic_address+FOOLOS_APIC_SPUR_INT; *reg=0xffffffff; // all bits 1 and interrupt 255 for(int i=0;iprocessors;i++) { if(pros->boot==i)continue; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"starting cpu %d",i); uint8_t dest=pros->local_apic_id[i]; reg=pros->local_apic_address+FOOLOS_APIC_INT_COMMAND_HIGH; *reg=dest<<24; // destination apic. reg=pros->local_apic_address+FOOLOS_APIC_INT_COMMAND_LOW; *reg=(5<<8)|(1<<14); // 101 INIT // do we really neet this? // todo: use some real sleep (not implemented yet :( ) sleep(30); // start proc 0x7 = 0x7000; etc.. *reg=(6<<8)|(1<<14)|0x7; // 110 SIPI } }