src/cpu/x86/vm/vm_version_ext_x86.cpp

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 10026
8c95980d0b66
parent 9858
b985cbb00e68
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset d3b4d62f391f

apetushkov@9858 1 /*
apetushkov@9858 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
apetushkov@9858 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
apetushkov@9858 4 *
apetushkov@9858 5 * This code is free software; you can redistribute it and/or modify it
apetushkov@9858 6 * under the terms of the GNU General Public License version 2 only, as
apetushkov@9858 7 * published by the Free Software Foundation.
apetushkov@9858 8 *
apetushkov@9858 9 * This code is distributed in the hope that it will be useful, but WITHOUT
apetushkov@9858 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
apetushkov@9858 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
apetushkov@9858 12 * version 2 for more details (a copy is included in the LICENSE file that
apetushkov@9858 13 * accompanied this code).
apetushkov@9858 14 *
apetushkov@9858 15 * You should have received a copy of the GNU General Public License version
apetushkov@9858 16 * 2 along with this work; if not, write to the Free Software Foundation,
apetushkov@9858 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
apetushkov@9858 18 *
apetushkov@9858 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
apetushkov@9858 20 * or visit www.oracle.com if you need additional information or have any
apetushkov@9858 21 * questions.
apetushkov@9858 22 *
apetushkov@9858 23 */
apetushkov@9858 24
apetushkov@9858 25 #include "precompiled.hpp"
apetushkov@9858 26 #include "jvm.h"
apetushkov@9858 27 #include "utilities/macros.hpp"
apetushkov@9858 28 #include "asm/macroAssembler.hpp"
apetushkov@9858 29 #include "asm/macroAssembler.inline.hpp"
apetushkov@9858 30 #include "memory/allocation.inline.hpp"
apetushkov@9858 31 #include "memory/resourceArea.hpp"
apetushkov@9858 32 #include "runtime/java.hpp"
apetushkov@9858 33 #include "runtime/stubCodeGenerator.hpp"
apetushkov@9858 34 #include "vm_version_ext_x86.hpp"
apetushkov@9858 35
apetushkov@9858 36 typedef enum {
apetushkov@9858 37 CPU_FAMILY_8086_8088 = 0,
apetushkov@9858 38 CPU_FAMILY_INTEL_286 = 2,
apetushkov@9858 39 CPU_FAMILY_INTEL_386 = 3,
apetushkov@9858 40 CPU_FAMILY_INTEL_486 = 4,
apetushkov@9858 41 CPU_FAMILY_PENTIUM = 5,
apetushkov@9858 42 CPU_FAMILY_PENTIUMPRO = 6, // Same family several models
apetushkov@9858 43 CPU_FAMILY_PENTIUM_4 = 0xF
apetushkov@9858 44 } FamilyFlag;
apetushkov@9858 45
apetushkov@9858 46 typedef enum {
apetushkov@9858 47 RDTSCP_FLAG = 0x08000000, // bit 27
apetushkov@9858 48 INTEL64_FLAG = 0x20000000 // bit 29
apetushkov@9858 49 } _featureExtendedEdxFlag;
apetushkov@9858 50
apetushkov@9858 51 #define CPUID_STANDARD_FN 0x0
apetushkov@9858 52 #define CPUID_STANDARD_FN_1 0x1
apetushkov@9858 53 #define CPUID_STANDARD_FN_4 0x4
apetushkov@9858 54 #define CPUID_STANDARD_FN_B 0xb
apetushkov@9858 55
apetushkov@9858 56 #define CPUID_EXTENDED_FN 0x80000000
apetushkov@9858 57 #define CPUID_EXTENDED_FN_1 0x80000001
apetushkov@9858 58 #define CPUID_EXTENDED_FN_2 0x80000002
apetushkov@9858 59 #define CPUID_EXTENDED_FN_3 0x80000003
apetushkov@9858 60 #define CPUID_EXTENDED_FN_4 0x80000004
apetushkov@9858 61 #define CPUID_EXTENDED_FN_7 0x80000007
apetushkov@9858 62 #define CPUID_EXTENDED_FN_8 0x80000008
apetushkov@9858 63
apetushkov@9858 64 typedef enum {
apetushkov@9858 65 FPU_FLAG = 0x00000001,
apetushkov@9858 66 VME_FLAG = 0x00000002,
apetushkov@9858 67 DE_FLAG = 0x00000004,
apetushkov@9858 68 PSE_FLAG = 0x00000008,
apetushkov@9858 69 TSC_FLAG = 0x00000010,
apetushkov@9858 70 MSR_FLAG = 0x00000020,
apetushkov@9858 71 PAE_FLAG = 0x00000040,
apetushkov@9858 72 MCE_FLAG = 0x00000080,
apetushkov@9858 73 CX8_FLAG = 0x00000100,
apetushkov@9858 74 APIC_FLAG = 0x00000200,
apetushkov@9858 75 SEP_FLAG = 0x00000800,
apetushkov@9858 76 MTRR_FLAG = 0x00001000,
apetushkov@9858 77 PGE_FLAG = 0x00002000,
apetushkov@9858 78 MCA_FLAG = 0x00004000,
apetushkov@9858 79 CMOV_FLAG = 0x00008000,
apetushkov@9858 80 PAT_FLAG = 0x00010000,
apetushkov@9858 81 PSE36_FLAG = 0x00020000,
apetushkov@9858 82 PSNUM_FLAG = 0x00040000,
apetushkov@9858 83 CLFLUSH_FLAG = 0x00080000,
apetushkov@9858 84 DTS_FLAG = 0x00200000,
apetushkov@9858 85 ACPI_FLAG = 0x00400000,
apetushkov@9858 86 MMX_FLAG = 0x00800000,
apetushkov@9858 87 FXSR_FLAG = 0x01000000,
apetushkov@9858 88 SSE_FLAG = 0x02000000,
apetushkov@9858 89 SSE2_FLAG = 0x04000000,
apetushkov@9858 90 SS_FLAG = 0x08000000,
apetushkov@9858 91 HTT_FLAG = 0x10000000,
apetushkov@9858 92 TM_FLAG = 0x20000000
apetushkov@9858 93 } FeatureEdxFlag;
apetushkov@9858 94
apetushkov@9858 95 static BufferBlob* cpuid_brand_string_stub_blob;
apetushkov@9858 96 static const int cpuid_brand_string_stub_size = 550;
apetushkov@9858 97
apetushkov@9858 98 extern "C" {
apetushkov@9858 99 typedef void (*getCPUIDBrandString_stub_t)(void*);
apetushkov@9858 100 }
apetushkov@9858 101
apetushkov@9858 102 static getCPUIDBrandString_stub_t getCPUIDBrandString_stub = NULL;
apetushkov@9858 103
apetushkov@9858 104 class VM_Version_Ext_StubGenerator: public StubCodeGenerator {
apetushkov@9858 105 public:
apetushkov@9858 106
apetushkov@9858 107 VM_Version_Ext_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
apetushkov@9858 108
apetushkov@9858 109 address generate_getCPUIDBrandString(void) {
apetushkov@9858 110 // Flags to test CPU type.
apetushkov@9858 111 const uint32_t HS_EFL_AC = 0x40000;
apetushkov@9858 112 const uint32_t HS_EFL_ID = 0x200000;
apetushkov@9858 113 // Values for when we don't have a CPUID instruction.
apetushkov@9858 114 const int CPU_FAMILY_SHIFT = 8;
apetushkov@9858 115 const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT);
apetushkov@9858 116 const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
apetushkov@9858 117
apetushkov@9858 118 Label detect_486, cpu486, detect_586, done, ext_cpuid;
apetushkov@9858 119
apetushkov@9858 120 StubCodeMark mark(this, "VM_Version_Ext", "getCPUIDNameInfo_stub");
apetushkov@9858 121 # define __ _masm->
apetushkov@9858 122
apetushkov@9858 123 address start = __ pc();
apetushkov@9858 124
apetushkov@9858 125 //
apetushkov@9858 126 // void getCPUIDBrandString(VM_Version::CpuidInfo* cpuid_info);
apetushkov@9858 127 //
apetushkov@9858 128 // LP64: rcx and rdx are first and second argument registers on windows
apetushkov@9858 129
apetushkov@9858 130 __ push(rbp);
apetushkov@9858 131 #ifdef _LP64
apetushkov@9858 132 __ mov(rbp, c_rarg0); // cpuid_info address
apetushkov@9858 133 #else
apetushkov@9858 134 __ movptr(rbp, Address(rsp, 8)); // cpuid_info address
apetushkov@9858 135 #endif
apetushkov@9858 136 __ push(rbx);
apetushkov@9858 137 __ push(rsi);
apetushkov@9858 138 __ pushf(); // preserve rbx, and flags
apetushkov@9858 139 __ pop(rax);
apetushkov@9858 140 __ push(rax);
apetushkov@9858 141 __ mov(rcx, rax);
apetushkov@9858 142 //
apetushkov@9858 143 // if we are unable to change the AC flag, we have a 386
apetushkov@9858 144 //
apetushkov@9858 145 __ xorl(rax, HS_EFL_AC);
apetushkov@9858 146 __ push(rax);
apetushkov@9858 147 __ popf();
apetushkov@9858 148 __ pushf();
apetushkov@9858 149 __ pop(rax);
apetushkov@9858 150 __ cmpptr(rax, rcx);
apetushkov@9858 151 __ jccb(Assembler::notEqual, detect_486);
apetushkov@9858 152
apetushkov@9858 153 __ movl(rax, CPU_FAMILY_386);
apetushkov@9858 154 __ jmp(done);
apetushkov@9858 155
apetushkov@9858 156 //
apetushkov@9858 157 // If we are unable to change the ID flag, we have a 486 which does
apetushkov@9858 158 // not support the "cpuid" instruction.
apetushkov@9858 159 //
apetushkov@9858 160 __ bind(detect_486);
apetushkov@9858 161 __ mov(rax, rcx);
apetushkov@9858 162 __ xorl(rax, HS_EFL_ID);
apetushkov@9858 163 __ push(rax);
apetushkov@9858 164 __ popf();
apetushkov@9858 165 __ pushf();
apetushkov@9858 166 __ pop(rax);
apetushkov@9858 167 __ cmpptr(rcx, rax);
apetushkov@9858 168 __ jccb(Assembler::notEqual, detect_586);
apetushkov@9858 169
apetushkov@9858 170 __ bind(cpu486);
apetushkov@9858 171 __ movl(rax, CPU_FAMILY_486);
apetushkov@9858 172 __ jmp(done);
apetushkov@9858 173
apetushkov@9858 174 //
apetushkov@9858 175 // At this point, we have a chip which supports the "cpuid" instruction
apetushkov@9858 176 //
apetushkov@9858 177 __ bind(detect_586);
apetushkov@9858 178 __ xorl(rax, rax);
apetushkov@9858 179 __ cpuid();
apetushkov@9858 180 __ orl(rax, rax);
apetushkov@9858 181 __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input
apetushkov@9858 182 // value of at least 1, we give up and
apetushkov@9858 183 // assume a 486
apetushkov@9858 184
apetushkov@9858 185 //
apetushkov@9858 186 // Extended cpuid(0x80000000) for processor brand string detection
apetushkov@9858 187 //
apetushkov@9858 188 __ bind(ext_cpuid);
apetushkov@9858 189 __ movl(rax, CPUID_EXTENDED_FN);
apetushkov@9858 190 __ cpuid();
apetushkov@9858 191 __ cmpl(rax, CPUID_EXTENDED_FN_4);
apetushkov@9858 192 __ jcc(Assembler::below, done);
apetushkov@9858 193
apetushkov@9858 194 //
apetushkov@9858 195 // Extended cpuid(0x80000002) // first 16 bytes in brand string
apetushkov@9858 196 //
apetushkov@9858 197 __ movl(rax, CPUID_EXTENDED_FN_2);
apetushkov@9858 198 __ cpuid();
apetushkov@9858 199 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_0_offset())));
apetushkov@9858 200 __ movl(Address(rsi, 0), rax);
apetushkov@9858 201 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_1_offset())));
apetushkov@9858 202 __ movl(Address(rsi, 0), rbx);
apetushkov@9858 203 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_2_offset())));
apetushkov@9858 204 __ movl(Address(rsi, 0), rcx);
apetushkov@9858 205 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_3_offset())));
apetushkov@9858 206 __ movl(Address(rsi,0), rdx);
apetushkov@9858 207
apetushkov@9858 208 //
apetushkov@9858 209 // Extended cpuid(0x80000003) // next 16 bytes in brand string
apetushkov@9858 210 //
apetushkov@9858 211 __ movl(rax, CPUID_EXTENDED_FN_3);
apetushkov@9858 212 __ cpuid();
apetushkov@9858 213 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_4_offset())));
apetushkov@9858 214 __ movl(Address(rsi, 0), rax);
apetushkov@9858 215 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_5_offset())));
apetushkov@9858 216 __ movl(Address(rsi, 0), rbx);
apetushkov@9858 217 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_6_offset())));
apetushkov@9858 218 __ movl(Address(rsi, 0), rcx);
apetushkov@9858 219 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_7_offset())));
apetushkov@9858 220 __ movl(Address(rsi,0), rdx);
apetushkov@9858 221
apetushkov@9858 222 //
apetushkov@9858 223 // Extended cpuid(0x80000004) // last 16 bytes in brand string
apetushkov@9858 224 //
apetushkov@9858 225 __ movl(rax, CPUID_EXTENDED_FN_4);
apetushkov@9858 226 __ cpuid();
apetushkov@9858 227 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_8_offset())));
apetushkov@9858 228 __ movl(Address(rsi, 0), rax);
apetushkov@9858 229 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_9_offset())));
apetushkov@9858 230 __ movl(Address(rsi, 0), rbx);
apetushkov@9858 231 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_10_offset())));
apetushkov@9858 232 __ movl(Address(rsi, 0), rcx);
apetushkov@9858 233 __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_11_offset())));
apetushkov@9858 234 __ movl(Address(rsi,0), rdx);
apetushkov@9858 235
apetushkov@9858 236 //
apetushkov@9858 237 // return
apetushkov@9858 238 //
apetushkov@9858 239 __ bind(done);
apetushkov@9858 240 __ popf();
apetushkov@9858 241 __ pop(rsi);
apetushkov@9858 242 __ pop(rbx);
apetushkov@9858 243 __ pop(rbp);
apetushkov@9858 244 __ ret(0);
apetushkov@9858 245
apetushkov@9858 246 # undef __
apetushkov@9858 247
apetushkov@9858 248 return start;
apetushkov@9858 249 };
apetushkov@9858 250 };
apetushkov@9858 251
apetushkov@9858 252
apetushkov@9858 253 // VM_Version_Ext statics
apetushkov@9858 254 const size_t VM_Version_Ext::VENDOR_LENGTH = 13;
apetushkov@9858 255 const size_t VM_Version_Ext::CPU_EBS_MAX_LENGTH = (3 * 4 * 4 + 1);
apetushkov@9858 256 const size_t VM_Version_Ext::CPU_TYPE_DESC_BUF_SIZE = 256;
apetushkov@9858 257 const size_t VM_Version_Ext::CPU_DETAILED_DESC_BUF_SIZE = 4096;
apetushkov@9858 258 char* VM_Version_Ext::_cpu_brand_string = NULL;
apetushkov@9858 259 jlong VM_Version_Ext::_max_qualified_cpu_frequency = 0;
apetushkov@9858 260
apetushkov@9858 261 int VM_Version_Ext::_no_of_threads = 0;
apetushkov@9858 262 int VM_Version_Ext::_no_of_cores = 0;
apetushkov@9858 263 int VM_Version_Ext::_no_of_packages = 0;
apetushkov@9858 264
apetushkov@9858 265 void VM_Version_Ext::initialize(void) {
apetushkov@9858 266 ResourceMark rm;
apetushkov@9858 267
apetushkov@9858 268 cpuid_brand_string_stub_blob = BufferBlob::create("getCPUIDBrandString_stub", cpuid_brand_string_stub_size);
apetushkov@9858 269 if (cpuid_brand_string_stub_blob == NULL) {
apetushkov@9858 270 vm_exit_during_initialization("Unable to allocate getCPUIDBrandString_stub");
apetushkov@9858 271 }
apetushkov@9858 272 CodeBuffer c(cpuid_brand_string_stub_blob);
apetushkov@9858 273 VM_Version_Ext_StubGenerator g(&c);
apetushkov@9858 274 getCPUIDBrandString_stub = CAST_TO_FN_PTR(getCPUIDBrandString_stub_t,
apetushkov@9858 275 g.generate_getCPUIDBrandString());
apetushkov@9858 276 }
apetushkov@9858 277
apetushkov@9858 278 const char* VM_Version_Ext::cpu_model_description(void) {
apetushkov@9858 279 uint32_t cpu_family = extended_cpu_family();
apetushkov@9858 280 uint32_t cpu_model = extended_cpu_model();
apetushkov@9858 281 const char* model = NULL;
apetushkov@9858 282
apetushkov@9858 283 if (cpu_family == CPU_FAMILY_PENTIUMPRO) {
apetushkov@9858 284 for (uint32_t i = 0; i <= cpu_model; i++) {
apetushkov@9858 285 model = _model_id_pentium_pro[i];
apetushkov@9858 286 if (model == NULL) {
apetushkov@9858 287 break;
apetushkov@9858 288 }
apetushkov@9858 289 }
apetushkov@9858 290 }
apetushkov@9858 291 return model;
apetushkov@9858 292 }
apetushkov@9858 293
apetushkov@9858 294 const char* VM_Version_Ext::cpu_brand_string(void) {
apetushkov@9858 295 if (_cpu_brand_string == NULL) {
apetushkov@9858 296 _cpu_brand_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_EBS_MAX_LENGTH, mtInternal);
apetushkov@9858 297 if (NULL == _cpu_brand_string) {
apetushkov@9858 298 return NULL;
apetushkov@9858 299 }
apetushkov@9858 300 int ret_val = cpu_extended_brand_string(_cpu_brand_string, CPU_EBS_MAX_LENGTH);
apetushkov@9858 301 if (ret_val != OS_OK) {
apetushkov@9858 302 FREE_C_HEAP_ARRAY(char, _cpu_brand_string, mtInternal);
apetushkov@9858 303 _cpu_brand_string = NULL;
apetushkov@9858 304 }
apetushkov@9858 305 }
apetushkov@9858 306 return _cpu_brand_string;
apetushkov@9858 307 }
apetushkov@9858 308
apetushkov@9858 309 const char* VM_Version_Ext::cpu_brand(void) {
apetushkov@9858 310 const char* brand = NULL;
apetushkov@9858 311
apetushkov@9858 312 if ((_cpuid_info.std_cpuid1_ebx.value & 0xFF) > 0) {
apetushkov@9858 313 int brand_num = _cpuid_info.std_cpuid1_ebx.value & 0xFF;
apetushkov@9858 314 brand = _brand_id[0];
apetushkov@9858 315 for (int i = 0; brand != NULL && i <= brand_num; i += 1) {
apetushkov@9858 316 brand = _brand_id[i];
apetushkov@9858 317 }
apetushkov@9858 318 }
apetushkov@9858 319 return brand;
apetushkov@9858 320 }
apetushkov@9858 321
apetushkov@9858 322 bool VM_Version_Ext::cpu_is_em64t(void) {
apetushkov@9858 323 return ((_cpuid_info.ext_cpuid1_edx.value & INTEL64_FLAG) == INTEL64_FLAG);
apetushkov@9858 324 }
apetushkov@9858 325
apetushkov@9858 326 bool VM_Version_Ext::is_netburst(void) {
apetushkov@9858 327 return (is_intel() && (extended_cpu_family() == CPU_FAMILY_PENTIUM_4));
apetushkov@9858 328 }
apetushkov@9858 329
apetushkov@9858 330 bool VM_Version_Ext::supports_tscinv_ext(void) {
apetushkov@9858 331 if (!supports_tscinv_bit()) {
apetushkov@9858 332 return false;
apetushkov@9858 333 }
apetushkov@9858 334
apetushkov@9858 335 if (is_intel()) {
apetushkov@9858 336 return true;
apetushkov@9858 337 }
apetushkov@9858 338
apetushkov@9858 339 if (is_amd()) {
apetushkov@9858 340 return !is_amd_Barcelona();
apetushkov@9858 341 }
apetushkov@9858 342
apetushkov@9858 343 return false;
apetushkov@9858 344 }
apetushkov@9858 345
apetushkov@9858 346 void VM_Version_Ext::resolve_cpu_information_details(void) {
apetushkov@9858 347
apetushkov@9858 348 // in future we want to base this information on proper cpu
apetushkov@9858 349 // and cache topology enumeration such as:
apetushkov@9858 350 // Intel 64 Architecture Processor Topology Enumeration
apetushkov@9858 351 // which supports system cpu and cache topology enumeration
apetushkov@9858 352 // either using 2xAPICIDs or initial APICIDs
apetushkov@9858 353
apetushkov@9858 354 // currently only rough cpu information estimates
apetushkov@9858 355 // which will not necessarily reflect the exact configuration of the system
apetushkov@9858 356
apetushkov@9858 357 // this is the number of logical hardware threads
apetushkov@9858 358 // visible to the operating system
apetushkov@9858 359 _no_of_threads = os::processor_count();
apetushkov@9858 360
apetushkov@9858 361 // find out number of threads per cpu package
apetushkov@9858 362 int threads_per_package = threads_per_core() * cores_per_cpu();
apetushkov@9858 363
apetushkov@9858 364 // use amount of threads visible to the process in order to guess number of sockets
apetushkov@9858 365 _no_of_packages = _no_of_threads / threads_per_package;
apetushkov@9858 366
apetushkov@9858 367 // process might only see a subset of the total number of threads
apetushkov@9858 368 // from a single processor package. Virtualization/resource management for example.
apetushkov@9858 369 // If so then just write a hard 1 as num of pkgs.
apetushkov@9858 370 if (0 == _no_of_packages) {
apetushkov@9858 371 _no_of_packages = 1;
apetushkov@9858 372 }
apetushkov@9858 373
apetushkov@9858 374 // estimate the number of cores
apetushkov@9858 375 _no_of_cores = cores_per_cpu() * _no_of_packages;
apetushkov@9858 376 }
apetushkov@9858 377
apetushkov@9858 378 int VM_Version_Ext::number_of_threads(void) {
apetushkov@9858 379 if (_no_of_threads == 0) {
apetushkov@9858 380 resolve_cpu_information_details();
apetushkov@9858 381 }
apetushkov@9858 382 return _no_of_threads;
apetushkov@9858 383 }
apetushkov@9858 384
apetushkov@9858 385 int VM_Version_Ext::number_of_cores(void) {
apetushkov@9858 386 if (_no_of_cores == 0) {
apetushkov@9858 387 resolve_cpu_information_details();
apetushkov@9858 388 }
apetushkov@9858 389 return _no_of_cores;
apetushkov@9858 390 }
apetushkov@9858 391
apetushkov@9858 392 int VM_Version_Ext::number_of_sockets(void) {
apetushkov@9858 393 if (_no_of_packages == 0) {
apetushkov@9858 394 resolve_cpu_information_details();
apetushkov@9858 395 }
apetushkov@9858 396 return _no_of_packages;
apetushkov@9858 397 }
apetushkov@9858 398
apetushkov@9858 399 const char* VM_Version_Ext::cpu_family_description(void) {
apetushkov@9858 400 int cpu_family_id = extended_cpu_family();
apetushkov@9858 401 if (is_amd()) {
apetushkov@9858 402 return _family_id_amd[cpu_family_id];
apetushkov@9858 403 }
apetushkov@9858 404 if (is_intel()) {
apetushkov@9858 405 if (cpu_family_id == CPU_FAMILY_PENTIUMPRO) {
apetushkov@9858 406 return cpu_model_description();
apetushkov@9858 407 }
apetushkov@9858 408 return _family_id_intel[cpu_family_id];
apetushkov@9858 409 }
apetushkov@9858 410 return "Unknown x86";
apetushkov@9858 411 }
apetushkov@9858 412
apetushkov@9858 413 int VM_Version_Ext::cpu_type_description(char* const buf, size_t buf_len) {
apetushkov@9858 414 assert(buf != NULL, "buffer is NULL!");
apetushkov@9858 415 assert(buf_len >= CPU_TYPE_DESC_BUF_SIZE, "buffer len should at least be == CPU_TYPE_DESC_BUF_SIZE!");
apetushkov@9858 416
apetushkov@9858 417 const char* cpu_type = NULL;
apetushkov@9858 418 const char* x64 = NULL;
apetushkov@9858 419
apetushkov@9858 420 if (is_intel()) {
apetushkov@9858 421 cpu_type = "Intel";
apetushkov@9858 422 x64 = cpu_is_em64t() ? " Intel64" : "";
apetushkov@9858 423 } else if (is_amd()) {
apetushkov@9858 424 cpu_type = "AMD";
apetushkov@9858 425 x64 = cpu_is_em64t() ? " AMD64" : "";
apetushkov@9858 426 } else {
apetushkov@9858 427 cpu_type = "Unknown x86";
apetushkov@9858 428 x64 = cpu_is_em64t() ? " x86_64" : "";
apetushkov@9858 429 }
apetushkov@9858 430
apetushkov@9858 431 jio_snprintf(buf, buf_len, "%s %s%s SSE SSE2%s%s%s%s%s%s%s%s",
apetushkov@9858 432 cpu_type,
apetushkov@9858 433 cpu_family_description(),
apetushkov@9858 434 supports_ht() ? " (HT)" : "",
apetushkov@9858 435 supports_sse3() ? " SSE3" : "",
apetushkov@9858 436 supports_ssse3() ? " SSSE3" : "",
apetushkov@9858 437 supports_sse4_1() ? " SSE4.1" : "",
apetushkov@9858 438 supports_sse4_2() ? " SSE4.2" : "",
apetushkov@9858 439 supports_sse4a() ? " SSE4A" : "",
apetushkov@9858 440 is_netburst() ? " Netburst" : "",
apetushkov@9858 441 is_intel_family_core() ? " Core" : "",
apetushkov@9858 442 x64);
apetushkov@9858 443
apetushkov@9858 444 return OS_OK;
apetushkov@9858 445 }
apetushkov@9858 446
apetushkov@9858 447 int VM_Version_Ext::cpu_extended_brand_string(char* const buf, size_t buf_len) {
apetushkov@9858 448 assert(buf != NULL, "buffer is NULL!");
apetushkov@9858 449 assert(buf_len >= CPU_EBS_MAX_LENGTH, "buffer len should at least be == CPU_EBS_MAX_LENGTH!");
apetushkov@9858 450 assert(getCPUIDBrandString_stub != NULL, "not initialized");
apetushkov@9858 451
apetushkov@9858 452 // invoke newly generated asm code to fetch CPU Brand String
apetushkov@9858 453 getCPUIDBrandString_stub(&_cpuid_info);
apetushkov@9858 454
apetushkov@9858 455 // fetch results into buffer
apetushkov@9858 456 *((uint32_t*) &buf[0]) = _cpuid_info.proc_name_0;
apetushkov@9858 457 *((uint32_t*) &buf[4]) = _cpuid_info.proc_name_1;
apetushkov@9858 458 *((uint32_t*) &buf[8]) = _cpuid_info.proc_name_2;
apetushkov@9858 459 *((uint32_t*) &buf[12]) = _cpuid_info.proc_name_3;
apetushkov@9858 460 *((uint32_t*) &buf[16]) = _cpuid_info.proc_name_4;
apetushkov@9858 461 *((uint32_t*) &buf[20]) = _cpuid_info.proc_name_5;
apetushkov@9858 462 *((uint32_t*) &buf[24]) = _cpuid_info.proc_name_6;
apetushkov@9858 463 *((uint32_t*) &buf[28]) = _cpuid_info.proc_name_7;
apetushkov@9858 464 *((uint32_t*) &buf[32]) = _cpuid_info.proc_name_8;
apetushkov@9858 465 *((uint32_t*) &buf[36]) = _cpuid_info.proc_name_9;
apetushkov@9858 466 *((uint32_t*) &buf[40]) = _cpuid_info.proc_name_10;
apetushkov@9858 467 *((uint32_t*) &buf[44]) = _cpuid_info.proc_name_11;
apetushkov@9858 468
apetushkov@9858 469 return OS_OK;
apetushkov@9858 470 }
apetushkov@9858 471
apetushkov@9858 472 size_t VM_Version_Ext::cpu_write_support_string(char* const buf, size_t buf_len) {
apetushkov@9858 473 guarantee(buf != NULL, "buffer is NULL!");
apetushkov@9858 474 guarantee(buf_len > 0, "buffer len not enough!");
apetushkov@9858 475
apetushkov@9858 476 unsigned int flag = 0;
apetushkov@9858 477 unsigned int fi = 0;
apetushkov@9858 478 size_t written = 0;
apetushkov@9858 479 const char* prefix = "";
apetushkov@9858 480
apetushkov@9858 481 #define WRITE_TO_BUF(string) \
apetushkov@9858 482 { \
apetushkov@9858 483 int res = jio_snprintf(&buf[written], buf_len - written, "%s%s", prefix, string); \
apetushkov@9858 484 if (res < 0) { \
apetushkov@9858 485 return buf_len - 1; \
apetushkov@9858 486 } \
apetushkov@9858 487 written += res; \
apetushkov@9858 488 if (prefix[0] == '\0') { \
apetushkov@9858 489 prefix = ", "; \
apetushkov@9858 490 } \
apetushkov@9858 491 }
apetushkov@9858 492
apetushkov@9858 493 for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) {
apetushkov@9858 494 if (flag == HTT_FLAG && (((_cpuid_info.std_cpuid1_ebx.value >> 16) & 0xff) <= 1)) {
apetushkov@9858 495 continue; /* no hyperthreading */
apetushkov@9858 496 } else if (flag == SEP_FLAG && (cpu_family() == CPU_FAMILY_PENTIUMPRO && ((_cpuid_info.std_cpuid1_eax.value & 0xff) < 0x33))) {
apetushkov@9858 497 continue; /* no fast system call */
apetushkov@9858 498 }
apetushkov@9858 499 if ((_cpuid_info.std_cpuid1_edx.value & flag) && strlen(_feature_edx_id[fi]) > 0) {
apetushkov@9858 500 WRITE_TO_BUF(_feature_edx_id[fi]);
apetushkov@9858 501 }
apetushkov@9858 502 }
apetushkov@9858 503
apetushkov@9858 504 for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) {
apetushkov@9858 505 if ((_cpuid_info.std_cpuid1_ecx.value & flag) && strlen(_feature_ecx_id[fi]) > 0) {
apetushkov@9858 506 WRITE_TO_BUF(_feature_ecx_id[fi]);
apetushkov@9858 507 }
apetushkov@9858 508 }
apetushkov@9858 509
apetushkov@9858 510 for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) {
apetushkov@9858 511 if ((_cpuid_info.ext_cpuid1_ecx.value & flag) && strlen(_feature_extended_ecx_id[fi]) > 0) {
apetushkov@9858 512 WRITE_TO_BUF(_feature_extended_ecx_id[fi]);
apetushkov@9858 513 }
apetushkov@9858 514 }
apetushkov@9858 515
apetushkov@9858 516 for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) {
apetushkov@9858 517 if ((_cpuid_info.ext_cpuid1_edx.value & flag) && strlen(_feature_extended_edx_id[fi]) > 0) {
apetushkov@9858 518 WRITE_TO_BUF(_feature_extended_edx_id[fi]);
apetushkov@9858 519 }
apetushkov@9858 520 }
apetushkov@9858 521
apetushkov@9858 522 if (supports_tscinv_bit()) {
apetushkov@9858 523 WRITE_TO_BUF("Invariant TSC");
apetushkov@9858 524 }
apetushkov@9858 525
apetushkov@9858 526 return written;
apetushkov@9858 527 }
apetushkov@9858 528
apetushkov@9858 529 /**
apetushkov@9858 530 * Write a detailed description of the cpu to a given buffer, including
apetushkov@9858 531 * feature set.
apetushkov@9858 532 */
apetushkov@9858 533 int VM_Version_Ext::cpu_detailed_description(char* const buf, size_t buf_len) {
apetushkov@9858 534 assert(buf != NULL, "buffer is NULL!");
apetushkov@9858 535 assert(buf_len >= CPU_DETAILED_DESC_BUF_SIZE, "buffer len should at least be == CPU_DETAILED_DESC_BUF_SIZE!");
apetushkov@9858 536
apetushkov@9858 537 static const char* unknown = "<unknown>";
apetushkov@9858 538 char vendor_id[VENDOR_LENGTH];
apetushkov@9858 539 const char* family = NULL;
apetushkov@9858 540 const char* model = NULL;
apetushkov@9858 541 const char* brand = NULL;
apetushkov@9858 542 int outputLen = 0;
apetushkov@9858 543
apetushkov@9858 544 family = cpu_family_description();
apetushkov@9858 545 if (family == NULL) {
apetushkov@9858 546 family = unknown;
apetushkov@9858 547 }
apetushkov@9858 548
apetushkov@9858 549 model = cpu_model_description();
apetushkov@9858 550 if (model == NULL) {
apetushkov@9858 551 model = unknown;
apetushkov@9858 552 }
apetushkov@9858 553
apetushkov@9858 554 brand = cpu_brand_string();
apetushkov@9858 555
apetushkov@9858 556 if (brand == NULL) {
apetushkov@9858 557 brand = cpu_brand();
apetushkov@9858 558 if (brand == NULL) {
apetushkov@9858 559 brand = unknown;
apetushkov@9858 560 }
apetushkov@9858 561 }
apetushkov@9858 562
apetushkov@9858 563 *((uint32_t*) &vendor_id[0]) = _cpuid_info.std_vendor_name_0;
apetushkov@9858 564 *((uint32_t*) &vendor_id[4]) = _cpuid_info.std_vendor_name_2;
apetushkov@9858 565 *((uint32_t*) &vendor_id[8]) = _cpuid_info.std_vendor_name_1;
apetushkov@9858 566 vendor_id[VENDOR_LENGTH-1] = '\0';
apetushkov@9858 567
apetushkov@9858 568 outputLen = jio_snprintf(buf, buf_len, "Brand: %s, Vendor: %s\n"
apetushkov@9858 569 "Family: %s (0x%x), Model: %s (0x%x), Stepping: 0x%x\n"
apetushkov@9858 570 "Ext. family: 0x%x, Ext. model: 0x%x, Type: 0x%x, Signature: 0x%8.8x\n"
apetushkov@9858 571 "Features: ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n"
apetushkov@9858 572 "Ext. features: eax: 0x%8.8x, ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n"
apetushkov@9858 573 "Supports: ",
apetushkov@9858 574 brand,
apetushkov@9858 575 vendor_id,
apetushkov@9858 576 family,
apetushkov@9858 577 extended_cpu_family(),
apetushkov@9858 578 model,
apetushkov@9858 579 extended_cpu_model(),
apetushkov@9858 580 cpu_stepping(),
apetushkov@9858 581 _cpuid_info.std_cpuid1_eax.bits.ext_family,
apetushkov@9858 582 _cpuid_info.std_cpuid1_eax.bits.ext_model,
apetushkov@9858 583 _cpuid_info.std_cpuid1_eax.bits.proc_type,
apetushkov@9858 584 _cpuid_info.std_cpuid1_eax.value,
apetushkov@9858 585 _cpuid_info.std_cpuid1_ebx.value,
apetushkov@9858 586 _cpuid_info.std_cpuid1_ecx.value,
apetushkov@9858 587 _cpuid_info.std_cpuid1_edx.value,
apetushkov@9858 588 _cpuid_info.ext_cpuid1_eax,
apetushkov@9858 589 _cpuid_info.ext_cpuid1_ebx,
apetushkov@9858 590 _cpuid_info.ext_cpuid1_ecx,
apetushkov@9858 591 _cpuid_info.ext_cpuid1_edx);
apetushkov@9858 592
apetushkov@9858 593 if (outputLen < 0 || (size_t) outputLen >= buf_len - 1) {
apetushkov@9858 594 if (buf_len > 0) { buf[buf_len-1] = '\0'; }
apetushkov@9858 595 return OS_ERR;
apetushkov@9858 596 }
apetushkov@9858 597
apetushkov@9858 598 cpu_write_support_string(&buf[outputLen], buf_len - outputLen);
apetushkov@9858 599
apetushkov@9858 600 return OS_OK;
apetushkov@9858 601 }
apetushkov@9858 602
apetushkov@9858 603 const char* VM_Version_Ext::cpu_name(void) {
apetushkov@9858 604 char cpu_type_desc[CPU_TYPE_DESC_BUF_SIZE];
apetushkov@9858 605 size_t cpu_desc_len = sizeof(cpu_type_desc);
apetushkov@9858 606
apetushkov@9858 607 cpu_type_description(cpu_type_desc, cpu_desc_len);
apetushkov@9858 608 char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, cpu_desc_len, mtTracing);
apetushkov@9858 609 if (NULL == tmp) {
apetushkov@9858 610 return NULL;
apetushkov@9858 611 }
apetushkov@9858 612 strncpy(tmp, cpu_type_desc, cpu_desc_len);
apetushkov@9858 613 return tmp;
apetushkov@9858 614 }
apetushkov@9858 615
apetushkov@9858 616 const char* VM_Version_Ext::cpu_description(void) {
apetushkov@9858 617 char cpu_detailed_desc_buffer[CPU_DETAILED_DESC_BUF_SIZE];
apetushkov@9858 618 size_t cpu_detailed_desc_len = sizeof(cpu_detailed_desc_buffer);
apetushkov@9858 619
apetushkov@9858 620 cpu_detailed_description(cpu_detailed_desc_buffer, cpu_detailed_desc_len);
apetushkov@9858 621
apetushkov@9858 622 char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, cpu_detailed_desc_len, mtTracing);
apetushkov@9858 623
apetushkov@9858 624 if (NULL == tmp) {
apetushkov@9858 625 return NULL;
apetushkov@9858 626 }
apetushkov@9858 627
apetushkov@9858 628 strncpy(tmp, cpu_detailed_desc_buffer, cpu_detailed_desc_len);
apetushkov@9858 629 return tmp;
apetushkov@9858 630 }
apetushkov@9858 631
apetushkov@9858 632 /**
apetushkov@9858 633 * See Intel Application note 485 (chapter 10) for details
apetushkov@9858 634 * on frequency extraction from cpu brand string.
apetushkov@9858 635 * http://www.intel.com/content/dam/www/public/us/en/documents/application-notes/processor-identification-cpuid-instruction-note.pdf
apetushkov@9858 636 *
apetushkov@9858 637 */
apetushkov@9858 638 jlong VM_Version_Ext::max_qualified_cpu_freq_from_brand_string(void) {
apetushkov@9858 639 // get brand string
apetushkov@9858 640 const char* const brand_string = cpu_brand_string();
apetushkov@9858 641 if (brand_string == NULL) {
apetushkov@9858 642 return 0;
apetushkov@9858 643 }
apetushkov@9858 644
apetushkov@9858 645 const u8 MEGA = 1000000;
apetushkov@9858 646 u8 multiplier = 0;
apetushkov@9858 647 jlong frequency = 0;
apetushkov@9858 648
apetushkov@9858 649 // the frequency information in the cpu brand string
apetushkov@9858 650 // is given in either of two formats "x.xxyHz" or "xxxxyHz",
apetushkov@9858 651 // where y=M,G,T and x is digits
apetushkov@9858 652 const char* Hz_location = strchr(brand_string, 'H');
apetushkov@9858 653
apetushkov@9858 654 if (Hz_location != NULL) {
apetushkov@9858 655 if (*(Hz_location + 1) == 'z') {
apetushkov@9858 656 // switch on y in "yHz"
apetushkov@9858 657 switch(*(Hz_location - 1)) {
apetushkov@9858 658 case 'M' :
apetushkov@9858 659 // Set multiplier to frequency is in Hz
apetushkov@9858 660 multiplier = MEGA;
apetushkov@9858 661 break;
apetushkov@9858 662 case 'G' :
apetushkov@9858 663 multiplier = MEGA * 1000;
apetushkov@9858 664 break;
apetushkov@9858 665 case 'T' :
apetushkov@9858 666 multiplier = MEGA * 1000 * 1000;
apetushkov@9858 667 break;
apetushkov@9858 668 }
apetushkov@9858 669 }
apetushkov@9858 670 }
apetushkov@9858 671
apetushkov@9858 672 if (multiplier > 0) {
apetushkov@9858 673 // compute frequency (in Hz) from brand string
apetushkov@9858 674 if (*(Hz_location - 4) == '.') { // if format is "x.xx"
apetushkov@9858 675 frequency = (jlong)(*(Hz_location - 5) - '0') * (multiplier);
apetushkov@9858 676 frequency += (jlong)(*(Hz_location - 3) - '0') * (multiplier / 10);
apetushkov@9858 677 frequency += (jlong)(*(Hz_location - 2) - '0') * (multiplier / 100);
apetushkov@9858 678 } else { // format is "xxxx"
apetushkov@9858 679 frequency = (jlong)(*(Hz_location - 5) - '0') * 1000;
apetushkov@9858 680 frequency += (jlong)(*(Hz_location - 4) - '0') * 100;
apetushkov@9858 681 frequency += (jlong)(*(Hz_location - 3) - '0') * 10;
apetushkov@9858 682 frequency += (jlong)(*(Hz_location - 2) - '0');
apetushkov@9858 683 frequency *= multiplier;
apetushkov@9858 684 }
apetushkov@9858 685 }
apetushkov@9858 686 return frequency;
apetushkov@9858 687 }
apetushkov@9858 688
apetushkov@9858 689
apetushkov@9858 690 jlong VM_Version_Ext::maximum_qualified_cpu_frequency(void) {
apetushkov@9858 691 if (_max_qualified_cpu_frequency == 0) {
apetushkov@9858 692 _max_qualified_cpu_frequency = max_qualified_cpu_freq_from_brand_string();
apetushkov@9858 693 }
apetushkov@9858 694 return _max_qualified_cpu_frequency;
apetushkov@9858 695 }
apetushkov@9858 696
apetushkov@9858 697 const char* const VM_Version_Ext::_family_id_intel[] = {
apetushkov@9858 698 "8086/8088",
apetushkov@9858 699 "",
apetushkov@9858 700 "286",
apetushkov@9858 701 "386",
apetushkov@9858 702 "486",
apetushkov@9858 703 "Pentium",
apetushkov@9858 704 "Pentium Pro", //or Pentium-M/Woodcrest depeding on model
apetushkov@9858 705 "",
apetushkov@9858 706 "",
apetushkov@9858 707 "",
apetushkov@9858 708 "",
apetushkov@9858 709 "",
apetushkov@9858 710 "",
apetushkov@9858 711 "",
apetushkov@9858 712 "",
apetushkov@9858 713 "Pentium 4"
apetushkov@9858 714 };
apetushkov@9858 715
apetushkov@9858 716 const char* const VM_Version_Ext::_family_id_amd[] = {
apetushkov@9858 717 "",
apetushkov@9858 718 "",
apetushkov@9858 719 "",
apetushkov@9858 720 "",
apetushkov@9858 721 "5x86",
apetushkov@9858 722 "K5/K6",
apetushkov@9858 723 "Athlon/AthlonXP",
apetushkov@9858 724 "",
apetushkov@9858 725 "",
apetushkov@9858 726 "",
apetushkov@9858 727 "",
apetushkov@9858 728 "",
apetushkov@9858 729 "",
apetushkov@9858 730 "",
apetushkov@9858 731 "",
apetushkov@9858 732 "Opteron/Athlon64",
apetushkov@9858 733 "Opteron QC/Phenom" // Barcelona et.al.
apetushkov@9858 734 };
apetushkov@9858 735 // Partially from Intel 64 and IA-32 Architecture Software Developer's Manual,
apetushkov@9858 736 // September 2013, Vol 3C Table 35-1
apetushkov@9858 737 const char* const VM_Version_Ext::_model_id_pentium_pro[] = {
apetushkov@9858 738 "",
apetushkov@9858 739 "Pentium Pro",
apetushkov@9858 740 "",
apetushkov@9858 741 "Pentium II model 3",
apetushkov@9858 742 "",
apetushkov@9858 743 "Pentium II model 5/Xeon/Celeron",
apetushkov@9858 744 "Celeron",
apetushkov@9858 745 "Pentium III/Pentium III Xeon",
apetushkov@9858 746 "Pentium III/Pentium III Xeon",
apetushkov@9858 747 "Pentium M model 9", // Yonah
apetushkov@9858 748 "Pentium III, model A",
apetushkov@9858 749 "Pentium III, model B",
apetushkov@9858 750 "",
apetushkov@9858 751 "Pentium M model D", // Dothan
apetushkov@9858 752 "",
apetushkov@9858 753 "Core 2", // 0xf Woodcrest/Conroe/Merom/Kentsfield/Clovertown
apetushkov@9858 754 "",
apetushkov@9858 755 "",
apetushkov@9858 756 "",
apetushkov@9858 757 "",
apetushkov@9858 758 "",
apetushkov@9858 759 "",
apetushkov@9858 760 "Celeron", // 0x16 Celeron 65nm
apetushkov@9858 761 "Core 2", // 0x17 Penryn / Harpertown
apetushkov@9858 762 "",
apetushkov@9858 763 "",
apetushkov@9858 764 "Core i7", // 0x1A CPU_MODEL_NEHALEM_EP
apetushkov@9858 765 "Atom", // 0x1B Z5xx series Silverthorn
apetushkov@9858 766 "",
apetushkov@9858 767 "Core 2", // 0x1D Dunnington (6-core)
apetushkov@9858 768 "Nehalem", // 0x1E CPU_MODEL_NEHALEM
apetushkov@9858 769 "",
apetushkov@9858 770 "",
apetushkov@9858 771 "",
apetushkov@9858 772 "",
apetushkov@9858 773 "",
apetushkov@9858 774 "",
apetushkov@9858 775 "Westmere", // 0x25 CPU_MODEL_WESTMERE
apetushkov@9858 776 "",
apetushkov@9858 777 "",
apetushkov@9858 778 "", // 0x28
apetushkov@9858 779 "",
apetushkov@9858 780 "Sandy Bridge", // 0x2a "2nd Generation Intel Core i7, i5, i3"
apetushkov@9858 781 "",
apetushkov@9858 782 "Westmere-EP", // 0x2c CPU_MODEL_WESTMERE_EP
apetushkov@9858 783 "Sandy Bridge-EP", // 0x2d CPU_MODEL_SANDYBRIDGE_EP
apetushkov@9858 784 "Nehalem-EX", // 0x2e CPU_MODEL_NEHALEM_EX
apetushkov@9858 785 "Westmere-EX", // 0x2f CPU_MODEL_WESTMERE_EX
apetushkov@9858 786 "",
apetushkov@9858 787 "",
apetushkov@9858 788 "",
apetushkov@9858 789 "",
apetushkov@9858 790 "",
apetushkov@9858 791 "",
apetushkov@9858 792 "",
apetushkov@9858 793 "",
apetushkov@9858 794 "",
apetushkov@9858 795 "",
apetushkov@9858 796 "Ivy Bridge", // 0x3a
apetushkov@9858 797 "",
apetushkov@9858 798 "Haswell", // 0x3c "4th Generation Intel Core Processor"
apetushkov@9858 799 "", // 0x3d "Next Generation Intel Core Processor"
apetushkov@9858 800 "Ivy Bridge-EP", // 0x3e "Next Generation Intel Xeon Processor E7 Family"
apetushkov@9858 801 "", // 0x3f "Future Generation Intel Xeon Processor"
apetushkov@9858 802 "",
apetushkov@9858 803 "",
apetushkov@9858 804 "",
apetushkov@9858 805 "",
apetushkov@9858 806 "",
apetushkov@9858 807 "Haswell", // 0x45 "4th Generation Intel Core Processor"
apetushkov@9858 808 "Haswell", // 0x46 "4th Generation Intel Core Processor"
apetushkov@9858 809 NULL
apetushkov@9858 810 };
apetushkov@9858 811
apetushkov@9858 812 /* Brand ID is for back compability
apetushkov@9858 813 * Newer CPUs uses the extended brand string */
apetushkov@9858 814 const char* const VM_Version_Ext::_brand_id[] = {
apetushkov@9858 815 "",
apetushkov@9858 816 "Celeron processor",
apetushkov@9858 817 "Pentium III processor",
apetushkov@9858 818 "Intel Pentium III Xeon processor",
apetushkov@9858 819 "",
apetushkov@9858 820 "",
apetushkov@9858 821 "",
apetushkov@9858 822 "",
apetushkov@9858 823 "Intel Pentium 4 processor",
apetushkov@9858 824 NULL
apetushkov@9858 825 };
apetushkov@9858 826
apetushkov@9858 827
apetushkov@9858 828 const char* const VM_Version_Ext::_feature_edx_id[] = {
apetushkov@9858 829 "On-Chip FPU",
apetushkov@9858 830 "Virtual Mode Extensions",
apetushkov@9858 831 "Debugging Extensions",
apetushkov@9858 832 "Page Size Extensions",
apetushkov@9858 833 "Time Stamp Counter",
apetushkov@9858 834 "Model Specific Registers",
apetushkov@9858 835 "Physical Address Extension",
apetushkov@9858 836 "Machine Check Exceptions",
apetushkov@9858 837 "CMPXCHG8B Instruction",
apetushkov@9858 838 "On-Chip APIC",
apetushkov@9858 839 "",
apetushkov@9858 840 "Fast System Call",
apetushkov@9858 841 "Memory Type Range Registers",
apetushkov@9858 842 "Page Global Enable",
apetushkov@9858 843 "Machine Check Architecture",
apetushkov@9858 844 "Conditional Mov Instruction",
apetushkov@9858 845 "Page Attribute Table",
apetushkov@9858 846 "36-bit Page Size Extension",
apetushkov@9858 847 "Processor Serial Number",
apetushkov@9858 848 "CLFLUSH Instruction",
apetushkov@9858 849 "",
apetushkov@9858 850 "Debug Trace Store feature",
apetushkov@9858 851 "ACPI registers in MSR space",
apetushkov@9858 852 "Intel Architecture MMX Technology",
apetushkov@9858 853 "Fast Float Point Save and Restore",
apetushkov@9858 854 "Streaming SIMD extensions",
apetushkov@9858 855 "Streaming SIMD extensions 2",
apetushkov@9858 856 "Self-Snoop",
apetushkov@9858 857 "Hyper Threading",
apetushkov@9858 858 "Thermal Monitor",
apetushkov@9858 859 "",
apetushkov@9858 860 "Pending Break Enable"
apetushkov@9858 861 };
apetushkov@9858 862
apetushkov@9858 863 const char* const VM_Version_Ext::_feature_extended_edx_id[] = {
apetushkov@9858 864 "",
apetushkov@9858 865 "",
apetushkov@9858 866 "",
apetushkov@9858 867 "",
apetushkov@9858 868 "",
apetushkov@9858 869 "",
apetushkov@9858 870 "",
apetushkov@9858 871 "",
apetushkov@9858 872 "",
apetushkov@9858 873 "",
apetushkov@9858 874 "",
apetushkov@9858 875 "SYSCALL/SYSRET",
apetushkov@9858 876 "",
apetushkov@9858 877 "",
apetushkov@9858 878 "",
apetushkov@9858 879 "",
apetushkov@9858 880 "",
apetushkov@9858 881 "",
apetushkov@9858 882 "",
apetushkov@9858 883 "",
apetushkov@9858 884 "Execute Disable Bit",
apetushkov@9858 885 "",
apetushkov@9858 886 "",
apetushkov@9858 887 "",
apetushkov@9858 888 "",
apetushkov@9858 889 "",
apetushkov@9858 890 "",
apetushkov@9858 891 "RDTSCP",
apetushkov@9858 892 "",
apetushkov@9858 893 "Intel 64 Architecture",
apetushkov@9858 894 "",
apetushkov@9858 895 ""
apetushkov@9858 896 };
apetushkov@9858 897
apetushkov@9858 898 const char* const VM_Version_Ext::_feature_ecx_id[] = {
apetushkov@9858 899 "Streaming SIMD Extensions 3",
apetushkov@9858 900 "PCLMULQDQ",
apetushkov@9858 901 "64-bit DS Area",
apetushkov@9858 902 "MONITOR/MWAIT instructions",
apetushkov@9858 903 "CPL Qualified Debug Store",
apetushkov@9858 904 "Virtual Machine Extensions",
apetushkov@9858 905 "Safer Mode Extensions",
apetushkov@9858 906 "Enhanced Intel SpeedStep technology",
apetushkov@9858 907 "Thermal Monitor 2",
apetushkov@9858 908 "Supplemental Streaming SIMD Extensions 3",
apetushkov@9858 909 "L1 Context ID",
apetushkov@9858 910 "",
apetushkov@9858 911 "Fused Multiply-Add",
apetushkov@9858 912 "CMPXCHG16B",
apetushkov@9858 913 "xTPR Update Control",
apetushkov@9858 914 "Perfmon and Debug Capability",
apetushkov@9858 915 "",
apetushkov@9858 916 "Process-context identifiers",
apetushkov@9858 917 "Direct Cache Access",
apetushkov@9858 918 "Streaming SIMD extensions 4.1",
apetushkov@9858 919 "Streaming SIMD extensions 4.2",
apetushkov@9858 920 "x2APIC",
apetushkov@9858 921 "MOVBE",
apetushkov@9858 922 "Popcount instruction",
apetushkov@9858 923 "TSC-Deadline",
apetushkov@9858 924 "AESNI",
apetushkov@9858 925 "XSAVE",
apetushkov@9858 926 "OSXSAVE",
apetushkov@9858 927 "AVX",
apetushkov@9858 928 "F16C",
apetushkov@9858 929 "RDRAND",
apetushkov@9858 930 ""
apetushkov@9858 931 };
apetushkov@9858 932
apetushkov@9858 933 const char* const VM_Version_Ext::_feature_extended_ecx_id[] = {
apetushkov@9858 934 "LAHF/SAHF instruction support",
apetushkov@9858 935 "Core multi-processor leagacy mode",
apetushkov@9858 936 "",
apetushkov@9858 937 "",
apetushkov@9858 938 "",
apetushkov@9858 939 "Advanced Bit Manipulations: LZCNT",
apetushkov@9858 940 "SSE4A: MOVNTSS, MOVNTSD, EXTRQ, INSERTQ",
apetushkov@9858 941 "Misaligned SSE mode",
apetushkov@9858 942 "",
apetushkov@9858 943 "",
apetushkov@9858 944 "",
apetushkov@9858 945 "",
apetushkov@9858 946 "",
apetushkov@9858 947 "",
apetushkov@9858 948 "",
apetushkov@9858 949 "",
apetushkov@9858 950 "",
apetushkov@9858 951 "",
apetushkov@9858 952 "",
apetushkov@9858 953 "",
apetushkov@9858 954 "",
apetushkov@9858 955 "",
apetushkov@9858 956 "",
apetushkov@9858 957 "",
apetushkov@9858 958 "",
apetushkov@9858 959 "",
apetushkov@9858 960 "",
apetushkov@9858 961 "",
apetushkov@9858 962 "",
apetushkov@9858 963 "",
apetushkov@9858 964 "",
apetushkov@9858 965 ""
apetushkov@9858 966 };

mercurial