add debug option to check the written values

This commit is contained in:
erpalma
2018-08-13 15:44:18 -07:00
parent a463f753ee
commit ed06353021
2 changed files with 60 additions and 15 deletions

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse
import configparser import configparser
import dbus import dbus
import glob import glob
@@ -22,7 +23,6 @@ except ImportError:
import gobject as GObject import gobject as GObject
SYSFS_POWER_PATH = '/sys/class/power_supply/AC/online' SYSFS_POWER_PATH = '/sys/class/power_supply/AC/online'
CONFIG_PATH = '/etc/lenovo_fix.conf'
VOLTAGE_PLANES = { VOLTAGE_PLANES = {
'CORE': 0, 'CORE': 0,
@@ -110,7 +110,13 @@ def calc_time_window_vars(t):
def undervolt(config): def undervolt(config):
for plane in VOLTAGE_PLANES: for plane in VOLTAGE_PLANES:
writemsr(0x150, calc_undervolt_msr(plane, config.getfloat('UNDERVOLT', plane))) write_value = calc_undervolt_msr(plane, config.getfloat('UNDERVOLT', plane))
writemsr(0x150, write_value)
if args.debug:
write_value &= 0xFFFFFFFF
writemsr(0x150, 0x8000001000000000 | (VOLTAGE_PLANES[plane] << 40))
read_value = readmsr(0x150, flatten=True)
print('[D] Undervolt plane {:s} - write {:#x} - read {:#x}'.format(plane, write_value, read_value))
def calc_undervolt_msr(plane, offset): def calc_undervolt_msr(plane, offset):
@@ -123,7 +129,7 @@ def calc_undervolt_msr(plane, offset):
def load_config(): def load_config():
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(CONFIG_PATH) config.read(args.config)
# config values sanity check # config values sanity check
for power_source in ('AC', 'BATTERY'): for power_source in ('AC', 'BATTERY'):
@@ -196,10 +202,13 @@ def calc_reg_values(config):
def set_hwp(pref): def set_hwp(pref):
# set HWP energy performance hints # set HWP energy performance hints
assert pref in ('performance', 'balance_performance', 'default', 'balance_power', 'power') assert pref in ('performance', 'balance_performance', 'default', 'balance_power', 'power')
n = glob.glob('/sys/devices/system/cpu/cpu[0-9]*/cpufreq/energy_performance_preference') CPUs = ['/sys/devices/system/cpu/{:d}/cpufreq/energy_performance_preference'.format(x) for x in range(cpu_count())]
for c in n: for i, c in enumerate(CPUs):
with open(c, 'wb') as f: with open(c, 'wb') as f:
f.write(pref.encode()) f.write(pref.encode())
if args.debug:
with open(c) as f:
print('[D] HWP for cpu{:d} - write {:s} - read {:s}'.format(i, pref, f.read()))
def power_thread(config, regs, exit_event): def power_thread(config, regs, exit_event):
@@ -216,17 +225,32 @@ def power_thread(config, regs, exit_event):
# set temperature trip point # set temperature trip point
if 'MSR_TEMPERATURE_TARGET' in regs[power['source']]: if 'MSR_TEMPERATURE_TARGET' in regs[power['source']]:
writemsr(0x1a2, regs[power['source']]['MSR_TEMPERATURE_TARGET']) write_value = regs[power['source']]['MSR_TEMPERATURE_TARGET']
writemsr(0x1a2, write_value)
if args.debug:
read_value = readmsr(0x1a2, 24, 29, flatten=True)
print('[D] TEMPERATURE_TARGET - write {:#x} - read {:#x}'.format(write_value >> 24, read_value))
# set cTDP # set cTDP
if 'MSR_CONFIG_TDP_CONTROL' in regs[power['source']]: if 'MSR_CONFIG_TDP_CONTROL' in regs[power['source']]:
writemsr(0x64b, regs[power['source']]['MSR_CONFIG_TDP_CONTROL']) write_value = regs[power['source']]['MSR_CONFIG_TDP_CONTROL']
writemsr(0x64b, write_value)
if args.debug:
read_value = readmsr(0x64b, 0, 1, flatten=True)
print('[D] CONFIG_TDP_CONTROL - write {:#x} - read {:#x}'.format(write_value, read_value))
# set PL1/2 on MSR # set PL1/2 on MSR
writemsr(0x610, regs[power['source']]['MSR_PKG_POWER_LIMIT']) write_value = regs[power['source']]['MSR_PKG_POWER_LIMIT']
writemsr(0x610, write_value)
if args.debug:
read_value = readmsr(0x610, 0, 55, flatten=True)
print('[D] MSR PACKAGE_POWER_LIMIT - write {:#x} - read {:#x}'.format(write_value, read_value))
# set MCHBAR register to the same PL1/2 values # set MCHBAR register to the same PL1/2 values
mchbar_mmio.write32(0, regs[power['source']]['MSR_PKG_POWER_LIMIT'] & 0xffffffff) mchbar_mmio.write32(0, write_value & 0xffffffff)
mchbar_mmio.write32(4, regs[power['source']]['MSR_PKG_POWER_LIMIT'] >> 32) mchbar_mmio.write32(4, write_value >> 32)
if args.debug:
read_value = mchbar_mmio.read32(0) | (mchbar_mmio.read32(4) << 32)
print('[D] MCHBAR PACKAGE_POWER_LIMIT - write {:#x} - read {:#x}'.format(write_value, read_value))
wait_t = config.getfloat(power['source'], 'Update_Rate_s') wait_t = config.getfloat(power['source'], 'Update_Rate_s')
enable_hwp_mode = config.getboolean('AC', 'HWP_Mode', fallback=False) enable_hwp_mode = config.getboolean('AC', 'HWP_Mode', fallback=False)
@@ -242,10 +266,17 @@ def power_thread(config, regs, exit_event):
def main(): def main():
global args
if os.geteuid() != 0: if os.geteuid() != 0:
print('[E] No root no party. Try again with sudo.') print('[E] No root no party. Try again with sudo.')
sys.exit(1) sys.exit(1)
parser = argparse.ArgumentParser()
parser.add_argument('--debug', action='store_true', help='add some debug info and additional checks')
parser.add_argument('--config', default='/etc/lenovo_fix.conf', help='override default config file path')
args = parser.parse_args()
power['source'] = 'BATTERY' if is_on_battery() else 'AC' power['source'] = 'BATTERY' if is_on_battery() else 'AC'
config = load_config() config = load_config()

24
mmio.py
View File

@@ -61,11 +61,7 @@ class MMIO(object):
try: try:
self.mapping = mmap.mmap( self.mapping = mmap.mmap(
fd, fd, self._aligned_size, flags=mmap.MAP_SHARED, prot=mmap.PROT_WRITE, offset=self._aligned_physaddr)
self._aligned_size,
flags=mmap.MAP_SHARED,
prot=mmap.PROT_WRITE,
offset=self._aligned_physaddr)
except OSError as e: except OSError as e:
raise MMIOError(e.errno, "Mapping /dev/mem: " + e.strerror) raise MMIOError(e.errno, "Mapping /dev/mem: " + e.strerror)
@@ -83,6 +79,24 @@ class MMIO(object):
if (offset + length) > self._aligned_size: if (offset + length) > self._aligned_size:
raise ValueError("Offset out of bounds.") raise ValueError("Offset out of bounds.")
def read32(self, offset):
"""Read 32-bits from the specified `offset` in bytes, relative to the
base physical address of the MMIO region.
Args:
offset (int, long): offset from base physical address, in bytes.
Returns:
int: 32-bit value read.
Raises:
TypeError: if `offset` type is invalid.
ValueError: if `offset` is out of bounds.
"""
if not isinstance(offset, (int, long)):
raise TypeError("Invalid offset type, should be integer.")
offset = self._adjust_offset(offset)
self._validate_offset(offset, 4)
return struct.unpack("=L", self.mapping[offset:offset + 4])[0]
def write32(self, offset, value): def write32(self, offset, value):
"""Write 32-bits to the specified `offset` in bytes, relative to the """Write 32-bits to the specified `offset` in bytes, relative to the
base physical address of the MMIO region. base physical address of the MMIO region.