0001
0002 #ifndef _ASM_UM_CPUFEATURE_H
0003 #define _ASM_UM_CPUFEATURE_H
0004
0005 #include <asm/processor.h>
0006
0007 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
0008
0009 #include <asm/asm.h>
0010 #include <linux/bitops.h>
0011
0012 extern const char * const x86_cap_flags[NCAPINTS*32];
0013 extern const char * const x86_power_flags[32];
0014 #define X86_CAP_FMT "%s"
0015 #define x86_cap_flag(flag) x86_cap_flags[flag]
0016
0017
0018
0019
0020
0021 extern const char * const x86_bug_flags[NBUGINTS*32];
0022
0023 #define test_cpu_cap(c, bit) \
0024 test_bit(bit, (unsigned long *)((c)->x86_capability))
0025
0026
0027
0028
0029
0030
0031
0032
0033 #define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
0034 (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
0035
0036 #define cpu_has(c, bit) \
0037 test_cpu_cap(c, bit)
0038
0039 #define this_cpu_has(bit) \
0040 (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
0041 x86_this_cpu_test_bit(bit, \
0042 (unsigned long __percpu *)&cpu_info.x86_capability))
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #define cpu_feature_enabled(bit) \
0053 (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
0054
0055 #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
0056
0057 #define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability))
0058
0059 extern void setup_clear_cpu_cap(unsigned int bit);
0060
0061 #define setup_force_cpu_cap(bit) do { \
0062 set_cpu_cap(&boot_cpu_data, bit); \
0063 set_bit(bit, (unsigned long *)cpu_caps_set); \
0064 } while (0)
0065
0066 #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 static __always_inline bool _static_cpu_has(u16 bit)
0077 {
0078 asm_volatile_goto("1: jmp 6f\n"
0079 "2:\n"
0080 ".skip -(((5f-4f) - (2b-1b)) > 0) * "
0081 "((5f-4f) - (2b-1b)),0x90\n"
0082 "3:\n"
0083 ".section .altinstructions,\"a\"\n"
0084 " .long 1b - .\n"
0085 " .long 4f - .\n"
0086 " .word %P[always]\n"
0087 " .byte 3b - 1b\n"
0088 " .byte 5f - 4f\n"
0089 " .byte 3b - 2b\n"
0090 ".previous\n"
0091 ".section .altinstr_replacement,\"ax\"\n"
0092 "4: jmp %l[t_no]\n"
0093 "5:\n"
0094 ".previous\n"
0095 ".section .altinstructions,\"a\"\n"
0096 " .long 1b - .\n"
0097 " .long 0\n"
0098 " .word %P[feature]\n"
0099 " .byte 3b - 1b\n"
0100 " .byte 0\n"
0101 " .byte 0\n"
0102 ".previous\n"
0103 ".section .altinstr_aux,\"ax\"\n"
0104 "6:\n"
0105 " testb %[bitnum],%[cap_byte]\n"
0106 " jnz %l[t_yes]\n"
0107 " jmp %l[t_no]\n"
0108 ".previous\n"
0109 : : [feature] "i" (bit),
0110 [always] "i" (X86_FEATURE_ALWAYS),
0111 [bitnum] "i" (1 << (bit & 7)),
0112 [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
0113 : : t_yes, t_no);
0114 t_yes:
0115 return true;
0116 t_no:
0117 return false;
0118 }
0119
0120 #define static_cpu_has(bit) \
0121 ( \
0122 __builtin_constant_p(boot_cpu_has(bit)) ? \
0123 boot_cpu_has(bit) : \
0124 _static_cpu_has(bit) \
0125 )
0126
0127 #define cpu_has_bug(c, bit) cpu_has(c, (bit))
0128 #define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
0129
0130 #define static_cpu_has_bug(bit) static_cpu_has((bit))
0131 #define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
0132 #define boot_cpu_set_bug(bit) set_cpu_cap(&boot_cpu_data, (bit))
0133
0134 #define MAX_CPU_FEATURES (NCAPINTS * 32)
0135 #define cpu_have_feature boot_cpu_has
0136
0137 #define CPU_FEATURE_TYPEFMT "x86,ven%04Xfam%04Xmod%04X"
0138 #define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
0139 boot_cpu_data.x86_model
0140
0141 #endif
0142 #endif