xref: /onnv-gate/usr/src/uts/i86pc/os/cpuid_subr.c (revision 10551:62422ea6e65b)
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 /*
239482SKuriakose.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 /*
289482SKuriakose.Kuruvilla@Sun.COM  * Portions Copyright 2009 Advanced Micro Devices, Inc.
299482SKuriakose.Kuruvilla@Sun.COM  */
309482SKuriakose.Kuruvilla@Sun.COM 
319482SKuriakose.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>
539482SKuriakose.Kuruvilla@Sun.COM #include <sys/bitmap.h>
547532SSean.Ye@Sun.COM #include <sys/x86_archext.h>
559482SKuriakose.Kuruvilla@Sun.COM #include <sys/pci_cfgspace.h>
569482SKuriakose.Kuruvilla@Sun.COM #ifdef __xpv
579482SKuriakose.Kuruvilla@Sun.COM #include <sys/hypervisor.h>
589482SKuriakose.Kuruvilla@Sun.COM #endif
597532SSean.Ye@Sun.COM 
607532SSean.Ye@Sun.COM /*
619482SKuriakose.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
659482SKuriakose.Kuruvilla@Sun.COM  *		2 for family 0x10
669482SKuriakose.Kuruvilla@Sun.COM  *		3 for family 0x11
679482SKuriakose.Kuruvilla@Sun.COM  * Second index by (model & 0x3) for family 0fh
689482SKuriakose.Kuruvilla@Sun.COM  * or CPUID bits for later families
697532SSean.Ye@Sun.COM  */
70*10551SSrihari.Venkatesan@Sun.COM static uint32_t amd_skts[4][8] = {
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 	{
76*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_754,		/* 0b000 */
77*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_940,		/* 0b001 */
78*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_754,		/* 0b010 */
79*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_939,		/* 0b011 */
80*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b100 */
81*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b101 */
82*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b110 */
83*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN	/* 0b111 */
847532SSean.Ye@Sun.COM 	},
857532SSean.Ye@Sun.COM 	/*
867532SSean.Ye@Sun.COM 	 * Family 0xf revisions F and G
877532SSean.Ye@Sun.COM 	 */
887532SSean.Ye@Sun.COM #define	A_SKTS_1			1
897532SSean.Ye@Sun.COM 	{
90*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_S1g1,	/* 0b000 */
91*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_F1207,	/* 0b001 */
92*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b010 */
93*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_AM2,		/* 0b011 */
94*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b100 */
95*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b101 */
96*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b110 */
97*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN	/* 0b111 */
987532SSean.Ye@Sun.COM 	},
997532SSean.Ye@Sun.COM 	/*
1009482SKuriakose.Kuruvilla@Sun.COM 	 * Family 0x10
1017532SSean.Ye@Sun.COM 	 */
1027532SSean.Ye@Sun.COM #define	A_SKTS_2			2
1037532SSean.Ye@Sun.COM 	{
104*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_F1207,	/* 0b000 */
105*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_AM,		/* 0b001 */
106*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_S1g3,	/* 0b010 */
107*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_G34,		/* 0b011 */
108*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_ASB2,	/* 0b100 */
109*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_C32,		/* 0b101 */
110*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b110 */
111*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN	/* 0b111 */
1129482SKuriakose.Kuruvilla@Sun.COM 	},
1139482SKuriakose.Kuruvilla@Sun.COM 
1149482SKuriakose.Kuruvilla@Sun.COM 	/*
1159482SKuriakose.Kuruvilla@Sun.COM 	 * Family 0x11
1169482SKuriakose.Kuruvilla@Sun.COM 	 */
1179482SKuriakose.Kuruvilla@Sun.COM #define	A_SKTS_3			3
1189482SKuriakose.Kuruvilla@Sun.COM 	{
119*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b000 */
120*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b001 */
121*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_S1g2,	/* 0b010 */
122*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b011 */
123*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b100 */
124*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b101 */
125*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN,	/* 0b110 */
126*10551SSrihari.Venkatesan@Sun.COM 		X86_SOCKET_UNKNOWN	/* 0b111 */
1277532SSean.Ye@Sun.COM 	}
1287532SSean.Ye@Sun.COM };
1297532SSean.Ye@Sun.COM 
1309482SKuriakose.Kuruvilla@Sun.COM struct amd_sktmap_s {
1319482SKuriakose.Kuruvilla@Sun.COM 	uint32_t	skt_code;
1329482SKuriakose.Kuruvilla@Sun.COM 	char		sktstr[16];
1339482SKuriakose.Kuruvilla@Sun.COM };
134*10551SSrihari.Venkatesan@Sun.COM static struct amd_sktmap_s amd_sktmap[15] = {
1359482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_754,	"754" },
1369482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_939,	"939" },
1379482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_940,	"940" },
1389482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_S1g1,	"S1g1" },
1399482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM2,	"AM2" },
1409482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_F1207,	"F(1207)" },
1419482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_S1g2,	"S1g2" },
1429482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_S1g3,	"S1g3" },
1439482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM,	"AM" },
1449482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM2R2,	"AM2r2" },
1459482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_AM3,	"AM3" },
1469482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_G34,	"G34" },
147*10551SSrihari.Venkatesan@Sun.COM 	{ X86_SOCKET_ASB2,	"ASB2" },
148*10551SSrihari.Venkatesan@Sun.COM 	{ X86_SOCKET_C32,	"C32" },
1499482SKuriakose.Kuruvilla@Sun.COM 	{ X86_SOCKET_UNKNOWN,	"Unknown" }
1509482SKuriakose.Kuruvilla@Sun.COM };
1519482SKuriakose.Kuruvilla@Sun.COM 
1527532SSean.Ye@Sun.COM /*
1537532SSean.Ye@Sun.COM  * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
1547532SSean.Ye@Sun.COM  * combination to chip "revision" and socket type.
1557532SSean.Ye@Sun.COM  *
1567532SSean.Ye@Sun.COM  * The first member of this array that matches a given family, extended model
1577532SSean.Ye@Sun.COM  * plus model range, and stepping range will be considered a match.
1587532SSean.Ye@Sun.COM  */
1597532SSean.Ye@Sun.COM static const struct amd_rev_mapent {
1607532SSean.Ye@Sun.COM 	uint_t rm_family;
1617532SSean.Ye@Sun.COM 	uint_t rm_modello;
1627532SSean.Ye@Sun.COM 	uint_t rm_modelhi;
1637532SSean.Ye@Sun.COM 	uint_t rm_steplo;
1647532SSean.Ye@Sun.COM 	uint_t rm_stephi;
1657532SSean.Ye@Sun.COM 	uint32_t rm_chiprev;
1667532SSean.Ye@Sun.COM 	const char *rm_chiprevstr;
1677532SSean.Ye@Sun.COM 	int rm_sktidx;
1687532SSean.Ye@Sun.COM } amd_revmap[] = {
1697532SSean.Ye@Sun.COM 	/*
1707532SSean.Ye@Sun.COM 	 * =============== AuthenticAMD Family 0xf ===============
1717532SSean.Ye@Sun.COM 	 */
1727532SSean.Ye@Sun.COM 
1737532SSean.Ye@Sun.COM 	/*
1747532SSean.Ye@Sun.COM 	 * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1.
1757532SSean.Ye@Sun.COM 	 */
1767532SSean.Ye@Sun.COM 	{ 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 },
1777532SSean.Ye@Sun.COM 	{ 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 },
1787532SSean.Ye@Sun.COM 	/*
1797532SSean.Ye@Sun.COM 	 * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8
1807532SSean.Ye@Sun.COM 	 */
1817532SSean.Ye@Sun.COM 	{ 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_F_REV_C0, "C0", A_SKTS_0 },
1827532SSean.Ye@Sun.COM 	/*
1837532SSean.Ye@Sun.COM 	 * Rev CG is the rest of extended model 0x0 - i.e., everything
1847532SSean.Ye@Sun.COM 	 * but the rev B and C0 combinations covered above.
1857532SSean.Ye@Sun.COM 	 */
1867532SSean.Ye@Sun.COM 	{ 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_CG, "CG", A_SKTS_0 },
1877532SSean.Ye@Sun.COM 	/*
1887532SSean.Ye@Sun.COM 	 * Rev D has extended model 0x1.
1897532SSean.Ye@Sun.COM 	 */
1907532SSean.Ye@Sun.COM 	{ 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_D, "D", A_SKTS_0 },
1917532SSean.Ye@Sun.COM 	/*
1927532SSean.Ye@Sun.COM 	 * Rev E has extended model 0x2.
1937532SSean.Ye@Sun.COM 	 * Extended model 0x3 is unused but available to grow into.
1947532SSean.Ye@Sun.COM 	 */
1957532SSean.Ye@Sun.COM 	{ 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_E, "E", A_SKTS_0 },
1967532SSean.Ye@Sun.COM 	/*
1977532SSean.Ye@Sun.COM 	 * Rev F has extended models 0x4 and 0x5.
1987532SSean.Ye@Sun.COM 	 */
1997532SSean.Ye@Sun.COM 	{ 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_F, "F", A_SKTS_1 },
2007532SSean.Ye@Sun.COM 	/*
2017532SSean.Ye@Sun.COM 	 * Rev G has extended model 0x6.
2027532SSean.Ye@Sun.COM 	 */
2037532SSean.Ye@Sun.COM 	{ 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
2047532SSean.Ye@Sun.COM 
2057532SSean.Ye@Sun.COM 	/*
2067532SSean.Ye@Sun.COM 	 * =============== AuthenticAMD Family 0x10 ===============
2077532SSean.Ye@Sun.COM 	 */
2087532SSean.Ye@Sun.COM 
2097532SSean.Ye@Sun.COM 	/*
2107532SSean.Ye@Sun.COM 	 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
2117532SSean.Ye@Sun.COM 	 * Give all of model 0 stepping range to rev A.
2127532SSean.Ye@Sun.COM 	 */
2137532SSean.Ye@Sun.COM 	{ 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
2147532SSean.Ye@Sun.COM 
2157532SSean.Ye@Sun.COM 	/*
2167532SSean.Ye@Sun.COM 	 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
2177532SSean.Ye@Sun.COM 	 * Give all of model 2 stepping range to rev B.
2187532SSean.Ye@Sun.COM 	 */
2197532SSean.Ye@Sun.COM 	{ 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
2208375SKit.Chow@Sun.COM 
2218375SKit.Chow@Sun.COM 	/*
2228375SKit.Chow@Sun.COM 	 * Rev C has models 4-6 (depending on L3 cache configuration)
2239482SKuriakose.Kuruvilla@Sun.COM 	 * Give all of models 4-6 stepping range to rev C.
2248375SKit.Chow@Sun.COM 	 */
2258375SKit.Chow@Sun.COM 	{ 0x10, 0x04, 0x06, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_C, "C", A_SKTS_2 },
2269482SKuriakose.Kuruvilla@Sun.COM 
2279482SKuriakose.Kuruvilla@Sun.COM 	/*
2289482SKuriakose.Kuruvilla@Sun.COM 	 * Rev D has models 8 and 9
2299482SKuriakose.Kuruvilla@Sun.COM 	 * Give all of model 8 and 9 stepping range to rev D.
2309482SKuriakose.Kuruvilla@Sun.COM 	 */
2319482SKuriakose.Kuruvilla@Sun.COM 	{ 0x10, 0x08, 0x09, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_D, "D", A_SKTS_2 },
2329482SKuriakose.Kuruvilla@Sun.COM 
2339482SKuriakose.Kuruvilla@Sun.COM 	/*
2349482SKuriakose.Kuruvilla@Sun.COM 	 * =============== AuthenticAMD Family 0x11 ===============
2359482SKuriakose.Kuruvilla@Sun.COM 	 */
2369482SKuriakose.Kuruvilla@Sun.COM 	{ 0x11, 0x03, 0x3, 0x0, 0xf, X86_CHIPREV_AMD_11, "B", A_SKTS_3 },
2377532SSean.Ye@Sun.COM };
2387532SSean.Ye@Sun.COM 
2397532SSean.Ye@Sun.COM static void
synth_amd_info(uint_t family,uint_t model,uint_t step,uint32_t * skt_p,uint32_t * chiprev_p,const char ** chiprevstr_p)2407532SSean.Ye@Sun.COM synth_amd_info(uint_t family, uint_t model, uint_t step,
2417532SSean.Ye@Sun.COM     uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
2427532SSean.Ye@Sun.COM {
2437532SSean.Ye@Sun.COM 	const struct amd_rev_mapent *rmp;
2447532SSean.Ye@Sun.COM 	int found = 0;
2457532SSean.Ye@Sun.COM 	int i;
2467532SSean.Ye@Sun.COM 
2479482SKuriakose.Kuruvilla@Sun.COM 	if (family < 0xf)
2487532SSean.Ye@Sun.COM 		return;
2497532SSean.Ye@Sun.COM 
2507532SSean.Ye@Sun.COM 	for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
2517532SSean.Ye@Sun.COM 	    i++, rmp++) {
2527532SSean.Ye@Sun.COM 		if (family == rmp->rm_family &&
2537532SSean.Ye@Sun.COM 		    model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
2547532SSean.Ye@Sun.COM 		    step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
2557532SSean.Ye@Sun.COM 			found = 1;
2567532SSean.Ye@Sun.COM 			break;
2577532SSean.Ye@Sun.COM 		}
2587532SSean.Ye@Sun.COM 	}
2597532SSean.Ye@Sun.COM 
2609482SKuriakose.Kuruvilla@Sun.COM 	if (!found)
2619482SKuriakose.Kuruvilla@Sun.COM 		return;
2629482SKuriakose.Kuruvilla@Sun.COM 
2639482SKuriakose.Kuruvilla@Sun.COM 	if (chiprev_p != NULL)
2649482SKuriakose.Kuruvilla@Sun.COM 		*chiprev_p = rmp->rm_chiprev;
2659482SKuriakose.Kuruvilla@Sun.COM 	if (chiprevstr_p != NULL)
2669482SKuriakose.Kuruvilla@Sun.COM 		*chiprevstr_p = rmp->rm_chiprevstr;
2679482SKuriakose.Kuruvilla@Sun.COM 
2689482SKuriakose.Kuruvilla@Sun.COM 	if (skt_p != NULL) {
2699482SKuriakose.Kuruvilla@Sun.COM 		int platform;
2709482SKuriakose.Kuruvilla@Sun.COM 
2719482SKuriakose.Kuruvilla@Sun.COM #ifdef __xpv
2729482SKuriakose.Kuruvilla@Sun.COM 		/* PV guest */
2739482SKuriakose.Kuruvilla@Sun.COM 		if (!is_controldom()) {
2749482SKuriakose.Kuruvilla@Sun.COM 			*skt_p = X86_SOCKET_UNKNOWN;
2759482SKuriakose.Kuruvilla@Sun.COM 			return;
2769482SKuriakose.Kuruvilla@Sun.COM 		}
2779482SKuriakose.Kuruvilla@Sun.COM #endif
2789482SKuriakose.Kuruvilla@Sun.COM 		platform = get_hwenv();
2799482SKuriakose.Kuruvilla@Sun.COM 
2809482SKuriakose.Kuruvilla@Sun.COM 		if ((platform == HW_XEN_HVM) || (platform == HW_VMWARE)) {
2819482SKuriakose.Kuruvilla@Sun.COM 			*skt_p = X86_SOCKET_UNKNOWN;
2829482SKuriakose.Kuruvilla@Sun.COM 		} else if (family == 0xf) {
2837532SSean.Ye@Sun.COM 			*skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
2849482SKuriakose.Kuruvilla@Sun.COM 		} else {
2859482SKuriakose.Kuruvilla@Sun.COM 			/*
2869482SKuriakose.Kuruvilla@Sun.COM 			 * Starting with family 10h, socket type is stored in
2879482SKuriakose.Kuruvilla@Sun.COM 			 * CPUID Fn8000_0001_EBX
2889482SKuriakose.Kuruvilla@Sun.COM 			 */
2899482SKuriakose.Kuruvilla@Sun.COM 			struct cpuid_regs cp;
2909482SKuriakose.Kuruvilla@Sun.COM 			int idx;
2919482SKuriakose.Kuruvilla@Sun.COM 
2929482SKuriakose.Kuruvilla@Sun.COM 			cp.cp_eax = 0x80000001;
2939482SKuriakose.Kuruvilla@Sun.COM 			(void) __cpuid_insn(&cp);
2949482SKuriakose.Kuruvilla@Sun.COM 
2959482SKuriakose.Kuruvilla@Sun.COM 			/* PkgType bits */
2969482SKuriakose.Kuruvilla@Sun.COM 			idx = BITX(cp.cp_ebx, 31, 28);
2979482SKuriakose.Kuruvilla@Sun.COM 
298*10551SSrihari.Venkatesan@Sun.COM 			if (idx > 7) {
2999482SKuriakose.Kuruvilla@Sun.COM 				/* Reserved bits */
3009482SKuriakose.Kuruvilla@Sun.COM 				*skt_p = X86_SOCKET_UNKNOWN;
3019482SKuriakose.Kuruvilla@Sun.COM 			} else if (family == 0x10 &&
3029482SKuriakose.Kuruvilla@Sun.COM 			    amd_skts[rmp->rm_sktidx][idx] ==
3039482SKuriakose.Kuruvilla@Sun.COM 			    X86_SOCKET_AM) {
3049482SKuriakose.Kuruvilla@Sun.COM 				/*
3059482SKuriakose.Kuruvilla@Sun.COM 				 * Look at Ddr3Mode bit of DRAM Configuration
3069482SKuriakose.Kuruvilla@Sun.COM 				 * High Register to decide whether this is
3079482SKuriakose.Kuruvilla@Sun.COM 				 * AM2r2 (aka AM2+) or AM3.
3089482SKuriakose.Kuruvilla@Sun.COM 				 */
3099482SKuriakose.Kuruvilla@Sun.COM 				uint32_t val;
3109482SKuriakose.Kuruvilla@Sun.COM 
3119482SKuriakose.Kuruvilla@Sun.COM 				val = pci_getl_func(0, 24, 2, 0x94);
3129482SKuriakose.Kuruvilla@Sun.COM 				if (BITX(val, 8, 8))
3139482SKuriakose.Kuruvilla@Sun.COM 					*skt_p = X86_SOCKET_AM3;
3149482SKuriakose.Kuruvilla@Sun.COM 				else
3159482SKuriakose.Kuruvilla@Sun.COM 					*skt_p = X86_SOCKET_AM2R2;
3169482SKuriakose.Kuruvilla@Sun.COM 			} else {
3179482SKuriakose.Kuruvilla@Sun.COM 				*skt_p = amd_skts[rmp->rm_sktidx][idx];
3189482SKuriakose.Kuruvilla@Sun.COM 			}
3199482SKuriakose.Kuruvilla@Sun.COM 		}
3207532SSean.Ye@Sun.COM 	}
3217532SSean.Ye@Sun.COM }
3227532SSean.Ye@Sun.COM 
3237532SSean.Ye@Sun.COM uint32_t
_cpuid_skt(uint_t vendor,uint_t family,uint_t model,uint_t step)3247532SSean.Ye@Sun.COM _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
3257532SSean.Ye@Sun.COM {
3267532SSean.Ye@Sun.COM 	uint32_t skt = X86_SOCKET_UNKNOWN;
3277532SSean.Ye@Sun.COM 
3287532SSean.Ye@Sun.COM 	switch (vendor) {
3297532SSean.Ye@Sun.COM 	case X86_VENDOR_AMD:
3307532SSean.Ye@Sun.COM 		synth_amd_info(family, model, step, &skt, NULL, NULL);
3317532SSean.Ye@Sun.COM 		break;
3327532SSean.Ye@Sun.COM 
3337532SSean.Ye@Sun.COM 	default:
3347532SSean.Ye@Sun.COM 		break;
3357532SSean.Ye@Sun.COM 
3367532SSean.Ye@Sun.COM 	}
3377532SSean.Ye@Sun.COM 
3387532SSean.Ye@Sun.COM 	return (skt);
3397532SSean.Ye@Sun.COM }
3407532SSean.Ye@Sun.COM 
3419482SKuriakose.Kuruvilla@Sun.COM const char *
_cpuid_sktstr(uint_t vendor,uint_t family,uint_t model,uint_t step)3429482SKuriakose.Kuruvilla@Sun.COM _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
3439482SKuriakose.Kuruvilla@Sun.COM {
3449482SKuriakose.Kuruvilla@Sun.COM 	const char *sktstr = "Unknown";
3459482SKuriakose.Kuruvilla@Sun.COM 	struct amd_sktmap_s *sktmapp;
3469482SKuriakose.Kuruvilla@Sun.COM 	uint32_t skt = X86_SOCKET_UNKNOWN;
3479482SKuriakose.Kuruvilla@Sun.COM 
3489482SKuriakose.Kuruvilla@Sun.COM 	switch (vendor) {
3499482SKuriakose.Kuruvilla@Sun.COM 	case X86_VENDOR_AMD:
3509482SKuriakose.Kuruvilla@Sun.COM 		synth_amd_info(family, model, step, &skt, NULL, NULL);
3519482SKuriakose.Kuruvilla@Sun.COM 
3529482SKuriakose.Kuruvilla@Sun.COM 		sktmapp = amd_sktmap;
3539482SKuriakose.Kuruvilla@Sun.COM 		while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) {
3549482SKuriakose.Kuruvilla@Sun.COM 			if (sktmapp->skt_code == skt)
3559482SKuriakose.Kuruvilla@Sun.COM 				break;
3569482SKuriakose.Kuruvilla@Sun.COM 			sktmapp++;
3579482SKuriakose.Kuruvilla@Sun.COM 		}
3589482SKuriakose.Kuruvilla@Sun.COM 		sktstr = sktmapp->sktstr;
3599482SKuriakose.Kuruvilla@Sun.COM 		break;
3609482SKuriakose.Kuruvilla@Sun.COM 
3619482SKuriakose.Kuruvilla@Sun.COM 	default:
3629482SKuriakose.Kuruvilla@Sun.COM 		break;
3639482SKuriakose.Kuruvilla@Sun.COM 
3649482SKuriakose.Kuruvilla@Sun.COM 	}
3659482SKuriakose.Kuruvilla@Sun.COM 
3669482SKuriakose.Kuruvilla@Sun.COM 	return (sktstr);
3679482SKuriakose.Kuruvilla@Sun.COM }
3689482SKuriakose.Kuruvilla@Sun.COM 
3697532SSean.Ye@Sun.COM uint32_t
_cpuid_chiprev(uint_t vendor,uint_t family,uint_t model,uint_t step)3707532SSean.Ye@Sun.COM _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step)
3717532SSean.Ye@Sun.COM {
3727532SSean.Ye@Sun.COM 	uint32_t chiprev = X86_CHIPREV_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, &chiprev, NULL);
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 (chiprev);
3857532SSean.Ye@Sun.COM }
3867532SSean.Ye@Sun.COM 
3877532SSean.Ye@Sun.COM const char *
_cpuid_chiprevstr(uint_t vendor,uint_t family,uint_t model,uint_t step)3887532SSean.Ye@Sun.COM _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step)
3897532SSean.Ye@Sun.COM {
3907532SSean.Ye@Sun.COM 	const char *revstr = "Unknown";
3917532SSean.Ye@Sun.COM 
3927532SSean.Ye@Sun.COM 	switch (vendor) {
3937532SSean.Ye@Sun.COM 	case X86_VENDOR_AMD:
3947532SSean.Ye@Sun.COM 		synth_amd_info(family, model, step, NULL, NULL, &revstr);
3957532SSean.Ye@Sun.COM 		break;
3967532SSean.Ye@Sun.COM 
3977532SSean.Ye@Sun.COM 	default:
3987532SSean.Ye@Sun.COM 		break;
3997532SSean.Ye@Sun.COM 
4007532SSean.Ye@Sun.COM 	}
4017532SSean.Ye@Sun.COM 
4027532SSean.Ye@Sun.COM 	return (revstr);
4037532SSean.Ye@Sun.COM 
4047532SSean.Ye@Sun.COM }
4057532SSean.Ye@Sun.COM 
4067532SSean.Ye@Sun.COM /*
4077532SSean.Ye@Sun.COM  * CyrixInstead is a variable used by the Cyrix detection code
4087532SSean.Ye@Sun.COM  * in locore.
4097532SSean.Ye@Sun.COM  */
4107532SSean.Ye@Sun.COM const char CyrixInstead[] = X86_VENDORSTR_CYRIX;
4117532SSean.Ye@Sun.COM 
4127532SSean.Ye@Sun.COM /*
4137532SSean.Ye@Sun.COM  * Map the vendor string to a type code
4147532SSean.Ye@Sun.COM  */
4157532SSean.Ye@Sun.COM uint_t
_cpuid_vendorstr_to_vendorcode(char * vendorstr)4167532SSean.Ye@Sun.COM _cpuid_vendorstr_to_vendorcode(char *vendorstr)
4177532SSean.Ye@Sun.COM {
4187532SSean.Ye@Sun.COM 	if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0)
4197532SSean.Ye@Sun.COM 		return (X86_VENDOR_Intel);
4207532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0)
4217532SSean.Ye@Sun.COM 		return (X86_VENDOR_AMD);
4227532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0)
4237532SSean.Ye@Sun.COM 		return (X86_VENDOR_TM);
4247532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, CyrixInstead) == 0)
4257532SSean.Ye@Sun.COM 		return (X86_VENDOR_Cyrix);
4267532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0)
4277532SSean.Ye@Sun.COM 		return (X86_VENDOR_UMC);
4287532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0)
4297532SSean.Ye@Sun.COM 		return (X86_VENDOR_NexGen);
4307532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0)
4317532SSean.Ye@Sun.COM 		return (X86_VENDOR_Centaur);
4327532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0)
4337532SSean.Ye@Sun.COM 		return (X86_VENDOR_Rise);
4347532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0)
4357532SSean.Ye@Sun.COM 		return (X86_VENDOR_SiS);
4367532SSean.Ye@Sun.COM 	else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0)
4377532SSean.Ye@Sun.COM 		return (X86_VENDOR_NSC);
4387532SSean.Ye@Sun.COM 	else
4397532SSean.Ye@Sun.COM 		return (X86_VENDOR_IntelClone);
4407532SSean.Ye@Sun.COM }
441