1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2266d63a7SIngo Molnar #ifndef _ASM_X86_CPU_DEVICE_ID 3266d63a7SIngo Molnar #define _ASM_X86_CPU_DEVICE_ID 4644e9cbbSAndi Kleen 5644e9cbbSAndi Kleen /* 671cf8cfdSTony Luck * Can't use <linux/bitfield.h> because it generates expressions that 771cf8cfdSTony Luck * cannot be used in structure initializers. Bitfield construction 871cf8cfdSTony Luck * here must match the union in struct cpuinfo_86: 971cf8cfdSTony Luck * union { 1071cf8cfdSTony Luck * struct { 1171cf8cfdSTony Luck * __u8 x86_model; 1271cf8cfdSTony Luck * __u8 x86; 1371cf8cfdSTony Luck * __u8 x86_vendor; 1471cf8cfdSTony Luck * __u8 x86_reserved; 1571cf8cfdSTony Luck * }; 1671cf8cfdSTony Luck * __u32 x86_vfm; 1771cf8cfdSTony Luck * }; 1871cf8cfdSTony Luck */ 1971cf8cfdSTony Luck #define VFM_MODEL_BIT 0 2071cf8cfdSTony Luck #define VFM_FAMILY_BIT 8 2171cf8cfdSTony Luck #define VFM_VENDOR_BIT 16 2271cf8cfdSTony Luck #define VFM_RSVD_BIT 24 2371cf8cfdSTony Luck 2471cf8cfdSTony Luck #define VFM_MODEL_MASK GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT) 2571cf8cfdSTony Luck #define VFM_FAMILY_MASK GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT) 2671cf8cfdSTony Luck #define VFM_VENDOR_MASK GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT) 2771cf8cfdSTony Luck 2871cf8cfdSTony Luck #define VFM_MODEL(vfm) (((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT) 2971cf8cfdSTony Luck #define VFM_FAMILY(vfm) (((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT) 3071cf8cfdSTony Luck #define VFM_VENDOR(vfm) (((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT) 3171cf8cfdSTony Luck 3271cf8cfdSTony Luck #define VFM_MAKE(_vendor, _family, _model) ( \ 3371cf8cfdSTony Luck ((_model) << VFM_MODEL_BIT) | \ 3471cf8cfdSTony Luck ((_family) << VFM_FAMILY_BIT) | \ 3571cf8cfdSTony Luck ((_vendor) << VFM_VENDOR_BIT) \ 3671cf8cfdSTony Luck ) 3771cf8cfdSTony Luck 3871cf8cfdSTony Luck /* 39644e9cbbSAndi Kleen * Declare drivers belonging to specific x86 CPUs 40644e9cbbSAndi Kleen * Similar in spirit to pci_device_id and related PCI functions 4120d43744SThomas Gleixner * 42ba5bade4SThomas Gleixner * The wildcard initializers are in mod_devicetable.h because 43ba5bade4SThomas Gleixner * file2alias needs them. Sigh. 44ba5bade4SThomas Gleixner */ 4520d43744SThomas Gleixner #include <linux/mod_devicetable.h> 4620d43744SThomas Gleixner /* Get the INTEL_FAM* model defines */ 4720d43744SThomas Gleixner #include <asm/intel-family.h> 4820d43744SThomas Gleixner /* And the X86_VENDOR_* ones */ 4920d43744SThomas Gleixner #include <asm/processor.h> 50ba5bade4SThomas Gleixner 5120d43744SThomas Gleixner /* Centaur FAM6 models */ 5220d43744SThomas Gleixner #define X86_CENTAUR_FAM6_C7_A 0xa 5320d43744SThomas Gleixner #define X86_CENTAUR_FAM6_C7_D 0xd 5420d43744SThomas Gleixner #define X86_CENTAUR_FAM6_NANO 0xf 5520d43744SThomas Gleixner 56*65ac09c9STony Luck /* x86_cpu_id::flags */ 57*65ac09c9STony Luck #define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0) 58*65ac09c9STony Luck 59e9d71445SMark Gross #define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) 6020d43744SThomas Gleixner /** 61e9d71445SMark Gross * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching 6220d43744SThomas Gleixner * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY 6320d43744SThomas Gleixner * The name is expanded to X86_VENDOR_@_vendor 6420d43744SThomas Gleixner * @_family: The family number or X86_FAMILY_ANY 6520d43744SThomas Gleixner * @_model: The model number, model constant or X86_MODEL_ANY 66e9d71445SMark Gross * @_steppings: Bitmask for steppings, stepping constant or X86_STEPPING_ANY 6720d43744SThomas Gleixner * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY 6820d43744SThomas Gleixner * @_data: Driver specific data or NULL. The internal storage 6920d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 7020d43744SThomas Gleixner * etc. is casted to unsigned long internally. 7120d43744SThomas Gleixner * 7220d43744SThomas Gleixner * Use only if you need all selectors. Otherwise use one of the shorter 7320d43744SThomas Gleixner * macros of the X86_MATCH_* family. If there is no matching shorthand 7420d43744SThomas Gleixner * macro, consider to add one. If you really need to wrap one of the macros 7520d43744SThomas Gleixner * into another macro at the usage site for good reasons, then please 7620d43744SThomas Gleixner * start this local macro with X86_MATCH to allow easy grepping. 7720d43744SThomas Gleixner */ 78e9d71445SMark Gross #define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ 79e9d71445SMark Gross _steppings, _feature, _data) { \ 8020d43744SThomas Gleixner .vendor = X86_VENDOR_##_vendor, \ 8120d43744SThomas Gleixner .family = _family, \ 8220d43744SThomas Gleixner .model = _model, \ 83e9d71445SMark Gross .steppings = _steppings, \ 8420d43744SThomas Gleixner .feature = _feature, \ 85*65ac09c9STony Luck .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ 8620d43744SThomas Gleixner .driver_data = (unsigned long) _data \ 87ba5bade4SThomas Gleixner } 88ba5bade4SThomas Gleixner 8971cf8cfdSTony Luck #define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ 9071cf8cfdSTony Luck _steppings, _feature, _data) { \ 9171cf8cfdSTony Luck .vendor = _vendor, \ 9271cf8cfdSTony Luck .family = _family, \ 9371cf8cfdSTony Luck .model = _model, \ 9471cf8cfdSTony Luck .steppings = _steppings, \ 9571cf8cfdSTony Luck .feature = _feature, \ 96*65ac09c9STony Luck .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ 9771cf8cfdSTony Luck .driver_data = (unsigned long) _data \ 9871cf8cfdSTony Luck } 9971cf8cfdSTony Luck 10020d43744SThomas Gleixner /** 101e9d71445SMark Gross * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Macro for CPU matching 102e9d71445SMark Gross * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY 103e9d71445SMark Gross * The name is expanded to X86_VENDOR_@_vendor 104e9d71445SMark Gross * @_family: The family number or X86_FAMILY_ANY 105e9d71445SMark Gross * @_model: The model number, model constant or X86_MODEL_ANY 106e9d71445SMark Gross * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY 107e9d71445SMark Gross * @_data: Driver specific data or NULL. The internal storage 108e9d71445SMark Gross * format is unsigned long. The supplied value, pointer 109e9d71445SMark Gross * etc. is casted to unsigned long internally. 110e9d71445SMark Gross * 111e9d71445SMark Gross * The steppings arguments of X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE() is 112e9d71445SMark Gross * set to wildcards. 113e9d71445SMark Gross */ 114e9d71445SMark Gross #define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, model, feature, data) \ 115e9d71445SMark Gross X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(vendor, family, model, \ 116e9d71445SMark Gross X86_STEPPING_ANY, feature, data) 117e9d71445SMark Gross 118e9d71445SMark Gross /** 11920d43744SThomas Gleixner * X86_MATCH_VENDOR_FAM_FEATURE - Macro for matching vendor, family and CPU feature 12020d43744SThomas Gleixner * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY 12120d43744SThomas Gleixner * The name is expanded to X86_VENDOR_@vendor 12220d43744SThomas Gleixner * @family: The family number or X86_FAMILY_ANY 12320d43744SThomas Gleixner * @feature: A X86_FEATURE bit 12420d43744SThomas Gleixner * @data: Driver specific data or NULL. The internal storage 12520d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 12620d43744SThomas Gleixner * etc. is casted to unsigned long internally. 12720d43744SThomas Gleixner * 12820d43744SThomas Gleixner * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are 12920d43744SThomas Gleixner * set to wildcards. 13020d43744SThomas Gleixner */ 13120d43744SThomas Gleixner #define X86_MATCH_VENDOR_FAM_FEATURE(vendor, family, feature, data) \ 13220d43744SThomas Gleixner X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, \ 13320d43744SThomas Gleixner X86_MODEL_ANY, feature, data) 13420d43744SThomas Gleixner 13520d43744SThomas Gleixner /** 13620d43744SThomas Gleixner * X86_MATCH_VENDOR_FEATURE - Macro for matching vendor and CPU feature 13720d43744SThomas Gleixner * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY 13820d43744SThomas Gleixner * The name is expanded to X86_VENDOR_@vendor 13920d43744SThomas Gleixner * @feature: A X86_FEATURE bit 14020d43744SThomas Gleixner * @data: Driver specific data or NULL. The internal storage 14120d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 14220d43744SThomas Gleixner * etc. is casted to unsigned long internally. 14320d43744SThomas Gleixner * 14420d43744SThomas Gleixner * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are 14520d43744SThomas Gleixner * set to wildcards. 14620d43744SThomas Gleixner */ 14720d43744SThomas Gleixner #define X86_MATCH_VENDOR_FEATURE(vendor, feature, data) \ 14820d43744SThomas Gleixner X86_MATCH_VENDOR_FAM_FEATURE(vendor, X86_FAMILY_ANY, feature, data) 14920d43744SThomas Gleixner 15020d43744SThomas Gleixner /** 15120d43744SThomas Gleixner * X86_MATCH_FEATURE - Macro for matching a CPU feature 15220d43744SThomas Gleixner * @feature: A X86_FEATURE bit 15320d43744SThomas Gleixner * @data: Driver specific data or NULL. The internal storage 15420d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 15520d43744SThomas Gleixner * etc. is casted to unsigned long internally. 15620d43744SThomas Gleixner * 15720d43744SThomas Gleixner * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are 15820d43744SThomas Gleixner * set to wildcards. 15920d43744SThomas Gleixner */ 16020d43744SThomas Gleixner #define X86_MATCH_FEATURE(feature, data) \ 16120d43744SThomas Gleixner X86_MATCH_VENDOR_FEATURE(ANY, feature, data) 16220d43744SThomas Gleixner 16320d43744SThomas Gleixner /** 16420d43744SThomas Gleixner * X86_MATCH_VENDOR_FAM_MODEL - Match vendor, family and model 16520d43744SThomas Gleixner * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY 16620d43744SThomas Gleixner * The name is expanded to X86_VENDOR_@vendor 16720d43744SThomas Gleixner * @family: The family number or X86_FAMILY_ANY 16820d43744SThomas Gleixner * @model: The model number, model constant or X86_MODEL_ANY 16920d43744SThomas Gleixner * @data: Driver specific data or NULL. The internal storage 17020d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 17120d43744SThomas Gleixner * etc. is casted to unsigned long internally. 17220d43744SThomas Gleixner * 17320d43744SThomas Gleixner * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are 17420d43744SThomas Gleixner * set to wildcards. 17520d43744SThomas Gleixner */ 17620d43744SThomas Gleixner #define X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, data) \ 17720d43744SThomas Gleixner X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, model, \ 17820d43744SThomas Gleixner X86_FEATURE_ANY, data) 17920d43744SThomas Gleixner 18020d43744SThomas Gleixner /** 18120d43744SThomas Gleixner * X86_MATCH_VENDOR_FAM - Match vendor and family 18220d43744SThomas Gleixner * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY 18320d43744SThomas Gleixner * The name is expanded to X86_VENDOR_@vendor 18420d43744SThomas Gleixner * @family: The family number or X86_FAMILY_ANY 18520d43744SThomas Gleixner * @data: Driver specific data or NULL. The internal storage 18620d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 18720d43744SThomas Gleixner * etc. is casted to unsigned long internally. 18820d43744SThomas Gleixner * 18920d43744SThomas Gleixner * All other missing arguments to X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are 19020d43744SThomas Gleixner * set of wildcards. 19120d43744SThomas Gleixner */ 19220d43744SThomas Gleixner #define X86_MATCH_VENDOR_FAM(vendor, family, data) \ 19320d43744SThomas Gleixner X86_MATCH_VENDOR_FAM_MODEL(vendor, family, X86_MODEL_ANY, data) 19420d43744SThomas Gleixner 19520d43744SThomas Gleixner /** 19620d43744SThomas Gleixner * X86_MATCH_INTEL_FAM6_MODEL - Match vendor INTEL, family 6 and model 19720d43744SThomas Gleixner * @model: The model name without the INTEL_FAM6_ prefix or ANY 19820d43744SThomas Gleixner * The model name is expanded to INTEL_FAM6_@model internally 19920d43744SThomas Gleixner * @data: Driver specific data or NULL. The internal storage 20020d43744SThomas Gleixner * format is unsigned long. The supplied value, pointer 20120d43744SThomas Gleixner * etc. is casted to unsigned long internally. 20220d43744SThomas Gleixner * 20320d43744SThomas Gleixner * The vendor is set to INTEL, the family to 6 and all other missing 20420d43744SThomas Gleixner * arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are set to wildcards. 20520d43744SThomas Gleixner * 20620d43744SThomas Gleixner * See X86_MATCH_VENDOR_FAM_MODEL_FEATURE() for further information. 20720d43744SThomas Gleixner */ 20820d43744SThomas Gleixner #define X86_MATCH_INTEL_FAM6_MODEL(model, data) \ 20920d43744SThomas Gleixner X86_MATCH_VENDOR_FAM_MODEL(INTEL, 6, INTEL_FAM6_##model, data) 21020d43744SThomas Gleixner 211d8422f6bSBorislav Petkov #define X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(model, steppings, data) \ 212d8422f6bSBorislav Petkov X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ 213d8422f6bSBorislav Petkov steppings, X86_FEATURE_ANY, data) 214d8422f6bSBorislav Petkov 21571cf8cfdSTony Luck /** 21671cf8cfdSTony Luck * X86_MATCH_VFM - Match encoded vendor/family/model 21771cf8cfdSTony Luck * @vfm: Encoded 8-bits each for vendor, family, model 21871cf8cfdSTony Luck * @data: Driver specific data or NULL. The internal storage 21971cf8cfdSTony Luck * format is unsigned long. The supplied value, pointer 22071cf8cfdSTony Luck * etc. is cast to unsigned long internally. 22171cf8cfdSTony Luck * 22271cf8cfdSTony Luck * Stepping and feature are set to wildcards 22371cf8cfdSTony Luck */ 22471cf8cfdSTony Luck #define X86_MATCH_VFM(vfm, data) \ 22571cf8cfdSTony Luck X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ 22671cf8cfdSTony Luck VFM_VENDOR(vfm), \ 22771cf8cfdSTony Luck VFM_FAMILY(vfm), \ 22871cf8cfdSTony Luck VFM_MODEL(vfm), \ 22971cf8cfdSTony Luck X86_STEPPING_ANY, X86_FEATURE_ANY, data) 23071cf8cfdSTony Luck 23171cf8cfdSTony Luck /** 23271cf8cfdSTony Luck * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping 23371cf8cfdSTony Luck * @vfm: Encoded 8-bits each for vendor, family, model 23471cf8cfdSTony Luck * @steppings: Bitmask of steppings to match 23571cf8cfdSTony Luck * @data: Driver specific data or NULL. The internal storage 23671cf8cfdSTony Luck * format is unsigned long. The supplied value, pointer 23771cf8cfdSTony Luck * etc. is cast to unsigned long internally. 23871cf8cfdSTony Luck * 23971cf8cfdSTony Luck * feature is set to wildcard 24071cf8cfdSTony Luck */ 24171cf8cfdSTony Luck #define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data) \ 24271cf8cfdSTony Luck X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ 24371cf8cfdSTony Luck VFM_VENDOR(vfm), \ 24471cf8cfdSTony Luck VFM_FAMILY(vfm), \ 24571cf8cfdSTony Luck VFM_MODEL(vfm), \ 24671cf8cfdSTony Luck steppings, X86_FEATURE_ANY, data) 24771cf8cfdSTony Luck 24871cf8cfdSTony Luck /** 24971cf8cfdSTony Luck * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature 25071cf8cfdSTony Luck * @vfm: Encoded 8-bits each for vendor, family, model 25171cf8cfdSTony Luck * @feature: A X86_FEATURE bit 25271cf8cfdSTony Luck * @data: Driver specific data or NULL. The internal storage 25371cf8cfdSTony Luck * format is unsigned long. The supplied value, pointer 25471cf8cfdSTony Luck * etc. is cast to unsigned long internally. 25571cf8cfdSTony Luck * 25671cf8cfdSTony Luck * Steppings is set to wildcard 25771cf8cfdSTony Luck */ 25871cf8cfdSTony Luck #define X86_MATCH_VFM_FEATURE(vfm, feature, data) \ 25971cf8cfdSTony Luck X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ 26071cf8cfdSTony Luck VFM_VENDOR(vfm), \ 26171cf8cfdSTony Luck VFM_FAMILY(vfm), \ 26271cf8cfdSTony Luck VFM_MODEL(vfm), \ 26371cf8cfdSTony Luck X86_STEPPING_ANY, feature, data) 26471cf8cfdSTony Luck 265ba5bade4SThomas Gleixner /* 2660f42b790SKan Liang * Match specific microcode revisions. 2670f42b790SKan Liang * 2680f42b790SKan Liang * vendor/family/model/stepping must be all set. 2690f42b790SKan Liang * 2700f42b790SKan Liang * Only checks against the boot CPU. When mixed-stepping configs are 2710f42b790SKan Liang * valid for a CPU model, add a quirk for every valid stepping and 2720f42b790SKan Liang * do the fine-tuning in the quirk handler. 2730f42b790SKan Liang */ 2740f42b790SKan Liang 2750f42b790SKan Liang struct x86_cpu_desc { 276266d63a7SIngo Molnar u8 x86_family; 277266d63a7SIngo Molnar u8 x86_vendor; 278266d63a7SIngo Molnar u8 x86_model; 279266d63a7SIngo Molnar u8 x86_stepping; 280266d63a7SIngo Molnar u32 x86_microcode_rev; 2810f42b790SKan Liang }; 2820f42b790SKan Liang 283266d63a7SIngo Molnar #define INTEL_CPU_DESC(model, stepping, revision) { \ 2840f42b790SKan Liang .x86_family = 6, \ 2850f42b790SKan Liang .x86_vendor = X86_VENDOR_INTEL, \ 286266d63a7SIngo Molnar .x86_model = (model), \ 287266d63a7SIngo Molnar .x86_stepping = (stepping), \ 288266d63a7SIngo Molnar .x86_microcode_rev = (revision), \ 2890f42b790SKan Liang } 2900f42b790SKan Liang 291266d63a7SIngo Molnar extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); 2920f42b790SKan Liang extern bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table); 2930f42b790SKan Liang 294266d63a7SIngo Molnar #endif /* _ASM_X86_CPU_DEVICE_ID */ 295