/* TEMPORARILY DISABLED * #include "kernel/kernel.h" #include #include "asm_x86.h" #include "smp.h" #include "lib/string/string.h" typedef struct mp_fps_struct { uint32_t sig; //signature "_MP_" uint32_t conf; //pointer to config struct uint8_t length; //should be 1 uint8_t version; // 1=1.1, 4=1.4 uint8_t checksum; uint8_t features1; uint8_t features2; uint8_t res1; //reserved uint8_t res2; uint8_t res3; }mp_fps; typedef struct mp_config_struct { uint32_t sig; //signature "PCMP" uint16_t length; //base table length uint8_t version; //revision 1=1.1 4=1.4 uint8_t checksum; uint32_t oemid1; //OEM id (ascii) uint32_t oemid2; uint32_t prodid1; //Product id (ascii) uint32_t prodid2; uint32_t prodid3; uint32_t oem_table; //pointer (optional) uint16_t oem_size; //size of this table uint16_t entries; //entry count (following the header) uint32_t local_apic; //local apic address (same for every cpu) uint16_t length_ext; //extended table length (optional) uint8_t check_ext; //checksum for ext. table }mp_config; typedef struct proc_struct { uint8_t type; //0=processor uint8_t apic_id; uint8_t apic_ver; uint8_t cpu_bits; uint32_t cpu_sig; uint32_t cpu_flags; }proc_entry; //entries are sorted. (otherwise ignore. bochs!) uint8_t *walk_mp_table(uint8_t *start_addr,smp_processors *smp) { if(*start_addr==0x0||*start_addr==0x2) klog("entry type: %d",*start_addr); // that is a processor if(*start_addr==0x00) { proc_entry *pro=start_addr; klog("local apic id: %02X",pro->apic_id); klog("cpu enabled bit: %s",pro->cpu_bits&1?"yes":"no"); klog("bootstrap cpu bit: %s",pro->cpu_bits&2?"yes":"no"); // that is a enabled processor if(pro->cpu_bits&1) { if(smp->processors>=SMP_MAX_PROC) kpanic("we do not support that many processors. recompile with higher SMP_MAX_PROC."); smp->local_apic_id[smp->processors]=pro->apic_id; // that is the bootstrap processor if(pro->cpu_bits&2)smp->boot=smp->processors; smp->processors++; } return start_addr+20; } return start_addr+8; } void do_mp_conf(mp_config *addr,smp_processors *procdata) { char buf[]="XXXX"; uint32_t *buf_addr=buf; *buf_addr=addr->sig; klog("mp_config table addr: %08X",addr); klog("mp_config signature: %s",buf); klog("mp_config version: %02X",addr->version); klog("mp_config # of entries: %d",addr->entries); klog("mp_config local apic addr: 0x%08X",addr->local_apic); klog("mp_config tabel length: %d",addr->length); uint8_t *start_addr=addr; start_addr+=44; procdata->processors=0; procdata->local_apic_address=addr->local_apic; for(int i=0;ientries;i++) { start_addr=walk_mp_table(start_addr,procdata); } } bool do_mp_fps(mp_fps *addr,smp_processors *procdata) { if(addr->length!=1)return false; if(addr->version!=1&&addr->version!=4)return false; char buf[]="XXXX"; uint32_t *buf_addr=buf; *buf_addr=addr->sig; klog("signature: %s",buf); klog("conf: %08X",addr->conf); klog("ver: %02X",addr->version); klog("f1: %02X",addr->features1); if(addr->features1!=0)kpanic("Intel default config not supported yet!"); do_mp_conf(addr->conf,procdata); return true; } // todo: check checksum,version etc. and narrow down search bool mp_find(smp_processors *procdata) { klog("Looking for Mp Floating Ponter Struct..."); uint8_t *addr=0x8000; while((uint32_t)addr<=0xfffff) { if(!strcmp_l("_MP_",(char*)addr,4)) { // klog("Found at 0x%04X",addr); if(do_mp_fps(addr,procdata))return true; } addr++; } addr=0x190000-1025; while((uint32_t)addr<=0x190000+1024) { if(!strcmp_l("_MP_",(char*)addr,4)) { // klog("Found at 0x%04X",addr); if(do_mp_fps(addr,procdata))return true; } addr++; } return false; } */