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