From b5e82df407bb0d3055955fc5c0efadd3763915fb Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 14:11:33 +0200 Subject: [PATCH 01/12] Add AMD support for INFO_VOLTAGE in cpu_msrinfo() --- libcpuid/rdmsr.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index ebc73a8..f7baa88 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -417,6 +417,8 @@ static int perfmsr_measure(struct msr_driver_t* handle, int msr) #define PLATFORM_INFO_MSR 206 #define PLATFORM_INFO_MSR_low 8 #define PLATFORM_INFO_MSR_high 15 +#define MSR_PSTATE_S 0xC0010063 +#define MSR_PSTATE_0 0xC0010064 static int get_bits_value(uint64_t val, int highbit, int lowbit) { @@ -534,6 +536,17 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) double ret = (double) val / (1 << 13); return (ret > 0) ? (int) (ret * 100) : CPU_INVALID_VALUE; } + else if(cpuid_get_vendor() == VENDOR_AMD) + { + /* http://support.amd.com/TechDocs/42301_15h_Mod_00h-0Fh_BKDG.pdf + MSRC001_0063[2:0] = CurPstate + MSRC001_00[6B:64][15:9] = CpuVid */ + uint64_t CurPstate = cpu_rdmsr_range(handle, MSR_PSTATE_S, 2, 0, &error_indx); + if(0 <= CurPstate && CurPstate <= 7) { // Support 8 P-states + uint64_t CpuVid = cpu_rdmsr_range(handle, MSR_PSTATE_0 + CurPstate, 15, 9, &error_indx); + return (int) (1.550 - 0.0125 * CpuVid) * 100; // 2.4.1.6.3 - Serial VID (SVI) Encodings + } + } return CPU_INVALID_VALUE; } case INFO_BCLK: From c9926ab6f7967afc3cfc00040520c2a0dd70ceb7 Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 14:59:55 +0200 Subject: [PATCH 02/12] Imrove cpu_rdmsr_range(), make header similar to cpu_rdmsr() --- libcpuid/cpuid_main.c | 1 + libcpuid/libcpuid.h | 1 + libcpuid/rdmsr.c | 55 ++++++++++++++++++------------------------- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/libcpuid/cpuid_main.c b/libcpuid/cpuid_main.c index 4681228..1472598 100644 --- a/libcpuid/cpuid_main.c +++ b/libcpuid/cpuid_main.c @@ -635,6 +635,7 @@ const char* cpuid_error(void) { ERR_INVMSR , "Invalid MSR"}, { ERR_INVCNB , "Invalid core number"}, { ERR_HANDLE_R , "Error on handle read"}, + { ERR_INVRANGE , "Invalid given range"}, }; unsigned i; for (i = 0; i < COUNT_OF(matchtable); i++) diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index 257b99e..37bb11c 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -396,6 +396,7 @@ typedef enum { ERR_INVMSR = -13, /*!< "Invalid MSR" */ ERR_INVCNB = -14, /*!< "Invalid core number" */ ERR_HANDLE_R = -15, /*!< "Error on handle read" */ + ERR_INVRANGE = -16, /*!< "Invalid given range" */ } cpu_error_t; /** diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index f7baa88..21aac36 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -431,43 +431,31 @@ static int get_bits_value(uint64_t val, int highbit, int lowbit) return (int) data; } -static uint64_t cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t reg, unsigned int highbit, - unsigned int lowbit, int* error_indx) +static int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, + uint8_t lowbit, uint64_t* result) { - uint64_t data; - int bits; - *error_indx =0; + const uint8_t bits = highbit - lowbit + 1; - if (cpu_rdmsr(handle, reg, &data)) { - *error_indx = 1; + if(highbit > 63 || lowbit > highbit) + return set_error(ERR_INVRANGE); + + if(cpu_rdmsr(handle, msr_index, result)) return set_error(ERR_HANDLE_R); - } - bits = highbit - lowbit + 1; - if (bits < 64) + if(bits < 64) { /* Show only part of register */ - data >>= lowbit; - data &= (1ULL << bits) - 1; + *result >>= lowbit; + *result &= (1ULL << bits) - 1; } - /* Make sure we get sign correct */ - if (data & (1ULL << (bits - 1))) - { - data &= ~(1ULL << (bits - 1)); -#pragma warning(disable: 4146) - data = -data; -#pragma warning(default: 4146) - } - - *error_indx = 0; - return (data); + return 0; } int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) { uint64_t r; - int err, error_indx, cur_clock; + int err, cur_clock; static int max_clock = 0, multiplier = 0; static double bclk = 0.0; uint64_t val; @@ -502,9 +490,11 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) if(cpuid_get_vendor() == VENDOR_INTEL) { if(!multiplier) - multiplier = (int) cpu_rdmsr_range(handle, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &error_indx); - if(multiplier > 0) + cpu_rdmsr_range(handle, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &val); + if(val > 0) { + multiplier = (int) val; return multiplier * 100; + } } err = cpu_rdmsr(handle, 0x198, &r); if (err) return CPU_INVALID_VALUE; @@ -515,10 +505,10 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) { // https://github.com/ajaiantilal/i7z/blob/5023138d7c35c4667c938b853e5ea89737334e92/helper_functions.c#L59 - val = cpu_rdmsr_range(handle, IA32_THERM_STATUS, 63, 0, &error_indx); + cpu_rdmsr_range(handle, IA32_THERM_STATUS, 63, 0, &val); digital_readout = get_bits_value(val, 23, 16); thermal_status = get_bits_value(val, 32, 31); - val = cpu_rdmsr_range(handle, IA32_TEMPERATURE_TARGET, 63, 0, &error_indx); + cpu_rdmsr_range(handle, IA32_TEMPERATURE_TARGET, 63, 0, &val); PROCHOT_temp = get_bits_value(val, 23, 16); // These bits are thermal status : 1 if supported, 0 else @@ -532,7 +522,7 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) { if(cpuid_get_vendor() == VENDOR_INTEL) { - uint64_t val = cpu_rdmsr_range(handle, MSR_PERF_STATUS, 47, 32, &error_indx); + cpu_rdmsr_range(handle, MSR_PERF_STATUS, 47, 32, &val); double ret = (double) val / (1 << 13); return (ret > 0) ? (int) (ret * 100) : CPU_INVALID_VALUE; } @@ -541,9 +531,10 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) /* http://support.amd.com/TechDocs/42301_15h_Mod_00h-0Fh_BKDG.pdf MSRC001_0063[2:0] = CurPstate MSRC001_00[6B:64][15:9] = CpuVid */ - uint64_t CurPstate = cpu_rdmsr_range(handle, MSR_PSTATE_S, 2, 0, &error_indx); - if(0 <= CurPstate && CurPstate <= 7) { // Support 8 P-states - uint64_t CpuVid = cpu_rdmsr_range(handle, MSR_PSTATE_0 + CurPstate, 15, 9, &error_indx); + uint64_t CpuVid; + cpu_rdmsr_range(handle, MSR_PSTATE_S, 2, 0, &val); + if(0 <= val && val <= 7) { // Support 8 P-states + cpu_rdmsr_range(handle, MSR_PSTATE_0 + val, 15, 9, &CpuVid); return (int) (1.550 - 0.0125 * CpuVid) * 100; // 2.4.1.6.3 - Serial VID (SVI) Encodings } } From 9ce0158b88cc7b9a21bcddeb0d0f4af58738a297 Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 16:32:40 +0200 Subject: [PATCH 03/12] Use get_bits_value() inside cpu_rdmsr_range() --- libcpuid/rdmsr.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 21aac36..9ddccd6 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -420,35 +420,30 @@ static int perfmsr_measure(struct msr_driver_t* handle, int msr) #define MSR_PSTATE_S 0xC0010063 #define MSR_PSTATE_0 0xC0010064 -static int get_bits_value(uint64_t val, int highbit, int lowbit) +static uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) { uint64_t data = val; - int bits = highbit - lowbit + 1; - if(bits < 64){ - data >>= lowbit; - data &= (1ULL<>= lowbit; + data &= (1ULL << bits) - 1; } - return (int) data; + + return data; } static int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, uint8_t lowbit, uint64_t* result) { - const uint8_t bits = highbit - lowbit + 1; - if(highbit > 63 || lowbit > highbit) return set_error(ERR_INVRANGE); if(cpu_rdmsr(handle, msr_index, result)) return set_error(ERR_HANDLE_R); - if(bits < 64) - { - /* Show only part of register */ - *result >>= lowbit; - *result &= (1ULL << bits) - 1; - } - + *result = get_bits_value(*result, highbit, lowbit); return 0; } From 1d5ac6f23f369c4c3be877265ed2a243528e2f39 Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 16:47:06 +0200 Subject: [PATCH 04/12] Set cpu_rdmsr_range() and get_bits_value() as public functions --- libcpuid/exports.def | 2 ++ libcpuid/libcpuid.h | 30 ++++++++++++++++++++++++++++++ libcpuid/libcpuid.sym | 2 ++ libcpuid/rdmsr.c | 28 ++++++++++++++-------------- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/libcpuid/exports.def b/libcpuid/exports.def index d05a010..8905d58 100644 --- a/libcpuid/exports.def +++ b/libcpuid/exports.def @@ -30,3 +30,5 @@ cpu_clock_by_ic @26 cpuid_get_total_cpus @27 cpu_msr_driver_open_core @28 cpuid_get_vendor @29 +cpu_rdmsr_range @30 +get_bits_value @31 diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index 37bb11c..ebff735 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -882,6 +882,36 @@ typedef enum { multiplied by 100. */ } cpu_msrinfo_request_t; +/** + * @brief Similar to \ref cpu_rdmsr, but extract a range of bits + * + * It is similar to use \ref cpu_rdmsr then \ref get_bits_value. + * + * @param handle - a handle to the MSR reader driver, as created by + * cpu_msr_driver_open + * @param msr_index - the numeric ID of the MSR you want to read + * @param highbit - the high bit in range, must be inferior to 64 + * @param lowbit - the low bit in range, must be equal or superior to 0 + * @param result - a pointer to a 64-bit integer, where the MSR value is stored + * + * @returns zero if successful, and some negative number on error. + * The error message can be obtained by calling \ref cpuid_error. + * @see cpu_error_t + */ +int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, + uint8_t lowbit, uint64_t* result); + +/** + * @brief Extract a range of bits from MSR value + * + * @param val - a 64-bit integer, where the MSR value is stored + * @param highbit - the high bit in range, must be inferior to 64 + * @param lowbit - the low bit in range, must be equal or superior to 0 + * + * @returns bits between highbit and lowbit + */ +uint64_t get_bits_value(uint64_t val, int highbit, int lowbit); + /** * @brief Reads extended CPU information from Model-Specific Registers. * @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open diff --git a/libcpuid/libcpuid.sym b/libcpuid/libcpuid.sym index f743c6e..30ff700 100644 --- a/libcpuid/libcpuid.sym +++ b/libcpuid/libcpuid.sym @@ -27,3 +27,5 @@ cpu_clock_by_ic cpuid_get_total_cpus cpu_msr_driver_open_core cpuid_get_vendor +cpu_rdmsr_range +get_bits_value diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 9ddccd6..f64ee0d 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -420,7 +420,20 @@ static int perfmsr_measure(struct msr_driver_t* handle, int msr) #define MSR_PSTATE_S 0xC0010063 #define MSR_PSTATE_0 0xC0010064 -static uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) +int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, + uint8_t lowbit, uint64_t* result) +{ + if(highbit > 63 || lowbit > highbit) + return set_error(ERR_INVRANGE); + + if(cpu_rdmsr(handle, msr_index, result)) + return set_error(ERR_HANDLE_R); + + *result = get_bits_value(*result, highbit, lowbit); + return 0; +} + +uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) { uint64_t data = val; const uint8_t bits = highbit - lowbit + 1; @@ -434,19 +447,6 @@ static uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) return data; } -static int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, - uint8_t lowbit, uint64_t* result) -{ - if(highbit > 63 || lowbit > highbit) - return set_error(ERR_INVRANGE); - - if(cpu_rdmsr(handle, msr_index, result)) - return set_error(ERR_HANDLE_R); - - *result = get_bits_value(*result, highbit, lowbit); - return 0; -} - int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) { uint64_t r; From 841c975e959ce219f4012bd0b544b6b7f2e9d10d Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 16:51:38 +0200 Subject: [PATCH 05/12] Make get_bits_value() more robust --- libcpuid/rdmsr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index f64ee0d..31e1bbc 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -438,7 +438,7 @@ uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) uint64_t data = val; const uint8_t bits = highbit - lowbit + 1; - if(bits < 64) { + if(bits < 64 && highbit < 64 && lowbit < highbit) { /* Show only part of register */ data >>= lowbit; data &= (1ULL << bits) - 1; From 6c70d53a185bfe289e459b1197a23cde21712a5b Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 17:18:59 +0200 Subject: [PATCH 06/12] Do some rearrangements in rdmsr.c file I need to do that to add support for FreeBSD --- libcpuid/rdmsr.c | 92 ++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 31e1bbc..ad3cc98 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -31,39 +31,7 @@ #include "libcpuid_util.h" #include "rdtsc.h" -#ifndef _WIN32 -# ifdef __APPLE__ -/* On Darwin, we still do not support RDMSR, so supply dummy struct - and functions */ -struct msr_driver_t { int dummy; }; -struct msr_driver_t* cpu_msr_driver_open(void) -{ - set_error(ERR_NOT_IMP); - return NULL; -} - -struct msr_driver_t* cpu_msr_driver_open_core(int core_num) -{ - set_error(ERR_NOT_IMP); - return NULL; -} - -int cpu_rdmsr(struct msr_driver_t* driver, int msr_index, uint64_t* result) -{ - return set_error(ERR_NOT_IMP); -} - -int cpu_msr_driver_close(struct msr_driver_t* driver) -{ - return set_error(ERR_NOT_IMP); -} - -#define MSRINFO_DEFINED -int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which) -{ - return set_error(ERR_NOT_IMP); -} -# else /* __APPLE__ */ +#if defined (__linux__) || defined (__gnu_linux__) /* Assuming linux with /dev/cpu/x/msr: */ #include #include @@ -105,6 +73,7 @@ struct msr_driver_t* cpu_msr_driver_open_core(int core_num) handle->fd = fd; return handle; } + int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result) { ssize_t ret; @@ -125,8 +94,10 @@ int cpu_msr_driver_close(struct msr_driver_t* drv) } return 0; } -# endif /* __APPLE__ */ -#else /* _WIN32 */ + +/* #endif defined (__linux__) || defined (__gnu_linux__) */ + +#elif defined (_WIN32) #include #include #include @@ -240,7 +211,6 @@ static BOOL wait_for_service_state(SC_HANDLE hService, DWORD dwDesiredState, SER return fOK; } - static int load_driver(struct msr_driver_t* drv) { LPTSTR lpszInfo = __TEXT("RDMSR Executor Driver"); @@ -348,7 +318,7 @@ clean_up: #define FILE_DEVICE_UNKNOWN 0x00000022 #define IOCTL_UNKNOWN_BASE FILE_DEVICE_UNKNOWN -#define IOCTL_PROCVIEW_RDMSR CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0803, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_PROCVIEW_RDMSR CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0803, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result) { @@ -384,7 +354,53 @@ int cpu_msr_driver_close(struct msr_driver_t* drv) return 0; } -#endif /* _WIN32 */ +/* endif defined (_WIN32) */ + +#else /* Unsupported OS */ +/* On others OS (lie Darwin), we still do not support RDMSR, so supply dummy struct + and functions */ +struct msr_driver_t { int dummy; }; +struct msr_driver_t* cpu_msr_driver_open(void) +{ + set_error(ERR_NOT_IMP); + return NULL; +} + +struct msr_driver_t* cpu_msr_driver_open_core(int core_num) +{ + set_error(ERR_NOT_IMP); + return NULL; +} + +int cpu_rdmsr(struct msr_driver_t* driver, int msr_index, uint64_t* result) +{ + return set_error(ERR_NOT_IMP); +} + +int cpu_msr_driver_close(struct msr_driver_t* driver) +{ + return set_error(ERR_NOT_IMP); +} + +#define MSRINFO_DEFINED +int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, + uint8_t lowbit, uint64_t* result) +{ + return set_error(ERR_NOT_IMP); +} + +uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) +{ + return set_error(ERR_NOT_IMP); +} + +int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which) +{ + return set_error(ERR_NOT_IMP); +} + +#endif /* Unsupported OS */ + static int rdmsr_supported(void) { From 5272d9f06089b8680bb9ab8b365d98c4646a8f7b Mon Sep 17 00:00:00 2001 From: X0rg Date: Wed, 18 May 2016 18:06:23 +0200 Subject: [PATCH 07/12] Add MSR support for FreeBSD Tested on GhostBSD (based on FreeBSD) It should work on DragonFlyBSD (the cpuctl driver has been ported from FreeBSD) The situation for OpenBSD and NetBSD is not clear ; not supported --- libcpuid/rdmsr.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index ad3cc98..c103293 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -97,6 +97,75 @@ int cpu_msr_driver_close(struct msr_driver_t* drv) /* #endif defined (__linux__) || defined (__gnu_linux__) */ +#elif defined (__FreeBSD__) || defined (__DragonFly__) +/* Assuming FreeBSD with /dev/cpuctlX */ +#include +#include +#include +#include +#include + +struct msr_driver_t { int fd; }; +static int rdmsr_supported(void); +struct msr_driver_t* cpu_msr_driver_open(void) +{ + return cpu_msr_driver_open_core(0); +} + +struct msr_driver_t* cpu_msr_driver_open_core(int core_num) +{ + char msr[32]; + struct msr_driver_t* handle; + if(core_num < 0 && cpuid_get_total_cpus() <= core_num) + { + set_error(ERR_INVCNB); + return NULL; + } + if (!rdmsr_supported()) { + set_error(ERR_NO_RDMSR); + return NULL; + } + sprintf(msr, "/dev/cpuctl%i", core_num); + int fd = open(msr, O_RDONLY); + if (fd < 0) { + if (errno == EIO) { + set_error(ERR_NO_RDMSR); + return NULL; + } + set_error(ERR_NO_DRIVER); + return NULL; + } + handle = (struct msr_driver_t*) malloc(sizeof(struct msr_driver_t)); + handle->fd = fd; + return handle; +} + +int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result) +{ + cpuctl_msr_args_t args; + args.msr = msr_index; + + if (!driver || driver->fd < 0) + return set_error(ERR_HANDLE); + + if(ioctl(driver->fd, CPUCTL_RDMSR, &args)) + return set_error(ERR_INVMSR); + + *result = args.data; + return 0; +} + +int cpu_msr_driver_close(struct msr_driver_t* drv) +{ + if (drv && drv->fd >= 0) { + close(drv->fd); + free(drv); + } + return 0; +} + +/* #endif defined (__FreeBSD__) || defined (__DragonFly__) */ + #elif defined (_WIN32) #include #include From aaa7e155a98ef482976f8d3433b44c95a398610d Mon Sep 17 00:00:00 2001 From: X0rg Date: Wed, 18 May 2016 18:13:35 +0200 Subject: [PATCH 08/12] Fix some warnings rdmsr.c:616:10: warning: comparison of 0 <= unsigned expression is always true [-Wtautological-compare] if(0 <= val && val <= 7) { // Support 8 P-states ~ ^ ~~~ rdmsr.c:572:8: warning: variable 'val' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] if(!multiplier) ^~~~~~~~~~~ rdmsr.c:574:8: note: uninitialized use occurs here if(val > 0) { ^~~ rdmsr.c:572:5: note: remove the 'if' if its condition is always true if(!multiplier) ^~~~~~~~~~~~~~~ rdmsr.c:541:14: note: initialize the variable 'val' to silence this warning uint64_t val; ^ = 0 2 warnings generated. --- libcpuid/rdmsr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index c103293..d6d6678 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -569,12 +569,12 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) { if(cpuid_get_vendor() == VENDOR_INTEL) { - if(!multiplier) + if(!multiplier) { cpu_rdmsr_range(handle, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &val); - if(val > 0) { multiplier = (int) val; - return multiplier * 100; } + if(multiplier > 0) + return multiplier * 100; } err = cpu_rdmsr(handle, 0x198, &r); if (err) return CPU_INVALID_VALUE; @@ -613,7 +613,7 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) MSRC001_00[6B:64][15:9] = CpuVid */ uint64_t CpuVid; cpu_rdmsr_range(handle, MSR_PSTATE_S, 2, 0, &val); - if(0 <= val && val <= 7) { // Support 8 P-states + if(val <= 7) { // Support 8 P-states cpu_rdmsr_range(handle, MSR_PSTATE_0 + val, 15, 9, &CpuVid); return (int) (1.550 - 0.0125 * CpuVid) * 100; // 2.4.1.6.3 - Serial VID (SVI) Encodings } From 801d4c982a60e71a828e79c787336c1e0e34fb9e Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 18:42:11 +0200 Subject: [PATCH 09/12] Fix checking of core_num in cpu_msr_driver_open_core() --- libcpuid/libcpuid.h | 4 ++-- libcpuid/rdmsr.c | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index ebff735..163e4b8 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -822,7 +822,7 @@ struct msr_driver_t* cpu_msr_driver_open(void); /** * @brief Similar to \ref cpu_msr_driver_open, but accept one parameter * - * This function works on Linux only + * This function works on certain operating system (GNU/Linux, FreeBSD) * * @param core_num specify the core number for MSR. * The first core number is 0. @@ -832,7 +832,7 @@ struct msr_driver_t* cpu_msr_driver_open(void); * The error message can be obtained by calling \ref cpuid_error. * @see cpu_error_t */ -struct msr_driver_t* cpu_msr_driver_open_core(int core_num); +struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num); /** * @brief Reads a Model-Specific Register (MSR) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index d6d6678..e663a25 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -46,12 +46,11 @@ struct msr_driver_t* cpu_msr_driver_open(void) return cpu_msr_driver_open_core(0); } -struct msr_driver_t* cpu_msr_driver_open_core(int core_num) +struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num) { char msr[32]; struct msr_driver_t* handle; - if(core_num < 0 && cpuid_get_total_cpus() <= core_num) - { + if (core_num >= cpuid_get_total_cpus()) { set_error(ERR_INVCNB); return NULL; } @@ -112,12 +111,11 @@ struct msr_driver_t* cpu_msr_driver_open(void) return cpu_msr_driver_open_core(0); } -struct msr_driver_t* cpu_msr_driver_open_core(int core_num) +struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num) { char msr[32]; struct msr_driver_t* handle; - if(core_num < 0 && cpuid_get_total_cpus() <= core_num) - { + if (core_num >= cpuid_get_total_cpus()) { set_error(ERR_INVCNB); return NULL; } From 85bac12db478bbfe4fa0a72765779bb7d1cc387c Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 20:46:47 +0200 Subject: [PATCH 10/12] Drop get_bits_value() --- libcpuid/exports.def | 1 - libcpuid/libcpuid.h | 13 ------------- libcpuid/libcpuid.sym | 1 - libcpuid/rdmsr.c | 30 ++++++++---------------------- 4 files changed, 8 insertions(+), 37 deletions(-) diff --git a/libcpuid/exports.def b/libcpuid/exports.def index 8905d58..72b78e8 100644 --- a/libcpuid/exports.def +++ b/libcpuid/exports.def @@ -31,4 +31,3 @@ cpuid_get_total_cpus @27 cpu_msr_driver_open_core @28 cpuid_get_vendor @29 cpu_rdmsr_range @30 -get_bits_value @31 diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index 163e4b8..67f822b 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -885,8 +885,6 @@ typedef enum { /** * @brief Similar to \ref cpu_rdmsr, but extract a range of bits * - * It is similar to use \ref cpu_rdmsr then \ref get_bits_value. - * * @param handle - a handle to the MSR reader driver, as created by * cpu_msr_driver_open * @param msr_index - the numeric ID of the MSR you want to read @@ -901,17 +899,6 @@ typedef enum { int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, uint8_t lowbit, uint64_t* result); -/** - * @brief Extract a range of bits from MSR value - * - * @param val - a 64-bit integer, where the MSR value is stored - * @param highbit - the high bit in range, must be inferior to 64 - * @param lowbit - the low bit in range, must be equal or superior to 0 - * - * @returns bits between highbit and lowbit - */ -uint64_t get_bits_value(uint64_t val, int highbit, int lowbit); - /** * @brief Reads extended CPU information from Model-Specific Registers. * @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open diff --git a/libcpuid/libcpuid.sym b/libcpuid/libcpuid.sym index 30ff700..d0c61e4 100644 --- a/libcpuid/libcpuid.sym +++ b/libcpuid/libcpuid.sym @@ -28,4 +28,3 @@ cpuid_get_total_cpus cpu_msr_driver_open_core cpuid_get_vendor cpu_rdmsr_range -get_bits_value diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index e663a25..8c2f322 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -456,11 +456,6 @@ int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t hig return set_error(ERR_NOT_IMP); } -uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) -{ - return set_error(ERR_NOT_IMP); -} - int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which) { return set_error(ERR_NOT_IMP); @@ -506,28 +501,21 @@ static int perfmsr_measure(struct msr_driver_t* handle, int msr) int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, uint8_t lowbit, uint64_t* result) { + const uint8_t bits = highbit - lowbit + 1; + if(highbit > 63 || lowbit > highbit) return set_error(ERR_INVRANGE); if(cpu_rdmsr(handle, msr_index, result)) return set_error(ERR_HANDLE_R); - *result = get_bits_value(*result, highbit, lowbit); - return 0; -} - -uint64_t get_bits_value(uint64_t val, int highbit, int lowbit) -{ - uint64_t data = val; - const uint8_t bits = highbit - lowbit + 1; - if(bits < 64 && highbit < 64 && lowbit < highbit) { /* Show only part of register */ - data >>= lowbit; - data &= (1ULL << bits) - 1; + *result >>= lowbit; + *result &= (1ULL << bits) - 1; } - return data; + return 0; } int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) @@ -583,11 +571,9 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which) { // https://github.com/ajaiantilal/i7z/blob/5023138d7c35c4667c938b853e5ea89737334e92/helper_functions.c#L59 - cpu_rdmsr_range(handle, IA32_THERM_STATUS, 63, 0, &val); - digital_readout = get_bits_value(val, 23, 16); - thermal_status = get_bits_value(val, 32, 31); - cpu_rdmsr_range(handle, IA32_TEMPERATURE_TARGET, 63, 0, &val); - PROCHOT_temp = get_bits_value(val, 23, 16); + cpu_rdmsr_range(handle, IA32_THERM_STATUS, 23, 16, &digital_readout); + cpu_rdmsr_range(handle, IA32_THERM_STATUS, 32, 31, &thermal_status); + cpu_rdmsr_range(handle, IA32_TEMPERATURE_TARGET, 23, 16, &PROCHOT_temp); // These bits are thermal status : 1 if supported, 0 else if(thermal_status) From c2c32a1a709f8d628ebe0b1282cd4dd5e4421f22 Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 20:51:13 +0200 Subject: [PATCH 11/12] Remove unnecessary tests in cpu_rdmsr_range() --- libcpuid/rdmsr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 8c2f322..26375b1 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -509,7 +509,7 @@ int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t hig if(cpu_rdmsr(handle, msr_index, result)) return set_error(ERR_HANDLE_R); - if(bits < 64 && highbit < 64 && lowbit < highbit) { + if(bits < 64) { /* Show only part of register */ *result >>= lowbit; *result &= (1ULL << bits) - 1; From b067c6807348e3cf054dfb854501f5fb7deb05c2 Mon Sep 17 00:00:00 2001 From: Xorg Date: Thu, 19 May 2016 08:46:19 +0200 Subject: [PATCH 12/12] Use unsigned type instead of uint8_t as parameter for cpu_msr_driver_open_core() --- libcpuid/libcpuid.h | 2 +- libcpuid/rdmsr.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index 67f822b..988c793 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -832,7 +832,7 @@ struct msr_driver_t* cpu_msr_driver_open(void); * The error message can be obtained by calling \ref cpuid_error. * @see cpu_error_t */ -struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num); +struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num); /** * @brief Reads a Model-Specific Register (MSR) diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 26375b1..8537a53 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -46,7 +46,7 @@ struct msr_driver_t* cpu_msr_driver_open(void) return cpu_msr_driver_open_core(0); } -struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num) +struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num) { char msr[32]; struct msr_driver_t* handle; @@ -58,7 +58,7 @@ struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num) set_error(ERR_NO_RDMSR); return NULL; } - sprintf(msr, "/dev/cpu/%i/msr", core_num); + sprintf(msr, "/dev/cpu/%u/msr", core_num); int fd = open(msr, O_RDONLY); if (fd < 0) { if (errno == EIO) { @@ -111,7 +111,7 @@ struct msr_driver_t* cpu_msr_driver_open(void) return cpu_msr_driver_open_core(0); } -struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num) +struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num) { char msr[32]; struct msr_driver_t* handle; @@ -123,7 +123,7 @@ struct msr_driver_t* cpu_msr_driver_open_core(uint8_t core_num) set_error(ERR_NO_RDMSR); return NULL; } - sprintf(msr, "/dev/cpuctl%i", core_num); + sprintf(msr, "/dev/cpuctl%u", core_num); int fd = open(msr, O_RDONLY); if (fd < 0) { if (errno == EIO) { @@ -220,7 +220,7 @@ struct msr_driver_t* cpu_msr_driver_open(void) return drv; } -struct msr_driver_t* cpu_msr_driver_open_core(int core_num) +struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num) { warnf("cpu_msr_driver_open_core(): parameter ignored (function is the same as cpu_msr_driver_open)\n"); return cpu_msr_driver_open(); @@ -433,7 +433,7 @@ struct msr_driver_t* cpu_msr_driver_open(void) return NULL; } -struct msr_driver_t* cpu_msr_driver_open_core(int core_num) +struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num) { set_error(ERR_NOT_IMP); return NULL;