xref: /illumos-gate/usr/src/uts/intel/os/cpuid_subr.c (revision 1a2d662a91cee3bf82f41cd47c7ae6f3825d9db2)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27  */
28 
29 /*
30  * Portions Copyright 2009 Advanced Micro Devices, Inc.
31  */
32 
33 /*
34  * Copyright 2012 Jens Elkner <jel+illumos@cs.uni-magdeburg.de>
35  * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
36  * Copyright 2019 Joyent, Inc.
37  * Copyright 2024 Oxide Computer Company
38  */
39 
40 /*
41  * Support functions that interpret CPUID and similar information.
42  * These should not be used from anywhere other than cpuid.c and
43  * cmi_hw.c - as such we will not list them in any header file
44  * such as x86_archext.h.
45  *
46  * In cpuid.c we process CPUID information for each cpu_t instance
47  * we're presented with, and stash this raw information and material
48  * derived from it in per-cpu_t structures.
49  *
50  * If we are virtualized then the CPUID information derived from CPUID
51  * instructions executed in the guest is based on whatever the hypervisor
52  * wanted to make things look like, and the cpu_t are not necessarily in 1:1
53  * or fixed correspondence with real processor execution resources.  In cmi_hw.c
54  * we are interested in the native properties of a processor - for fault
55  * management (and potentially other, such as power management) purposes;
56  * it will tunnel through to real hardware information, and use the
57  * functionality provided in this file to process it.
58  */
59 
60 #include <sys/types.h>
61 #include <sys/systm.h>
62 #include <sys/bitmap.h>
63 #include <sys/x86_archext.h>
64 #include <sys/pci_cfgspace.h>
65 #include <sys/sysmacros.h>
66 #ifdef __xpv
67 #include <sys/hypervisor.h>
68 #endif
69 
70 /*
71  * AMD socket types.
72  * First index defines a processor family; see notes inline.  The second index
73  * selects the socket type by either (model & 0x3) for family 0fh or the CPUID
74  * pkg bits (Fn8000_0001_EBX[31:28]) for later families.
75  */
76 static uint32_t amd_skts[][16] = {
77 	/*
78 	 * Family 0xf revisions B through E
79 	 */
80 #define	A_SKTS_0			0
81 	{
82 		[0] = X86_SOCKET_754,
83 		[1] = X86_SOCKET_940,
84 		[2] = X86_SOCKET_754,
85 		[3] = X86_SOCKET_939,
86 	},
87 	/*
88 	 * Family 0xf revisions F and G
89 	 */
90 #define	A_SKTS_1			1
91 	{
92 		[0] = X86_SOCKET_S1g1,
93 		[1] = X86_SOCKET_F1207,
94 		[3] = X86_SOCKET_AM2
95 	},
96 	/*
97 	 * Family 0x10
98 	 */
99 #define	A_SKTS_2			2
100 	{
101 		[0] = X86_SOCKET_F1207,
102 		[1] = X86_SOCKET_AM2R2,
103 		[2] = X86_SOCKET_S1g3,
104 		[3] = X86_SOCKET_G34,
105 		[4] = X86_SOCKET_ASB2,
106 		[5] = X86_SOCKET_C32
107 	},
108 
109 	/*
110 	 * Family 0x11
111 	 */
112 #define	A_SKTS_3			3
113 	{
114 		[2] = X86_SOCKET_S1g2
115 	},
116 
117 	/*
118 	 * Family 0x12
119 	 */
120 #define	A_SKTS_4			4
121 	{
122 		[1] = X86_SOCKET_FS1,
123 		[2] = X86_SOCKET_FM1
124 	},
125 
126 	/*
127 	 * Family 0x14
128 	 */
129 #define	A_SKTS_5			5
130 	{
131 		[0] = X86_SOCKET_FT1
132 	},
133 
134 	/*
135 	 * Family 0x15 models 00 - 0f
136 	 */
137 #define	A_SKTS_6			6
138 	{
139 		[1] = X86_SOCKET_AM3R2,
140 		[3] = X86_SOCKET_G34,
141 		[5] = X86_SOCKET_C32
142 	},
143 
144 	/*
145 	 * Family 0x15 models 10 - 1f
146 	 */
147 #define	A_SKTS_7			7
148 	{
149 		[0] = X86_SOCKET_FP2,
150 		[1] = X86_SOCKET_FS1R2,
151 		[2] = X86_SOCKET_FM2
152 	},
153 
154 	/*
155 	 * Family 0x15 models 30-3f
156 	 */
157 #define	A_SKTS_8			8
158 	{
159 		[0] = X86_SOCKET_FP3,
160 		[1] = X86_SOCKET_FM2R2
161 	},
162 
163 	/*
164 	 * Family 0x15 models 60-6f
165 	 */
166 #define	A_SKTS_9			9
167 	{
168 		[0] = X86_SOCKET_FP4,
169 		[2] = X86_SOCKET_AM4,
170 		[3] = X86_SOCKET_FM2R2
171 	},
172 
173 	/*
174 	 * Family 0x15 models 70-7f
175 	 */
176 #define	A_SKTS_10			10
177 	{
178 		[0] = X86_SOCKET_FP4,
179 		[2] = X86_SOCKET_AM4,
180 		[4] = X86_SOCKET_FT4
181 	},
182 
183 	/*
184 	 * Family 0x16 models 00-0f
185 	 */
186 #define	A_SKTS_11			11
187 	{
188 		[0] = X86_SOCKET_FT3,
189 		[1] = X86_SOCKET_FS1B
190 	},
191 
192 	/*
193 	 * Family 0x16 models 30-3f
194 	 */
195 #define	A_SKTS_12			12
196 	{
197 		[0] = X86_SOCKET_FT3B,
198 		[3] = X86_SOCKET_FP4
199 	},
200 
201 	/*
202 	 * Family 0x17 models 00-0f	(Zen 1 - Naples, Ryzen)
203 	 */
204 #define	A_SKTS_NAPLES			13
205 	{
206 		[2] = X86_SOCKET_AM4,
207 		[4] = X86_SOCKET_SP3,
208 		[7] = X86_SOCKET_SP3R2
209 	},
210 
211 	/*
212 	 * Family 0x17 models 10-2f	(Zen 1 - APU: Raven Ridge)
213 	 *				(Zen 1 - APU: Banded Kestrel)
214 	 *				(Zen 1 - APU: Dali)
215 	 */
216 #define	A_SKTS_RAVEN			14
217 	{
218 		[0] = X86_SOCKET_FP5,
219 		[2] = X86_SOCKET_AM4
220 	},
221 
222 	/*
223 	 * Family 0x17 models 30-3f	(Zen 2 - Rome)
224 	 */
225 #define	A_SKTS_ROME			15
226 	{
227 		[4] = X86_SOCKET_SP3,
228 		[7] = X86_SOCKET_SP3R2
229 	},
230 
231 	/*
232 	 * Family 0x17 models 60-6f	(Zen 2 - Renoir)
233 	 */
234 #define	A_SKTS_RENOIR			16
235 	{
236 		[0] = X86_SOCKET_FP6,
237 		[2] = X86_SOCKET_AM4
238 	},
239 
240 	/*
241 	 * Family 0x17 models 70-7f	(Zen 2 - Matisse)
242 	 */
243 #define	A_SKTS_MATISSE			17
244 	{
245 		[2] = X86_SOCKET_AM4,
246 	},
247 
248 	/*
249 	 * Family 0x18 models 00-0f	(Dhyana)
250 	 */
251 #define	A_SKTS_DHYANA			18
252 	{
253 		[4] = X86_SOCKET_SL1,
254 		[6] = X86_SOCKET_DM1,
255 		[7] = X86_SOCKET_SL1R2
256 	},
257 
258 	/*
259 	 * Family 0x19 models 00-0f	(Zen 3 - Milan)
260 	 */
261 #define	A_SKTS_MILAN			19
262 	{
263 		[4] = X86_SOCKET_SP3,
264 		[7] = X86_SOCKET_STRX4
265 	},
266 
267 	/*
268 	 * Family 0x19 models 20-2f	(Zen 3 - Vermeer)
269 	 */
270 #define	A_SKTS_VERMEER			20
271 	{
272 		[2] = X86_SOCKET_AM4,
273 	},
274 
275 	/*
276 	 * Family 0x19 models 50-5f	(Zen 3 - Cezanne)
277 	 */
278 #define	A_SKTS_CEZANNE			21
279 	{
280 		[0] = X86_SOCKET_FP6,
281 		[2] = X86_SOCKET_AM4
282 	},
283 
284 	/*
285 	 * Family 0x19 models 10-1f	(Zen 4 - Genoa)
286 	 */
287 #define	A_SKTS_GENOA			22
288 	{
289 		[4] = X86_SOCKET_SP5,
290 		[8] = X86_SOCKET_TR5
291 	},
292 
293 	/*
294 	 * Family 0x19 models 40-4f	(Zen 3 - Rembrandt)
295 	 */
296 #define	A_SKTS_REMBRANDT			23
297 	{
298 		[0] = X86_SOCKET_AM5,
299 		[1] = X86_SOCKET_FP7,
300 		[2] = X86_SOCKET_FP7R2
301 	},
302 
303 	/*
304 	 * Family 0x19 models 60-6f	(Zen 4 - Raphael)
305 	 */
306 #define	A_SKTS_RAPHAEL			24
307 	{
308 		[0] = X86_SOCKET_AM5,
309 		[1] = X86_SOCKET_FL1
310 	},
311 
312 	/*
313 	 * The always-unknown socket group, used for undocumented parts.  It
314 	 * need not be last; the position is arbitrary. The default initializer
315 	 * for this is zero which is x86 socket unknown.
316 	 */
317 #define	A_SKTS_UNKNOWN			25
318 	{
319 	},
320 	/*
321 	 * Family 0x17 models 90-97	(Zen 2 - Van Gogh)
322 	 */
323 #define	A_SKTS_VANGOGH			26
324 	{
325 		[3] = X86_SOCKET_FF3
326 	},
327 	/*
328 	 * Family 0x17 models a0-af	(Zen 2 - Mendocino)
329 	 */
330 #define	A_SKTS_MENDOCINO			27
331 	{
332 		[1] = X86_SOCKET_FT6
333 	},
334 
335 	/*
336 	 * Family 0x19 models 70-7f	(Zen 4 - Phoenix)
337 	 */
338 #define	A_SKTS_PHOENIX			28
339 	{
340 		[0] = X86_SOCKET_AM5,
341 		[1] = X86_SOCKET_FP8,
342 		[4] = X86_SOCKET_FP7,
343 		[5] = X86_SOCKET_FP7R2,
344 	},
345 
346 	/*
347 	 * Family 0x19 models a0-af	(Zen 4c - Bergamo/Siena)
348 	 */
349 #define	A_SKTS_BERGAMO			29
350 	{
351 		[4] = X86_SOCKET_SP5,
352 		[8] = X86_SOCKET_SP6
353 	},
354 	/*
355 	 * Family 0x1a models 00-1f	(Zen 5[c] - Turin)
356 	 */
357 #define	A_SKTS_TURIN			30
358 	{
359 		[4] = X86_SOCKET_SP5,
360 	},
361 
362 	/*
363 	 * Family 0x1a models 20-2f	(Zen 5 - Strix)
364 	 */
365 #define	A_SKTS_STRIX			31
366 	{
367 		[1] = X86_SOCKET_FP8
368 	},
369 
370 	/*
371 	 * Family 0x1a models 40-4f	(Zen 5 - Granite Ridge)
372 	 */
373 #define	A_SKTS_GRANITE_RIDGE		32
374 	{
375 		[0] = X86_SOCKET_AM5,
376 		[1] = X86_SOCKET_FL1
377 	}
378 };
379 
380 struct amd_sktmap_s {
381 	uint32_t	skt_code;
382 	char		sktstr[16];
383 };
384 static struct amd_sktmap_s amd_sktmap_strs[] = {
385 	{ X86_SOCKET_754,	"754" },
386 	{ X86_SOCKET_939,	"939" },
387 	{ X86_SOCKET_940,	"940" },
388 	{ X86_SOCKET_S1g1,	"S1g1" },
389 	{ X86_SOCKET_AM2,	"AM2" },
390 	{ X86_SOCKET_F1207,	"F(1207)" },
391 	{ X86_SOCKET_S1g2,	"S1g2" },
392 	{ X86_SOCKET_S1g3,	"S1g3" },
393 	{ X86_SOCKET_AM,	"AM" },
394 	{ X86_SOCKET_AM2R2,	"AM2r2" },
395 	{ X86_SOCKET_AM3,	"AM3" },
396 	{ X86_SOCKET_G34,	"G34" },
397 	{ X86_SOCKET_ASB2,	"ASB2" },
398 	{ X86_SOCKET_C32,	"C32" },
399 	{ X86_SOCKET_S1g4,	"S1g4" },
400 	{ X86_SOCKET_FT1,	"FT1" },
401 	{ X86_SOCKET_FM1,	"FM1" },
402 	{ X86_SOCKET_FS1,	"FS1" },
403 	{ X86_SOCKET_AM3R2,	"AM3r2" },
404 	{ X86_SOCKET_FP2,	"FP2" },
405 	{ X86_SOCKET_FS1R2,	"FS1r2" },
406 	{ X86_SOCKET_FM2,	"FM2" },
407 	{ X86_SOCKET_FP3,	"FP3" },
408 	{ X86_SOCKET_FM2R2,	"FM2r2" },
409 	{ X86_SOCKET_FP4,	"FP4" },
410 	{ X86_SOCKET_AM4,	"AM4" },
411 	{ X86_SOCKET_FT3,	"FT3" },
412 	{ X86_SOCKET_FT4,	"FT4" },
413 	{ X86_SOCKET_FS1B,	"FS1b" },
414 	{ X86_SOCKET_FT3B,	"FT3b" },
415 	{ X86_SOCKET_SP3,	"SP3" },
416 	{ X86_SOCKET_SP3R2,	"SP3r2" },
417 	{ X86_SOCKET_FP5,	"FP5" },
418 	{ X86_SOCKET_FP6,	"FP6" },
419 	{ X86_SOCKET_STRX4,	"sTRX4" },
420 	{ X86_SOCKET_SL1,	"SL1" },
421 	{ X86_SOCKET_SL1R2,	"SL1R2" },
422 	{ X86_SOCKET_DM1,	"DM1" },
423 	{ X86_SOCKET_SP5,	"SP5" },
424 	{ X86_SOCKET_AM5,	"AM5" },
425 	{ X86_SOCKET_FP7,	"FP7" },
426 	{ X86_SOCKET_FP7R2,	"FP7r2" },
427 	{ X86_SOCKET_FF3,	"FF3" },
428 	{ X86_SOCKET_FT6,	"FT6" },
429 	{ X86_SOCKET_FP8,	"FP8" },
430 	{ X86_SOCKET_FL1,	"FL1" },
431 	{ X86_SOCKET_SP6,	"SP6" },
432 	{ X86_SOCKET_TR5,	"TR5" },
433 	{ X86_SOCKET_UNKNOWN,	"Unknown" }	/* Must be last! */
434 };
435 
436 /* Keep the array above in sync with the definitions in x86_archext.h. */
437 CTASSERT(ARRAY_SIZE(amd_sktmap_strs) == X86_NUM_SOCKETS + 1);
438 
439 /*
440  * Table for mapping AMD family/model/stepping ranges onto three derived items:
441  *
442  * * The "chiprev" and associated string, which is generally the AMD silicon
443  * revision along with a symbolic representation of the marketing (not cpuid)
444  * family.  In line with the overall cpuid usage, we refer to this as a
445  * processor family.
446  * * The uarch, which is analogous to the chiprev and provides the
447  * microarchitecture/core generation and silicon revision.  Note that this is
448  * distinct from the package-level silicon/product revision and is often common
449  * to multiple product lines offered at a given time.
450  * * The socket map selector, used to translate this collection of products'
451  * last 4 model bits (for family 0xf only) or Fn8000_0001_EBX[30:28] into a
452  * socket ID.
453  *
454  * The first member of this array that matches a given family, extended model
455  * plus model range, and stepping range will be considered a match.  This allows
456  * us to end each cpuid family and/or processor family with a catchall that
457  * while less specific than we might like still allows us to provide a fair
458  * amount of detail to both other kernel consumers and userland.
459  */
460 static const struct amd_rev_mapent {
461 	uint_t rm_family;
462 	uint_t rm_modello;
463 	uint_t rm_modelhi;
464 	uint_t rm_steplo;
465 	uint_t rm_stephi;
466 	x86_chiprev_t rm_chiprev;
467 	const char *rm_chiprevstr;
468 	x86_uarchrev_t rm_uarchrev;
469 	uint_t rm_sktidx;
470 } amd_revmap[] = {
471 	/*
472 	 * =============== AuthenticAMD Family 0xf ===============
473 	 */
474 
475 	/*
476 	 * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1.
477 	 */
478 	{ 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_LEGACY_F_REV_B, "B",
479 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_0 },
480 	{ 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_LEGACY_F_REV_B, "B",
481 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_0 },
482 	/*
483 	 * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8
484 	 */
485 	{ 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_LEGACY_F_REV_C0, "C0",
486 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_0 },
487 	/*
488 	 * Rev CG is the rest of extended model 0x0 - i.e., everything
489 	 * but the rev B and C0 combinations covered above.
490 	 */
491 	{ 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_CG, "CG",
492 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_0 },
493 	/*
494 	 * Rev D has extended model 0x1.
495 	 */
496 	{ 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_D, "D",
497 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_0 },
498 	/*
499 	 * Rev E has extended model 0x2.
500 	 * Extended model 0x3 is unused but available to grow into.
501 	 */
502 	{ 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_E, "E",
503 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_0 },
504 	/*
505 	 * Rev F has extended models 0x4 and 0x5.
506 	 */
507 	{ 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_F, "F",
508 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_1 },
509 	/*
510 	 * Rev G has extended model 0x6.
511 	 */
512 	{ 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_G, "G",
513 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_1 },
514 
515 	/*
516 	 * =============== AuthenticAMD Family 0x10 ===============
517 	 */
518 
519 	/*
520 	 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
521 	 * Give all of model 0 stepping range to rev A.
522 	 */
523 	{ 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_LEGACY_10_REV_A, "A",
524 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
525 
526 	/*
527 	 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
528 	 * Give all of model 2 stepping range to rev B.
529 	 */
530 	{ 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_B, "B",
531 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
532 
533 	/*
534 	 * Rev C has models 4-6 (depending on L3 cache configuration)
535 	 * Give all of models 4-6 stepping range 0-2 to rev C2.
536 	 */
537 	{ 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_LEGACY_10_REV_C2, "C2",
538 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
539 
540 	/*
541 	 * Rev C has models 4-6 (depending on L3 cache configuration)
542 	 * Give all of models 4-6 stepping range >= 3 to rev C3.
543 	 */
544 	{ 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_C3, "C3",
545 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
546 
547 	/*
548 	 * Rev D has models 8 and 9
549 	 * Give all of model 8 and 9 stepping 0 to rev D0.
550 	 */
551 	{ 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_LEGACY_10_REV_D0, "D0",
552 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
553 
554 	/*
555 	 * Rev D has models 8 and 9
556 	 * Give all of model 8 and 9 stepping range >= 1 to rev D1.
557 	 */
558 	{ 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_D1, "D1",
559 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
560 
561 	/*
562 	 * Rev E has models A and stepping 0
563 	 * Give all of model A stepping range to rev E.
564 	 */
565 	{ 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_E, "E",
566 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
567 
568 	{ 0x10, 0x0, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_UNKNOWN, "??",
569 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_2 },
570 
571 	/*
572 	 * =============== AuthenticAMD Family 0x11 ===============
573 	 */
574 	{ 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_11_REV_B, "B",
575 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_3 },
576 	{ 0x11, 0x00, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_11_UNKNOWN, "??",
577 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_3 },
578 
579 	/*
580 	 * =============== AuthenticAMD Family 0x12 ===============
581 	 */
582 	{ 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_12_REV_B, "B",
583 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_4 },
584 	{ 0x12, 0x00, 0x00, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_12_UNKNOWN, "??",
585 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_4 },
586 
587 	/*
588 	 * =============== AuthenticAMD Family 0x14 ===============
589 	 */
590 	{ 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_REV_B, "B",
591 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_5 },
592 	{ 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_REV_C, "C",
593 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_5 },
594 	{ 0x14, 0x00, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_UNKNOWN, "??",
595 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_5 },
596 
597 	/*
598 	 * =============== AuthenticAMD Family 0x15 ===============
599 	 */
600 	{ 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_OROCHI_REV_B2, "OR-B2",
601 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_6 },
602 	{ 0x15, 0x02, 0x02, 0x0, 0x0, X86_CHIPREV_AMD_OROCHI_REV_C0, "OR-C0",
603 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_6 },
604 	{ 0x15, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_OROCHI_UNKNOWN, "OR-??",
605 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_6 },
606 
607 	{ 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_TRINITY_REV_A1, "TN-A1",
608 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_7 },
609 	{ 0x15, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_TRINITY_UNKNOWN, "TN-??",
610 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_7 },
611 
612 	{ 0x15, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_KAVERI_REV_A1, "KV-A1",
613 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_8 },
614 	{ 0x15, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_KAVERI_UNKNOWN, "KV-??",
615 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_8 },
616 
617 	/*
618 	 * The Carrizo rev guide mentions A0 as having an ID of "00600F00h" but
619 	 * this appears to be a typo as elsewhere it's given as "00660F00h".  We
620 	 * assume the latter is correct.
621 	 */
622 	{ 0x15, 0x60, 0x60, 0x0, 0x0, X86_CHIPREV_AMD_CARRIZO_REV_A0, "CZ-A0",
623 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_9 },
624 	{ 0x15, 0x60, 0x60, 0x1, 0x1, X86_CHIPREV_AMD_CARRIZO_REV_A1, "CZ-A1",
625 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_9 },
626 	/*
627 	 * CZ-DDR4 and BR-A1 are indistinguishable via cpuid; the rev guide
628 	 * indicates that they should be distinguished by the contents of the
629 	 * OSVW MSR, but this register is just a software scratch space which
630 	 * means the actual method of distinguishing the two is not documented
631 	 * and on PCs will be done by a BIOS.  In the extremely unlikely event
632 	 * it becomes necessary to distinguish these, an OSVW-driven fixup can
633 	 * be added.
634 	 */
635 	{ 0x15, 0x65, 0x65, 0x1, 0x1, X86_CHIPREV_AMD_CARRIZO_REV_DDR4,
636 	    "CZ-DDR4", X86_UARCHREV_AMD_LEGACY, A_SKTS_9 },
637 	{ 0x15, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_CARRIZO_UNKNOWN, "CZ-??",
638 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_9 },
639 
640 	{ 0x15, 0x70, 0x70, 0x0, 0x0, X86_CHIPREV_AMD_STONEY_RIDGE_REV_A0,
641 	    "ST-A0", X86_UARCHREV_AMD_LEGACY, A_SKTS_10 },
642 	{ 0x15, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_STONEY_RIDGE_UNKNOWN,
643 	    "ST-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_10 },
644 
645 	/*
646 	 * =============== AuthenticAMD Family 0x16 ===============
647 	 */
648 	{ 0x16, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_AMD_KABINI_A1, "KB-A1",
649 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_11 },
650 	{ 0x16, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_KABINI_UNKNOWN, "KB-??",
651 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_11 },
652 
653 	{ 0x16, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_MULLINS_A1, "ML-A1",
654 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_12 },
655 	{ 0x16, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_MULLINS_UNKNOWN, "ML-??",
656 	    X86_UARCHREV_AMD_LEGACY, A_SKTS_12 },
657 
658 	/*
659 	 * =============== AuthenticAMD Family 0x17 ===============
660 	 */
661 	/* Naples == Zeppelin == ZP */
662 	{ 0x17, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_NAPLES_A0, "ZP-A0",
663 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_NAPLES },
664 	{ 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_NAPLES_B1, "ZP-B1",
665 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_NAPLES },
666 	{ 0x17, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_NAPLES_B2, "ZP-B2",
667 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_NAPLES },
668 	{ 0x17, 0x00, 0x07, 0x0, 0xf, X86_CHIPREV_AMD_NAPLES_UNKNOWN, "ZP-??",
669 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_NAPLES },
670 	{ 0x17, 0x08, 0x08, 0x2, 0x2, X86_CHIPREV_AMD_PINNACLE_RIDGE_B2,
671 	    "PiR-B2", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_NAPLES },
672 	{ 0x17, 0x08, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_PINNACLE_RIDGE_UNKNOWN,
673 	    "PiR-??", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_NAPLES },
674 
675 	{ 0x17, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_RAVEN_RIDGE_B0,
676 	    "RV-B0", X86_UARCHREV_AMD_ZEN1, A_SKTS_RAVEN },
677 	{ 0x17, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_RAVEN_RIDGE_B1,
678 	    "RV-B1", X86_UARCHREV_AMD_ZEN1, A_SKTS_RAVEN },
679 	{ 0x17, 0x10, 0x17, 0x0, 0xf, X86_CHIPREV_AMD_RAVEN_RIDGE_UNKNOWN,
680 	    "RV-??", X86_UARCHREV_AMD_ZEN1, A_SKTS_RAVEN },
681 	{ 0x17, 0x18, 0x18, 0x1, 0x1, X86_CHIPREV_AMD_PICASSO_B1, "PCO-B1",
682 	    X86_UARCHREV_AMD_ZENPLUS, A_SKTS_RAVEN },
683 	{ 0x17, 0x18, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_PICASSO_UNKNOWN, "PCO-??",
684 	    X86_UARCHREV_AMD_ZENPLUS, A_SKTS_RAVEN },
685 
686 	{ 0x17, 0x20, 0x20, 0x1, 0x1, X86_CHIPREV_AMD_DALI_A1, "RV2X-A1",
687 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_RAVEN },
688 	{ 0x17, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_DALI_UNKNOWN, "RV2X-??",
689 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_RAVEN },
690 
691 	/* Rome == Starship == SSP */
692 	{ 0x17, 0x30, 0x30, 0x0, 0x0, X86_CHIPREV_AMD_ROME_A0, "SSP-A0",
693 	    X86_UARCHREV_AMD_ZEN2_A0, A_SKTS_ROME },
694 	{ 0x17, 0x31, 0x31, 0x0, 0x0, X86_CHIPREV_AMD_ROME_B0, "SSP-B0",
695 	    X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_ROME },
696 	{ 0x17, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_ROME_UNKNOWN, "SSP-??",
697 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_ROME },
698 
699 	{ 0x17, 0x60, 0x60, 0x1, 0x1, X86_CHIPREV_AMD_RENOIR_A1, "RN-A1",
700 	    X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_RENOIR },
701 	{ 0x17, 0x60, 0x67, 0x0, 0xf, X86_CHIPREV_AMD_RENOIR_UNKNOWN, "RN-??",
702 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_RENOIR },
703 	{ 0x17, 0x68, 0x68, 0x1, 0x1, X86_CHIPREV_AMD_RENOIR_LCN_A1, "LCN-A1",
704 	    X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_RENOIR },
705 	{ 0x17, 0x68, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_RENOIR_UNKNOWN, "LCN-??",
706 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_RENOIR },
707 
708 	{ 0x17, 0x71, 0x71, 0x0, 0x0, X86_CHIPREV_AMD_MATISSE_B0, "MTS-B0",
709 	    X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_MATISSE },
710 	{ 0x17, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_MATISSE_UNKNOWN, "MTS-??",
711 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_MATISSE },
712 
713 	{ 0x17, 0x90, 0x97, 0x0, 0xf, X86_CHIPREV_AMD_VAN_GOGH_UNKNOWN, "??",
714 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_VANGOGH },
715 	{ 0x17, 0x98, 0x9f, 0x0, 0xf, X86_CHIPREV_AMD_VAN_GOGH_UNKNOWN, "??",
716 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_UNKNOWN },
717 
718 	{ 0x17, 0xa0, 0xaf, 0x0, 0xf, X86_CHIPREV_AMD_MENDOCINO_UNKNOWN, "??",
719 	    X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_MENDOCINO },
720 
721 	/*
722 	 * =============== HygonGenuine Family 0x18 ===============
723 	 */
724 	{ 0x18, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_HYGON_DHYANA_A1, "DN_A1",
725 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_DHYANA },
726 	{ 0x18, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_HYGON_DHYANA_UNKNOWN, "DN_??",
727 	    X86_UARCHREV_AMD_ZEN1, A_SKTS_DHYANA },
728 
729 	/*
730 	 * =============== AuthenticAMD Family 0x19 ===============
731 	 */
732 	/* Milan == Genesis == GN */
733 	{ 0x19, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_MILAN_A0, "GN-A0",
734 	    X86_UARCHREV_AMD_ZEN3_A0, A_SKTS_MILAN },
735 	{ 0x19, 0x01, 0x01, 0x0, 0x0, X86_CHIPREV_AMD_MILAN_B0, "GN-B0",
736 	    X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_MILAN },
737 	{ 0x19, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_MILAN_B1, "GN-B1",
738 	    X86_UARCHREV_AMD_ZEN3_B1, A_SKTS_MILAN },
739 	/* Marketed as Milan-X but still GN */
740 	{ 0x19, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_MILAN_B2, "GN-B2",
741 	    X86_UARCHREV_AMD_ZEN3_B2, A_SKTS_MILAN },
742 	{ 0x19, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_MILAN_UNKNOWN, "GN-??",
743 	    X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_MILAN },
744 
745 	/* Genoa == Stones == RS */
746 	{ 0x19, 0x10, 0x10, 0x0, 0x0, X86_CHIPREV_AMD_GENOA_A0, "RS-A0",
747 	    X86_UARCHREV_AMD_ZEN4_A0, A_SKTS_GENOA },
748 	/* RS-A0 & RS-A1 both map to Zen 4 uarch A0 */
749 	{ 0x19, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_GENOA_A1, "RS-A1",
750 	    X86_UARCHREV_AMD_ZEN4_A0, A_SKTS_GENOA },
751 	{ 0x19, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_GENOA_B0, "RS-B0",
752 	    X86_UARCHREV_AMD_ZEN4_B0, A_SKTS_GENOA },
753 	{ 0x19, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_GENOA_B1, "RS-B1",
754 	    X86_UARCHREV_AMD_ZEN4_B1, A_SKTS_GENOA },
755 	{ 0x19, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_GENOA_UNKNOWN, "RS-??",
756 	    X86_UARCHREV_AMD_ZEN4_UNKNOWN, A_SKTS_GENOA },
757 
758 	{ 0x19, 0x20, 0x20, 0x0, 0x0, X86_CHIPREV_AMD_VERMEER_A0, "VMR-A0",
759 	    X86_UARCHREV_AMD_ZEN3_A0, A_SKTS_VERMEER },
760 	{ 0x19, 0x21, 0x21, 0x0, 0x0, X86_CHIPREV_AMD_VERMEER_B0, "VMR-B0",
761 	    X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_VERMEER },
762 	{ 0x19, 0x21, 0x21, 0x2, 0x2, X86_CHIPREV_AMD_VERMEER_B2, "VMR-B2",
763 	    X86_UARCHREV_AMD_ZEN3_B2, A_SKTS_VERMEER },
764 	{ 0x19, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_VERMEER_UNKNOWN, "VMR-??",
765 	    X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_VERMEER },
766 
767 	/* Rev guide is missing AM5 information, including A0 and B0 */
768 	{ 0x19, 0x40, 0x40, 0x0, 0x0, X86_CHIPREV_AMD_REMBRANDT_A0, "RMB-A0",
769 	    X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_REMBRANDT },
770 	{ 0x19, 0x44, 0x44, 0x0, 0x0, X86_CHIPREV_AMD_REMBRANDT_B0, "RMB-B0",
771 	    X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_REMBRANDT },
772 	{ 0x19, 0x44, 0x44, 0x1, 0x1, X86_CHIPREV_AMD_REMBRANDT_B1, "RMB-B1",
773 	    X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_REMBRANDT },
774 	{ 0x19, 0x40, 0x4f, 0x0, 0xf, X86_CHIPREV_AMD_REMBRANDT_UNKNOWN,
775 	    "RMB-??", X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_REMBRANDT },
776 
777 	/* Cezanne */
778 	{ 0x19, 0x50, 0x50, 0x0, 0x0, X86_CHIPREV_AMD_CEZANNE_A0, "CZN-A0",
779 	    X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_CEZANNE },
780 	{ 0x19, 0x50, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_CEZANNE_UNKNOWN, "CZN-??",
781 	    X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_CEZANNE },
782 
783 	/* Raphael */
784 	{ 0x19, 0x61, 0x61, 0x2, 0x2, X86_CHIPREV_AMD_RAPHAEL_B2, "RPL-B2",
785 	    X86_UARCHREV_AMD_ZEN4_B2, A_SKTS_RAPHAEL },
786 	{ 0x19, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_RAPHAEL_UNKNOWN, "RPL-??",
787 	    X86_UARCHREV_AMD_ZEN4_UNKNOWN, A_SKTS_RAPHAEL },
788 
789 	/* Phoenix */
790 	{ 0x19, 0x74, 0x74, 0x1, 0x1, X86_CHIPREV_AMD_PHOENIX_A1, "PHX-A1",
791 	    X86_UARCHREV_AMD_ZEN4_A1, A_SKTS_PHOENIX },
792 	{ 0x19, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_PHOENIX_UNKNOWN, "PHX-??",
793 	    X86_UARCHREV_AMD_ZEN4_UNKNOWN, A_SKTS_PHOENIX },
794 
795 	/* Bergamo / Siena */
796 	{ 0x19, 0xa0, 0xaf, 0x0, 0x0, X86_CHIPREV_AMD_BERGAMO_A0, "RSDN-A0",
797 	    X86_UARCHREV_AMD_ZEN4_A0, A_SKTS_BERGAMO },
798 	{ 0x19, 0xa0, 0xaf, 0x1, 0x1, X86_CHIPREV_AMD_BERGAMO_A1, "RSDN-A1",
799 	    X86_UARCHREV_AMD_ZEN4_A1, A_SKTS_BERGAMO },
800 	{ 0x19, 0xa0, 0xaf, 0x2, 0x2, X86_CHIPREV_AMD_BERGAMO_A2, "RSDN-A2",
801 	    X86_UARCHREV_AMD_ZEN4_A2, A_SKTS_BERGAMO },
802 	{ 0x19, 0xa0, 0xaf, 0x0, 0xf, X86_CHIPREV_AMD_BERGAMO_UNKNOWN, "???",
803 	    X86_UARCHREV_AMD_ZEN4_UNKNOWN, A_SKTS_BERGAMO },
804 
805 	/*
806 	 * =============== AuthenticAMD Family 0x1a ===============
807 	 */
808 	/* Turin */
809 	{ 0x1a, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_TURIN_A0, "BRH-A0",
810 	    X86_UARCHREV_AMD_ZEN5_A0, A_SKTS_TURIN },
811 	/* BRH-A0 & BRH-B0 both map to Zen 5 uarch A0 */
812 	{ 0x1a, 0x01, 0x01, 0x0, 0x0, X86_CHIPREV_AMD_TURIN_B0, "BRH-B0",
813 	    X86_UARCHREV_AMD_ZEN5_A0, A_SKTS_TURIN },
814 	/* BRH-B1 maps to Zen 5 uarch B0 */
815 	{ 0x1a, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_TURIN_B1, "BRH-B1",
816 	    X86_UARCHREV_AMD_ZEN5_B0, A_SKTS_TURIN },
817 	{ 0x1a, 0x02, 0x02, 0x0, 0x0, X86_CHIPREV_AMD_TURIN_C0, "BRH-C0",
818 	    X86_UARCHREV_AMD_ZEN5_C0, A_SKTS_TURIN },
819 	{ 0x1a, 0x02, 0x02, 0x1, 0x1, X86_CHIPREV_AMD_TURIN_C1, "BRH-C1",
820 	    X86_UARCHREV_AMD_ZEN5_C1, A_SKTS_TURIN },
821 	{ 0x1a, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_TURIN_UNKNOWN, "BRH-???",
822 	    X86_UARCHREV_AMD_ZEN5_UNKNOWN, A_SKTS_TURIN },
823 	{ 0x1a, 0x10, 0x10, 0x0, 0x0, X86_CHIPREV_AMD_DENSE_TURIN_A0,
824 	    "BRHD-A0", X86_UARCHREV_AMD_ZEN5_A0, A_SKTS_TURIN },
825 	{ 0x1a, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_DENSE_TURIN_B0,
826 	    "BRHD-B0", X86_UARCHREV_AMD_ZEN5_B0, A_SKTS_TURIN },
827 	/* BRHD-B0 & BRHD-B1 both map to Zen 5 uarch B0 */
828 	{ 0x1a, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_DENSE_TURIN_B1,
829 	    "BRHD-B1", X86_UARCHREV_AMD_ZEN5_B0, A_SKTS_TURIN },
830 	{ 0x1a, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_DENSE_TURIN_UNKNOWN,
831 	    "BRHD-???", X86_UARCHREV_AMD_ZEN5_UNKNOWN, A_SKTS_TURIN },
832 
833 	/* Strix */
834 	{ 0x1a, 0x24, 0x24, 0x0, 0x0, X86_CHIPREV_AMD_STRIX_B0,
835 	    "STX-B0", X86_UARCHREV_AMD_ZEN5_B0, A_SKTS_STRIX },
836 	{ 0x1a, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_STRIX_UNKNOWN,
837 	    "STX-???", X86_UARCHREV_AMD_ZEN5_UNKNOWN, A_SKTS_STRIX },
838 
839 	/* Granite Ridge */
840 	{ 0x1a, 0x44, 0x44, 0x0, 0x0, X86_CHIPREV_AMD_GRANITE_RIDGE_B0,
841 	    "GNR-B0", X86_UARCHREV_AMD_ZEN5_B0, A_SKTS_GRANITE_RIDGE },
842 	{ 0x1a, 0x40, 0x4f, 0x0, 0xf, X86_CHIPREV_AMD_GRANITE_RIDGE_UNKNOWN,
843 	    "GNR-???", X86_UARCHREV_AMD_ZEN5_UNKNOWN, A_SKTS_GRANITE_RIDGE }
844 
845 };
846 
847 /*
848  * AMD keeps the socket type in CPUID Fn8000_0001_EBX, bits 31:28.
849  */
850 static uint32_t
851 synth_amd_skt_cpuid(uint_t family, uint_t sktid)
852 {
853 	struct cpuid_regs cp;
854 	uint_t idx;
855 
856 	cp.cp_eax = 0x80000001;
857 	(void) __cpuid_insn(&cp);
858 
859 	/* PkgType bits */
860 	idx = BITX(cp.cp_ebx, 31, 28);
861 
862 	if (family == 0x10) {
863 		uint32_t val;
864 
865 		val = pci_getl_func(0, 24, 2, 0x94);
866 		if (BITX(val, 8, 8)) {
867 			if (amd_skts[sktid][idx] == X86_SOCKET_AM2R2) {
868 				return (X86_SOCKET_AM3);
869 			} else if (amd_skts[sktid][idx] == X86_SOCKET_S1g3) {
870 				return (X86_SOCKET_S1g4);
871 			}
872 		}
873 	}
874 
875 	return (amd_skts[sktid][idx]);
876 }
877 
878 static void
879 synth_amd_info(uint_t family, uint_t model, uint_t step,
880     uint32_t *skt_p, x86_chiprev_t *chiprev_p, const char **chiprevstr_p,
881     x86_uarchrev_t *uarchrev_p)
882 {
883 	const struct amd_rev_mapent *rmp;
884 	int found = 0;
885 	int i;
886 
887 	if (family < 0xf)
888 		return;
889 
890 	for (i = 0, rmp = amd_revmap; i < ARRAY_SIZE(amd_revmap); i++, rmp++) {
891 		if (family == rmp->rm_family &&
892 		    model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
893 		    step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
894 			found = 1;
895 			break;
896 		}
897 	}
898 
899 	if (found) {
900 		if (chiprev_p != NULL)
901 			*chiprev_p = rmp->rm_chiprev;
902 		if (chiprevstr_p != NULL)
903 			*chiprevstr_p = rmp->rm_chiprevstr;
904 		if (uarchrev_p != NULL)
905 			*uarchrev_p = rmp->rm_uarchrev;
906 	}
907 
908 	if (skt_p != NULL) {
909 		int platform;
910 
911 #ifdef __xpv
912 		/* PV guest */
913 		if (!is_controldom()) {
914 			*skt_p = X86_SOCKET_UNKNOWN;
915 			return;
916 		}
917 #endif
918 		platform = get_hwenv();
919 
920 		if ((platform & HW_VIRTUAL) != 0) {
921 			*skt_p = X86_SOCKET_UNKNOWN;
922 			return;
923 		}
924 
925 		if (!found)
926 			return;
927 
928 		if (family == 0xf) {
929 			*skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
930 		} else {
931 			*skt_p = synth_amd_skt_cpuid(family, rmp->rm_sktidx);
932 		}
933 	}
934 }
935 
936 uint32_t
937 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
938 {
939 	uint32_t skt = X86_SOCKET_UNKNOWN;
940 
941 	switch (vendor) {
942 	case X86_VENDOR_AMD:
943 	case X86_VENDOR_HYGON:
944 		synth_amd_info(family, model, step, &skt, NULL, NULL, NULL);
945 		break;
946 
947 	default:
948 		break;
949 
950 	}
951 
952 	return (skt);
953 }
954 
955 const char *
956 _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
957 {
958 	const char *sktstr = "Unknown";
959 	struct amd_sktmap_s *sktmapp;
960 	uint32_t skt = X86_SOCKET_UNKNOWN;
961 
962 	switch (vendor) {
963 	case X86_VENDOR_AMD:
964 	case X86_VENDOR_HYGON:
965 		synth_amd_info(family, model, step, &skt, NULL, NULL, NULL);
966 
967 		sktmapp = amd_sktmap_strs;
968 		while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) {
969 			if (sktmapp->skt_code == skt)
970 				break;
971 			sktmapp++;
972 		}
973 		sktstr = sktmapp->sktstr;
974 		break;
975 
976 	default:
977 		break;
978 
979 	}
980 
981 	return (sktstr);
982 }
983 
984 x86_chiprev_t
985 _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step)
986 {
987 	x86_chiprev_t chiprev = X86_CHIPREV_UNKNOWN;
988 
989 	switch (vendor) {
990 	case X86_VENDOR_AMD:
991 	case X86_VENDOR_HYGON:
992 		synth_amd_info(family, model, step, NULL, &chiprev, NULL, NULL);
993 		break;
994 
995 	default:
996 		break;
997 
998 	}
999 
1000 	return (chiprev);
1001 }
1002 
1003 x86_uarchrev_t
1004 _cpuid_uarchrev(uint_t vendor, uint_t family, uint_t model, uint_t step)
1005 {
1006 	x86_uarchrev_t uarchrev = X86_UARCHREV_UNKNOWN;
1007 
1008 	switch (vendor) {
1009 	case X86_VENDOR_AMD:
1010 	case X86_VENDOR_HYGON:
1011 		synth_amd_info(family, model, step, NULL, NULL, NULL,
1012 		    &uarchrev);
1013 		break;
1014 
1015 	default:
1016 		break;
1017 
1018 	}
1019 
1020 	return (uarchrev);
1021 }
1022 
1023 const char *
1024 _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
1025 {
1026 	const char *revstr = "Unknown";
1027 
1028 	switch (vendor) {
1029 	case X86_VENDOR_AMD:
1030 	case X86_VENDOR_HYGON:
1031 		synth_amd_info(family, model, step, NULL, NULL, &revstr, NULL);
1032 		break;
1033 
1034 	default:
1035 		break;
1036 
1037 	}
1038 
1039 	return (revstr);
1040 
1041 }
1042 
1043 /*
1044  * Map the vendor string to a type code
1045  */
1046 uint_t
1047 _cpuid_vendorstr_to_vendorcode(char *vendorstr)
1048 {
1049 	if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0)
1050 		return (X86_VENDOR_Intel);
1051 	else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0)
1052 		return (X86_VENDOR_AMD);
1053 	else if (strcmp(vendorstr, X86_VENDORSTR_HYGON) == 0)
1054 		return (X86_VENDOR_HYGON);
1055 	else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0)
1056 		return (X86_VENDOR_TM);
1057 	else if (strcmp(vendorstr, X86_VENDORSTR_CYRIX) == 0)
1058 		return (X86_VENDOR_Cyrix);
1059 	else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0)
1060 		return (X86_VENDOR_UMC);
1061 	else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0)
1062 		return (X86_VENDOR_NexGen);
1063 	else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0)
1064 		return (X86_VENDOR_Centaur);
1065 	else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0)
1066 		return (X86_VENDOR_Rise);
1067 	else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0)
1068 		return (X86_VENDOR_SiS);
1069 	else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0)
1070 		return (X86_VENDOR_NSC);
1071 	else
1072 		return (X86_VENDOR_IntelClone);
1073 }
1074