xref: /onnv-gate/usr/src/uts/i86pc/os/cpuid_subr.c (revision 9482:42f3d60af7ca)
17532SSean.Ye@Sun.COM /*
27532SSean.Ye@Sun.COM  * CDDL HEADER START
37532SSean.Ye@Sun.COM  *
47532SSean.Ye@Sun.COM  * The contents of this file are subject to the terms of the
57532SSean.Ye@Sun.COM  * Common Development and Distribution License (the "License").
67532SSean.Ye@Sun.COM  * You may not use this file except in compliance with the License.
77532SSean.Ye@Sun.COM  *
87532SSean.Ye@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97532SSean.Ye@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107532SSean.Ye@Sun.COM  * See the License for the specific language governing permissions
117532SSean.Ye@Sun.COM  * and limitations under the License.
127532SSean.Ye@Sun.COM  *
137532SSean.Ye@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147532SSean.Ye@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157532SSean.Ye@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167532SSean.Ye@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177532SSean.Ye@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187532SSean.Ye@Sun.COM  *
197532SSean.Ye@Sun.COM  * CDDL HEADER END
207532SSean.Ye@Sun.COM  */
217532SSean.Ye@Sun.COM 
227532SSean.Ye@Sun.COM /*
23*9482SKuriakose.Kuruvilla@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247532SSean.Ye@Sun.COM  * Use is subject to license terms.
257532SSean.Ye@Sun.COM  */
267532SSean.Ye@Sun.COM 
277532SSean.Ye@Sun.COM /*
28*9482SKuriakose.Kuruvilla@Sun.COM  * Portions Copyright 2009 Advanced Micro Devices, Inc.
29*9482SKuriakose.Kuruvilla@Sun.COM  */
30*9482SKuriakose.Kuruvilla@Sun.COM 
31*9482SKuriakose.Kuruvilla@Sun.COM /*
327532SSean.Ye@Sun.COM  * Support functions that interpret CPUID and similar information.
337532SSean.Ye@Sun.COM  * These should not be used from anywhere other than cpuid.c and
347532SSean.Ye@Sun.COM  * cmi_hw.c - as such we will not list them in any header file
357532SSean.Ye@Sun.COM  * such as x86_archext.h.
367532SSean.Ye@Sun.COM  *
377532SSean.Ye@Sun.COM  * In cpuid.c we process CPUID information for each cpu_t instance
387532SSean.Ye@Sun.COM  * we're presented with, and stash this raw information and material
397532SSean.Ye@Sun.COM  * derived from it in per-cpu_t structures.
407532SSean.Ye@Sun.COM  *
417532SSean.Ye@Sun.COM  * If we are virtualized then the CPUID information derived from CPUID
427532SSean.Ye@Sun.COM  * instructions executed in the guest is based on whatever the hypervisor
437532SSean.Ye@Sun.COM  * wanted to make things look like, and the cpu_t are not necessarily in 1:1
447532SSean.Ye@Sun.COM  * or fixed correspondence with real processor execution resources.  In cmi_hw.c
457532SSean.Ye@Sun.COM  * we are interested in the native properties of a processor - for fault
467532SSean.Ye@Sun.COM  * management (and potentially other, such as power management) purposes;
477532SSean.Ye@Sun.COM  * it will tunnel through to real hardware information, and use the
487532SSean.Ye@Sun.COM  * functionality provided in this file to process it.
497532SSean.Ye@Sun.COM  */
507532SSean.Ye@Sun.COM 
517532SSean.Ye@Sun.COM #include <sys/types.h>
527532SSean.Ye@Sun.COM #include <sys/systm.h>
53*9482SKuriakose.Kuruvilla@Sun.COM #include <sys/bitmap.h>
547532SSean.Ye@Sun.COM #include <sys/x86_archext.h>
55*9482SKuriakose.Kuruvilla@Sun.COM #include <sys/pci_cfgspace.h>
56*9482SKuriakose.Kuruvilla@Sun.COM #ifdef __xpv
57*9482SKuriakose.Kuruvilla@Sun.COM #include <sys/hypervisor.h>
58*9482SKuriakose.Kuruvilla@Sun.COM #endif
597532SSean.Ye@Sun.COM 
607532SSean.Ye@Sun.COM /*
61*9482SKuriakose.Kuruvilla@Sun.COM  * AMD socket types.
627532SSean.Ye@Sun.COM  * First index :
637532SSean.Ye@Sun.COM  *		0 for family 0xf, revs B thru E
647532SSean.Ye@Sun.COM  *		1 for family 0xf, revs F and G
65*9482SKuriakose.Kuruvilla@Sun.COM  *		2 for family 0x10
66*9482SKuriakose.Kuruvilla@Sun.COM  *		3 for family 0x11
67*9482SKuriakose.Kuruvilla@Sun.COM  * Second index by (model & 0x3) for family 0fh
68*9482SKuriakose.Kuruvilla@Sun.COM  * or CPUID bits for later families
697532SSean.Ye@Sun.COM  */
70*9482SKuriakose.Kuruvilla@Sun.COM static uint32_t amd_skts[4][4] = {
717532SSean.Ye@Sun.COM 	/*
727532SSean.Ye@Sun.COM 	 * Family 0xf revisions B through E
737532SSean.Ye@Sun.COM 	 */
747532SSean.Ye@Sun.COM #define	A_SKTS_0			0
757532SSean.Ye@Sun.COM 	{
767532SSean.Ye@Sun.COM 		X86_SOCKET_754,		/* 0b00 */
777532SSean.Ye@Sun.COM 		X86_SOCKET_940,		/* 0b01 */
787532SSean.Ye@Sun.COM 		X86_SOCKET_754,		/* 0b10 */
797532SSean.Ye@Sun.COM 		X86_SOCKET_939		/* 0b11 */
807532SSean.Ye@Sun.COM 	},
817532SSean.Ye@Sun.COM 	/*
827532SSean.Ye@Sun.COM 	 * Family 0xf revisions F and G
837532SSean.Ye@Sun.COM 	 */
847532SSean.Ye@Sun.COM #define	A_SKTS_1			1
857532SSean.Ye@Sun.COM 	{
867532SSean.Ye@Sun.COM 		X86_SOCKET_S1g1,	/* 0b00 */
877532SSean.Ye@Sun.COM 		X86_SOCKET_F1207,	/* 0b01 */
887532SSean.Ye@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b10 */
897532SSean.Ye@Sun.COM 		X86_SOCKET_AM2		/* 0b11 */
907532SSean.Ye@Sun.COM 	},
917532SSean.Ye@Sun.COM 	/*
92*9482SKuriakose.Kuruvilla@Sun.COM 	 * Family 0x10
937532SSean.Ye@Sun.COM 	 */
947532SSean.Ye@Sun.COM #define	A_SKTS_2			2
957532SSean.Ye@Sun.COM 	{
967532SSean.Ye@Sun.COM 		X86_SOCKET_F1207,	/* 0b00 */
97*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_AM,		/* 0b01 */
98*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_S1g3,	/* 0b10 */
99*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_G34,		/* 0b11 */
100*9482SKuriakose.Kuruvilla@Sun.COM 	},
101*9482SKuriakose.Kuruvilla@Sun.COM 
102*9482SKuriakose.Kuruvilla@Sun.COM 	/*
103*9482SKuriakose.Kuruvilla@Sun.COM 	 * Family 0x11
104*9482SKuriakose.Kuruvilla@Sun.COM 	 */
105*9482SKuriakose.Kuruvilla@Sun.COM #define	A_SKTS_3			3
106*9482SKuriakose.Kuruvilla@Sun.COM 	{
107*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b00 */
108*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b01 */
109*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_S1g2,	/* 0b10 */
110*9482SKuriakose.Kuruvilla@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b11 */
1117532SSean.Ye@Sun.COM 	}
1127532SSean.Ye@Sun.COM };
1137532SSean.Ye@Sun.COM 
114*9482SKuriakose.Kuruvilla@Sun.COM struct amd_sktmap_s {
115*9482SKuriakose.Kuruvilla@Sun.COM 	uint32_t	skt_code;
116*9482SKuriakose.Kuruvilla@Sun.COM 	char		sktstr[16];
117*9482SKuriakose.Kuruvilla@Sun.COM };
118*9482SKuriakose.Kuruvilla@Sun.COM static struct amd_sktmap_s amd_sktmap[13] = {
119*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_754,	"754" },
120*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_939,	"939" },
121*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_940,	"940" },
122*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_S1g1,	"S1g1" },
123*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM2,	"AM2" },
124*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_F1207,	"F(1207)" },
125*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_S1g2,	"S1g2" },
126*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_S1g3,	"S1g3" },
127*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM,	"AM" },
128*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM2R2,	"AM2r2" },
129*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM3,	"AM3" },
130*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_G34,	"G34" },
131*9482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_UNKNOWN,	"Unknown" }
132*9482SKuriakose.Kuruvilla@Sun.COM };
133*9482SKuriakose.Kuruvilla@Sun.COM 
1347532SSean.Ye@Sun.COM /*
1357532SSean.Ye@Sun.COM  * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
1367532SSean.Ye@Sun.COM  * combination to chip "revision" and socket type.
1377532SSean.Ye@Sun.COM  *
1387532SSean.Ye@Sun.COM  * The first member of this array that matches a given family, extended model
1397532SSean.Ye@Sun.COM  * plus model range, and stepping range will be considered a match.
1407532SSean.Ye@Sun.COM  */
1417532SSean.Ye@Sun.COM static const struct amd_rev_mapent {
1427532SSean.Ye@Sun.COM 	uint_t rm_family;
1437532SSean.Ye@Sun.COM 	uint_t rm_modello;
1447532SSean.Ye@Sun.COM 	uint_t rm_modelhi;
1457532SSean.Ye@Sun.COM 	uint_t rm_steplo;
1467532SSean.Ye@Sun.COM 	uint_t rm_stephi;
1477532SSean.Ye@Sun.COM 	uint32_t rm_chiprev;
1487532SSean.Ye@Sun.COM 	const char *rm_chiprevstr;
1497532SSean.Ye@Sun.COM 	int rm_sktidx;
1507532SSean.Ye@Sun.COM } amd_revmap[] = {
1517532SSean.Ye@Sun.COM 	/*
1527532SSean.Ye@Sun.COM 	 * =============== AuthenticAMD Family 0xf ===============
1537532SSean.Ye@Sun.COM 	 */
1547532SSean.Ye@Sun.COM 
1557532SSean.Ye@Sun.COM 	/*
1567532SSean.Ye@Sun.COM 	 * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1.
1577532SSean.Ye@Sun.COM 	 */
1587532SSean.Ye@Sun.COM 	{ 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 },
1597532SSean.Ye@Sun.COM 	{ 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 },
1607532SSean.Ye@Sun.COM 	/*
1617532SSean.Ye@Sun.COM 	 * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8
1627532SSean.Ye@Sun.COM 	 */
1637532SSean.Ye@Sun.COM 	{ 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_F_REV_C0, "C0", A_SKTS_0 },
1647532SSean.Ye@Sun.COM 	/*
1657532SSean.Ye@Sun.COM 	 * Rev CG is the rest of extended model 0x0 - i.e., everything
1667532SSean.Ye@Sun.COM 	 * but the rev B and C0 combinations covered above.
1677532SSean.Ye@Sun.COM 	 */
1687532SSean.Ye@Sun.COM 	{ 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_CG, "CG", A_SKTS_0 },
1697532SSean.Ye@Sun.COM 	/*
1707532SSean.Ye@Sun.COM 	 * Rev D has extended model 0x1.
1717532SSean.Ye@Sun.COM 	 */
1727532SSean.Ye@Sun.COM 	{ 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_D, "D", A_SKTS_0 },
1737532SSean.Ye@Sun.COM 	/*
1747532SSean.Ye@Sun.COM 	 * Rev E has extended model 0x2.
1757532SSean.Ye@Sun.COM 	 * Extended model 0x3 is unused but available to grow into.
1767532SSean.Ye@Sun.COM 	 */
1777532SSean.Ye@Sun.COM 	{ 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_E, "E", A_SKTS_0 },
1787532SSean.Ye@Sun.COM 	/*
1797532SSean.Ye@Sun.COM 	 * Rev F has extended models 0x4 and 0x5.
1807532SSean.Ye@Sun.COM 	 */
1817532SSean.Ye@Sun.COM 	{ 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_F, "F", A_SKTS_1 },
1827532SSean.Ye@Sun.COM 	/*
1837532SSean.Ye@Sun.COM 	 * Rev G has extended model 0x6.
1847532SSean.Ye@Sun.COM 	 */
1857532SSean.Ye@Sun.COM 	{ 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
1867532SSean.Ye@Sun.COM 
1877532SSean.Ye@Sun.COM 	/*
1887532SSean.Ye@Sun.COM 	 * =============== AuthenticAMD Family 0x10 ===============
1897532SSean.Ye@Sun.COM 	 */
1907532SSean.Ye@Sun.COM 
1917532SSean.Ye@Sun.COM 	/*
1927532SSean.Ye@Sun.COM 	 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
1937532SSean.Ye@Sun.COM 	 * Give all of model 0 stepping range to rev A.
1947532SSean.Ye@Sun.COM 	 */
1957532SSean.Ye@Sun.COM 	{ 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
1967532SSean.Ye@Sun.COM 
1977532SSean.Ye@Sun.COM 	/*
1987532SSean.Ye@Sun.COM 	 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
1997532SSean.Ye@Sun.COM 	 * Give all of model 2 stepping range to rev B.
2007532SSean.Ye@Sun.COM 	 */
2017532SSean.Ye@Sun.COM 	{ 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
2028375SKit.Chow@Sun.COM 
2038375SKit.Chow@Sun.COM 	/*
2048375SKit.Chow@Sun.COM 	 * Rev C has models 4-6 (depending on L3 cache configuration)
205*9482SKuriakose.Kuruvilla@Sun.COM 	 * Give all of models 4-6 stepping range to rev C.
2068375SKit.Chow@Sun.COM 	 */
2078375SKit.Chow@Sun.COM 	{ 0x10, 0x04, 0x06, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_C, "C", A_SKTS_2 },
208*9482SKuriakose.Kuruvilla@Sun.COM 
209*9482SKuriakose.Kuruvilla@Sun.COM 	/*
210*9482SKuriakose.Kuruvilla@Sun.COM 	 * Rev D has models 8 and 9
211*9482SKuriakose.Kuruvilla@Sun.COM 	 * Give all of model 8 and 9 stepping range to rev D.
212*9482SKuriakose.Kuruvilla@Sun.COM 	 */
213*9482SKuriakose.Kuruvilla@Sun.COM 	{ 0x10, 0x08, 0x09, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_D, "D", A_SKTS_2 },
214*9482SKuriakose.Kuruvilla@Sun.COM 
215*9482SKuriakose.Kuruvilla@Sun.COM 	/*
216*9482SKuriakose.Kuruvilla@Sun.COM 	 * =============== AuthenticAMD Family 0x11 ===============
217*9482SKuriakose.Kuruvilla@Sun.COM 	 */
218*9482SKuriakose.Kuruvilla@Sun.COM 	{ 0x11, 0x03, 0x3, 0x0, 0xf, X86_CHIPREV_AMD_11, "B", A_SKTS_3 },
2197532SSean.Ye@Sun.COM };
2207532SSean.Ye@Sun.COM 
2217532SSean.Ye@Sun.COM static void
2227532SSean.Ye@Sun.COM synth_amd_info(uint_t family, uint_t model, uint_t step,
2237532SSean.Ye@Sun.COM     uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
2247532SSean.Ye@Sun.COM {
2257532SSean.Ye@Sun.COM 	const struct amd_rev_mapent *rmp;
2267532SSean.Ye@Sun.COM 	int found = 0;
2277532SSean.Ye@Sun.COM 	int i;
2287532SSean.Ye@Sun.COM 
229*9482SKuriakose.Kuruvilla@Sun.COM 	if (family < 0xf)
2307532SSean.Ye@Sun.COM 		return;
2317532SSean.Ye@Sun.COM 
2327532SSean.Ye@Sun.COM 	for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
2337532SSean.Ye@Sun.COM 	    i++, rmp++) {
2347532SSean.Ye@Sun.COM 		if (family == rmp->rm_family &&
2357532SSean.Ye@Sun.COM 		    model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
2367532SSean.Ye@Sun.COM 		    step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
2377532SSean.Ye@Sun.COM 			found = 1;
2387532SSean.Ye@Sun.COM 			break;
2397532SSean.Ye@Sun.COM 		}
2407532SSean.Ye@Sun.COM 	}
2417532SSean.Ye@Sun.COM 
242*9482SKuriakose.Kuruvilla@Sun.COM 	if (!found)
243*9482SKuriakose.Kuruvilla@Sun.COM 		return;
244*9482SKuriakose.Kuruvilla@Sun.COM 
245*9482SKuriakose.Kuruvilla@Sun.COM 	if (chiprev_p != NULL)
246*9482SKuriakose.Kuruvilla@Sun.COM 		*chiprev_p = rmp->rm_chiprev;
247*9482SKuriakose.Kuruvilla@Sun.COM 	if (chiprevstr_p != NULL)
248*9482SKuriakose.Kuruvilla@Sun.COM 		*chiprevstr_p = rmp->rm_chiprevstr;
249*9482SKuriakose.Kuruvilla@Sun.COM 
250*9482SKuriakose.Kuruvilla@Sun.COM 	if (skt_p != NULL) {
251*9482SKuriakose.Kuruvilla@Sun.COM 		int platform;
252*9482SKuriakose.Kuruvilla@Sun.COM 
253*9482SKuriakose.Kuruvilla@Sun.COM #ifdef __xpv
254*9482SKuriakose.Kuruvilla@Sun.COM 		/* PV guest */
255*9482SKuriakose.Kuruvilla@Sun.COM 		if (!is_controldom()) {
256*9482SKuriakose.Kuruvilla@Sun.COM 			*skt_p = X86_SOCKET_UNKNOWN;
257*9482SKuriakose.Kuruvilla@Sun.COM 			return;
258*9482SKuriakose.Kuruvilla@Sun.COM 		}
259*9482SKuriakose.Kuruvilla@Sun.COM #endif
260*9482SKuriakose.Kuruvilla@Sun.COM 		platform = get_hwenv();
261*9482SKuriakose.Kuruvilla@Sun.COM 
262*9482SKuriakose.Kuruvilla@Sun.COM 		if ((platform == HW_XEN_HVM) || (platform == HW_VMWARE)) {
263*9482SKuriakose.Kuruvilla@Sun.COM 			*skt_p = X86_SOCKET_UNKNOWN;
264*9482SKuriakose.Kuruvilla@Sun.COM 		} else if (family == 0xf) {
2657532SSean.Ye@Sun.COM 			*skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
266*9482SKuriakose.Kuruvilla@Sun.COM 		} else {
267*9482SKuriakose.Kuruvilla@Sun.COM 			/*
268*9482SKuriakose.Kuruvilla@Sun.COM 			 * Starting with family 10h, socket type is stored in
269*9482SKuriakose.Kuruvilla@Sun.COM 			 * CPUID Fn8000_0001_EBX
270*9482SKuriakose.Kuruvilla@Sun.COM 			 */
271*9482SKuriakose.Kuruvilla@Sun.COM 			struct cpuid_regs cp;
272*9482SKuriakose.Kuruvilla@Sun.COM 			int idx;
273*9482SKuriakose.Kuruvilla@Sun.COM 
274*9482SKuriakose.Kuruvilla@Sun.COM 			cp.cp_eax = 0x80000001;
275*9482SKuriakose.Kuruvilla@Sun.COM 			(void) __cpuid_insn(&cp);
276*9482SKuriakose.Kuruvilla@Sun.COM 
277*9482SKuriakose.Kuruvilla@Sun.COM 			/* PkgType bits */
278*9482SKuriakose.Kuruvilla@Sun.COM 			idx = BITX(cp.cp_ebx, 31, 28);
279*9482SKuriakose.Kuruvilla@Sun.COM 
280*9482SKuriakose.Kuruvilla@Sun.COM 			if (idx > 3) {
281*9482SKuriakose.Kuruvilla@Sun.COM 				/* Reserved bits */
282*9482SKuriakose.Kuruvilla@Sun.COM 				*skt_p = X86_SOCKET_UNKNOWN;
283*9482SKuriakose.Kuruvilla@Sun.COM 			} else if (family == 0x10 &&
284*9482SKuriakose.Kuruvilla@Sun.COM 			    amd_skts[rmp->rm_sktidx][idx] ==
285*9482SKuriakose.Kuruvilla@Sun.COM 			    X86_SOCKET_AM) {
286*9482SKuriakose.Kuruvilla@Sun.COM 				/*
287*9482SKuriakose.Kuruvilla@Sun.COM 				 * Look at Ddr3Mode bit of DRAM Configuration
288*9482SKuriakose.Kuruvilla@Sun.COM 				 * High Register to decide whether this is
289*9482SKuriakose.Kuruvilla@Sun.COM 				 * AM2r2 (aka AM2+) or AM3.
290*9482SKuriakose.Kuruvilla@Sun.COM 				 */
291*9482SKuriakose.Kuruvilla@Sun.COM 				uint32_t val;
292*9482SKuriakose.Kuruvilla@Sun.COM 
293*9482SKuriakose.Kuruvilla@Sun.COM 				val = pci_getl_func(0, 24, 2, 0x94);
294*9482SKuriakose.Kuruvilla@Sun.COM 				if (BITX(val, 8, 8))
295*9482SKuriakose.Kuruvilla@Sun.COM 					*skt_p = X86_SOCKET_AM3;
296*9482SKuriakose.Kuruvilla@Sun.COM 				else
297*9482SKuriakose.Kuruvilla@Sun.COM 					*skt_p = X86_SOCKET_AM2R2;
298*9482SKuriakose.Kuruvilla@Sun.COM 			} else {
299*9482SKuriakose.Kuruvilla@Sun.COM 				*skt_p = amd_skts[rmp->rm_sktidx][idx];
300*9482SKuriakose.Kuruvilla@Sun.COM 			}
301*9482SKuriakose.Kuruvilla@Sun.COM 		}
3027532SSean.Ye@Sun.COM 	}
3037532SSean.Ye@Sun.COM }
3047532SSean.Ye@Sun.COM 
3057532SSean.Ye@Sun.COM uint32_t
3067532SSean.Ye@Sun.COM _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
3077532SSean.Ye@Sun.COM {
3087532SSean.Ye@Sun.COM 	uint32_t skt = X86_SOCKET_UNKNOWN;
3097532SSean.Ye@Sun.COM 
3107532SSean.Ye@Sun.COM 	switch (vendor) {
3117532SSean.Ye@Sun.COM 	case X86_VENDOR_AMD:
3127532SSean.Ye@Sun.COM 		synth_amd_info(family, model, step, &skt, NULL, NULL);
3137532SSean.Ye@Sun.COM 		break;
3147532SSean.Ye@Sun.COM 
3157532SSean.Ye@Sun.COM 	default:
3167532SSean.Ye@Sun.COM 		break;
3177532SSean.Ye@Sun.COM 
3187532SSean.Ye@Sun.COM 	}
3197532SSean.Ye@Sun.COM 
3207532SSean.Ye@Sun.COM 	return (skt);
3217532SSean.Ye@Sun.COM }
3227532SSean.Ye@Sun.COM 
323*9482SKuriakose.Kuruvilla@Sun.COM const char *
324*9482SKuriakose.Kuruvilla@Sun.COM _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
325*9482SKuriakose.Kuruvilla@Sun.COM {
326*9482SKuriakose.Kuruvilla@Sun.COM 	const char *sktstr = "Unknown";
327*9482SKuriakose.Kuruvilla@Sun.COM 	struct amd_sktmap_s *sktmapp;
328*9482SKuriakose.Kuruvilla@Sun.COM 	uint32_t skt = X86_SOCKET_UNKNOWN;
329*9482SKuriakose.Kuruvilla@Sun.COM 
330*9482SKuriakose.Kuruvilla@Sun.COM 	switch (vendor) {
331*9482SKuriakose.Kuruvilla@Sun.COM 	case X86_VENDOR_AMD:
332*9482SKuriakose.Kuruvilla@Sun.COM 		synth_amd_info(family, model, step, &skt, NULL, NULL);
333*9482SKuriakose.Kuruvilla@Sun.COM 
334*9482SKuriakose.Kuruvilla@Sun.COM 		sktmapp = amd_sktmap;
335*9482SKuriakose.Kuruvilla@Sun.COM 		while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) {
336*9482SKuriakose.Kuruvilla@Sun.COM 			if (sktmapp->skt_code == skt)
337*9482SKuriakose.Kuruvilla@Sun.COM 				break;
338*9482SKuriakose.Kuruvilla@Sun.COM 			sktmapp++;
339*9482SKuriakose.Kuruvilla@Sun.COM 		}
340*9482SKuriakose.Kuruvilla@Sun.COM 		sktstr = sktmapp->sktstr;
341*9482SKuriakose.Kuruvilla@Sun.COM 		break;
342*9482SKuriakose.Kuruvilla@Sun.COM 
343*9482SKuriakose.Kuruvilla@Sun.COM 	default:
344*9482SKuriakose.Kuruvilla@Sun.COM 		break;
345*9482SKuriakose.Kuruvilla@Sun.COM 
346*9482SKuriakose.Kuruvilla@Sun.COM 	}
347*9482SKuriakose.Kuruvilla@Sun.COM 
348*9482SKuriakose.Kuruvilla@Sun.COM 	return (sktstr);
349*9482SKuriakose.Kuruvilla@Sun.COM }
350*9482SKuriakose.Kuruvilla@Sun.COM 
3517532SSean.Ye@Sun.COM uint32_t
3527532SSean.Ye@Sun.COM _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step)
3537532SSean.Ye@Sun.COM {
3547532SSean.Ye@Sun.COM 	uint32_t chiprev = X86_CHIPREV_UNKNOWN;
3557532SSean.Ye@Sun.COM 
3567532SSean.Ye@Sun.COM 	switch (vendor) {
3577532SSean.Ye@Sun.COM 	case X86_VENDOR_AMD:
3587532SSean.Ye@Sun.COM 		synth_amd_info(family, model, step, NULL, &chiprev, NULL);
3597532SSean.Ye@Sun.COM 		break;
3607532SSean.Ye@Sun.COM 
3617532SSean.Ye@Sun.COM 	default:
3627532SSean.Ye@Sun.COM 		break;
3637532SSean.Ye@Sun.COM 
3647532SSean.Ye@Sun.COM 	}
3657532SSean.Ye@Sun.COM 
3667532SSean.Ye@Sun.COM 	return (chiprev);
3677532SSean.Ye@Sun.COM }
3687532SSean.Ye@Sun.COM 
3697532SSean.Ye@Sun.COM const char *
3707532SSean.Ye@Sun.COM _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
3717532SSean.Ye@Sun.COM {
3727532SSean.Ye@Sun.COM 	const char *revstr = "Unknown";
3737532SSean.Ye@Sun.COM 
3747532SSean.Ye@Sun.COM 	switch (vendor) {
3757532SSean.Ye@Sun.COM 	case X86_VENDOR_AMD:
3767532SSean.Ye@Sun.COM 		synth_amd_info(family, model, step, NULL, NULL, &revstr);
3777532SSean.Ye@Sun.COM 		break;
3787532SSean.Ye@Sun.COM 
3797532SSean.Ye@Sun.COM 	default:
3807532SSean.Ye@Sun.COM 		break;
3817532SSean.Ye@Sun.COM 
3827532SSean.Ye@Sun.COM 	}
3837532SSean.Ye@Sun.COM 
3847532SSean.Ye@Sun.COM 	return (revstr);
3857532SSean.Ye@Sun.COM 
3867532SSean.Ye@Sun.COM }
3877532SSean.Ye@Sun.COM 
3887532SSean.Ye@Sun.COM /*
3897532SSean.Ye@Sun.COM  * CyrixInstead is a variable used by the Cyrix detection code
3907532SSean.Ye@Sun.COM  * in locore.
3917532SSean.Ye@Sun.COM  */
3927532SSean.Ye@Sun.COM const char CyrixInstead[] = X86_VENDORSTR_CYRIX;
3937532SSean.Ye@Sun.COM 
3947532SSean.Ye@Sun.COM /*
3957532SSean.Ye@Sun.COM  * Map the vendor string to a type code
3967532SSean.Ye@Sun.COM  */
3977532SSean.Ye@Sun.COM uint_t
3987532SSean.Ye@Sun.COM _cpuid_vendorstr_to_vendorcode(char *vendorstr)
3997532SSean.Ye@Sun.COM {
4007532SSean.Ye@Sun.COM 	if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0)
4017532SSean.Ye@Sun.COM 		return (X86_VENDOR_Intel);
4027532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0)
4037532SSean.Ye@Sun.COM 		return (X86_VENDOR_AMD);
4047532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0)
4057532SSean.Ye@Sun.COM 		return (X86_VENDOR_TM);
4067532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, CyrixInstead) == 0)
4077532SSean.Ye@Sun.COM 		return (X86_VENDOR_Cyrix);
4087532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0)
4097532SSean.Ye@Sun.COM 		return (X86_VENDOR_UMC);
4107532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0)
4117532SSean.Ye@Sun.COM 		return (X86_VENDOR_NexGen);
4127532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0)
4137532SSean.Ye@Sun.COM 		return (X86_VENDOR_Centaur);
4147532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0)
4157532SSean.Ye@Sun.COM 		return (X86_VENDOR_Rise);
4167532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0)
4177532SSean.Ye@Sun.COM 		return (X86_VENDOR_SiS);
4187532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0)
4197532SSean.Ye@Sun.COM 		return (X86_VENDOR_NSC);
4207532SSean.Ye@Sun.COM 	else
4217532SSean.Ye@Sun.COM 		return (X86_VENDOR_IntelClone);
4227532SSean.Ye@Sun.COM }
423