mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Clean up cpuid code, make selection of cpu/mem info available on Linux, macOS and FreeBSD
This commit is contained in:
parent
604d826aa3
commit
dcb793aed4
@ -14,6 +14,13 @@
|
|||||||
#include "graphicsStateGuardian.h"
|
#include "graphicsStateGuardian.h"
|
||||||
#include "displayInformation.h"
|
#include "displayInformation.h"
|
||||||
|
|
||||||
|
// For __rdtsc
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <intrin.h>
|
||||||
|
#elif defined(__GNUC__) && !defined(__APPLE__)
|
||||||
|
#include <x86intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if these two DisplayModes are identical.
|
* Returns true if these two DisplayModes are identical.
|
||||||
*/
|
*/
|
||||||
@ -58,12 +65,6 @@ DisplayInformation::
|
|||||||
if (_display_mode_array != NULL) {
|
if (_display_mode_array != NULL) {
|
||||||
delete[] _display_mode_array;
|
delete[] _display_mode_array;
|
||||||
}
|
}
|
||||||
if (_cpu_id_data != NULL) {
|
|
||||||
delete _cpu_id_data;
|
|
||||||
}
|
|
||||||
if (_cpu_brand_string != NULL) {
|
|
||||||
delete _cpu_brand_string;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,12 +135,6 @@ DisplayInformation() {
|
|||||||
_driver_date_day = 0;
|
_driver_date_day = 0;
|
||||||
_driver_date_year = 0;
|
_driver_date_year = 0;
|
||||||
|
|
||||||
_cpu_id_version = 1;
|
|
||||||
_cpu_id_size = 0;
|
|
||||||
_cpu_id_data = 0;
|
|
||||||
|
|
||||||
_cpu_vendor_string = 0;
|
|
||||||
_cpu_brand_string = 0;
|
|
||||||
_cpu_version_information = 0;
|
_cpu_version_information = 0;
|
||||||
_cpu_brand_index = 0;
|
_cpu_brand_index = 0;
|
||||||
|
|
||||||
@ -152,7 +147,6 @@ DisplayInformation() {
|
|||||||
_num_logical_cpus = 0;
|
_num_logical_cpus = 0;
|
||||||
|
|
||||||
_get_memory_information_function = 0;
|
_get_memory_information_function = 0;
|
||||||
_cpu_time_function = 0;
|
|
||||||
_update_cpu_frequency_function = 0;
|
_update_cpu_frequency_function = 0;
|
||||||
|
|
||||||
_os_version_major = -1;
|
_os_version_major = -1;
|
||||||
@ -493,62 +487,17 @@ get_driver_date_year() {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int DisplayInformation::
|
const string &DisplayInformation::
|
||||||
get_cpu_id_version() {
|
get_cpu_vendor_string() const {
|
||||||
return _cpu_id_version;
|
return _cpu_vendor_string;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of 32-bit values for cpu id binary data.
|
|
||||||
*/
|
|
||||||
int DisplayInformation::
|
|
||||||
get_cpu_id_size() {
|
|
||||||
return _cpu_id_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns part of cpu id binary data based on the index.
|
|
||||||
*/
|
|
||||||
unsigned int DisplayInformation::
|
|
||||||
get_cpu_id_data(int index) {
|
|
||||||
unsigned int data;
|
|
||||||
|
|
||||||
data = 0;
|
|
||||||
if (index >= 0 && index < _cpu_id_size) {
|
|
||||||
data = _cpu_id_data [index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const char *DisplayInformation::
|
const string &DisplayInformation::
|
||||||
get_cpu_vendor_string() {
|
get_cpu_brand_string() const {
|
||||||
const char *string;
|
return _cpu_brand_string;
|
||||||
|
|
||||||
string = _cpu_vendor_string;
|
|
||||||
if (string == 0) {
|
|
||||||
string = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const char *DisplayInformation::
|
|
||||||
get_cpu_brand_string() {
|
|
||||||
const char *string;
|
|
||||||
|
|
||||||
string = _cpu_brand_string;
|
|
||||||
if (string == 0) {
|
|
||||||
string = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -576,18 +525,17 @@ get_cpu_frequency() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Equivalent to the rdtsc processor instruction.
|
||||||
*/
|
*/
|
||||||
uint64_t DisplayInformation::
|
uint64_t DisplayInformation::
|
||||||
get_cpu_time() {
|
get_cpu_time() {
|
||||||
uint64_t cpu_time;
|
#if defined(_MSC_VER) || (defined(__GNUC__) && !defined(__APPLE__))
|
||||||
|
return __rdtsc();
|
||||||
cpu_time = 0;
|
#else
|
||||||
if (_cpu_time_function) {
|
unsigned int lo, hi = 0;
|
||||||
cpu_time = _cpu_time_function();
|
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
|
||||||
}
|
return ((uint64_t)hi << 32) | lo;
|
||||||
|
#endif
|
||||||
return cpu_time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,17 +94,13 @@ PUBLISHED:
|
|||||||
int get_driver_date_day();
|
int get_driver_date_day();
|
||||||
int get_driver_date_year();
|
int get_driver_date_year();
|
||||||
|
|
||||||
int get_cpu_id_version();
|
const string &get_cpu_vendor_string() const;
|
||||||
int get_cpu_id_size();
|
const string &get_cpu_brand_string() const;
|
||||||
unsigned int get_cpu_id_data(int index);
|
|
||||||
|
|
||||||
const char *get_cpu_vendor_string();
|
|
||||||
const char *get_cpu_brand_string();
|
|
||||||
unsigned int get_cpu_version_information();
|
unsigned int get_cpu_version_information();
|
||||||
unsigned int get_cpu_brand_index();
|
unsigned int get_cpu_brand_index();
|
||||||
|
|
||||||
uint64_t get_cpu_frequency();
|
uint64_t get_cpu_frequency();
|
||||||
uint64_t get_cpu_time();
|
static uint64_t get_cpu_time();
|
||||||
|
|
||||||
uint64_t get_maximum_cpu_frequency();
|
uint64_t get_maximum_cpu_frequency();
|
||||||
uint64_t get_current_cpu_frequency();
|
uint64_t get_current_cpu_frequency();
|
||||||
@ -158,12 +154,9 @@ public:
|
|||||||
int _driver_date_day;
|
int _driver_date_day;
|
||||||
int _driver_date_year;
|
int _driver_date_year;
|
||||||
|
|
||||||
int _cpu_id_version;
|
|
||||||
int _cpu_id_size;
|
|
||||||
unsigned int *_cpu_id_data;
|
|
||||||
|
|
||||||
char *_cpu_vendor_string;
|
string _cpu_vendor_string;
|
||||||
char *_cpu_brand_string;
|
string _cpu_brand_string;
|
||||||
unsigned int _cpu_version_information;
|
unsigned int _cpu_version_information;
|
||||||
unsigned int _cpu_brand_index;
|
unsigned int _cpu_brand_index;
|
||||||
|
|
||||||
@ -176,7 +169,6 @@ public:
|
|||||||
int _num_logical_cpus;
|
int _num_logical_cpus;
|
||||||
|
|
||||||
void (*_get_memory_information_function) (DisplayInformation *display_information);
|
void (*_get_memory_information_function) (DisplayInformation *display_information);
|
||||||
uint64_t (*_cpu_time_function) (void);
|
|
||||||
int (*_update_cpu_frequency_function) (int processor_number, DisplayInformation *display_information);
|
int (*_update_cpu_frequency_function) (int processor_number, DisplayInformation *display_information);
|
||||||
|
|
||||||
int _os_version_major;
|
int _os_version_major;
|
||||||
|
@ -18,6 +18,92 @@
|
|||||||
#include "mutexHolder.h"
|
#include "mutexHolder.h"
|
||||||
#include "displayInformation.h"
|
#include "displayInformation.h"
|
||||||
|
|
||||||
|
#ifdef IS_LINUX
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IS_OSX
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IS_FREEBSD
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||||
|
// GCC and Clang offer a useful cpuid.h header.
|
||||||
|
#include <cpuid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// MSVC has a __cpuid intrinsic.
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
union cpuid_info {
|
||||||
|
char str[16];
|
||||||
|
struct {
|
||||||
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the highest cpuid leaf that is supported by the CPU.
|
||||||
|
*/
|
||||||
|
static inline uint32_t get_cpuid_max(uint32_t leaf) {
|
||||||
|
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||||
|
return __get_cpuid_max(leaf, 0);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
uint32_t p[4] = {0};
|
||||||
|
__cpuid((int *)p, leaf);
|
||||||
|
return p[0];
|
||||||
|
#else
|
||||||
|
unsigned int eax = 0;
|
||||||
|
__asm__ ("cpuid\n\t"
|
||||||
|
: "=a" (eax)
|
||||||
|
: "0" (leaf));
|
||||||
|
return eax;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets cpuid info for the given leaf.
|
||||||
|
*/
|
||||||
|
static inline void get_cpuid(uint32_t leaf, cpuid_info &info) {
|
||||||
|
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||||
|
__cpuid(leaf, info.eax, info.ebx, info.ecx, info.edx);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
__cpuid((int *)info.str, leaf);
|
||||||
|
#else
|
||||||
|
__asm__ ("cpuid\n\t"
|
||||||
|
: "=a" (info.eax), "=b" (info.ebx), "=c" (info.ecx), "=d" (info.edx)
|
||||||
|
: "0" (leaf));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IS_LINUX
|
||||||
|
/**
|
||||||
|
* Updates the current memory usage statistics in the DisplayInformation.
|
||||||
|
*/
|
||||||
|
static void update_memory_info(DisplayInformation *info) {
|
||||||
|
struct sysinfo meminfo;
|
||||||
|
if (sysinfo(&meminfo) == 0) {
|
||||||
|
info->_physical_memory = meminfo.totalram;
|
||||||
|
info->_available_physical_memory = meminfo.freeram;
|
||||||
|
info->_page_file_size = meminfo.totalswap;
|
||||||
|
info->_available_page_file_size = meminfo.freeswap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TypeHandle GraphicsPipe::_type_handle;
|
TypeHandle GraphicsPipe::_type_handle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,24 +124,78 @@ GraphicsPipe() :
|
|||||||
_display_width = 0;
|
_display_width = 0;
|
||||||
_display_height = 0;
|
_display_height = 0;
|
||||||
|
|
||||||
_display_information = new DisplayInformation ( );
|
_display_information = new DisplayInformation();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
cpuid_info info;
|
||||||
* Don't try to copy GraphicsPipes.
|
const uint32_t max_cpuid = get_cpuid_max(0);
|
||||||
*/
|
const uint32_t max_extended = get_cpuid_max(0x80000000);
|
||||||
GraphicsPipe::
|
|
||||||
GraphicsPipe(const GraphicsPipe &) {
|
|
||||||
_is_valid = false;
|
|
||||||
nassertv(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (max_cpuid >= 1) {
|
||||||
* Don't try to copy GraphicsPipes.
|
get_cpuid(0, info);
|
||||||
*/
|
swap(info.ecx, info.edx);
|
||||||
void GraphicsPipe::
|
_display_information->_cpu_vendor_string = string(info.str + 4, 12);
|
||||||
operator = (const GraphicsPipe &) {
|
|
||||||
nassertv(false);
|
get_cpuid(1, info);
|
||||||
|
_display_information->_cpu_version_information = info.eax;
|
||||||
|
_display_information->_cpu_brand_index = info.ebx & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_extended >= 0x80000004) {
|
||||||
|
string brand;
|
||||||
|
get_cpuid(0x80000002, info);
|
||||||
|
brand += string(info.str, strnlen(info.str, 16));
|
||||||
|
get_cpuid(0x80000003, info);
|
||||||
|
brand += string(info.str, strnlen(info.str, 16));
|
||||||
|
get_cpuid(0x80000004, info);
|
||||||
|
brand += string(info.str, strnlen(info.str, 16));
|
||||||
|
_display_information->_cpu_brand_string = move(brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(IS_OSX)
|
||||||
|
// macOS exposes a lot of useful information through sysctl.
|
||||||
|
size_t len = sizeof(uint64_t);
|
||||||
|
sysctlbyname("hw.memsize", &_display_information->_physical_memory, &len, NULL, 0);
|
||||||
|
len = sizeof(uint64_t);
|
||||||
|
sysctlbyname("hw.cpufrequency", &_display_information->_cpu_frequency, &len, NULL, 0);
|
||||||
|
len = sizeof(uint64_t);
|
||||||
|
sysctlbyname("hw.cpufrequency", &_display_information->_current_cpu_frequency, &len, NULL, 0);
|
||||||
|
len = sizeof(uint64_t);
|
||||||
|
sysctlbyname("hw.cpufrequency_max", &_display_information->_maximum_cpu_frequency, &len, NULL, 0);
|
||||||
|
len = sizeof(int);
|
||||||
|
sysctlbyname("hw.physicalcpu", &_display_information->_num_cpu_cores, &len, NULL, 0);
|
||||||
|
len = sizeof(int);
|
||||||
|
sysctlbyname("hw.logicalcpu", &_display_information->_num_logical_cpus, &len, NULL, 0);
|
||||||
|
|
||||||
|
#elif defined(IS_LINUX)
|
||||||
|
_display_information->_get_memory_information_function = &update_memory_info;
|
||||||
|
update_memory_info(_display_information);
|
||||||
|
|
||||||
|
#elif defined(IS_FREEBSD)
|
||||||
|
size_t len = sizeof(uint64_t);
|
||||||
|
sysctlbyname("hw.physmem", &_display_information->_physical_memory, &len, NULL, 0);
|
||||||
|
len = sizeof(uint64_t);
|
||||||
|
sysctlbyname("vm.swap_total", &_display_information->_page_file_size, &len, NULL, 0);
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
MEMORYSTATUSEX status;
|
||||||
|
status.dwLength = sizeof(MEMORYSTATUSEX);
|
||||||
|
if (GlobalMemoryStatusEx(&status)) {
|
||||||
|
_display_information->_physical_memory = status.ullTotalPhys;
|
||||||
|
_display_information->_available_physical_memory = status.ullAvailPhys;
|
||||||
|
_display_information->_page_file_size = status.ullTotalPageFile;
|
||||||
|
_display_information->_available_page_file_size = status.ullAvailPageFile;
|
||||||
|
_display_information->_process_virtual_memory = status.ullTotalVirtual;
|
||||||
|
_display_information->_available_process_virtual_memory = status.ullAvailVirtual;
|
||||||
|
_display_information->_memory_load = status.dwMemoryLoad;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(IS_LINUX) || defined(IS_FREEBSD)
|
||||||
|
long nproc = sysconf(_SC_NPROCESSORS_CONF);
|
||||||
|
if (nproc > 0) {
|
||||||
|
_display_information->_num_logical_cpus = nproc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,8 +53,8 @@ class EXPCL_PANDA_DISPLAY GraphicsPipe : public TypedReferenceCount {
|
|||||||
protected:
|
protected:
|
||||||
GraphicsPipe();
|
GraphicsPipe();
|
||||||
private:
|
private:
|
||||||
GraphicsPipe(const GraphicsPipe ©);
|
GraphicsPipe(const GraphicsPipe ©) DELETED;
|
||||||
void operator = (const GraphicsPipe ©);
|
GraphicsPipe &operator = (const GraphicsPipe ©) DELETED_ASSIGN;
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
virtual ~GraphicsPipe();
|
virtual ~GraphicsPipe();
|
||||||
|
@ -20,10 +20,7 @@
|
|||||||
|
|
||||||
#include "psapi.h"
|
#include "psapi.h"
|
||||||
#include "powrprof.h"
|
#include "powrprof.h"
|
||||||
|
|
||||||
#ifdef _WIN64
|
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
TypeHandle WinGraphicsPipe::_type_handle;
|
TypeHandle WinGraphicsPipe::_type_handle;
|
||||||
|
|
||||||
@ -99,443 +96,6 @@ void get_memory_information (DisplayInformation *display_information) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef union {
|
|
||||||
uint64_t long_integer;
|
|
||||||
}
|
|
||||||
LONG_INTEGER;
|
|
||||||
|
|
||||||
uint64_t cpu_time_function (void) {
|
|
||||||
#ifdef _WIN64
|
|
||||||
return __rdtsc();
|
|
||||||
#else
|
|
||||||
LONG_INTEGER long_integer;
|
|
||||||
LONG_INTEGER *long_integer_pointer;
|
|
||||||
|
|
||||||
long_integer_pointer = &long_integer;
|
|
||||||
|
|
||||||
__asm {
|
|
||||||
mov ebx,[long_integer_pointer]
|
|
||||||
rdtsc
|
|
||||||
mov [ebx + 0], eax
|
|
||||||
mov [ebx + 4], edx
|
|
||||||
}
|
|
||||||
|
|
||||||
return long_integer.long_integer;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned char al;
|
|
||||||
unsigned char ah;
|
|
||||||
};
|
|
||||||
unsigned int eax;
|
|
||||||
};
|
|
||||||
unsigned int ebx;
|
|
||||||
unsigned int ecx;
|
|
||||||
unsigned int edx;
|
|
||||||
};
|
|
||||||
} CPU_ID_REGISTERS;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int maximum_cpu_id_input;
|
|
||||||
char cpu_vendor [16];
|
|
||||||
};
|
|
||||||
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0;
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_1;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
// eax
|
|
||||||
union {
|
|
||||||
unsigned int eax;
|
|
||||||
unsigned int version_information;
|
|
||||||
struct {
|
|
||||||
unsigned int stepping_id : 4;
|
|
||||||
unsigned int model : 4;
|
|
||||||
unsigned int family : 4;
|
|
||||||
unsigned int processor_type : 2;
|
|
||||||
unsigned int reserved_0 : 2;
|
|
||||||
unsigned int extended_model_id : 4;
|
|
||||||
unsigned int extended_family_id : 8;
|
|
||||||
unsigned int reserved_1 : 4;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// ebx
|
|
||||||
union {
|
|
||||||
unsigned int ebx;
|
|
||||||
struct {
|
|
||||||
unsigned int brand_index : 8;
|
|
||||||
unsigned int clflush : 8;
|
|
||||||
unsigned int maximum_logical_processors : 8;
|
|
||||||
unsigned int initial_apic_id : 8;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// ecx
|
|
||||||
union {
|
|
||||||
unsigned int ecx;
|
|
||||||
struct {
|
|
||||||
unsigned int sse3 : 1;
|
|
||||||
unsigned int reserved_1_to_2 : 2;
|
|
||||||
unsigned int monitor : 1;
|
|
||||||
unsigned int ds_cpl : 1;
|
|
||||||
unsigned int vmx : 1;
|
|
||||||
unsigned int reserved_6 : 1;
|
|
||||||
unsigned int est : 1;
|
|
||||||
unsigned int tm2 : 1;
|
|
||||||
unsigned int reserved_9 : 1;
|
|
||||||
unsigned int cnxt_id : 1;
|
|
||||||
unsigned int reserved_11_to_12 : 2;
|
|
||||||
unsigned int cmpxchg16b : 1;
|
|
||||||
unsigned int xtpr_disable : 1;
|
|
||||||
unsigned int reserved_15_to_31 : 17;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// edx
|
|
||||||
union {
|
|
||||||
unsigned int edx;
|
|
||||||
struct {
|
|
||||||
unsigned int fpu : 1;
|
|
||||||
unsigned int vme : 1;
|
|
||||||
unsigned int de : 1;
|
|
||||||
unsigned int pse : 1;
|
|
||||||
unsigned int tsc : 1;
|
|
||||||
unsigned int msr : 1;
|
|
||||||
unsigned int pae : 1;
|
|
||||||
unsigned int mce : 1;
|
|
||||||
unsigned int cx8 : 1;
|
|
||||||
unsigned int apic : 1;
|
|
||||||
unsigned int reserved_10 : 1;
|
|
||||||
unsigned int sep : 1;
|
|
||||||
unsigned int mtrr : 1;
|
|
||||||
unsigned int pge : 1;
|
|
||||||
unsigned int mca : 1;
|
|
||||||
unsigned int cmov : 1;
|
|
||||||
unsigned int pat : 1;
|
|
||||||
unsigned int pse_36 : 1;
|
|
||||||
unsigned int psn : 1;
|
|
||||||
unsigned int cflush : 1;
|
|
||||||
unsigned int reserved_20 : 1;
|
|
||||||
unsigned int ds : 1;
|
|
||||||
unsigned int acpi : 1;
|
|
||||||
unsigned int mmx : 1;
|
|
||||||
unsigned int fxsr : 1;
|
|
||||||
unsigned int sse : 1;
|
|
||||||
unsigned int sse2 : 1;
|
|
||||||
unsigned int ss : 1;
|
|
||||||
unsigned int htt : 1;
|
|
||||||
unsigned int tm : 1;
|
|
||||||
unsigned int reserved_30 : 1;
|
|
||||||
unsigned int pbe : 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAXIMUM_2 8
|
|
||||||
#define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof(CPU_ID_REGISTERS))
|
|
||||||
|
|
||||||
union {
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_2;
|
|
||||||
unsigned char character_array_2 [MAXIMUM_CHARACTERS];
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2];
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000000;
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000001;
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
char cpu_brand_string [sizeof(CPU_ID_REGISTERS) * 3];
|
|
||||||
struct {
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000002;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000003;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000004;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned int eax;
|
|
||||||
unsigned int ebx;
|
|
||||||
union {
|
|
||||||
unsigned int ecx;
|
|
||||||
struct {
|
|
||||||
unsigned int l1_data_cache_line_size : 8;
|
|
||||||
unsigned int l1_data_reserved_8_to_15 : 8;
|
|
||||||
unsigned int l1_data_associativity : 8;
|
|
||||||
unsigned int l1_data_cache_size : 8;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
unsigned int edx;
|
|
||||||
struct {
|
|
||||||
unsigned int l1_code_cache_line_size : 8;
|
|
||||||
unsigned int l1_code_reserved_8_to_15 : 8;
|
|
||||||
unsigned int l1_code_associativity : 8;
|
|
||||||
unsigned int l1_code_cache_size : 8;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000005;
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned int eax;
|
|
||||||
unsigned int ebx;
|
|
||||||
union {
|
|
||||||
unsigned int ecx;
|
|
||||||
struct {
|
|
||||||
unsigned int l2_cache_line_size : 8;
|
|
||||||
unsigned int l2_reserved_8_to_11 : 4;
|
|
||||||
unsigned int l2_associativity : 4;
|
|
||||||
unsigned int l2_cache_size : 16;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
unsigned int edx;
|
|
||||||
};
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000006;
|
|
||||||
};
|
|
||||||
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000008;
|
|
||||||
|
|
||||||
unsigned int cache_line_size;
|
|
||||||
unsigned int log_base_2_cache_line_size;
|
|
||||||
} CPU_ID;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_1;
|
|
||||||
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000000;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000001;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000002;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000003;
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000004;
|
|
||||||
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000006;
|
|
||||||
|
|
||||||
CPU_ID_REGISTERS cpu_id_registers_0x80000008;
|
|
||||||
} CPU_ID_BINARY_DATA;
|
|
||||||
|
|
||||||
void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) {
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0 = cpu_id->cpu_id_registers_0;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_1 = cpu_id->cpu_id_registers_1;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000000 = cpu_id->cpu_id_registers_0x80000000;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000001 = cpu_id->cpu_id_registers_0x80000001;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000002 = cpu_id->cpu_id_registers_0x80000002;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000003 = cpu_id->cpu_id_registers_0x80000003;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000004 = cpu_id->cpu_id_registers_0x80000004;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000006 = cpu_id->cpu_id_registers_0x80000006;
|
|
||||||
cpu_id_binary_data->cpu_id_registers_0x80000008 = cpu_id->cpu_id_registers_0x80000008;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) {
|
|
||||||
memset (cpu_id, 0, sizeof(CPU_ID));
|
|
||||||
|
|
||||||
cpu_id->cpu_id_registers_0 = cpu_id_binary_data->cpu_id_registers_0;
|
|
||||||
cpu_id->cpu_id_registers_1 = cpu_id_binary_data->cpu_id_registers_1;
|
|
||||||
cpu_id->cpu_id_registers_0x80000000 = cpu_id_binary_data->cpu_id_registers_0x80000000;
|
|
||||||
cpu_id->cpu_id_registers_0x80000001 = cpu_id_binary_data->cpu_id_registers_0x80000001;
|
|
||||||
cpu_id->cpu_id_registers_0x80000002 = cpu_id_binary_data->cpu_id_registers_0x80000002;
|
|
||||||
cpu_id->cpu_id_registers_0x80000003 = cpu_id_binary_data->cpu_id_registers_0x80000003;
|
|
||||||
cpu_id->cpu_id_registers_0x80000004 = cpu_id_binary_data->cpu_id_registers_0x80000004;
|
|
||||||
cpu_id->cpu_id_registers_0x80000006 = cpu_id_binary_data->cpu_id_registers_0x80000006;
|
|
||||||
cpu_id->cpu_id_registers_0x80000008 = cpu_id_binary_data->cpu_id_registers_0x80000008;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpuid(int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
|
|
||||||
int state;
|
|
||||||
|
|
||||||
state = false;
|
|
||||||
__try {
|
|
||||||
if (input_eax == 0) {
|
|
||||||
// the order of ecx and edx is swapped when saved to make a proper
|
|
||||||
// vendor string
|
|
||||||
#ifdef _WIN64
|
|
||||||
__cpuid((int*)cpu_id_registers, input_eax);
|
|
||||||
unsigned int tmp = cpu_id_registers->edx;
|
|
||||||
cpu_id_registers->edx = cpu_id_registers->ecx;
|
|
||||||
cpu_id_registers->ecx = tmp;
|
|
||||||
#else
|
|
||||||
__asm {
|
|
||||||
mov eax, [input_eax]
|
|
||||||
mov edi, [cpu_id_registers]
|
|
||||||
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
mov [edi + 0], eax
|
|
||||||
mov [edi + 4], ebx
|
|
||||||
mov [edi + 8], edx
|
|
||||||
mov [edi + 12], ecx
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifdef _WIN64
|
|
||||||
__cpuid((int*)cpu_id_registers, input_eax);
|
|
||||||
#else
|
|
||||||
__asm {
|
|
||||||
mov eax, [input_eax]
|
|
||||||
mov edi, [cpu_id_registers]
|
|
||||||
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
mov [edi + 0], eax
|
|
||||||
mov [edi + 4], ebx
|
|
||||||
mov [edi + 8], ecx
|
|
||||||
mov [edi + 12], edx
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
state = true;
|
|
||||||
}
|
|
||||||
__except (1) {
|
|
||||||
state = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_cpu_id(CPU_ID *cpu_id) {
|
|
||||||
printf("CPUID\n");
|
|
||||||
printf(" vendor = %s\n", cpu_id->cpu_vendor);
|
|
||||||
printf(" brand string %s\n", cpu_id->cpu_brand_string);
|
|
||||||
printf(" maximum_cpu_id_input = %u\n", cpu_id->maximum_cpu_id_input);
|
|
||||||
printf(" maximum extended information = 0x%X\n", cpu_id->cpu_id_registers_0x80000000.eax);
|
|
||||||
|
|
||||||
printf(" MMX = %u\n", cpu_id->mmx);
|
|
||||||
printf(" SSE = %u\n", cpu_id->sse);
|
|
||||||
printf(" SSE2 = %u\n", cpu_id->sse2);
|
|
||||||
printf(" SSE3 = %u\n", cpu_id->sse3);
|
|
||||||
|
|
||||||
printf(" EST = %u\n", cpu_id->est);
|
|
||||||
|
|
||||||
if (cpu_id->maximum_cpu_id_input >= 1) {
|
|
||||||
printf(" version_information\n");
|
|
||||||
printf(" stepping_id %u\n", cpu_id->stepping_id);
|
|
||||||
printf(" model %u\n", cpu_id->model);
|
|
||||||
printf(" family %u\n", cpu_id->family);
|
|
||||||
printf(" processor_type %u\n", cpu_id->processor_type);
|
|
||||||
printf(" extended_model_id %u\n", cpu_id->extended_model_id);
|
|
||||||
printf(" extended_family_id %u\n", cpu_id->extended_family_id);
|
|
||||||
|
|
||||||
printf(" brand_index %u\n", cpu_id->brand_index);
|
|
||||||
printf(" clflush %u\n", cpu_id->clflush);
|
|
||||||
printf(" maximum_logical_processors %u\n", cpu_id->maximum_logical_processors);
|
|
||||||
printf(" initial_apic_id %u\n", cpu_id->initial_apic_id);
|
|
||||||
|
|
||||||
// printf(" cache_line_size %u\n", cpu_id->cache_line_size); printf("
|
|
||||||
// log_base_2_cache_line_size %u\n", cpu_id->log_base_2_cache_line_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) {
|
|
||||||
printf(" l1_data_cache_line_size %d\n", cpu_id->l1_data_cache_line_size);
|
|
||||||
printf(" l1_data_associativity %d\n", cpu_id->l1_data_associativity);
|
|
||||||
printf(" l1_data_cache_size %dK\n", cpu_id->l1_data_cache_size);
|
|
||||||
|
|
||||||
printf(" l1_code_cache_line_size %d\n", cpu_id->l1_code_cache_line_size);
|
|
||||||
printf(" l1_code_associativity %d\n", cpu_id->l1_code_associativity);
|
|
||||||
printf(" l1_code_cache_size %dK\n", cpu_id->l1_code_cache_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) {
|
|
||||||
printf(" l2_cache_line_size %d\n", cpu_id->l2_cache_line_size);
|
|
||||||
printf(" l2_associativity %d\n", cpu_id->l2_associativity);
|
|
||||||
printf(" l2_cache_size %dK\n", cpu_id->l2_cache_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int initialize_cpu_id(CPU_ID *cpu_id) {
|
|
||||||
int debug = false;
|
|
||||||
memset(cpu_id, 0, sizeof(CPU_ID));
|
|
||||||
|
|
||||||
if (cpuid(0, &cpu_id->cpu_id_registers_0)) {
|
|
||||||
if (cpu_id->maximum_cpu_id_input >= 1) {
|
|
||||||
cpuid(1, &cpu_id->cpu_id_registers_1);
|
|
||||||
}
|
|
||||||
if (cpu_id->maximum_cpu_id_input >= 2) {
|
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
cpuid(2, &cpu_id->cpu_id_registers_2);
|
|
||||||
if (debug) {
|
|
||||||
printf(" al = %u\n", cpu_id->cpu_id_registers_2.al);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index = 1; index < cpu_id->cpu_id_registers_2.al && index < MAXIMUM_2; index++) {
|
|
||||||
cpuid(2, &cpu_id->cpu_id_registers_2_array [index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index = 1; index < MAXIMUM_CHARACTERS; index++) {
|
|
||||||
if (cpu_id->character_array_2 [index]) {
|
|
||||||
if (debug) {
|
|
||||||
printf(" cache/TLB byte = %X\n", cpu_id->character_array_2 [index]);
|
|
||||||
}
|
|
||||||
switch (cpu_id->character_array_2 [index]) {
|
|
||||||
case 0x0A:
|
|
||||||
case 0x0C:
|
|
||||||
cpu_id->cache_line_size = 32;
|
|
||||||
cpu_id->log_base_2_cache_line_size = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x2C:
|
|
||||||
case 0x60:
|
|
||||||
case 0x66:
|
|
||||||
case 0x67:
|
|
||||||
case 0x68:
|
|
||||||
cpu_id->cache_line_size = 64;
|
|
||||||
cpu_id->log_base_2_cache_line_size = 6;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cpuid(0x80000000, &cpu_id->cpu_id_registers_0x80000000);
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000001) {
|
|
||||||
cpuid(0x80000001, &cpu_id->cpu_id_registers_0x80000001);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000004) {
|
|
||||||
cpuid(0x80000002, &cpu_id->cpu_id_registers_0x80000002);
|
|
||||||
cpuid(0x80000003, &cpu_id->cpu_id_registers_0x80000003);
|
|
||||||
cpuid(0x80000004, &cpu_id->cpu_id_registers_0x80000004);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) {
|
|
||||||
cpuid(0x80000005, &cpu_id->cpu_id_registers_0x80000005);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) {
|
|
||||||
cpuid(0x80000006, &cpu_id->cpu_id_registers_0x80000006);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000008) {
|
|
||||||
cpuid(0x80000008, &cpu_id->cpu_id_registers_0x80000008);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) {
|
int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) {
|
||||||
int update;
|
int update;
|
||||||
|
|
||||||
@ -776,9 +336,6 @@ lookup_cpu_data() {
|
|||||||
// set callback for memory function
|
// set callback for memory function
|
||||||
_display_information->_get_memory_information_function = get_memory_information;
|
_display_information->_get_memory_information_function = get_memory_information;
|
||||||
|
|
||||||
// set callback for cpu time function
|
|
||||||
_display_information->_cpu_time_function = cpu_time_function;
|
|
||||||
|
|
||||||
// determine CPU frequency
|
// determine CPU frequency
|
||||||
uint64_t time;
|
uint64_t time;
|
||||||
uint64_t end_time;
|
uint64_t end_time;
|
||||||
@ -803,12 +360,12 @@ lookup_cpu_data() {
|
|||||||
if (QueryPerformanceFrequency(&frequency)) {
|
if (QueryPerformanceFrequency(&frequency)) {
|
||||||
if (frequency.QuadPart > 0) {
|
if (frequency.QuadPart > 0) {
|
||||||
if (QueryPerformanceCounter (&counter)) {
|
if (QueryPerformanceCounter (&counter)) {
|
||||||
time = cpu_time_function();
|
time = __rdtsc();
|
||||||
end.QuadPart = counter.QuadPart + frequency.QuadPart;
|
end.QuadPart = counter.QuadPart + frequency.QuadPart;
|
||||||
while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
|
while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
|
||||||
|
|
||||||
}
|
}
|
||||||
end_time = cpu_time_function();
|
end_time = __rdtsc();
|
||||||
|
|
||||||
_display_information->_cpu_frequency = end_time - time;
|
_display_information->_cpu_frequency = end_time - time;
|
||||||
}
|
}
|
||||||
@ -821,54 +378,6 @@ lookup_cpu_data() {
|
|||||||
sprintf(string, "CPU frequency: %I64d\n", _display_information->_cpu_frequency);
|
sprintf(string, "CPU frequency: %I64d\n", _display_information->_cpu_frequency);
|
||||||
windisplay_cat.info() << string;
|
windisplay_cat.info() << string;
|
||||||
|
|
||||||
|
|
||||||
// CPUID
|
|
||||||
CPU_ID cpu_id;
|
|
||||||
|
|
||||||
windisplay_cat.info() << "start CPU ID\n";
|
|
||||||
|
|
||||||
if (initialize_cpu_id(&cpu_id)) {
|
|
||||||
CPU_ID_BINARY_DATA *cpu_id_binary_data;
|
|
||||||
|
|
||||||
cpu_id_binary_data = new (CPU_ID_BINARY_DATA);
|
|
||||||
if (cpu_id_binary_data) {
|
|
||||||
cpu_id_to_cpu_id_binary_data(&cpu_id, cpu_id_binary_data);
|
|
||||||
_display_information->_cpu_id_size = sizeof(CPU_ID_BINARY_DATA) / sizeof(unsigned int);
|
|
||||||
_display_information->_cpu_id_data = (unsigned int *) cpu_id_binary_data;
|
|
||||||
|
|
||||||
_display_information->_cpu_vendor_string = strdup(cpu_id.cpu_vendor);
|
|
||||||
_display_information->_cpu_brand_string = strdup(cpu_id.cpu_brand_string);
|
|
||||||
_display_information->_cpu_version_information = cpu_id.version_information;
|
|
||||||
_display_information->_cpu_brand_index = cpu_id.brand_index;
|
|
||||||
|
|
||||||
if (windisplay_cat.is_debug()) {
|
|
||||||
windisplay_cat.debug()
|
|
||||||
<< hex << _display_information->_cpu_id_version << dec << "|";
|
|
||||||
|
|
||||||
int index;
|
|
||||||
for (index = 0; index < _display_information->_cpu_id_size; ++index) {
|
|
||||||
unsigned int data;
|
|
||||||
data = _display_information->_cpu_id_data[index];
|
|
||||||
|
|
||||||
windisplay_cat.debug(false)
|
|
||||||
<< hex << data << dec;
|
|
||||||
if (index < _display_information->_cpu_id_size - 1) {
|
|
||||||
windisplay_cat.debug(false)
|
|
||||||
<< "|";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
windisplay_cat.debug(false)
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (windisplay_cat.is_debug()) {
|
|
||||||
parse_cpu_id(&cpu_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
windisplay_cat.info() << "end CPU ID\n";
|
|
||||||
|
|
||||||
// Number of CPU's
|
// Number of CPU's
|
||||||
count_number_of_cpus(_display_information);
|
count_number_of_cpus(_display_information);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user