€•C)Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ-/translations/zh_CN/arch/powerpc/cpu_features”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/zh_TW/arch/powerpc/cpu_features”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/it_IT/arch/powerpc/cpu_features”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ja_JP/arch/powerpc/cpu_features”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ko_KR/arch/powerpc/cpu_features”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/sp_SP/arch/powerpc/cpu_features”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ CPU Features”h]”hŒ CPU Features”…””}”(hh¨hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hh£hžhhŸŒG/var/lib/git/docbuild/linux/Documentation/arch/powerpc/cpu_features.rst”h KubhŒ paragraph”“”)”}”(hŒ3Hollis Blanchard 5 Jun 2002”h]”(hŒHollis Blanchard <”…””}”(hh¹hžhhŸNh NubhŒ reference”“”)”}”(hŒhollis@austin.ibm.com”h]”hŒhollis@austin.ibm.com”…””}”(hhÃhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:hollis@austin.ibm.com”uh1hÁhh¹ubhŒ > 5 Jun 2002”…””}”(hh¹hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hŒ®This document describes the system (including self-modifying code) used in the PPC Linux kernel to support a variety of PowerPC CPUs without requiring compile-time selection.”h]”hŒ®This document describes the system (including self-modifying code) used in the PPC Linux kernel to support a variety of PowerPC CPUs without requiring compile-time selection.”…””}”(hhÝhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hŒòEarly in the boot process the ppc32 kernel detects the current CPU type and chooses a set of features accordingly. Some examples include Altivec support, split instruction and data caches, and if the CPU supports the DOZE and NAP sleep modes.”h]”hŒòEarly in the boot process the ppc32 kernel detects the current CPU type and chooses a set of features accordingly. Some examples include Altivec support, split instruction and data caches, and if the CPU supports the DOZE and NAP sleep modes.”…””}”(hhëhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K hh£hžhubh¸)”}”(hXCDetection of the feature set is simple. A list of processors can be found in arch/powerpc/kernel/cputable.c. The PVR register is masked and compared with each value in the list. If a match is found, the cpu_features of cur_cpu_spec is assigned to the feature bitmask for this processor and a __setup_cpu function is called.”h]”hXCDetection of the feature set is simple. A list of processors can be found in arch/powerpc/kernel/cputable.c. The PVR register is masked and compared with each value in the list. If a match is found, the cpu_features of cur_cpu_spec is assigned to the feature bitmask for this processor and a __setup_cpu function is called.”…””}”(hhùhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hŒ£C code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a particular feature bit. This is done in quite a few places, for example in ppc_setup_l2cr().”h]”hŒ§C code may test ‘cur_cpu_spec[smp_processor_id()]->cpu_features’ for a particular feature bit. This is done in quite a few places, for example in ppc_setup_l2cr().”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hXImplementing cpufeatures in assembly is a little more involved. There are several paths that are performance-critical and would suffer if an array index, structure dereference, and conditional branch were added. To avoid the performance penalty but still allow for runtime (rather than compile-time) CPU selection, unused code is replaced by 'nop' instructions. This nop'ing is based on CPU 0's capabilities, so a multi-processor system with non-identical processors will not work (but such a system would likely have other problems anyways).”h]”hX&Implementing cpufeatures in assembly is a little more involved. There are several paths that are performance-critical and would suffer if an array index, structure dereference, and conditional branch were added. To avoid the performance penalty but still allow for runtime (rather than compile-time) CPU selection, unused code is replaced by ‘nop’ instructions. This nop’ing is based on CPU 0’s capabilities, so a multi-processor system with non-identical processors will not work (but such a system would likely have other problems anyways).”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hŒýAfter detecting the processor type, the kernel patches out sections of code that shouldn't be used by writing nop's over it. Using cpufeatures requires just 2 macros (found in arch/powerpc/include/asm/cputable.h), as seen in head.S transfer_to_handler::”h]”hXAfter detecting the processor type, the kernel patches out sections of code that shouldn’t be used by writing nop’s over it. Using cpufeatures requires just 2 macros (found in arch/powerpc/include/asm/cputable.h), as seen in head.S transfer_to_handler:”…””}”(hj#hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K$hh£hžhubhŒ literal_block”“”)”}”(hŒá#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 */”h]”hŒá#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 */”…””}”hj3sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j1hŸh¶h K)hh£hžhubh¸)”}”(hŒpIf CPU 0 supports Altivec, the code is left untouched. If it doesn't, both instructions are replaced with nop's.”h]”hŒtIf CPU 0 supports Altivec, the code is left untouched. If it doesn’t, both instructions are replaced with nop’s.”…””}”(hjChžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K0hh£hžhubh¸)”}”(hXThe END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros should be used in the majority of cases.”h]”hXThe END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros should be used in the majority of cases.”…””}”(hjQhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K3hh£hžhubh¸)”}”(hXZThe END_FTR_SECTION macros are implemented by storing information about this code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups (arch/powerpc/kernel/misc.S) is invoked, it will iterate over the records in __ftr_fixup, and if the required feature is not present it will loop writing nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.”h]”hX`The END_FTR_SECTION macros are implemented by storing information about this code in the ‘__ftr_fixup’ ELF section. When do_cpu_ftr_fixups (arch/powerpc/kernel/misc.S) is invoked, it will iterate over the records in __ftr_fixup, and if the required feature is not present it will loop writing nop’s from each BEGIN_FTR_SECTION to END_FTR_SECTION.”…””}”(hj_hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K8hh£hžhubeh}”(h]”Œ cpu-features”ah ]”h"]”Œ cpu features”ah$]”h&]”uh1h¡hhhžhhŸh¶h Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h¶uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(h¦NŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j˜Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h¶Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”jrjosŒ nametypes”}”jr‰sh}”joh£sŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.