xref: /titanic_51/usr/src/uts/i86pc/os/cpuid_subr.c (revision 79ec9da85c2648e2e165ce68612ad0cb6e185618)
1e4b86885SCheng Sean Ye /*
2e4b86885SCheng Sean Ye  * CDDL HEADER START
3e4b86885SCheng Sean Ye  *
4e4b86885SCheng Sean Ye  * The contents of this file are subject to the terms of the
5e4b86885SCheng Sean Ye  * Common Development and Distribution License (the "License").
6e4b86885SCheng Sean Ye  * You may not use this file except in compliance with the License.
7e4b86885SCheng Sean Ye  *
8e4b86885SCheng Sean Ye  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e4b86885SCheng Sean Ye  * or http://www.opensolaris.org/os/licensing.
10e4b86885SCheng Sean Ye  * See the License for the specific language governing permissions
11e4b86885SCheng Sean Ye  * and limitations under the License.
12e4b86885SCheng Sean Ye  *
13e4b86885SCheng Sean Ye  * When distributing Covered Code, include this CDDL HEADER in each
14e4b86885SCheng Sean Ye  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e4b86885SCheng Sean Ye  * If applicable, add the following below this CDDL HEADER, with the
16e4b86885SCheng Sean Ye  * fields enclosed by brackets "[]" replaced with your own identifying
17e4b86885SCheng Sean Ye  * information: Portions Copyright [yyyy] [name of copyright owner]
18e4b86885SCheng Sean Ye  *
19e4b86885SCheng Sean Ye  * CDDL HEADER END
20e4b86885SCheng Sean Ye  */
21e4b86885SCheng Sean Ye 
22e4b86885SCheng Sean Ye /*
2389e921d5SKuriakose Kuruvilla  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24e4b86885SCheng Sean Ye  * Use is subject to license terms.
25*79ec9da8SYuri Pankov  *
26*79ec9da8SYuri Pankov  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27e4b86885SCheng Sean Ye  */
28e4b86885SCheng Sean Ye 
29e4b86885SCheng Sean Ye /*
3089e921d5SKuriakose Kuruvilla  * Portions Copyright 2009 Advanced Micro Devices, Inc.
3189e921d5SKuriakose Kuruvilla  */
3289e921d5SKuriakose Kuruvilla 
3389e921d5SKuriakose Kuruvilla /*
3479321794SJens Elkner  * Copyright 2012 Jens Elkner <jel+illumos@cs.uni-magdeburg.de>
3579321794SJens Elkner  * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
3679321794SJens Elkner  */
3779321794SJens Elkner 
3879321794SJens Elkner /*
39e4b86885SCheng Sean Ye  * Support functions that interpret CPUID and similar information.
40e4b86885SCheng Sean Ye  * These should not be used from anywhere other than cpuid.c and
41e4b86885SCheng Sean Ye  * cmi_hw.c - as such we will not list them in any header file
42e4b86885SCheng Sean Ye  * such as x86_archext.h.
43e4b86885SCheng Sean Ye  *
44e4b86885SCheng Sean Ye  * In cpuid.c we process CPUID information for each cpu_t instance
45e4b86885SCheng Sean Ye  * we're presented with, and stash this raw information and material
46e4b86885SCheng Sean Ye  * derived from it in per-cpu_t structures.
47e4b86885SCheng Sean Ye  *
48e4b86885SCheng Sean Ye  * If we are virtualized then the CPUID information derived from CPUID
49e4b86885SCheng Sean Ye  * instructions executed in the guest is based on whatever the hypervisor
50e4b86885SCheng Sean Ye  * wanted to make things look like, and the cpu_t are not necessarily in 1:1
51e4b86885SCheng Sean Ye  * or fixed correspondence with real processor execution resources.  In cmi_hw.c
52e4b86885SCheng Sean Ye  * we are interested in the native properties of a processor - for fault
53e4b86885SCheng Sean Ye  * management (and potentially other, such as power management) purposes;
54e4b86885SCheng Sean Ye  * it will tunnel through to real hardware information, and use the
55e4b86885SCheng Sean Ye  * functionality provided in this file to process it.
56e4b86885SCheng Sean Ye  */
57e4b86885SCheng Sean Ye 
58e4b86885SCheng Sean Ye #include <sys/types.h>
59e4b86885SCheng Sean Ye #include <sys/systm.h>
6089e921d5SKuriakose Kuruvilla #include <sys/bitmap.h>
61e4b86885SCheng Sean Ye #include <sys/x86_archext.h>
6289e921d5SKuriakose Kuruvilla #include <sys/pci_cfgspace.h>
6389e921d5SKuriakose Kuruvilla #ifdef __xpv
6489e921d5SKuriakose Kuruvilla #include <sys/hypervisor.h>
6589e921d5SKuriakose Kuruvilla #endif
66e4b86885SCheng Sean Ye 
67e4b86885SCheng Sean Ye /*
6889e921d5SKuriakose Kuruvilla  * AMD socket types.
69e4b86885SCheng Sean Ye  * First index :
70e4b86885SCheng Sean Ye  *		0 for family 0xf, revs B thru E
71e4b86885SCheng Sean Ye  *		1 for family 0xf, revs F and G
7289e921d5SKuriakose Kuruvilla  *		2 for family 0x10
7389e921d5SKuriakose Kuruvilla  *		3 for family 0x11
7479321794SJens Elkner  *		4 for family 0x12
7579321794SJens Elkner  *		5 for family 0x14
7679321794SJens Elkner  *		6 for family 0x15, models 00 - 0f
7779321794SJens Elkner  *		7 for family 0x15, models 10 - 1f
7879321794SJens Elkner  * Second index by (model & 0x3) for family 0fh,
7979321794SJens Elkner  * CPUID pkg bits (Fn8000_0001_EBX[31:28]) for later families.
80e4b86885SCheng Sean Ye  */
8179321794SJens Elkner static uint32_t amd_skts[8][8] = {
82e4b86885SCheng Sean Ye 	/*
83e4b86885SCheng Sean Ye 	 * Family 0xf revisions B through E
84e4b86885SCheng Sean Ye 	 */
85e4b86885SCheng Sean Ye #define	A_SKTS_0			0
86e4b86885SCheng Sean Ye 	{
87bd15239eSSrihari Venkatesan 		X86_SOCKET_754,		/* 0b000 */
88bd15239eSSrihari Venkatesan 		X86_SOCKET_940,		/* 0b001 */
89bd15239eSSrihari Venkatesan 		X86_SOCKET_754,		/* 0b010 */
90bd15239eSSrihari Venkatesan 		X86_SOCKET_939,		/* 0b011 */
91bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b100 */
92bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b101 */
93bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b110 */
94bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN	/* 0b111 */
95e4b86885SCheng Sean Ye 	},
96e4b86885SCheng Sean Ye 	/*
97e4b86885SCheng Sean Ye 	 * Family 0xf revisions F and G
98e4b86885SCheng Sean Ye 	 */
99e4b86885SCheng Sean Ye #define	A_SKTS_1			1
100e4b86885SCheng Sean Ye 	{
101bd15239eSSrihari Venkatesan 		X86_SOCKET_S1g1,	/* 0b000 */
102bd15239eSSrihari Venkatesan 		X86_SOCKET_F1207,	/* 0b001 */
103bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b010 */
104bd15239eSSrihari Venkatesan 		X86_SOCKET_AM2,		/* 0b011 */
105bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b100 */
106bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b101 */
107bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b110 */
108bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN	/* 0b111 */
109e4b86885SCheng Sean Ye 	},
110e4b86885SCheng Sean Ye 	/*
11189e921d5SKuriakose Kuruvilla 	 * Family 0x10
112e4b86885SCheng Sean Ye 	 */
113e4b86885SCheng Sean Ye #define	A_SKTS_2			2
114e4b86885SCheng Sean Ye 	{
115bd15239eSSrihari Venkatesan 		X86_SOCKET_F1207,	/* 0b000 */
11679321794SJens Elkner 		X86_SOCKET_AM2R2,	/* 0b001 */
117bd15239eSSrihari Venkatesan 		X86_SOCKET_S1g3,	/* 0b010 */
118bd15239eSSrihari Venkatesan 		X86_SOCKET_G34,		/* 0b011 */
119bd15239eSSrihari Venkatesan 		X86_SOCKET_ASB2,	/* 0b100 */
120bd15239eSSrihari Venkatesan 		X86_SOCKET_C32,		/* 0b101 */
121bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b110 */
122bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN	/* 0b111 */
12389e921d5SKuriakose Kuruvilla 	},
12489e921d5SKuriakose Kuruvilla 
12589e921d5SKuriakose Kuruvilla 	/*
12689e921d5SKuriakose Kuruvilla 	 * Family 0x11
12789e921d5SKuriakose Kuruvilla 	 */
12889e921d5SKuriakose Kuruvilla #define	A_SKTS_3			3
12989e921d5SKuriakose Kuruvilla 	{
130bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b000 */
131bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b001 */
132bd15239eSSrihari Venkatesan 		X86_SOCKET_S1g2,	/* 0b010 */
133bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b011 */
134bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b100 */
135bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b101 */
136bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN,	/* 0b110 */
137bd15239eSSrihari Venkatesan 		X86_SOCKET_UNKNOWN	/* 0b111 */
13879321794SJens Elkner 	},
13979321794SJens Elkner 
14079321794SJens Elkner 	/*
14179321794SJens Elkner 	 * Family 0x12
14279321794SJens Elkner 	 */
14379321794SJens Elkner #define	A_SKTS_4			4
14479321794SJens Elkner 	{
14579321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b000 */
14679321794SJens Elkner 		X86_SOCKET_FS1,		/* 0b001 */
14779321794SJens Elkner 		X86_SOCKET_FM1,		/* 0b010 */
14879321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b011 */
14979321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b100 */
15079321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b101 */
15179321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b110 */
15279321794SJens Elkner 		X86_SOCKET_UNKNOWN	/* 0b111 */
15379321794SJens Elkner 	},
15479321794SJens Elkner 
15579321794SJens Elkner 	/*
15679321794SJens Elkner 	 * Family 0x14
15779321794SJens Elkner 	 */
15879321794SJens Elkner #define	A_SKTS_5			5
15979321794SJens Elkner 	{
16079321794SJens Elkner 		X86_SOCKET_FT1,		/* 0b000 */
16179321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b001 */
16279321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b010 */
16379321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b011 */
16479321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b100 */
16579321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b101 */
16679321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b110 */
16779321794SJens Elkner 		X86_SOCKET_UNKNOWN	/* 0b111 */
16879321794SJens Elkner 	},
16979321794SJens Elkner 
17079321794SJens Elkner 	/*
17179321794SJens Elkner 	 * Family 0x15 models 00 - 0f
17279321794SJens Elkner 	 */
17379321794SJens Elkner #define	A_SKTS_6			6
17479321794SJens Elkner 	{
17579321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b000 */
17679321794SJens Elkner 		X86_SOCKET_AM3R2,	/* 0b001 */
17779321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b010 */
17879321794SJens Elkner 		X86_SOCKET_G34,		/* 0b011 */
17979321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b100 */
18079321794SJens Elkner 		X86_SOCKET_C32,		/* 0b101 */
18179321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b110 */
18279321794SJens Elkner 		X86_SOCKET_UNKNOWN	/* 0b111 */
18379321794SJens Elkner 	},
18479321794SJens Elkner 
18579321794SJens Elkner 	/*
18679321794SJens Elkner 	 * Family 0x15 models 10 - 1f
18779321794SJens Elkner 	 */
18879321794SJens Elkner #define	A_SKTS_7			7
18979321794SJens Elkner 	{
19079321794SJens Elkner 		X86_SOCKET_FP2,		/* 0b000 */
19179321794SJens Elkner 		X86_SOCKET_FS1R2,	/* 0b001 */
19279321794SJens Elkner 		X86_SOCKET_FM2,		/* 0b010 */
19379321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b011 */
19479321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b100 */
19579321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b101 */
19679321794SJens Elkner 		X86_SOCKET_UNKNOWN,	/* 0b110 */
19779321794SJens Elkner 		X86_SOCKET_UNKNOWN	/* 0b111 */
19879321794SJens Elkner 	},
19979321794SJens Elkner 
200e4b86885SCheng Sean Ye };
201e4b86885SCheng Sean Ye 
20289e921d5SKuriakose Kuruvilla struct amd_sktmap_s {
20389e921d5SKuriakose Kuruvilla 	uint32_t	skt_code;
20489e921d5SKuriakose Kuruvilla 	char		sktstr[16];
20589e921d5SKuriakose Kuruvilla };
20679321794SJens Elkner static struct amd_sktmap_s amd_sktmap[23] = {
20789e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_754,	"754" },
20889e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_939,	"939" },
20989e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_940,	"940" },
21089e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_S1g1,	"S1g1" },
21189e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_AM2,	"AM2" },
21289e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_F1207,	"F(1207)" },
21389e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_S1g2,	"S1g2" },
21489e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_S1g3,	"S1g3" },
21589e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_AM,	"AM" },
21689e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_AM2R2,	"AM2r2" },
21789e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_AM3,	"AM3" },
21889e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_G34,	"G34" },
219bd15239eSSrihari Venkatesan 	{ X86_SOCKET_ASB2,	"ASB2" },
220bd15239eSSrihari Venkatesan 	{ X86_SOCKET_C32,	"C32" },
22179321794SJens Elkner 	{ X86_SOCKET_FT1,	"FT1" },
22279321794SJens Elkner 	{ X86_SOCKET_FM1,	"FM1" },
22379321794SJens Elkner 	{ X86_SOCKET_FS1,	"FS1" },
22479321794SJens Elkner 	{ X86_SOCKET_AM3R2,	"AM3r2" },
22579321794SJens Elkner 	{ X86_SOCKET_FP2,	"FP2" },
22679321794SJens Elkner 	{ X86_SOCKET_FS1R2,	"FS1r2" },
22779321794SJens Elkner 	{ X86_SOCKET_FM2,	"FM2" },
22889e921d5SKuriakose Kuruvilla 	{ X86_SOCKET_UNKNOWN,	"Unknown" }
22989e921d5SKuriakose Kuruvilla };
23089e921d5SKuriakose Kuruvilla 
231e4b86885SCheng Sean Ye /*
232e4b86885SCheng Sean Ye  * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
233e4b86885SCheng Sean Ye  * combination to chip "revision" and socket type.
234e4b86885SCheng Sean Ye  *
235e4b86885SCheng Sean Ye  * The first member of this array that matches a given family, extended model
236e4b86885SCheng Sean Ye  * plus model range, and stepping range will be considered a match.
237e4b86885SCheng Sean Ye  */
238e4b86885SCheng Sean Ye static const struct amd_rev_mapent {
239e4b86885SCheng Sean Ye 	uint_t rm_family;
240e4b86885SCheng Sean Ye 	uint_t rm_modello;
241e4b86885SCheng Sean Ye 	uint_t rm_modelhi;
242e4b86885SCheng Sean Ye 	uint_t rm_steplo;
243e4b86885SCheng Sean Ye 	uint_t rm_stephi;
244e4b86885SCheng Sean Ye 	uint32_t rm_chiprev;
245e4b86885SCheng Sean Ye 	const char *rm_chiprevstr;
246e4b86885SCheng Sean Ye 	int rm_sktidx;
247e4b86885SCheng Sean Ye } amd_revmap[] = {
248e4b86885SCheng Sean Ye 	/*
249e4b86885SCheng Sean Ye 	 * =============== AuthenticAMD Family 0xf ===============
250e4b86885SCheng Sean Ye 	 */
251e4b86885SCheng Sean Ye 
252e4b86885SCheng Sean Ye 	/*
253e4b86885SCheng Sean Ye 	 * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1.
254e4b86885SCheng Sean Ye 	 */
255e4b86885SCheng Sean Ye 	{ 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 },
256e4b86885SCheng Sean Ye 	{ 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 },
257e4b86885SCheng Sean Ye 	/*
258e4b86885SCheng Sean Ye 	 * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8
259e4b86885SCheng Sean Ye 	 */
260e4b86885SCheng Sean Ye 	{ 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_F_REV_C0, "C0", A_SKTS_0 },
261e4b86885SCheng Sean Ye 	/*
262e4b86885SCheng Sean Ye 	 * Rev CG is the rest of extended model 0x0 - i.e., everything
263e4b86885SCheng Sean Ye 	 * but the rev B and C0 combinations covered above.
264e4b86885SCheng Sean Ye 	 */
265e4b86885SCheng Sean Ye 	{ 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_CG, "CG", A_SKTS_0 },
266e4b86885SCheng Sean Ye 	/*
267e4b86885SCheng Sean Ye 	 * Rev D has extended model 0x1.
268e4b86885SCheng Sean Ye 	 */
269e4b86885SCheng Sean Ye 	{ 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_D, "D", A_SKTS_0 },
270e4b86885SCheng Sean Ye 	/*
271e4b86885SCheng Sean Ye 	 * Rev E has extended model 0x2.
272e4b86885SCheng Sean Ye 	 * Extended model 0x3 is unused but available to grow into.
273e4b86885SCheng Sean Ye 	 */
274e4b86885SCheng Sean Ye 	{ 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_E, "E", A_SKTS_0 },
275e4b86885SCheng Sean Ye 	/*
276e4b86885SCheng Sean Ye 	 * Rev F has extended models 0x4 and 0x5.
277e4b86885SCheng Sean Ye 	 */
278e4b86885SCheng Sean Ye 	{ 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_F, "F", A_SKTS_1 },
279e4b86885SCheng Sean Ye 	/*
280e4b86885SCheng Sean Ye 	 * Rev G has extended model 0x6.
281e4b86885SCheng Sean Ye 	 */
282e4b86885SCheng Sean Ye 	{ 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
283e4b86885SCheng Sean Ye 
284e4b86885SCheng Sean Ye 	/*
285e4b86885SCheng Sean Ye 	 * =============== AuthenticAMD Family 0x10 ===============
286e4b86885SCheng Sean Ye 	 */
287e4b86885SCheng Sean Ye 
288e4b86885SCheng Sean Ye 	/*
289e4b86885SCheng Sean Ye 	 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
290e4b86885SCheng Sean Ye 	 * Give all of model 0 stepping range to rev A.
291e4b86885SCheng Sean Ye 	 */
292e4b86885SCheng Sean Ye 	{ 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
293e4b86885SCheng Sean Ye 
294e4b86885SCheng Sean Ye 	/*
295e4b86885SCheng Sean Ye 	 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
296e4b86885SCheng Sean Ye 	 * Give all of model 2 stepping range to rev B.
297e4b86885SCheng Sean Ye 	 */
298e4b86885SCheng Sean Ye 	{ 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
29964452efdSKit Chow 
30064452efdSKit Chow 	/*
30164452efdSKit Chow 	 * Rev C has models 4-6 (depending on L3 cache configuration)
30279321794SJens Elkner 	 * Give all of models 4-6 stepping range 0-2 to rev C2.
30364452efdSKit Chow 	 */
30479321794SJens Elkner 	{ 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_C2, "C2", A_SKTS_2 },
30579321794SJens Elkner 
30679321794SJens Elkner 	/*
30779321794SJens Elkner 	 * Rev C has models 4-6 (depending on L3 cache configuration)
30879321794SJens Elkner 	 * Give all of models 4-6 stepping range >= 3 to rev C3.
30979321794SJens Elkner 	 */
31079321794SJens Elkner 	{ 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_10_REV_C3, "C3", A_SKTS_2 },
31189e921d5SKuriakose Kuruvilla 
31289e921d5SKuriakose Kuruvilla 	/*
31389e921d5SKuriakose Kuruvilla 	 * Rev D has models 8 and 9
31479321794SJens Elkner 	 * Give all of model 8 and 9 stepping 0 to rev D0.
31589e921d5SKuriakose Kuruvilla 	 */
31679321794SJens Elkner 	{ 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_10_REV_D0, "D0", A_SKTS_2 },
31779321794SJens Elkner 
31879321794SJens Elkner 	/*
31979321794SJens Elkner 	 * Rev D has models 8 and 9
32079321794SJens Elkner 	 * Give all of model 8 and 9 stepping range >= 1 to rev D1.
32179321794SJens Elkner 	 */
32279321794SJens Elkner 	{ 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_10_REV_D1, "D1", A_SKTS_2 },
32379321794SJens Elkner 
32479321794SJens Elkner 	/*
32579321794SJens Elkner 	 * Rev E has models A and stepping 0
32679321794SJens Elkner 	 * Give all of model A stepping range to rev E.
32779321794SJens Elkner 	 */
32879321794SJens Elkner 	{ 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_E, "E", A_SKTS_2 },
32989e921d5SKuriakose Kuruvilla 
33089e921d5SKuriakose Kuruvilla 	/*
33189e921d5SKuriakose Kuruvilla 	 * =============== AuthenticAMD Family 0x11 ===============
33289e921d5SKuriakose Kuruvilla 	 */
33379321794SJens Elkner 	{ 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_11_REV_B, "B", A_SKTS_3 },
33479321794SJens Elkner 
33579321794SJens Elkner 	/*
33679321794SJens Elkner 	 * =============== AuthenticAMD Family 0x12 ===============
33779321794SJens Elkner 	 */
33879321794SJens Elkner 	{ 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_12_REV_B, "B", A_SKTS_4 },
33979321794SJens Elkner 
34079321794SJens Elkner 	/*
34179321794SJens Elkner 	 * =============== AuthenticAMD Family 0x14 ===============
34279321794SJens Elkner 	 */
34379321794SJens Elkner 	{ 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_B, "B", A_SKTS_5 },
34479321794SJens Elkner 	{ 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_C, "C", A_SKTS_5 },
34579321794SJens Elkner 
34679321794SJens Elkner 	/*
34779321794SJens Elkner 	 * =============== AuthenticAMD Family 0x15 ===============
34879321794SJens Elkner 	 */
34979321794SJens Elkner 	{ 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_15OR_REV_B2, "B2",
35079321794SJens Elkner 	    A_SKTS_6 },
35179321794SJens Elkner 	{ 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_15TN_REV_A1, "A1",
35279321794SJens Elkner 	    A_SKTS_7 },
353e4b86885SCheng Sean Ye };
354e4b86885SCheng Sean Ye 
355e4b86885SCheng Sean Ye static void
356e4b86885SCheng Sean Ye synth_amd_info(uint_t family, uint_t model, uint_t step,
357e4b86885SCheng Sean Ye     uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
358e4b86885SCheng Sean Ye {
359e4b86885SCheng Sean Ye 	const struct amd_rev_mapent *rmp;
360e4b86885SCheng Sean Ye 	int found = 0;
361e4b86885SCheng Sean Ye 	int i;
362e4b86885SCheng Sean Ye 
36389e921d5SKuriakose Kuruvilla 	if (family < 0xf)
364e4b86885SCheng Sean Ye 		return;
365e4b86885SCheng Sean Ye 
366e4b86885SCheng Sean Ye 	for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
367e4b86885SCheng Sean Ye 	    i++, rmp++) {
368e4b86885SCheng Sean Ye 		if (family == rmp->rm_family &&
369e4b86885SCheng Sean Ye 		    model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
370e4b86885SCheng Sean Ye 		    step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
371e4b86885SCheng Sean Ye 			found = 1;
372e4b86885SCheng Sean Ye 			break;
373e4b86885SCheng Sean Ye 		}
374e4b86885SCheng Sean Ye 	}
375e4b86885SCheng Sean Ye 
37689e921d5SKuriakose Kuruvilla 	if (!found)
37789e921d5SKuriakose Kuruvilla 		return;
37889e921d5SKuriakose Kuruvilla 
379e4b86885SCheng Sean Ye 	if (chiprev_p != NULL)
380e4b86885SCheng Sean Ye 		*chiprev_p = rmp->rm_chiprev;
381e4b86885SCheng Sean Ye 	if (chiprevstr_p != NULL)
382e4b86885SCheng Sean Ye 		*chiprevstr_p = rmp->rm_chiprevstr;
38389e921d5SKuriakose Kuruvilla 
38489e921d5SKuriakose Kuruvilla 	if (skt_p != NULL) {
38589e921d5SKuriakose Kuruvilla 		int platform;
38689e921d5SKuriakose Kuruvilla 
38789e921d5SKuriakose Kuruvilla #ifdef __xpv
38889e921d5SKuriakose Kuruvilla 		/* PV guest */
38989e921d5SKuriakose Kuruvilla 		if (!is_controldom()) {
39089e921d5SKuriakose Kuruvilla 			*skt_p = X86_SOCKET_UNKNOWN;
39189e921d5SKuriakose Kuruvilla 			return;
39289e921d5SKuriakose Kuruvilla 		}
39389e921d5SKuriakose Kuruvilla #endif
39489e921d5SKuriakose Kuruvilla 		platform = get_hwenv();
39589e921d5SKuriakose Kuruvilla 
396*79ec9da8SYuri Pankov 		if ((platform & HW_VIRTUAL) != 0) {
39789e921d5SKuriakose Kuruvilla 			*skt_p = X86_SOCKET_UNKNOWN;
39889e921d5SKuriakose Kuruvilla 		} else if (family == 0xf) {
39989e921d5SKuriakose Kuruvilla 			*skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
40089e921d5SKuriakose Kuruvilla 		} else {
40189e921d5SKuriakose Kuruvilla 			/*
40289e921d5SKuriakose Kuruvilla 			 * Starting with family 10h, socket type is stored in
40389e921d5SKuriakose Kuruvilla 			 * CPUID Fn8000_0001_EBX
40489e921d5SKuriakose Kuruvilla 			 */
40589e921d5SKuriakose Kuruvilla 			struct cpuid_regs cp;
40689e921d5SKuriakose Kuruvilla 			int idx;
40789e921d5SKuriakose Kuruvilla 
40889e921d5SKuriakose Kuruvilla 			cp.cp_eax = 0x80000001;
40989e921d5SKuriakose Kuruvilla 			(void) __cpuid_insn(&cp);
41089e921d5SKuriakose Kuruvilla 
41189e921d5SKuriakose Kuruvilla 			/* PkgType bits */
41289e921d5SKuriakose Kuruvilla 			idx = BITX(cp.cp_ebx, 31, 28);
41389e921d5SKuriakose Kuruvilla 
414bd15239eSSrihari Venkatesan 			if (idx > 7) {
41589e921d5SKuriakose Kuruvilla 				/* Reserved bits */
41689e921d5SKuriakose Kuruvilla 				*skt_p = X86_SOCKET_UNKNOWN;
41779321794SJens Elkner 			} else {
41879321794SJens Elkner 				*skt_p = amd_skts[rmp->rm_sktidx][idx];
41979321794SJens Elkner 			}
42079321794SJens Elkner 			if (family == 0x10) {
42189e921d5SKuriakose Kuruvilla 				/*
42289e921d5SKuriakose Kuruvilla 				 * Look at Ddr3Mode bit of DRAM Configuration
42389e921d5SKuriakose Kuruvilla 				 * High Register to decide whether this is
42479321794SJens Elkner 				 * actually AM3 or S1g4.
42589e921d5SKuriakose Kuruvilla 				 */
42689e921d5SKuriakose Kuruvilla 				uint32_t val;
42789e921d5SKuriakose Kuruvilla 
42889e921d5SKuriakose Kuruvilla 				val = pci_getl_func(0, 24, 2, 0x94);
42979321794SJens Elkner 				if (BITX(val, 8, 8)) {
43079321794SJens Elkner 					if (*skt_p == X86_SOCKET_AM2R2)
43189e921d5SKuriakose Kuruvilla 						*skt_p = X86_SOCKET_AM3;
43279321794SJens Elkner 					else if (*skt_p == X86_SOCKET_S1g3)
43379321794SJens Elkner 						*skt_p = X86_SOCKET_S1g4;
43479321794SJens Elkner 				}
43589e921d5SKuriakose Kuruvilla 			}
43689e921d5SKuriakose Kuruvilla 		}
437e4b86885SCheng Sean Ye 	}
438e4b86885SCheng Sean Ye }
439e4b86885SCheng Sean Ye 
440e4b86885SCheng Sean Ye uint32_t
441e4b86885SCheng Sean Ye _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
442e4b86885SCheng Sean Ye {
443e4b86885SCheng Sean Ye 	uint32_t skt = X86_SOCKET_UNKNOWN;
444e4b86885SCheng Sean Ye 
445e4b86885SCheng Sean Ye 	switch (vendor) {
446e4b86885SCheng Sean Ye 	case X86_VENDOR_AMD:
447e4b86885SCheng Sean Ye 		synth_amd_info(family, model, step, &skt, NULL, NULL);
448e4b86885SCheng Sean Ye 		break;
449e4b86885SCheng Sean Ye 
450e4b86885SCheng Sean Ye 	default:
451e4b86885SCheng Sean Ye 		break;
452e4b86885SCheng Sean Ye 
453e4b86885SCheng Sean Ye 	}
454e4b86885SCheng Sean Ye 
455e4b86885SCheng Sean Ye 	return (skt);
456e4b86885SCheng Sean Ye }
457e4b86885SCheng Sean Ye 
45889e921d5SKuriakose Kuruvilla const char *
45989e921d5SKuriakose Kuruvilla _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
46089e921d5SKuriakose Kuruvilla {
46189e921d5SKuriakose Kuruvilla 	const char *sktstr = "Unknown";
46289e921d5SKuriakose Kuruvilla 	struct amd_sktmap_s *sktmapp;
46389e921d5SKuriakose Kuruvilla 	uint32_t skt = X86_SOCKET_UNKNOWN;
46489e921d5SKuriakose Kuruvilla 
46589e921d5SKuriakose Kuruvilla 	switch (vendor) {
46689e921d5SKuriakose Kuruvilla 	case X86_VENDOR_AMD:
46789e921d5SKuriakose Kuruvilla 		synth_amd_info(family, model, step, &skt, NULL, NULL);
46889e921d5SKuriakose Kuruvilla 
46989e921d5SKuriakose Kuruvilla 		sktmapp = amd_sktmap;
47089e921d5SKuriakose Kuruvilla 		while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) {
47189e921d5SKuriakose Kuruvilla 			if (sktmapp->skt_code == skt)
47289e921d5SKuriakose Kuruvilla 				break;
47389e921d5SKuriakose Kuruvilla 			sktmapp++;
47489e921d5SKuriakose Kuruvilla 		}
47589e921d5SKuriakose Kuruvilla 		sktstr = sktmapp->sktstr;
47689e921d5SKuriakose Kuruvilla 		break;
47789e921d5SKuriakose Kuruvilla 
47889e921d5SKuriakose Kuruvilla 	default:
47989e921d5SKuriakose Kuruvilla 		break;
48089e921d5SKuriakose Kuruvilla 
48189e921d5SKuriakose Kuruvilla 	}
48289e921d5SKuriakose Kuruvilla 
48389e921d5SKuriakose Kuruvilla 	return (sktstr);
48489e921d5SKuriakose Kuruvilla }
48589e921d5SKuriakose Kuruvilla 
486e4b86885SCheng Sean Ye uint32_t
487e4b86885SCheng Sean Ye _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step)
488e4b86885SCheng Sean Ye {
489e4b86885SCheng Sean Ye 	uint32_t chiprev = X86_CHIPREV_UNKNOWN;
490e4b86885SCheng Sean Ye 
491e4b86885SCheng Sean Ye 	switch (vendor) {
492e4b86885SCheng Sean Ye 	case X86_VENDOR_AMD:
493e4b86885SCheng Sean Ye 		synth_amd_info(family, model, step, NULL, &chiprev, NULL);
494e4b86885SCheng Sean Ye 		break;
495e4b86885SCheng Sean Ye 
496e4b86885SCheng Sean Ye 	default:
497e4b86885SCheng Sean Ye 		break;
498e4b86885SCheng Sean Ye 
499e4b86885SCheng Sean Ye 	}
500e4b86885SCheng Sean Ye 
501e4b86885SCheng Sean Ye 	return (chiprev);
502e4b86885SCheng Sean Ye }
503e4b86885SCheng Sean Ye 
504e4b86885SCheng Sean Ye const char *
505e4b86885SCheng Sean Ye _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
506e4b86885SCheng Sean Ye {
507e4b86885SCheng Sean Ye 	const char *revstr = "Unknown";
508e4b86885SCheng Sean Ye 
509e4b86885SCheng Sean Ye 	switch (vendor) {
510e4b86885SCheng Sean Ye 	case X86_VENDOR_AMD:
511e4b86885SCheng Sean Ye 		synth_amd_info(family, model, step, NULL, NULL, &revstr);
512e4b86885SCheng Sean Ye 		break;
513e4b86885SCheng Sean Ye 
514e4b86885SCheng Sean Ye 	default:
515e4b86885SCheng Sean Ye 		break;
516e4b86885SCheng Sean Ye 
517e4b86885SCheng Sean Ye 	}
518e4b86885SCheng Sean Ye 
519e4b86885SCheng Sean Ye 	return (revstr);
520e4b86885SCheng Sean Ye 
521e4b86885SCheng Sean Ye }
522e4b86885SCheng Sean Ye 
523e4b86885SCheng Sean Ye /*
524e4b86885SCheng Sean Ye  * CyrixInstead is a variable used by the Cyrix detection code
525e4b86885SCheng Sean Ye  * in locore.
526e4b86885SCheng Sean Ye  */
527e4b86885SCheng Sean Ye const char CyrixInstead[] = X86_VENDORSTR_CYRIX;
528e4b86885SCheng Sean Ye 
529e4b86885SCheng Sean Ye /*
530e4b86885SCheng Sean Ye  * Map the vendor string to a type code
531e4b86885SCheng Sean Ye  */
532e4b86885SCheng Sean Ye uint_t
533e4b86885SCheng Sean Ye _cpuid_vendorstr_to_vendorcode(char *vendorstr)
534e4b86885SCheng Sean Ye {
535e4b86885SCheng Sean Ye 	if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0)
536e4b86885SCheng Sean Ye 		return (X86_VENDOR_Intel);
537e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0)
538e4b86885SCheng Sean Ye 		return (X86_VENDOR_AMD);
539e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0)
540e4b86885SCheng Sean Ye 		return (X86_VENDOR_TM);
541e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, CyrixInstead) == 0)
542e4b86885SCheng Sean Ye 		return (X86_VENDOR_Cyrix);
543e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0)
544e4b86885SCheng Sean Ye 		return (X86_VENDOR_UMC);
545e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0)
546e4b86885SCheng Sean Ye 		return (X86_VENDOR_NexGen);
547e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0)
548e4b86885SCheng Sean Ye 		return (X86_VENDOR_Centaur);
549e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0)
550e4b86885SCheng Sean Ye 		return (X86_VENDOR_Rise);
551e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0)
552e4b86885SCheng Sean Ye 		return (X86_VENDOR_SiS);
553e4b86885SCheng Sean Ye 	else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0)
554e4b86885SCheng Sean Ye 		return (X86_VENDOR_NSC);
555e4b86885SCheng Sean Ye 	else
556e4b86885SCheng Sean Ye 		return (X86_VENDOR_IntelClone);
557e4b86885SCheng Sean Ye }
558