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