CPU 特性¶
Hollis Blanchard <hollis@austin.ibm.com> 2002 年 6 月 5 日
本文件描述了 PPC Linux 核心中使用的系統(包括自修改程式碼),該系統支援各種 PowerPC CPU,而無需編譯時選擇。
在啟動過程的早期,ppc32 核心會檢測當前的 CPU 型別,並相應地選擇一組特性。 一些示例包括 Altivec 支援、分離的指令和資料快取,以及 CPU 是否支援 DOZE 和 NAP 睡眠模式。
特性集的檢測很簡單。 可以在 arch/powerpc/kernel/cputable.c 中找到處理器列表。 PVR 暫存器被遮蔽並與列表中的每個值進行比較。 如果找到匹配項,則 cur_cpu_spec 的 cpu_features 將被分配給該處理器的特性位掩碼,並呼叫 __setup_cpu 函式。
C 程式碼可以測試 'cur_cpu_spec[smp_processor_id()]->cpu_features' 是否具有特定的特性位。 這在很多地方完成,例如在 ppc_setup_l2cr() 中。
在彙編中實現 cpufeatures 稍微複雜一些。 有幾個路徑對效能至關重要,如果新增陣列索引、結構解引用和條件分支,則效能會受到影響。 為了避免效能損失,但仍然允許執行時(而不是編譯時)CPU 選擇,未使用的程式碼將被“nop”指令替換。 這種 nop'ing 基於 CPU 0 的功能,因此具有非相同處理器的多處理器系統將無法工作(但這樣的系統可能也會有其他問題)。
在檢測到處理器型別後,核心透過在不需要使用的程式碼段上寫入 nop 來修補掉它們。 使用 cpufeatures 只需要 2 個宏(在 arch/powerpc/include/asm/cputable.h 中找到),如 head.S transfer_to_handler 中所示
#ifdef CONFIG_ALTIVEC
BEGIN_FTR_SECTION
mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
stw r22,THREAD_VRSAVE(r23)
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif /* CONFIG_ALTIVEC */
如果 CPU 0 支援 Altivec,則程式碼保持不變。 如果不支援,則兩個指令都將替換為 nop。
END_FTR_SECTION 宏有兩個更簡單的變體:END_FTR_SECTION_IFSET 和 END_FTR_SECTION_IFCLR。 這些只是分別測試標誌是否已設定(在 cur_cpu_spec[0]->cpu_features 中)或已清除。 這兩個宏應在大多數情況下使用。
END_FTR_SECTION 宏透過在 '__ftr_fixup' ELF 部分中儲存有關此程式碼的資訊來實現。 當呼叫 do_cpu_ftr_fixups (arch/powerpc/kernel/misc.S) 時,它將迭代 __ftr_fixup 中的記錄,如果所需的特性不存在,它將迴圈寫入 nop,從每個 BEGIN_FTR_SECTION 到 END_FTR_SECTION。