1 /* |
1 /* |
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
208 // cpuid function 4 (deterministic cache parameters) |
216 // cpuid function 4 (deterministic cache parameters) |
209 DcpCpuid4Eax dcp_cpuid4_eax; |
217 DcpCpuid4Eax dcp_cpuid4_eax; |
210 DcpCpuid4Ebx dcp_cpuid4_ebx; |
218 DcpCpuid4Ebx dcp_cpuid4_ebx; |
211 uint32_t dcp_cpuid4_ecx; // unused currently |
219 uint32_t dcp_cpuid4_ecx; // unused currently |
212 uint32_t dcp_cpuid4_edx; // unused currently |
220 uint32_t dcp_cpuid4_edx; // unused currently |
|
221 |
|
222 // cpuid function 0xB (processor topology) |
|
223 // ecx = 0 |
|
224 uint32_t tpl_cpuidB0_eax; |
|
225 TplCpuidBEbx tpl_cpuidB0_ebx; |
|
226 uint32_t tpl_cpuidB0_ecx; // unused currently |
|
227 uint32_t tpl_cpuidB0_edx; // unused currently |
|
228 |
|
229 // ecx = 1 |
|
230 uint32_t tpl_cpuidB1_eax; |
|
231 TplCpuidBEbx tpl_cpuidB1_ebx; |
|
232 uint32_t tpl_cpuidB1_ecx; // unused currently |
|
233 uint32_t tpl_cpuidB1_edx; // unused currently |
|
234 |
|
235 // ecx = 2 |
|
236 uint32_t tpl_cpuidB2_eax; |
|
237 TplCpuidBEbx tpl_cpuidB2_ebx; |
|
238 uint32_t tpl_cpuidB2_ecx; // unused currently |
|
239 uint32_t tpl_cpuidB2_edx; // unused currently |
213 |
240 |
214 // cpuid function 0x80000000 // example, unused |
241 // cpuid function 0x80000000 // example, unused |
215 uint32_t ext_max_function; |
242 uint32_t ext_max_function; |
216 uint32_t ext_vendor_name_0; |
243 uint32_t ext_vendor_name_0; |
217 uint32_t ext_vendor_name_1; |
244 uint32_t ext_vendor_name_1; |
314 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } |
341 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } |
315 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } |
342 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } |
316 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } |
343 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } |
317 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } |
344 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } |
318 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } |
345 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } |
|
346 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } |
|
347 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } |
|
348 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } |
319 |
349 |
320 // Initialization |
350 // Initialization |
321 static void initialize(); |
351 static void initialize(); |
322 |
352 |
323 // Asserts |
353 // Asserts |
347 static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' |
377 static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' |
348 |
378 |
349 static uint cores_per_cpu() { |
379 static uint cores_per_cpu() { |
350 uint result = 1; |
380 uint result = 1; |
351 if (is_intel()) { |
381 if (is_intel()) { |
352 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); |
382 if (_cpuid_info.std_max_function >= 0xB) { |
|
383 result = _cpuid_info.tpl_cpuidB1_ebx.bits.logical_cpus / |
|
384 _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; |
|
385 } else { |
|
386 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); |
|
387 } |
353 } else if (is_amd()) { |
388 } else if (is_amd()) { |
354 result = (_cpuid_info.ext_cpuid8_ecx.bits.cores_per_cpu + 1); |
389 result = (_cpuid_info.ext_cpuid8_ecx.bits.cores_per_cpu + 1); |
355 } |
390 } |
356 return result; |
391 return result; |
357 } |
392 } |
358 |
393 |
359 static uint threads_per_core() { |
394 static uint threads_per_core() { |
360 uint result = 1; |
395 uint result = 1; |
361 if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { |
396 if (is_intel() && _cpuid_info.std_max_function >= 0xB) { |
|
397 result = _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; |
|
398 } else if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { |
362 result = _cpuid_info.std_cpuid1_ebx.bits.threads_per_cpu / |
399 result = _cpuid_info.std_cpuid1_ebx.bits.threads_per_cpu / |
363 cores_per_cpu(); |
400 cores_per_cpu(); |
364 } |
401 } |
365 return result; |
402 return result; |
366 } |
403 } |