Browse Source

moved config to /etc

erpalma 7 years ago
parent
commit
5d6cfaa572
4 changed files with 81 additions and 46 deletions
  1. 7 2
      Makefile
  2. 32 0
      etc/lenovo_fix.conf
  3. 42 44
      lenovo_fix.py
  4. 0 0
      systemd/lenovo_fix.service

+ 7 - 2
Makefile

@@ -2,6 +2,11 @@ all: install
 
 install:
 	install -d /usr/local/sbin/
-	install -m 700 lenovo_fix.py /usr/local/sbin/
 	install -d /etc/systemd/system/
-	install -m 644 lenovo_fix.service /etc/systemd/system/
+	install -m 700 lenovo_fix.py /usr/local/sbin/
+	install -m 644 systemd/lenovo_fix.service /etc/systemd/system/
+	@if test -f /etc/lenovo_fix.conf; then \
+    	echo "/etc/lenovo_fix.conf already exists; overwrite manually"; \
+	else \
+    	install -m 644 etc/lenovo_fix.conf /etc/; \
+    fi

+ 32 - 0
etc/lenovo_fix.conf

@@ -0,0 +1,32 @@
+[GENERAL]
+Enabled: True
+
+## Settings to apply while connected to Battery power
+[BATTERY]
+# Update the registers every this many seconds
+Update_Rate_s: 30
+# Max package power for time window #1
+PL1_Tdp_W: 29
+# Time window #1 duration
+PL1_Duration_s: 28
+# Max package power for time window #2
+PL2_Tdp_W: 44
+# Time window #2 duration
+PL2_Duration_S: 0.002
+# Max allowed temperature before throttling
+Trip_Temp_C: 85
+
+## Settings to apply while connected to AC power
+[AC]
+# Update the registers every this many seconds
+Update_Rate_s: 5
+# Max package power for time window #1
+PL1_Tdp_W: 44
+# Time window #1 duration
+PL1_Duration_s: 28
+# Max package power for time window #2
+PL2_Tdp_W: 44
+# Time window #2 duration
+PL2_Duration_S: 0.002
+# Max allowed temperature before throttling
+Trip_Temp_C: 97

+ 42 - 44
lenovo_fix.py

@@ -1,30 +1,16 @@
 #!/usr/bin/env python2
 
+import ConfigParser
 import glob
 import os
 import struct
 
+from collections import defaultdict
 from periphery import MMIO
 from time import sleep
 
-config = {
-    'AC': {
-        'UPDATE_RATE_SEC': 5,  # Update the registers every this many seconds
-        'PL1_TDP_W': 44,  # Max package power for time window #1
-        'PL1_DURATION_S': 28,  # Time window #1 duration
-        'PL2_TDP_W': 44,  # Max package power for time window #2
-        'PL2_DURATION_S': 0.002,  # Time window #2 duration
-        'TRIP_TEMP_C': 97  # Max allowed temperature before throttling
-    },
-    'BATTERY': {
-        'UPDATE_RATE_SEC': 30,  # Update the registers every this many seconds
-        'PL1_TDP_W': 29,  # Max package power for time window #1
-        'PL1_DURATION_S': 28,  # Time window #1 duration
-        'PL2_TDP_W': 44,  # Max package power for time window #2
-        'PL2_DURATION_S': 0.002,  # Time window #2 duration
-        'TRIP_TEMP_C': 85  # Max allowed temperature before throttling
-    },
-}
+SYSFS_POWER_PATH = '/sys/class/power_supply/AC/online'
+CONFIG_PATH = '/etc/lenovo_fix.conf'
 
 
 def writemsr(msr, val):
@@ -39,7 +25,7 @@ def writemsr(msr, val):
 
 
 def is_on_battery():
-    with open('/sys/class/power_supply/AC/online') as f:
+    with open(SYSFS_POWER_PATH) as f:
         return not bool(int(f.read()))
 
 
@@ -51,52 +37,64 @@ def calc_time_window_vars(t):
     raise Exception('Unable to find a good combination!')
 
 
-def check_config():
-    for k in config:
-        assert 0 < config[k]['UPDATE_RATE_SEC']
-        assert 0 < config[k]['PL1_TDP_W']
-        assert 0 < config[k]['PL2_TDP_W']
-        assert 0 < config[k]['PL1_DURATION_S']
-        assert 0 < config[k]['PL2_DURATION_S']
-        assert 40 < config[k]['TRIP_TEMP_C'] < 98
+def load_config():
+    config = ConfigParser.ConfigParser()
+    config.read(CONFIG_PATH)
 
+    for power_source in ('AC', 'BATTERY'):
+        assert 0 < config.getfloat(power_source, 'Update_Rate_s')
+        assert 0 < config.getfloat(power_source, 'PL1_Tdp_W')
+        assert 0 < config.getfloat(power_source, 'PL1_Duration_s')
+        assert 0 < config.getfloat(power_source, 'PL2_Tdp_W')
+        assert 0 < config.getfloat(power_source, 'PL2_Duration_S')
+        assert 40 < config.getfloat(power_source, 'Trip_Temp_C') < 98
 
-def calc_reg_values():
-    for k in config:
+    return config
+
+
+def calc_reg_values(config):
+    regs = defaultdict(dict)
+    for power_source in ('AC', 'BATTERY'):
         # the critical temperature for this CPU is 100 C
-        trip_offset = int(round(100 - config[k]['TRIP_TEMP_C']))
-        config[k]['MSR_TEMPERATURE_TARGET'] = trip_offset << 24
+        trip_offset = int(round(100 - config.getfloat(power_source, 'Trip_Temp_C')))
+        regs[power_source]['MSR_TEMPERATURE_TARGET'] = trip_offset << 24
 
         # 0.125 is the power unit of this CPU
-        PL1 = int(round(config[k]['PL1_TDP_W'] / 0.125))
-        Y, Z = calc_time_window_vars(config[k]['PL1_DURATION_S'])
+        PL1 = int(round(config.getfloat(power_source, 'PL1_Tdp_W') / 0.125))
+        Y, Z = calc_time_window_vars(config.getfloat(power_source, 'PL1_Duration_s'))
         TW1 = Y | (Z << 5)
 
-        PL2 = int(round(config[k]['PL2_TDP_W'] / 0.125))
-        Y, Z = calc_time_window_vars(config[k]['PL2_DURATION_S'])
+        PL2 = int(round(config.getfloat(power_source, 'PL2_Tdp_W') / 0.125))
+        Y, Z = calc_time_window_vars(config.getfloat(power_source, 'PL2_Duration_s'))
         TW2 = Y | (Z << 5)
 
-        config[k]['MSR_PKG_POWER_LIMIT'] = PL1 | (1 << 15) | (TW1 << 17) | (PL2 << 32) | (1 << 47) | (TW2 << 49)
+        regs[power_source]['MSR_PKG_POWER_LIMIT'] = PL1 | (1 << 15) | (TW1 << 17) | (PL2 << 32) | (1 << 47) | (
+            TW2 << 49)
+
+    return regs
 
 
 def main():
-    check_config()
-    calc_reg_values()
+    config = load_config()
+    regs = calc_reg_values(config)
+
+    if not config.getboolean('GENERAL', 'Enabled'):
+        return
 
     mchbar_mmio = MMIO(0xfed159a0, 8)
     while True:
-        cur_config = config['BATTERY' if is_on_battery() else 'AC']
+        power_source = 'BATTERY' if is_on_battery() else 'AC'
 
         # set temperature trip point
-        writemsr(0x1a2, cur_config['MSR_TEMPERATURE_TARGET'])
+        writemsr(0x1a2, regs[power_source]['MSR_TEMPERATURE_TARGET'])
 
         # set PL1/2 on MSR
-        writemsr(0x610, cur_config['MSR_PKG_POWER_LIMIT'])
+        writemsr(0x610, regs[power_source]['MSR_PKG_POWER_LIMIT'])
         # set MCHBAR register to the same PL1/2 values
-        mchbar_mmio.write32(0, cur_config['MSR_PKG_POWER_LIMIT'] & 0xffffffff)
-        mchbar_mmio.write32(4, cur_config['MSR_PKG_POWER_LIMIT'] >> 32)
+        mchbar_mmio.write32(0, regs[power_source]['MSR_PKG_POWER_LIMIT'] & 0xffffffff)
+        mchbar_mmio.write32(4, regs[power_source]['MSR_PKG_POWER_LIMIT'] >> 32)
 
-        sleep(cur_config['UPDATE_RATE_SEC'])
+        sleep(config.getfloat(power_source, 'Update_Rate_s'))
 
 
 if __name__ == '__main__':

+ 0 - 0
lenovo_fix.service → systemd/lenovo_fix.service