^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) CPU Features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Hollis Blanchard <hollis@austin.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) 5 Jun 2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) This document describes the system (including self-modifying code) used in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) PPC Linux kernel to support a variety of PowerPC CPUs without requiring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) compile-time selection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) Early in the boot process the ppc32 kernel detects the current CPU type and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) chooses a set of features accordingly. Some examples include Altivec support,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) split instruction and data caches, and if the CPU supports the DOZE and NAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) sleep modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) Detection of the feature set is simple. A list of processors can be found in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) arch/powerpc/kernel/cputable.c. The PVR register is masked and compared with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) each value in the list. If a match is found, the cpu_features of cur_cpu_spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) is assigned to the feature bitmask for this processor and a __setup_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) function is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) C code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) particular feature bit. This is done in quite a few places, for example
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) in ppc_setup_l2cr().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) Implementing cpufeatures in assembly is a little more involved. There are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) several paths that are performance-critical and would suffer if an array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) index, structure dereference, and conditional branch were added. To avoid the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) performance penalty but still allow for runtime (rather than compile-time) CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) selection, unused code is replaced by 'nop' instructions. This nop'ing is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) based on CPU 0's capabilities, so a multi-processor system with non-identical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) processors will not work (but such a system would likely have other problems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) anyways).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) After detecting the processor type, the kernel patches out sections of code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) that shouldn't be used by writing nop's over it. Using cpufeatures requires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) just 2 macros (found in arch/powerpc/include/asm/cputable.h), as seen in head.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) transfer_to_handler::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) BEGIN_FTR_SECTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) stw r22,THREAD_VRSAVE(r23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #endif /* CONFIG_ALTIVEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) If CPU 0 supports Altivec, the code is left untouched. If it doesn't, both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) instructions are replaced with nop's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) The END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) should be used in the majority of cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) The END_FTR_SECTION macros are implemented by storing information about this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) (arch/powerpc/kernel/misc.S) is invoked, it will iterate over the records in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __ftr_fixup, and if the required feature is not present it will loop writing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.