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