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
synth_amd_info(uint_t family,uint_t model,uint_t step,uint32_t * skt_p,uint32_t * chiprev_p,const char ** chiprevstr_p)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
_cpuid_skt(uint_t vendor,uint_t family,uint_t model,uint_t step)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 *
_cpuid_sktstr(uint_t vendor,uint_t family,uint_t model,uint_t step)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
_cpuid_chiprev(uint_t vendor,uint_t family,uint_t model,uint_t step)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 *
_cpuid_chiprevstr(uint_t vendor,uint_t family,uint_t model,uint_t step)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
_cpuid_vendorstr_to_vendorcode(char * vendorstr)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