mirror of
https://github.com/anrieff/libcpuid
synced 2024-11-10 22:59:13 +00:00
RDMSR: use double instead of uint64_t for AMD CPU multipliers
Multipliers can be a decimal number, like 7.5x
This commit is contained in:
parent
84f95c8ad0
commit
5a02be091a
1 changed files with 18 additions and 14 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue