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