diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 44acdf3..350a4e7 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -619,7 +619,7 @@ static int perfmsr_measure(struct msr_driver_t* handle, int msr) return (int) ((y - x) / (b - a)); } -static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, uint64_t *multiplier) +static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, double *multiplier) { int i, err; uint64_t CpuFid, CpuDid, CpuDidLSD; @@ -640,7 +640,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, uint64_ /* Constant values for common families */ const int magic_constant = (info->id->ext_family == 0x11) ? 0x8 : 0x10; - const int divisor = ((FUSION_C <= info->internal->code.amd) && (info->internal->code.amd <= FUSION_A)) ? 1 : 2; + const double divisor = ((FUSION_C <= info->internal->code.amd) && (info->internal->code.amd <= FUSION_A)) ? 1.0 : 2.0; /* Check if P-state is valid */ if (pstate < MSR_PSTATE_0 || MSR_PSTATE_7 < pstate) @@ -659,7 +659,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, uint64_ while (i < num_dids && divisor_t[i].did != CpuDid) i++; if (i < num_dids) - *multiplier = (uint64_t) ((CpuFid + 0x10) / divisor_t[i].divisor); + *multiplier = (double) ((CpuFid + magic_constant) / divisor_t[i].divisor); else err++; break; @@ -673,7 +673,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, uint64_ Note: This family contains only APUs */ err = cpu_rdmsr_range(info->handle, pstate, 8, 4, &CpuDid); err += cpu_rdmsr_range(info->handle, pstate, 3, 0, &CpuDidLSD); - *multiplier = (uint64_t) (((info->cpu_clock + 5) / 100 + 0x10) / (CpuDid + CpuDidLSD * 0.25 + 1)); + *multiplier = (double) (((info->cpu_clock + 5) / 100 + magic_constant) / (CpuDid + CpuDidLSD * 0.25 + 1)); break; case 0x10: /* BKDG 10h, page 429 @@ -701,7 +701,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, uint64_ Note: This family contains only APUs */ err = cpu_rdmsr_range(info->handle, pstate, 8, 6, &CpuDid); err += cpu_rdmsr_range(info->handle, pstate, 5, 0, &CpuFid); - *multiplier = (uint64_t) ((CpuFid + magic_constant) / (1ull << CpuDid)) / divisor; + *multiplier = (double) ((CpuFid + magic_constant) / (1ull << CpuDid)) / divisor; break; case 0x17: /* PPR 17h, pages 30 and 138-139 @@ -710,7 +710,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, uint64_ CoreCOF is (Core::X86::Msr::PStateDef[CpuFid[7:0]] / Core::X86::Msr::PStateDef[CpuDfsId]) * 200 */ err = cpu_rdmsr_range(info->handle, pstate, 13, 8, &CpuDid); err += cpu_rdmsr_range(info->handle, pstate, 7, 0, &CpuFid); - *multiplier = (uint64_t) (CpuFid / CpuDid) * 2; + *multiplier = (double) (CpuFid / CpuDid) * 2; break; default: err = 1; @@ -743,6 +743,7 @@ static uint32_t get_amd_last_pstate_addr(struct msr_info_t *info) static double get_info_min_multiplier(struct msr_info_t *info) { int err; + double mult; uint32_t addr; uint64_t reg; @@ -765,8 +766,8 @@ static double get_info_min_multiplier(struct msr_info_t *info) /* N.B.: Find the last P-state get_amd_last_pstate_addr() returns the last P-state, MSR_PSTATE_0 <= addr <= MSR_PSTATE_7 */ addr = get_amd_last_pstate_addr(info); - err = get_amd_multipliers(info, addr, ®); - if (!err) return (double) reg; + err = get_amd_multipliers(info, addr, &mult); + if (!err) return mult; } return (double) CPU_INVALID_VALUE / 100; @@ -775,6 +776,7 @@ static double get_info_min_multiplier(struct msr_info_t *info) static double get_info_cur_multiplier(struct msr_info_t *info) { int err; + double mult; uint64_t reg; if(info->id->vendor == VENDOR_INTEL && info->internal->code.intel == PENTIUM) { @@ -793,8 +795,8 @@ static double get_info_cur_multiplier(struct msr_info_t *info) /* Refer links above MSRC001_0063[2:0] is CurPstate */ err = cpu_rdmsr_range(info->handle, MSR_PSTATE_S, 2, 0, ®); - err += get_amd_multipliers(info, MSR_PSTATE_0 + (uint32_t) reg, ®); - if (!err) return (double) reg; + err += get_amd_multipliers(info, MSR_PSTATE_0 + (uint32_t) reg, &mult); + if (!err) return mult; } return (double) CPU_INVALID_VALUE / 100; @@ -803,6 +805,7 @@ static double get_info_cur_multiplier(struct msr_info_t *info) static double get_info_max_multiplier(struct msr_info_t *info) { int err; + double mult; uint64_t reg; if(info->id->vendor == VENDOR_INTEL && info->internal->code.intel == PENTIUM) { @@ -832,8 +835,8 @@ static double get_info_max_multiplier(struct msr_info_t *info) /* Refer links above MSRC001_0064 is Pb0 Pb0 is the highest-performance boosted P-state */ - err = get_amd_multipliers(info, MSR_PSTATE_0, ®); - if (!err) return (double) reg; + err = get_amd_multipliers(info, MSR_PSTATE_0, &mult); + if (!err) return mult; } return (double) CPU_INVALID_VALUE / 100; @@ -902,6 +905,7 @@ static double get_info_voltage(struct msr_info_t *info) static double get_info_bus_clock(struct msr_info_t *info) { int err; + double mult; uint32_t addr; uint64_t reg; @@ -924,8 +928,8 @@ static double get_info_bus_clock(struct msr_info_t *info) PstateMaxVal is the the lowest-performance non-boosted P-state */ addr = get_amd_last_pstate_addr(info); err = cpu_rdmsr_range(info->handle, MSR_PSTATE_L, 6, 4, ®); - err += get_amd_multipliers(info, addr - reg, ®); - if (!err) return (double) info->cpu_clock / reg; + err += get_amd_multipliers(info, addr - reg, &mult); + if (!err) return (double) info->cpu_clock / mult; } return (double) CPU_INVALID_VALUE / 100;