From 1d5ac6f23f369c4c3be877265ed2a243528e2f39 Mon Sep 17 00:00:00 2001 From: Xorg Date: Wed, 18 May 2016 16:47:06 +0200 Subject: [PATCH] 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;