読者です 読者をやめる 読者になる 読者になる

「Using ACPI (MADT) for SMP configuration information」のところを読む

kernel linux

昨日の「LinuxカーネルのSMPまわりの処理を調べてみる」の続きでUsing ACPI (MADT) for SMP configuration informationを出している箇所を見てみる。

メッセージを検索してみるとarch/x86/kernel/acpi/boot.cにあるacpi_process_madt()がヒット!
どこでメッセージを表示しているかは分かったので一旦ここまでのコールフローを見てみるとsetup_arch()ということが判明。
setup_arch()
 -> acpi_boot_init()
  -> acpi_process_madt()

(´-`).。oO(ところでMADTとは何かというのが重要だろう
まずはWikipediaACPIの項目を見てみると「システムにあるAPICの情報を記述したテーブル。MPTablesと同等の情報を提供するが、より高機能でハイパースレッディング対応した機械の場合必ず存在する。」と書かれている。i7の3770SはHT対応しているので必ず存在するらしい。ということで「Using ACPI (MADT)~」になるのかな。
ここで、読まなくてすむならそれに越したことは無い英語によるACPIの資料をダウンロード
このマニュアルの「5.2.12 Multiple APIC Description Table (MADT)」が今後必要になるだろうところ。

では、acpi_process_madt()に戻って内容を見てみる。

1260 static void __init acpi_process_madt(void)
1261 {
1262 #ifdef CONFIG_X86_LOCAL_APIC
1263         int error;
1264 
1265         if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
1266 
1267                 /*
1268                  * Parse MADT LAPIC entries
1269                  */
1270                 error = acpi_parse_madt_lapic_entries();
1271                 if (!error) {
1272                         acpi_lapic = 1;
1273 
1274                         /*
1275                          * Parse MADT IO-APIC entries
1276                          */
1277                         error = acpi_parse_madt_ioapic_entries();
1278                         if (!error) {
1279                                 acpi_set_irq_model_ioapic();
1280 
1281                                 smp_found_config = 1;
1282                         }
1283                 }
1284                 if (error == -EINVAL) {
1285                         /*
1286                          * Dell Precision Workstation 410, 610 come here.
1287                          */
1288                         printk(KERN_ERR PREFIX
1289                                "Invalid BIOS MADT, disabling ACPI\n");
1290                         disable_acpi();
1291                 }
1292         } else {
1293                 /*
1294                  * ACPI found no MADT, and so ACPI wants UP PIC mode.
1295                  * In the event an MPS table was found, forget it.
1296                  * Boot with "acpi=off" to use MPS on such a system.
1297                  */
1298                 if (smp_found_config) {
1299                         printk(KERN_WARNING PREFIX
1300                                 "No APIC-table, disabling MPS\n");
1301                         smp_found_config = 0;
1302                 }
1303         }
1304 
1305         /*
1306          * ACPI supports both logical (e.g. Hyper-Threading) and physical
1307          * processors, where MPS only supports physical.
1308          */
1309         if (acpi_lapic && acpi_ioapic)
1310                 printk(KERN_INFO "Using ACPI (MADT) for SMP configuration "
1311                        "information\n");
1312         else if (acpi_lapic)
1313                 printk(KERN_INFO "Using ACPI for processor (LAPIC) "
1314                        "configuration information\n");
1315 #endif
1316         return;
1317 }
1318 

最初にやっているのがacpi_table_parse()で引数としてACPI_SIG_MADTというものを渡しているのでMADTを探すんだろうというのは何となく想像つきますね。
ACPIの資料によるとMADTのシグネチャはACPIでACPI_SIG_MADTの定義をinclude/acpi/actbl1.hで見ると当たりの模様。

69 #define ACPI_SIG_MADT           "APIC"  /* Multiple APIC Description Table */

acpi_table_parse()は引数で渡ってきたシグネチャがACPIの場合はacpi_get_table_with_size()を呼んでMADTを探すという処理。ここはそんなに見るべき処理はなさそうなのでこれまで。

acpi_table_parse()でMADTが見つかったらif文の中に入って行き、acpi_parse_madt_lapic_entries()を呼ぶ。
資料でMADTの構造を見ると44バイト目から「Interrupt Controller Structure[n]」となっているのでここを読んでいく処理かな。

(´-`).。oO(次はacpi_parse_madt_lapic_entries()を見ていこ

Linux Kernel Development (3rd Edition) (Developer's Library)

Linux Kernel Development (3rd Edition) (Developer's Library)