12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Portions Copyright 2009 Advanced Micro Devices, Inc.
29 */
30
31 /*
32 * Support functions that interpret CPUID and similar information.
33 * These should not be used from anywhere other than cpuid.c and
34 * cmi_hw.c - as such we will not list them in any header file
35 * such as x86_archext.h.
36 *
37 * In cpuid.c we process CPUID information for each cpu_t instance
38 * we're presented with, and stash this raw information and material
39 * derived from it in per-cpu_t structures.
40 *
41 * If we are virtualized then the CPUID information derived from CPUID
42 * instructions executed in the guest is based on whatever the hypervisor
43 * wanted to make things look like, and the cpu_t are not necessarily in 1:1
44 * or fixed correspondence with real processor execution resources. In cmi_hw.c
45 * we are interested in the native properties of a processor - for fault
46 * management (and potentially other, such as power management) purposes;
47 * it will tunnel through to real hardware information, and use the
48 * functionality provided in this file to process it.
49 */
50
51 #include <sys/types.h>
52 #include <sys/systm.h>
53 #include <sys/bitmap.h>
54 #include <sys/x86_archext.h>
55 #include <sys/pci_cfgspace.h>
56 #ifdef __xpv
57 #include <sys/hypervisor.h>
58 #endif
59
60 /*
61 * AMD socket types.
62 * First index :
63 * 0 for family 0xf, revs B thru E
64 * 1 for family 0xf, revs F and G
65 * 2 for family 0x10
66 * 3 for family 0x11
67 * Second index by (model & 0x3) for family 0fh
68 * or CPUID bits for later families
69 */
70 static uint32_t amd_skts[4][8] = {
71 /*
72 * Family 0xf revisions B through E
73 */
74 #define A_SKTS_0 0
75 {
76 X86_SOCKET_754, /* 0b000 */
77 X86_SOCKET_940, /* 0b001 */
78 X86_SOCKET_754, /* 0b010 */
79 X86_SOCKET_939, /* 0b011 */
80 X86_SOCKET_UNKNOWN, /* 0b100 */
81 X86_SOCKET_UNKNOWN, /* 0b101 */
82 X86_SOCKET_UNKNOWN, /* 0b110 */
83 X86_SOCKET_UNKNOWN /* 0b111 */
84 },
85 /*
86 * Family 0xf revisions F and G
87 */
88 #define A_SKTS_1 1
89 {
90 X86_SOCKET_S1g1, /* 0b000 */
91 X86_SOCKET_F1207, /* 0b001 */
92 X86_SOCKET_UNKNOWN, /* 0b010 */
93 X86_SOCKET_AM2, /* 0b011 */
94 X86_SOCKET_UNKNOWN, /* 0b100 */
95 X86_SOCKET_UNKNOWN, /* 0b101 */
96 X86_SOCKET_UNKNOWN, /* 0b110 */
97 X86_SOCKET_UNKNOWN /* 0b111 */
98 },
99 /*
100 * Family 0x10
101 */
102 #define A_SKTS_2 2
103 {
104 X86_SOCKET_F1207, /* 0b000 */
105 X86_SOCKET_AM, /* 0b001 */
106 X86_SOCKET_S1g3, /* 0b010 */
107 X86_SOCKET_G34, /* 0b011 */
108 X86_SOCKET_ASB2, /* 0b100 */
109 X86_SOCKET_C32, /* 0b101 */
110 X86_SOCKET_UNKNOWN, /* 0b110 */
111 X86_SOCKET_UNKNOWN /* 0b111 */
112 },
113
114 /*
115 * Family 0x11
116 */
117 #define A_SKTS_3 3
118 {
119 X86_SOCKET_UNKNOWN, /* 0b000 */
120 X86_SOCKET_UNKNOWN, /* 0b001 */
121 X86_SOCKET_S1g2, /* 0b010 */
122 X86_SOCKET_UNKNOWN, /* 0b011 */
123 X86_SOCKET_UNKNOWN, /* 0b100 */
124 X86_SOCKET_UNKNOWN, /* 0b101 */
125 X86_SOCKET_UNKNOWN, /* 0b110 */
126 X86_SOCKET_UNKNOWN /* 0b111 */
127 }
128 };
129
130 struct amd_sktmap_s {
131 uint32_t skt_code;
132 char sktstr[16];
133 };
134 static struct amd_sktmap_s amd_sktmap[15] = {
135 { X86_SOCKET_754, "754" },
136 { X86_SOCKET_939, "939" },
137 { X86_SOCKET_940, "940" },
138 { X86_SOCKET_S1g1, "S1g1" },
139 { X86_SOCKET_AM2, "AM2" },
140 { X86_SOCKET_F1207, "F(1207)" },
141 { X86_SOCKET_S1g2, "S1g2" },
142 { X86_SOCKET_S1g3, "S1g3" },
143 { X86_SOCKET_AM, "AM" },
144 { X86_SOCKET_AM2R2, "AM2r2" },
145 { X86_SOCKET_AM3, "AM3" },
146 { X86_SOCKET_G34, "G34" },
147 { X86_SOCKET_ASB2, "ASB2" },
148 { X86_SOCKET_C32, "C32" },
149 { X86_SOCKET_UNKNOWN, "Unknown" }
150 };
151
152 /*
153 * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
154 * combination to chip "revision" and socket type.
155 *
156 * The first member of this array that matches a given family, extended model
157 * plus model range, and stepping range will be considered a match.
158 */
159 static const struct amd_rev_mapent {
160 uint_t rm_family;
161 uint_t rm_modello;
162 uint_t rm_modelhi;
163 uint_t rm_steplo;
164 uint_t rm_stephi;
165 uint32_t rm_chiprev;
166 const char *rm_chiprevstr;
167 int rm_sktidx;
168 } amd_revmap[] = {
203 { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
204
205 /*
206 * =============== AuthenticAMD Family 0x10 ===============
207 */
208
209 /*
210 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
211 * Give all of model 0 stepping range to rev A.
212 */
213 { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
214
215 /*
216 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
217 * Give all of model 2 stepping range to rev B.
218 */
219 { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
220
221 /*
222 * Rev C has models 4-6 (depending on L3 cache configuration)
223 * Give all of models 4-6 stepping range to rev C.
224 */
225 { 0x10, 0x04, 0x06, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_C, "C", A_SKTS_2 },
226
227 /*
228 * Rev D has models 8 and 9
229 * Give all of model 8 and 9 stepping range to rev D.
230 */
231 { 0x10, 0x08, 0x09, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_D, "D", A_SKTS_2 },
232
233 /*
234 * =============== AuthenticAMD Family 0x11 ===============
235 */
236 { 0x11, 0x03, 0x3, 0x0, 0xf, X86_CHIPREV_AMD_11, "B", A_SKTS_3 },
237 };
238
239 static void
240 synth_amd_info(uint_t family, uint_t model, uint_t step,
241 uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
242 {
243 const struct amd_rev_mapent *rmp;
244 int found = 0;
245 int i;
246
247 if (family < 0xf)
248 return;
249
250 for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
251 i++, rmp++) {
252 if (family == rmp->rm_family &&
253 model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
254 step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
255 found = 1;
256 break;
281 *skt_p = X86_SOCKET_UNKNOWN;
282 } else if (family == 0xf) {
283 *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
284 } else {
285 /*
286 * Starting with family 10h, socket type is stored in
287 * CPUID Fn8000_0001_EBX
288 */
289 struct cpuid_regs cp;
290 int idx;
291
292 cp.cp_eax = 0x80000001;
293 (void) __cpuid_insn(&cp);
294
295 /* PkgType bits */
296 idx = BITX(cp.cp_ebx, 31, 28);
297
298 if (idx > 7) {
299 /* Reserved bits */
300 *skt_p = X86_SOCKET_UNKNOWN;
301 } else if (family == 0x10 &&
302 amd_skts[rmp->rm_sktidx][idx] ==
303 X86_SOCKET_AM) {
304 /*
305 * Look at Ddr3Mode bit of DRAM Configuration
306 * High Register to decide whether this is
307 * AM2r2 (aka AM2+) or AM3.
308 */
309 uint32_t val;
310
311 val = pci_getl_func(0, 24, 2, 0x94);
312 if (BITX(val, 8, 8))
313 *skt_p = X86_SOCKET_AM3;
314 else
315 *skt_p = X86_SOCKET_AM2R2;
316 } else {
317 *skt_p = amd_skts[rmp->rm_sktidx][idx];
318 }
319 }
320 }
321 }
322
323 uint32_t
324 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
325 {
326 uint32_t skt = X86_SOCKET_UNKNOWN;
327
328 switch (vendor) {
329 case X86_VENDOR_AMD:
330 synth_amd_info(family, model, step, &skt, NULL, NULL);
331 break;
332
333 default:
334 break;
335
336 }
337
338 return (skt);
339 }
|
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Portions Copyright 2009 Advanced Micro Devices, Inc.
29 */
30
31 /*
32 * Copyright 2012 Jens Elkner <jel+illumos@cs.uni-magdeburg.de>
33 * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
34 */
35
36 /*
37 * Support functions that interpret CPUID and similar information.
38 * These should not be used from anywhere other than cpuid.c and
39 * cmi_hw.c - as such we will not list them in any header file
40 * such as x86_archext.h.
41 *
42 * In cpuid.c we process CPUID information for each cpu_t instance
43 * we're presented with, and stash this raw information and material
44 * derived from it in per-cpu_t structures.
45 *
46 * If we are virtualized then the CPUID information derived from CPUID
47 * instructions executed in the guest is based on whatever the hypervisor
48 * wanted to make things look like, and the cpu_t are not necessarily in 1:1
49 * or fixed correspondence with real processor execution resources. In cmi_hw.c
50 * we are interested in the native properties of a processor - for fault
51 * management (and potentially other, such as power management) purposes;
52 * it will tunnel through to real hardware information, and use the
53 * functionality provided in this file to process it.
54 */
55
56 #include <sys/types.h>
57 #include <sys/systm.h>
58 #include <sys/bitmap.h>
59 #include <sys/x86_archext.h>
60 #include <sys/pci_cfgspace.h>
61 #ifdef __xpv
62 #include <sys/hypervisor.h>
63 #endif
64
65 /*
66 * AMD socket types.
67 * First index :
68 * 0 for family 0xf, revs B thru E
69 * 1 for family 0xf, revs F and G
70 * 2 for family 0x10
71 * 3 for family 0x11
72 * 4 for family 0x12
73 * 5 for family 0x14
74 * 6 for family 0x15, models 00 - 0f
75 * 7 for family 0x15, models 10 - 1f
76 * Second index by (model & 0x3) for family 0fh,
77 * CPUID pkg bits (Fn8000_0001_EBX[31:28]) for later families.
78 */
79 static uint32_t amd_skts[8][8] = {
80 /*
81 * Family 0xf revisions B through E
82 */
83 #define A_SKTS_0 0
84 {
85 X86_SOCKET_754, /* 0b000 */
86 X86_SOCKET_940, /* 0b001 */
87 X86_SOCKET_754, /* 0b010 */
88 X86_SOCKET_939, /* 0b011 */
89 X86_SOCKET_UNKNOWN, /* 0b100 */
90 X86_SOCKET_UNKNOWN, /* 0b101 */
91 X86_SOCKET_UNKNOWN, /* 0b110 */
92 X86_SOCKET_UNKNOWN /* 0b111 */
93 },
94 /*
95 * Family 0xf revisions F and G
96 */
97 #define A_SKTS_1 1
98 {
99 X86_SOCKET_S1g1, /* 0b000 */
100 X86_SOCKET_F1207, /* 0b001 */
101 X86_SOCKET_UNKNOWN, /* 0b010 */
102 X86_SOCKET_AM2, /* 0b011 */
103 X86_SOCKET_UNKNOWN, /* 0b100 */
104 X86_SOCKET_UNKNOWN, /* 0b101 */
105 X86_SOCKET_UNKNOWN, /* 0b110 */
106 X86_SOCKET_UNKNOWN /* 0b111 */
107 },
108 /*
109 * Family 0x10
110 */
111 #define A_SKTS_2 2
112 {
113 X86_SOCKET_F1207, /* 0b000 */
114 X86_SOCKET_AM2R2, /* 0b001 */
115 X86_SOCKET_S1g3, /* 0b010 */
116 X86_SOCKET_G34, /* 0b011 */
117 X86_SOCKET_ASB2, /* 0b100 */
118 X86_SOCKET_C32, /* 0b101 */
119 X86_SOCKET_UNKNOWN, /* 0b110 */
120 X86_SOCKET_UNKNOWN /* 0b111 */
121 },
122
123 /*
124 * Family 0x11
125 */
126 #define A_SKTS_3 3
127 {
128 X86_SOCKET_UNKNOWN, /* 0b000 */
129 X86_SOCKET_UNKNOWN, /* 0b001 */
130 X86_SOCKET_S1g2, /* 0b010 */
131 X86_SOCKET_UNKNOWN, /* 0b011 */
132 X86_SOCKET_UNKNOWN, /* 0b100 */
133 X86_SOCKET_UNKNOWN, /* 0b101 */
134 X86_SOCKET_UNKNOWN, /* 0b110 */
135 X86_SOCKET_UNKNOWN /* 0b111 */
136 },
137
138 /*
139 * Family 0x12
140 */
141 #define A_SKTS_4 4
142 {
143 X86_SOCKET_UNKNOWN, /* 0b000 */
144 X86_SOCKET_FS1, /* 0b001 */
145 X86_SOCKET_FM1, /* 0b010 */
146 X86_SOCKET_UNKNOWN, /* 0b011 */
147 X86_SOCKET_UNKNOWN, /* 0b100 */
148 X86_SOCKET_UNKNOWN, /* 0b101 */
149 X86_SOCKET_UNKNOWN, /* 0b110 */
150 X86_SOCKET_UNKNOWN /* 0b111 */
151 },
152
153 /*
154 * Family 0x14
155 */
156 #define A_SKTS_5 5
157 {
158 X86_SOCKET_FT1, /* 0b000 */
159 X86_SOCKET_UNKNOWN, /* 0b001 */
160 X86_SOCKET_UNKNOWN, /* 0b010 */
161 X86_SOCKET_UNKNOWN, /* 0b011 */
162 X86_SOCKET_UNKNOWN, /* 0b100 */
163 X86_SOCKET_UNKNOWN, /* 0b101 */
164 X86_SOCKET_UNKNOWN, /* 0b110 */
165 X86_SOCKET_UNKNOWN /* 0b111 */
166 },
167
168 /*
169 * Family 0x15 models 00 - 0f
170 */
171 #define A_SKTS_6 6
172 {
173 X86_SOCKET_UNKNOWN, /* 0b000 */
174 X86_SOCKET_AM3R2, /* 0b001 */
175 X86_SOCKET_UNKNOWN, /* 0b010 */
176 X86_SOCKET_G34, /* 0b011 */
177 X86_SOCKET_UNKNOWN, /* 0b100 */
178 X86_SOCKET_C32, /* 0b101 */
179 X86_SOCKET_UNKNOWN, /* 0b110 */
180 X86_SOCKET_UNKNOWN /* 0b111 */
181 },
182
183 /*
184 * Family 0x15 models 10 - 1f
185 */
186 #define A_SKTS_7 7
187 {
188 X86_SOCKET_FP2, /* 0b000 */
189 X86_SOCKET_FS1R2, /* 0b001 */
190 X86_SOCKET_FM2, /* 0b010 */
191 X86_SOCKET_UNKNOWN, /* 0b011 */
192 X86_SOCKET_UNKNOWN, /* 0b100 */
193 X86_SOCKET_UNKNOWN, /* 0b101 */
194 X86_SOCKET_UNKNOWN, /* 0b110 */
195 X86_SOCKET_UNKNOWN /* 0b111 */
196 },
197
198 };
199
200 struct amd_sktmap_s {
201 uint32_t skt_code;
202 char sktstr[16];
203 };
204 static struct amd_sktmap_s amd_sktmap[23] = {
205 { X86_SOCKET_754, "754" },
206 { X86_SOCKET_939, "939" },
207 { X86_SOCKET_940, "940" },
208 { X86_SOCKET_S1g1, "S1g1" },
209 { X86_SOCKET_AM2, "AM2" },
210 { X86_SOCKET_F1207, "F(1207)" },
211 { X86_SOCKET_S1g2, "S1g2" },
212 { X86_SOCKET_S1g3, "S1g3" },
213 { X86_SOCKET_AM, "AM" },
214 { X86_SOCKET_AM2R2, "AM2r2" },
215 { X86_SOCKET_AM3, "AM3" },
216 { X86_SOCKET_G34, "G34" },
217 { X86_SOCKET_ASB2, "ASB2" },
218 { X86_SOCKET_C32, "C32" },
219 { X86_SOCKET_FT1, "FT1" },
220 { X86_SOCKET_FM1, "FM1" },
221 { X86_SOCKET_FS1, "FS1" },
222 { X86_SOCKET_AM3R2, "AM3r2" },
223 { X86_SOCKET_FP2, "FP2" },
224 { X86_SOCKET_FS1R2, "FS1r2" },
225 { X86_SOCKET_FM2, "FM2" },
226 { X86_SOCKET_UNKNOWN, "Unknown" }
227 };
228
229 /*
230 * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
231 * combination to chip "revision" and socket type.
232 *
233 * The first member of this array that matches a given family, extended model
234 * plus model range, and stepping range will be considered a match.
235 */
236 static const struct amd_rev_mapent {
237 uint_t rm_family;
238 uint_t rm_modello;
239 uint_t rm_modelhi;
240 uint_t rm_steplo;
241 uint_t rm_stephi;
242 uint32_t rm_chiprev;
243 const char *rm_chiprevstr;
244 int rm_sktidx;
245 } amd_revmap[] = {
280 { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
281
282 /*
283 * =============== AuthenticAMD Family 0x10 ===============
284 */
285
286 /*
287 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
288 * Give all of model 0 stepping range to rev A.
289 */
290 { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
291
292 /*
293 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
294 * Give all of model 2 stepping range to rev B.
295 */
296 { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
297
298 /*
299 * Rev C has models 4-6 (depending on L3 cache configuration)
300 * Give all of models 4-6 stepping range 0-2 to rev C2.
301 */
302 { 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_C2, "C2", A_SKTS_2 },
303
304 /*
305 * Rev C has models 4-6 (depending on L3 cache configuration)
306 * Give all of models 4-6 stepping range >= 3 to rev C3.
307 */
308 { 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_10_REV_C3, "C3", A_SKTS_2 },
309
310 /*
311 * Rev D has models 8 and 9
312 * Give all of model 8 and 9 stepping 0 to rev D0.
313 */
314 { 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_10_REV_D0, "D0", A_SKTS_2 },
315
316 /*
317 * Rev D has models 8 and 9
318 * Give all of model 8 and 9 stepping range >= 1 to rev D1.
319 */
320 { 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_10_REV_D1, "D1", A_SKTS_2 },
321
322 /*
323 * Rev E has models A and stepping 0
324 * Give all of model A stepping range to rev E.
325 */
326 { 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_E, "E", A_SKTS_2 },
327
328 /*
329 * =============== AuthenticAMD Family 0x11 ===============
330 */
331 { 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_11_REV_B, "B", A_SKTS_3 },
332
333 /*
334 * =============== AuthenticAMD Family 0x12 ===============
335 */
336 { 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_12_REV_B, "B", A_SKTS_4 },
337
338 /*
339 * =============== AuthenticAMD Family 0x14 ===============
340 */
341 { 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_B, "B", A_SKTS_5 },
342 { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_C, "C", A_SKTS_5 },
343
344 /*
345 * =============== AuthenticAMD Family 0x15 ===============
346 */
347 { 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_15OR_REV_B2, "B2",
348 A_SKTS_6 },
349 { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_15TN_REV_A1, "A1",
350 A_SKTS_7 },
351 };
352
353 static void
354 synth_amd_info(uint_t family, uint_t model, uint_t step,
355 uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
356 {
357 const struct amd_rev_mapent *rmp;
358 int found = 0;
359 int i;
360
361 if (family < 0xf)
362 return;
363
364 for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
365 i++, rmp++) {
366 if (family == rmp->rm_family &&
367 model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
368 step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
369 found = 1;
370 break;
395 *skt_p = X86_SOCKET_UNKNOWN;
396 } else if (family == 0xf) {
397 *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
398 } else {
399 /*
400 * Starting with family 10h, socket type is stored in
401 * CPUID Fn8000_0001_EBX
402 */
403 struct cpuid_regs cp;
404 int idx;
405
406 cp.cp_eax = 0x80000001;
407 (void) __cpuid_insn(&cp);
408
409 /* PkgType bits */
410 idx = BITX(cp.cp_ebx, 31, 28);
411
412 if (idx > 7) {
413 /* Reserved bits */
414 *skt_p = X86_SOCKET_UNKNOWN;
415 } else {
416 *skt_p = amd_skts[rmp->rm_sktidx][idx];
417 }
418 if (family == 0x10) {
419 /*
420 * Look at Ddr3Mode bit of DRAM Configuration
421 * High Register to decide whether this is
422 * actually AM3 or S1g4.
423 */
424 uint32_t val;
425
426 val = pci_getl_func(0, 24, 2, 0x94);
427 if (BITX(val, 8, 8)) {
428 if (*skt_p == X86_SOCKET_AM2R2)
429 *skt_p = X86_SOCKET_AM3;
430 else if (*skt_p == X86_SOCKET_S1g3)
431 *skt_p = X86_SOCKET_S1g4;
432 }
433 }
434 }
435 }
436 }
437
438 uint32_t
439 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
440 {
441 uint32_t skt = X86_SOCKET_UNKNOWN;
442
443 switch (vendor) {
444 case X86_VENDOR_AMD:
445 synth_amd_info(family, model, step, &skt, NULL, NULL);
446 break;
447
448 default:
449 break;
450
451 }
452
453 return (skt);
454 }
|