162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci#ifndef __ASM_POWERPC_FEATURE_FIXUPS_H 362306a36Sopenharmony_ci#define __ASM_POWERPC_FEATURE_FIXUPS_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <asm/asm-const.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* 1162306a36Sopenharmony_ci * Feature section common macros 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * Note that the entries now contain offsets between the table entry 1462306a36Sopenharmony_ci * and the code rather than absolute code pointers in order to be 1562306a36Sopenharmony_ci * useable with the vdso shared library. There is also an assumption 1662306a36Sopenharmony_ci * that values will be negative, that is, the fixup table has to be 1762306a36Sopenharmony_ci * located after the code it fixes up. 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci#if defined(CONFIG_PPC64) && !defined(__powerpc64__) 2062306a36Sopenharmony_ci/* 64 bits kernel, 32 bits code (ie. vdso32) */ 2162306a36Sopenharmony_ci#define FTR_ENTRY_LONG .8byte 2262306a36Sopenharmony_ci#define FTR_ENTRY_OFFSET .long 0xffffffff; .long 2362306a36Sopenharmony_ci#elif defined(CONFIG_PPC64) 2462306a36Sopenharmony_ci#define FTR_ENTRY_LONG .8byte 2562306a36Sopenharmony_ci#define FTR_ENTRY_OFFSET .8byte 2662306a36Sopenharmony_ci#else 2762306a36Sopenharmony_ci#define FTR_ENTRY_LONG .long 2862306a36Sopenharmony_ci#define FTR_ENTRY_OFFSET .long 2962306a36Sopenharmony_ci#endif 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define START_FTR_SECTION(label) label##1: 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define FTR_SECTION_ELSE_NESTED(label) \ 3462306a36Sopenharmony_cilabel##2: \ 3562306a36Sopenharmony_ci .pushsection __ftr_alt_##label,"a"; \ 3662306a36Sopenharmony_ci .align 2; \ 3762306a36Sopenharmony_cilabel##3: 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#ifndef CONFIG_CC_IS_CLANG 4162306a36Sopenharmony_ci#define CHECK_ALT_SIZE(else_size, body_size) \ 4262306a36Sopenharmony_ci .ifgt (else_size) - (body_size); \ 4362306a36Sopenharmony_ci .error "Feature section else case larger than body"; \ 4462306a36Sopenharmony_ci .endif; 4562306a36Sopenharmony_ci#else 4662306a36Sopenharmony_ci/* 4762306a36Sopenharmony_ci * If we use the ifgt syntax above, clang's assembler complains about the 4862306a36Sopenharmony_ci * expression being non-absolute when the code appears in an inline assembly 4962306a36Sopenharmony_ci * statement. 5062306a36Sopenharmony_ci * As a workaround use an .org directive that has no effect if the else case 5162306a36Sopenharmony_ci * instructions are smaller than the body, but fails otherwise. 5262306a36Sopenharmony_ci */ 5362306a36Sopenharmony_ci#define CHECK_ALT_SIZE(else_size, body_size) \ 5462306a36Sopenharmony_ci .org . + ((else_size) > (body_size)); 5562306a36Sopenharmony_ci#endif 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ 5862306a36Sopenharmony_cilabel##4: \ 5962306a36Sopenharmony_ci .popsection; \ 6062306a36Sopenharmony_ci .pushsection sect,"a"; \ 6162306a36Sopenharmony_ci .align 3; \ 6262306a36Sopenharmony_cilabel##5: \ 6362306a36Sopenharmony_ci FTR_ENTRY_LONG msk; \ 6462306a36Sopenharmony_ci FTR_ENTRY_LONG val; \ 6562306a36Sopenharmony_ci FTR_ENTRY_OFFSET label##1b-label##5b; \ 6662306a36Sopenharmony_ci FTR_ENTRY_OFFSET label##2b-label##5b; \ 6762306a36Sopenharmony_ci FTR_ENTRY_OFFSET label##3b-label##5b; \ 6862306a36Sopenharmony_ci FTR_ENTRY_OFFSET label##4b-label##5b; \ 6962306a36Sopenharmony_ci CHECK_ALT_SIZE((label##4b-label##3b), (label##2b-label##1b)); \ 7062306a36Sopenharmony_ci .popsection; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* CPU feature dependent sections */ 7462306a36Sopenharmony_ci#define BEGIN_FTR_SECTION_NESTED(label) START_FTR_SECTION(label) 7562306a36Sopenharmony_ci#define BEGIN_FTR_SECTION START_FTR_SECTION(97) 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci#define END_FTR_SECTION_NESTED(msk, val, label) \ 7862306a36Sopenharmony_ci FTR_SECTION_ELSE_NESTED(label) \ 7962306a36Sopenharmony_ci MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup) 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci#define END_FTR_SECTION(msk, val) \ 8262306a36Sopenharmony_ci END_FTR_SECTION_NESTED(msk, val, 97) 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#define END_FTR_SECTION_NESTED_IFSET(msk, label) \ 8562306a36Sopenharmony_ci END_FTR_SECTION_NESTED((msk), (msk), label) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) 8862306a36Sopenharmony_ci#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* CPU feature sections with alternatives, use BEGIN_FTR_SECTION to start */ 9162306a36Sopenharmony_ci#define FTR_SECTION_ELSE FTR_SECTION_ELSE_NESTED(97) 9262306a36Sopenharmony_ci#define ALT_FTR_SECTION_END_NESTED(msk, val, label) \ 9362306a36Sopenharmony_ci MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup) 9462306a36Sopenharmony_ci#define ALT_FTR_SECTION_END_NESTED_IFSET(msk, label) \ 9562306a36Sopenharmony_ci ALT_FTR_SECTION_END_NESTED(msk, msk, label) 9662306a36Sopenharmony_ci#define ALT_FTR_SECTION_END_NESTED_IFCLR(msk, label) \ 9762306a36Sopenharmony_ci ALT_FTR_SECTION_END_NESTED(msk, 0, label) 9862306a36Sopenharmony_ci#define ALT_FTR_SECTION_END(msk, val) \ 9962306a36Sopenharmony_ci ALT_FTR_SECTION_END_NESTED(msk, val, 97) 10062306a36Sopenharmony_ci#define ALT_FTR_SECTION_END_IFSET(msk) \ 10162306a36Sopenharmony_ci ALT_FTR_SECTION_END_NESTED_IFSET(msk, 97) 10262306a36Sopenharmony_ci#define ALT_FTR_SECTION_END_IFCLR(msk) \ 10362306a36Sopenharmony_ci ALT_FTR_SECTION_END_NESTED_IFCLR(msk, 97) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* MMU feature dependent sections */ 10662306a36Sopenharmony_ci#define BEGIN_MMU_FTR_SECTION_NESTED(label) START_FTR_SECTION(label) 10762306a36Sopenharmony_ci#define BEGIN_MMU_FTR_SECTION START_FTR_SECTION(97) 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#define END_MMU_FTR_SECTION_NESTED(msk, val, label) \ 11062306a36Sopenharmony_ci FTR_SECTION_ELSE_NESTED(label) \ 11162306a36Sopenharmony_ci MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#define END_MMU_FTR_SECTION(msk, val) \ 11462306a36Sopenharmony_ci END_MMU_FTR_SECTION_NESTED(msk, val, 97) 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci#define END_MMU_FTR_SECTION_NESTED_IFSET(msk, label) \ 11762306a36Sopenharmony_ci END_MMU_FTR_SECTION_NESTED((msk), (msk), label) 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#define END_MMU_FTR_SECTION_NESTED_IFCLR(msk, label) \ 12062306a36Sopenharmony_ci END_MMU_FTR_SECTION_NESTED((msk), 0, label) 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci#define END_MMU_FTR_SECTION_IFSET(msk) END_MMU_FTR_SECTION((msk), (msk)) 12362306a36Sopenharmony_ci#define END_MMU_FTR_SECTION_IFCLR(msk) END_MMU_FTR_SECTION((msk), 0) 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/* MMU feature sections with alternatives, use BEGIN_FTR_SECTION to start */ 12662306a36Sopenharmony_ci#define MMU_FTR_SECTION_ELSE_NESTED(label) FTR_SECTION_ELSE_NESTED(label) 12762306a36Sopenharmony_ci#define MMU_FTR_SECTION_ELSE MMU_FTR_SECTION_ELSE_NESTED(97) 12862306a36Sopenharmony_ci#define ALT_MMU_FTR_SECTION_END_NESTED(msk, val, label) \ 12962306a36Sopenharmony_ci MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup) 13062306a36Sopenharmony_ci#define ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, label) \ 13162306a36Sopenharmony_ci ALT_MMU_FTR_SECTION_END_NESTED(msk, msk, label) 13262306a36Sopenharmony_ci#define ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, label) \ 13362306a36Sopenharmony_ci ALT_MMU_FTR_SECTION_END_NESTED(msk, 0, label) 13462306a36Sopenharmony_ci#define ALT_MMU_FTR_SECTION_END(msk, val) \ 13562306a36Sopenharmony_ci ALT_MMU_FTR_SECTION_END_NESTED(msk, val, 97) 13662306a36Sopenharmony_ci#define ALT_MMU_FTR_SECTION_END_IFSET(msk) \ 13762306a36Sopenharmony_ci ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, 97) 13862306a36Sopenharmony_ci#define ALT_MMU_FTR_SECTION_END_IFCLR(msk) \ 13962306a36Sopenharmony_ci ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, 97) 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* Firmware feature dependent sections */ 14262306a36Sopenharmony_ci#define BEGIN_FW_FTR_SECTION_NESTED(label) START_FTR_SECTION(label) 14362306a36Sopenharmony_ci#define BEGIN_FW_FTR_SECTION START_FTR_SECTION(97) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci#define END_FW_FTR_SECTION_NESTED(msk, val, label) \ 14662306a36Sopenharmony_ci FTR_SECTION_ELSE_NESTED(label) \ 14762306a36Sopenharmony_ci MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci#define END_FW_FTR_SECTION(msk, val) \ 15062306a36Sopenharmony_ci END_FW_FTR_SECTION_NESTED(msk, val, 97) 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci#define END_FW_FTR_SECTION_IFSET(msk) END_FW_FTR_SECTION((msk), (msk)) 15362306a36Sopenharmony_ci#define END_FW_FTR_SECTION_IFCLR(msk) END_FW_FTR_SECTION((msk), 0) 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci/* Firmware feature sections with alternatives */ 15662306a36Sopenharmony_ci#define FW_FTR_SECTION_ELSE_NESTED(label) FTR_SECTION_ELSE_NESTED(label) 15762306a36Sopenharmony_ci#define FW_FTR_SECTION_ELSE FTR_SECTION_ELSE_NESTED(97) 15862306a36Sopenharmony_ci#define ALT_FW_FTR_SECTION_END_NESTED(msk, val, label) \ 15962306a36Sopenharmony_ci MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup) 16062306a36Sopenharmony_ci#define ALT_FW_FTR_SECTION_END_NESTED_IFSET(msk, label) \ 16162306a36Sopenharmony_ci ALT_FW_FTR_SECTION_END_NESTED(msk, msk, label) 16262306a36Sopenharmony_ci#define ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, label) \ 16362306a36Sopenharmony_ci ALT_FW_FTR_SECTION_END_NESTED(msk, 0, label) 16462306a36Sopenharmony_ci#define ALT_FW_FTR_SECTION_END(msk, val) \ 16562306a36Sopenharmony_ci ALT_FW_FTR_SECTION_END_NESTED(msk, val, 97) 16662306a36Sopenharmony_ci#define ALT_FW_FTR_SECTION_END_IFSET(msk) \ 16762306a36Sopenharmony_ci ALT_FW_FTR_SECTION_END_NESTED_IFSET(msk, 97) 16862306a36Sopenharmony_ci#define ALT_FW_FTR_SECTION_END_IFCLR(msk) \ 16962306a36Sopenharmony_ci ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, 97) 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#define ASM_FTR_IF(section_if, section_else, msk, val) \ 17462306a36Sopenharmony_ci stringify_in_c(BEGIN_FTR_SECTION) \ 17562306a36Sopenharmony_ci section_if "; " \ 17662306a36Sopenharmony_ci stringify_in_c(FTR_SECTION_ELSE) \ 17762306a36Sopenharmony_ci section_else "; " \ 17862306a36Sopenharmony_ci stringify_in_c(ALT_FTR_SECTION_END((msk), (val))) 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci#define ASM_FTR_IFSET(section_if, section_else, msk) \ 18162306a36Sopenharmony_ci ASM_FTR_IF(section_if, section_else, (msk), (msk)) 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#define ASM_FTR_IFCLR(section_if, section_else, msk) \ 18462306a36Sopenharmony_ci ASM_FTR_IF(section_if, section_else, (msk), 0) 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci#define ASM_MMU_FTR_IF(section_if, section_else, msk, val) \ 18762306a36Sopenharmony_ci stringify_in_c(BEGIN_MMU_FTR_SECTION) \ 18862306a36Sopenharmony_ci section_if "; " \ 18962306a36Sopenharmony_ci stringify_in_c(MMU_FTR_SECTION_ELSE) \ 19062306a36Sopenharmony_ci section_else "; " \ 19162306a36Sopenharmony_ci stringify_in_c(ALT_MMU_FTR_SECTION_END((msk), (val))) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci#define ASM_MMU_FTR_IFSET(section_if, section_else, msk) \ 19462306a36Sopenharmony_ci ASM_MMU_FTR_IF(section_if, section_else, (msk), (msk)) 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci#define ASM_MMU_FTR_IFCLR(section_if, section_else, msk) \ 19762306a36Sopenharmony_ci ASM_MMU_FTR_IF(section_if, section_else, (msk), 0) 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */ 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci/* LWSYNC feature sections */ 20262306a36Sopenharmony_ci#define START_LWSYNC_SECTION(label) label##1: 20362306a36Sopenharmony_ci#define MAKE_LWSYNC_SECTION_ENTRY(label, sect) \ 20462306a36Sopenharmony_cilabel##2: \ 20562306a36Sopenharmony_ci .pushsection sect,"a"; \ 20662306a36Sopenharmony_ci .align 2; \ 20762306a36Sopenharmony_cilabel##3: \ 20862306a36Sopenharmony_ci FTR_ENTRY_OFFSET label##1b-label##3b; \ 20962306a36Sopenharmony_ci .popsection; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define STF_ENTRY_BARRIER_FIXUP_SECTION \ 21262306a36Sopenharmony_ci953: \ 21362306a36Sopenharmony_ci .pushsection __stf_entry_barrier_fixup,"a"; \ 21462306a36Sopenharmony_ci .align 2; \ 21562306a36Sopenharmony_ci954: \ 21662306a36Sopenharmony_ci FTR_ENTRY_OFFSET 953b-954b; \ 21762306a36Sopenharmony_ci .popsection; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci#define STF_EXIT_BARRIER_FIXUP_SECTION \ 22062306a36Sopenharmony_ci955: \ 22162306a36Sopenharmony_ci .pushsection __stf_exit_barrier_fixup,"a"; \ 22262306a36Sopenharmony_ci .align 2; \ 22362306a36Sopenharmony_ci956: \ 22462306a36Sopenharmony_ci FTR_ENTRY_OFFSET 955b-956b; \ 22562306a36Sopenharmony_ci .popsection; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci#define UACCESS_FLUSH_FIXUP_SECTION \ 22862306a36Sopenharmony_ci959: \ 22962306a36Sopenharmony_ci .pushsection __uaccess_flush_fixup,"a"; \ 23062306a36Sopenharmony_ci .align 2; \ 23162306a36Sopenharmony_ci960: \ 23262306a36Sopenharmony_ci FTR_ENTRY_OFFSET 959b-960b; \ 23362306a36Sopenharmony_ci .popsection; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci#define ENTRY_FLUSH_FIXUP_SECTION \ 23662306a36Sopenharmony_ci957: \ 23762306a36Sopenharmony_ci .pushsection __entry_flush_fixup,"a"; \ 23862306a36Sopenharmony_ci .align 2; \ 23962306a36Sopenharmony_ci958: \ 24062306a36Sopenharmony_ci FTR_ENTRY_OFFSET 957b-958b; \ 24162306a36Sopenharmony_ci .popsection; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci#define SCV_ENTRY_FLUSH_FIXUP_SECTION \ 24462306a36Sopenharmony_ci957: \ 24562306a36Sopenharmony_ci .pushsection __scv_entry_flush_fixup,"a"; \ 24662306a36Sopenharmony_ci .align 2; \ 24762306a36Sopenharmony_ci958: \ 24862306a36Sopenharmony_ci FTR_ENTRY_OFFSET 957b-958b; \ 24962306a36Sopenharmony_ci .popsection; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci#define RFI_FLUSH_FIXUP_SECTION \ 25262306a36Sopenharmony_ci951: \ 25362306a36Sopenharmony_ci .pushsection __rfi_flush_fixup,"a"; \ 25462306a36Sopenharmony_ci .align 2; \ 25562306a36Sopenharmony_ci952: \ 25662306a36Sopenharmony_ci FTR_ENTRY_OFFSET 951b-952b; \ 25762306a36Sopenharmony_ci .popsection; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci#define NOSPEC_BARRIER_FIXUP_SECTION \ 26062306a36Sopenharmony_ci953: \ 26162306a36Sopenharmony_ci .pushsection __barrier_nospec_fixup,"a"; \ 26262306a36Sopenharmony_ci .align 2; \ 26362306a36Sopenharmony_ci954: \ 26462306a36Sopenharmony_ci FTR_ENTRY_OFFSET 953b-954b; \ 26562306a36Sopenharmony_ci .popsection; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci#define START_BTB_FLUSH_SECTION \ 26862306a36Sopenharmony_ci955: \ 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci#define END_BTB_FLUSH_SECTION \ 27162306a36Sopenharmony_ci956: \ 27262306a36Sopenharmony_ci .pushsection __btb_flush_fixup,"a"; \ 27362306a36Sopenharmony_ci .align 2; \ 27462306a36Sopenharmony_ci957: \ 27562306a36Sopenharmony_ci FTR_ENTRY_OFFSET 955b-957b; \ 27662306a36Sopenharmony_ci FTR_ENTRY_OFFSET 956b-957b; \ 27762306a36Sopenharmony_ci .popsection; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 28062306a36Sopenharmony_ci#include <linux/types.h> 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ciextern long stf_barrier_fallback; 28362306a36Sopenharmony_ciextern long entry_flush_fallback; 28462306a36Sopenharmony_ciextern long scv_entry_flush_fallback; 28562306a36Sopenharmony_ciextern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; 28662306a36Sopenharmony_ciextern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; 28762306a36Sopenharmony_ciextern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup; 28862306a36Sopenharmony_ciextern long __start___entry_flush_fixup, __stop___entry_flush_fixup; 28962306a36Sopenharmony_ciextern long __start___scv_entry_flush_fixup, __stop___scv_entry_flush_fixup; 29062306a36Sopenharmony_ciextern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; 29162306a36Sopenharmony_ciextern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; 29262306a36Sopenharmony_ciextern long __start__btb_flush_fixup, __stop__btb_flush_fixup; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_civoid apply_feature_fixups(void); 29562306a36Sopenharmony_civoid update_mmu_feature_fixups(unsigned long mask); 29662306a36Sopenharmony_civoid setup_feature_keys(void); 29762306a36Sopenharmony_ci#endif 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */ 300