void process_mp_configuration(void) { /* Scan MP table and find some information about MP configuration */ u32_t next; int cpu_count, bus_count, apic_count, ioint_count, lint_count; int i=mph.mpch_entry_count; u8_t this_entry; struct io_apic_entry ae; struct cpu_entry ce; struct io_int_entry ioie; struct l_int_entry lie; cpu_count= bus_count= apic_count= ioint_count= lint_count= 0; next=fps.fp_mp_table+sizeof (struct mp_config_header); while (i-- > 0) { phys_copy(next, vir2phys(&this_entry), 1); switch (this_entry) { case CPU_ENTRY_ID : if (++cpu_count > 2) ADDS_MP_STATUS("MP PANIC: only 2 cpus currently supported!\n"); phys_copy(next,vir2phys(&ce),sizeof(struct cpu_entry)); next+=sizeof(struct cpu_entry); PRINT_CPU_ENTRY(cpu); if ((ce.ce_flags & CE_EN_FLAG_MASK)==0) ADDS_MP_STATUS("MP PANIC: disabled apics not currently supported\n"); break; case BUS_ENTRY_ID : bus_count++; next+=sizeof(struct bus_entry); break; case IO_APIC_ENTRY_ID : if (++apic_count > 1) ADDS_MP_STATUS("MP PANIC: only 1 I/O APIC currently supported!\n"); phys_copy(next,vir2phys(&ae),sizeof(struct io_apic_entry)); next+=sizeof(struct io_apic_entry); /*PRINT_IO_APIC_ENTRY(ae);*/ if ((ae.ae_flags & AE_EN_FLAG_MASK)==0) ADDS_MP_STATUS("MP PANIC: disabled apic not currently supported!"); io_apic_base=ae.ae_address; break; case IO_INT_ENTRY_ID : ioint_count++; phys_copy(next,vir2phys(&ioie),sizeof(struct io_int_entry)); next+=sizeof(struct io_int_entry); /*PRINT_IO_INT_ENTRY(ioie);*/ break; case LOCAL_INT_ENTRY_ID : lint_count++; phys_copy(next,vir2phys(&lie),sizeof(struct l_int_entry)); next+=sizeof(struct l_int_entry); /*PRINT_LOCAL_ENTRY(lie);*/ break; default : ADDS_MP_STATUS("MP config table corrupt!\n"); i=0; /* break loop */ break; } } /*PRINT_MP_SUMMARY(cpu_count,bus_count,apic_count, ioint_count,lint_count);*/ if ((apic_count!=1)) ADDS_MP_STATUS("MP PANIC: only 1 I/O APIC currently supported!\n"); }
とりあえず、さくっと見ると2cpuまでしか対応してないとかわかるけど、それらは置いておいてどんな処理をしてるかを見るよ。
まずは以下の行。
int i=mph.mpch_entry_count;
このmpch_entry_countはMP Configuration Table Headerにある"ENTRY COUNT"フィールドから読み込んだ内容が入っていて、
単純に言うと何個データがあるかを教えてくれる。
次の行はMP Configuration Table Headerの先頭アドレス+MP Configuration Table Headerのサイズすることで、mphの直後にあるエントリのアドレスを算出。
next=fps.fp_mp_table+sizeof (struct mp_config_header);
ここで、エントリといってるのはプロセッサとかバスとかに関する情報が入っているテーブルのことで、以下の5個がある。
・Processor Entries
・Bus Entries
・I/O APIC Entries
・I/O Interrupt Assignment Entries
・Local Interrupt Assignment Entries
switch-case文にででくるcaseの種類は上記のエントリを表している。
全てのエントリの先頭8bitはエントリの種類を表す8bitのフィールドになってる。名前は"ENTRY TYPE"。
なので、switchに使ってるthis_entry変数がu8_tなのはこのためだと分かる。
後は、どのエントリの場合もほとんど同じ処理で、メモリからデータを読み込んで、自分のエントリのサイズ分アドレスを足して次のエントリを読みにいく。
これでエントリの読み込み処理は終わり。