read msr from a single cpu unless otherwise needed
This commit is contained in:
@@ -61,7 +61,8 @@ def writemsr(msr, val):
|
|||||||
|
|
||||||
|
|
||||||
# returns the value between from_bit and to_bit as unsigned long
|
# returns the value between from_bit and to_bit as unsigned long
|
||||||
def readmsr(msr, from_bit=0, to_bit=63):
|
def readmsr(msr, from_bit=0, to_bit=63, cpu=None, flatten=False):
|
||||||
|
assert cpu is None or cpu in range(cpu_count())
|
||||||
if from_bit > to_bit:
|
if from_bit > to_bit:
|
||||||
print('[E] Wrong readmsr bit params')
|
print('[E] Wrong readmsr bit params')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -73,13 +74,17 @@ def readmsr(msr, from_bit=0, to_bit=63):
|
|||||||
print('[E] Unable to load the msr module.')
|
print('[E] Unable to load the msr module.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
try:
|
try:
|
||||||
|
output = []
|
||||||
for addr in msr_list:
|
for addr in msr_list:
|
||||||
f = os.open(addr, os.O_RDONLY)
|
f = os.open(addr, os.O_RDONLY)
|
||||||
os.lseek(f, msr, os.SEEK_SET)
|
os.lseek(f, msr, os.SEEK_SET)
|
||||||
val = struct.unpack('Q', os.read(f, 8))[0]
|
val = struct.unpack('Q', os.read(f, 8))[0]
|
||||||
os.close(f)
|
os.close(f)
|
||||||
mask = sum(2**x for x in range(from_bit, to_bit + 1))
|
mask = sum(2**x for x in range(from_bit, to_bit + 1))
|
||||||
return (val & mask) >> from_bit
|
output.append((val & mask) >> from_bit)
|
||||||
|
if flatten:
|
||||||
|
return output[0] if len(set(output)) == 1 else output
|
||||||
|
return output[cpu] if cpu is not None else output
|
||||||
except (IOError, OSError) as e:
|
except (IOError, OSError) as e:
|
||||||
if e.errno == EPERM or e.errno == EACCES:
|
if e.errno == EPERM or e.errno == EACCES:
|
||||||
print('[E] Unable to read from MSR. Try to disable Secure Boot.')
|
print('[E] Unable to read from MSR. Try to disable Secure Boot.')
|
||||||
@@ -95,7 +100,7 @@ def is_on_battery():
|
|||||||
|
|
||||||
def calc_time_window_vars(t):
|
def calc_time_window_vars(t):
|
||||||
# 0.000977 is the time unit of my CPU
|
# 0.000977 is the time unit of my CPU
|
||||||
time_unit = 1.0 / 2**readmsr(0x606, 16, 19)
|
time_unit = 1.0 / 2**readmsr(0x606, 16, 19, cpu=0)
|
||||||
for Y in range(2**5):
|
for Y in range(2**5):
|
||||||
for Z in range(2**2):
|
for Z in range(2**2):
|
||||||
if t <= (2**Y) * (1. + Z / 4.) * time_unit:
|
if t <= (2**Y) * (1. + Z / 4.) * time_unit:
|
||||||
@@ -152,11 +157,11 @@ def load_config():
|
|||||||
def calc_reg_values(config):
|
def calc_reg_values(config):
|
||||||
regs = defaultdict(dict)
|
regs = defaultdict(dict)
|
||||||
for power_source in ('AC', 'BATTERY'):
|
for power_source in ('AC', 'BATTERY'):
|
||||||
if readmsr(0xce, 30, 30) != 1:
|
if readmsr(0xce, 30, 30, cpu=0) != 1:
|
||||||
print("[W] Setting temperature target is not supported by this CPU")
|
print("[W] Setting temperature target is not supported by this CPU")
|
||||||
else:
|
else:
|
||||||
# the critical temperature for my CPU is 100 'C
|
# the critical temperature for my CPU is 100 'C
|
||||||
critical_temp = readmsr(0x1a2, 16, 23)
|
critical_temp = readmsr(0x1a2, 16, 23, cpu=0)
|
||||||
# update the allowed temp range to keep at least 3 'C from the CPU critical temperature
|
# update the allowed temp range to keep at least 3 'C from the CPU critical temperature
|
||||||
global TRIP_TEMP_RANGE
|
global TRIP_TEMP_RANGE
|
||||||
TRIP_TEMP_RANGE[1] = min(TRIP_TEMP_RANGE[1], critical_temp - 3)
|
TRIP_TEMP_RANGE[1] = min(TRIP_TEMP_RANGE[1], critical_temp - 3)
|
||||||
@@ -165,7 +170,7 @@ def calc_reg_values(config):
|
|||||||
regs[power_source]['MSR_TEMPERATURE_TARGET'] = trip_offset << 24
|
regs[power_source]['MSR_TEMPERATURE_TARGET'] = trip_offset << 24
|
||||||
|
|
||||||
# 0.125 is the power unit of my CPU
|
# 0.125 is the power unit of my CPU
|
||||||
power_unit = 1.0 / 2**readmsr(0x606, 0, 3)
|
power_unit = 1.0 / 2**readmsr(0x606, 0, 3, cpu=0)
|
||||||
PL1 = int(round(config.getfloat(power_source, 'PL1_Tdp_W') / power_unit))
|
PL1 = int(round(config.getfloat(power_source, 'PL1_Tdp_W') / power_unit))
|
||||||
Y, Z = calc_time_window_vars(config.getfloat(power_source, 'PL1_Duration_s'))
|
Y, Z = calc_time_window_vars(config.getfloat(power_source, 'PL1_Duration_s'))
|
||||||
TW1 = Y | (Z << 5)
|
TW1 = Y | (Z << 5)
|
||||||
@@ -180,7 +185,7 @@ def calc_reg_values(config):
|
|||||||
# cTDP
|
# cTDP
|
||||||
c_tdp_target_value = config.getint(power_source, 'cTDP', fallback=None)
|
c_tdp_target_value = config.getint(power_source, 'cTDP', fallback=None)
|
||||||
if c_tdp_target_value is not None:
|
if c_tdp_target_value is not None:
|
||||||
if readmsr(0xce, 33, 34) < 2:
|
if readmsr(0xce, 33, 34, cpu=0) < 2:
|
||||||
print("[W] cTDP setting not supported by this CPU")
|
print("[W] cTDP setting not supported by this CPU")
|
||||||
else:
|
else:
|
||||||
valid_c_tdp_target_value = min(C_TDP_RANGE[1], max(C_TDP_RANGE[0], c_tdp_target_value))
|
valid_c_tdp_target_value = min(C_TDP_RANGE[1], max(C_TDP_RANGE[0], c_tdp_target_value))
|
||||||
|
|||||||
Reference in New Issue
Block a user