-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcorsair-power.py
More file actions
76 lines (61 loc) · 1.99 KB
/
Copy pathcorsair-power.py
File metadata and controls
76 lines (61 loc) · 1.99 KB
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
#!/usr/bin/env python3
"""
Monitor performance mode, fan speeds, temps, and power on Corsair AI Workstation 300.
ERAX MMIO region: 0xFEC40400 (SystemMemory, ACPI DSDT)
Field offsets from DSDT decompile (iasl):
FCMO 0x31 current mode (0=Balanced, 1=Max, 2=Quiet, 3=Super)
FN1L 0x35 fan 1 speed high byte
FN1H 0x36 fan 1 speed low byte RPM = (FN1L<<8)|FN1H
FN2L 0x37 fan 2 speed high byte
FN2H 0x38 fan 2 speed low byte RPM = (FN2L<<8)|FN2H
CPUT 0x70 CPU temp (°C)
GPUT 0x71 GPU temp (°C)
CPAD 0x72 CPU power (W)
GPAD 0x73 GPU power (W)
RAPL energy counter used for cross-check CPU package power.
"""
import mmap, os, time
ERAX_BASE = 0xFEC40400
RAPL_ENERGY = "/sys/class/powercap/intel-rapl:0/energy_uj"
MODES = {
0: "Balanced",
1: "Max ",
2: "Quiet ",
3: "Super ",
}
page_size = 4096
page_addr = ERAX_BASE & ~(page_size - 1)
base = ERAX_BASE - page_addr
fd = os.open("/dev/mem", os.O_RDONLY | os.O_SYNC)
m = mmap.mmap(fd, page_size, mmap.MAP_SHARED, mmap.PROT_READ, offset=page_addr)
def d(off):
return m[base + off]
def read_rapl():
with open(RAPL_ENERGY) as f:
return int(f.read())
print(f"{'Mode':<10} {'Fan1':>6} {'Fan2':>6} {'CPU°C':>6} {'GPU°C':>6} {'EC-CPU W':>9} {'EC-GPU W':>9} {'RAPL W':>7}")
print("-" * 70)
e0 = read_rapl()
t0 = time.monotonic()
try:
while True:
time.sleep(1.0)
e1 = read_rapl()
t1 = time.monotonic()
rapl = (e1 - e0) / ((t1 - t0) * 1e6)
e0, t0 = e1, t1
mode = MODES.get(d(0x31), f"Unk({d(0x31)})")
fan1 = (d(0x35) << 8) | d(0x36)
fan2 = (d(0x37) << 8) | d(0x38)
cput = d(0x70)
gput = d(0x71)
cpad = d(0x72)
gpad = d(0x73)
fan1s = f"{fan1}" if fan1 else "off"
fan2s = f"{fan2}" if fan2 else "off"
print(f"{mode:<10} {fan1s:>6} {fan2s:>6} {cput:>6} {gput:>6} {cpad:>9} {gpad:>9} {rapl:>7.1f}")
except KeyboardInterrupt:
pass
finally:
m.close()
os.close(fd)