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。