-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathundervolt.py
executable file
·163 lines (137 loc) · 4.13 KB
/
undervolt.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/python
# Got most of my info here: https://github.com/mihic/linux-intel-undervolt
# and here:
# http://forum.notebookreview.com/threads/undervolting-e-g-skylake-in-linux.807953/
# uses msr-tools which can be found here: https://01.org/msr-tools
import argparse
import glob
import os
import struct
import sys
def writemsr(msr, val):
n = glob.glob('/dev/cpu/[0-9]*/msr')
for c in n:
f = os.open(c, os.O_WRONLY)
os.lseek(f, msr, os.SEEK_SET)
os.write(f, struct.pack('Q', val))
os.close(f)
if not n:
raise OSError("msr module not loaded (run modprobe msr)")
def readmsr(msr, cpu=0):
f = os.open('/dev/cpu/%d/msr' % (cpu,), os.O_RDONLY)
os.lseek(f, msr, os.SEEK_SET)
val = struct.unpack('Q', os.read(f, 8))[0]
os.close(f)
return val
# convert negative decimal to two's complement hex
def convertmVtoHex(n):
return format(0xFFE00000 & ((round(n * 1.024) & 0xFFF) << 21), '08x')
# convert two's complement hex to negative decimal
def convertHextomV(n):
if n == 0:
return 0
# only works for negative numbers lol hopefully that's good enough
return ~ round((((n >> 21) ^ 0xFFF) - 2048) / 1.024)
def writeValues(value, index):
if int(value) > 0:
print("mV should be a negative number or zero!")
sys.exit()
msr_register = 0x150
constant = 80000
single_const = 1
read_write = 1
offset = convertmVtoHex(int(value))
val = "0x" + str(constant) + str(index) + \
str(single_const) + str(read_write) + offset
writemsr(msr_register, int(val, 16))
def checkValues():
msr_register = 0x150
constant = 80000
single_const = 1
read_write = 0
offset = convertmVtoHex(0)
index_names = ["cpu_core", "intel_gpu",
"cpu_cache", "system_agent", "analog_io"]
for x in range(0, 5):
value = "0x" + str(constant) + str(x) + \
str(single_const) + str(read_write) + str(offset)
writemsr(msr_register, int(value, 16))
print(str(x) + ", " + index_names[x] + ":")
out = readmsr(msr_register)
print(str(hex(out)) + " --> " + str(convertHextomV(out)))
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Undervolt Intel i7 6700HQ (not tested on others)')
parser.add_argument(
'--cpu-core',
metavar='mV',
help='undervolt the cpu core',
action='store'
)
parser.add_argument(
'--intel-gpu',
metavar='mV',
help='undervolt the intel gpu',
action='store'
)
parser.add_argument(
'--cpu-cache',
metavar='mV',
help='undervolt the cpu cache',
action='store'
)
parser.add_argument(
'--system-agent',
metavar='mV',
help='undervolt the system agent',
action='store'
)
parser.add_argument(
'--analog-io',
metavar='mV',
help='undervolt the analog I/O',
action='store'
)
parser.add_argument(
'-l',
'--list',
metavar='\b',
nargs=5,
type=int,
help='apply undervolt as list in the above order',
action='store'
)
parser.add_argument(
'-r',
'--reset',
help='reset voltages',
action='store_true'
)
parser.add_argument(
'-c',
'--check',
help='check undervoltage',
action='store_true'
)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
a = parser.parse_args()
if os.getuid() != 0:
args = ['sudo', sys.executable] + sys.argv + [os.environ]
os.execlpe('sudo', *args)
# probably a better way to do this
indicies = {"0": a.cpu_core, "1": a.intel_gpu,
"2": a.cpu_cache, "3": a.system_agent, "4": a.analog_io}
if a.check:
checkValues()
sys.exit()
if a.reset:
for key, value in indicies.items():
writeValues(0, key)
sys.exit()
for key, value in indicies.items():
if value is not None:
writeValues(value, key)
elif a.list is not None:
writeValues(a.list[int(key)], key)