18c2ecf20Sopenharmony_ci============ 28c2ecf20Sopenharmony_ciCPU Features 38c2ecf20Sopenharmony_ci============ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciHollis Blanchard <hollis@austin.ibm.com> 68c2ecf20Sopenharmony_ci5 Jun 2002 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ciThis document describes the system (including self-modifying code) used in the 98c2ecf20Sopenharmony_ciPPC Linux kernel to support a variety of PowerPC CPUs without requiring 108c2ecf20Sopenharmony_cicompile-time selection. 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ciEarly in the boot process the ppc32 kernel detects the current CPU type and 138c2ecf20Sopenharmony_cichooses a set of features accordingly. Some examples include Altivec support, 148c2ecf20Sopenharmony_cisplit instruction and data caches, and if the CPU supports the DOZE and NAP 158c2ecf20Sopenharmony_cisleep modes. 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciDetection of the feature set is simple. A list of processors can be found in 188c2ecf20Sopenharmony_ciarch/powerpc/kernel/cputable.c. The PVR register is masked and compared with 198c2ecf20Sopenharmony_cieach value in the list. If a match is found, the cpu_features of cur_cpu_spec 208c2ecf20Sopenharmony_ciis assigned to the feature bitmask for this processor and a __setup_cpu 218c2ecf20Sopenharmony_cifunction is called. 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciC code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a 248c2ecf20Sopenharmony_ciparticular feature bit. This is done in quite a few places, for example 258c2ecf20Sopenharmony_ciin ppc_setup_l2cr(). 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciImplementing cpufeatures in assembly is a little more involved. There are 288c2ecf20Sopenharmony_ciseveral paths that are performance-critical and would suffer if an array 298c2ecf20Sopenharmony_ciindex, structure dereference, and conditional branch were added. To avoid the 308c2ecf20Sopenharmony_ciperformance penalty but still allow for runtime (rather than compile-time) CPU 318c2ecf20Sopenharmony_ciselection, unused code is replaced by 'nop' instructions. This nop'ing is 328c2ecf20Sopenharmony_cibased on CPU 0's capabilities, so a multi-processor system with non-identical 338c2ecf20Sopenharmony_ciprocessors will not work (but such a system would likely have other problems 348c2ecf20Sopenharmony_cianyways). 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ciAfter detecting the processor type, the kernel patches out sections of code 378c2ecf20Sopenharmony_cithat shouldn't be used by writing nop's over it. Using cpufeatures requires 388c2ecf20Sopenharmony_cijust 2 macros (found in arch/powerpc/include/asm/cputable.h), as seen in head.S 398c2ecf20Sopenharmony_citransfer_to_handler:: 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci #ifdef CONFIG_ALTIVEC 428c2ecf20Sopenharmony_ci BEGIN_FTR_SECTION 438c2ecf20Sopenharmony_ci mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */ 448c2ecf20Sopenharmony_ci stw r22,THREAD_VRSAVE(r23) 458c2ecf20Sopenharmony_ci END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 468c2ecf20Sopenharmony_ci #endif /* CONFIG_ALTIVEC */ 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciIf CPU 0 supports Altivec, the code is left untouched. If it doesn't, both 498c2ecf20Sopenharmony_ciinstructions are replaced with nop's. 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ciThe END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET 528c2ecf20Sopenharmony_ciand END_FTR_SECTION_IFCLR. These simply test if a flag is set (in 538c2ecf20Sopenharmony_cicur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros 548c2ecf20Sopenharmony_cishould be used in the majority of cases. 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciThe END_FTR_SECTION macros are implemented by storing information about this 578c2ecf20Sopenharmony_cicode in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups 588c2ecf20Sopenharmony_ci(arch/powerpc/kernel/misc.S) is invoked, it will iterate over the records in 598c2ecf20Sopenharmony_ci__ftr_fixup, and if the required feature is not present it will loop writing 608c2ecf20Sopenharmony_cinop's from each BEGIN_FTR_SECTION to END_FTR_SECTION. 61