Replaces the open-coded write32(0, low) + write32(4, high) pair
(and the matching read32 merge in the debug path) with a single
64-bit access. Besides being less code, this also closes a small
window between the two 32-bit writes in which the register briefly
held (new_low, old_high).
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
Mirror the existing read32/write32 pattern for 64-bit accesses. The
MCHBAR PKG_POWER_LIMIT register is naturally a single 64-bit field,
and having a symmetric helper avoids the open-coded split into two
32-bit writes at the call site.
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
In polling mode, power['source'] is already set from is_on_battery
at the top of each iteration, so the HWP check was calling
is_on_battery a second time for the same value. Replace the whole
dbus-vs-polling branch with `power['source'] == 'AC'`, which is
correct for both methods and avoids the extra glob/file read (and a
fallback DBus round-trip).
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
- Replace remaining .format() calls with f-strings (ruff UP032 plus
manual cleanups for the formats ruff couldn't rewrite); replace
the lone %-format in mmio.MMIO.__str__ as well.
- Hoist `UNDERVOLT.<source>` and `ICCMAX.<source>` section names to
local variables in undervolt() / set_icc_max() so the f-string
appears once.
- Add type hints to the public mmio.MMIO methods (the only real
module boundary in the project).
- Run Black with the existing pyproject.toml config (line-length 120,
skip-string-normalization). No semantic changes.
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
- Remove `from __future__ import print_function` (Python 3 only).
- mmio.py: drop the Python 2 `long = int` shim and `(int, long)`
isinstance checks; make __enter__ return self so `with MMIO(...)`
works as expected.
- Drop the redundant `value = config.set(...)` assignment in
load_config (config.set returns None).
- Replace the personal "for my CPU" comments and the
"ugly code, just testing..." comment with brief docstrings that
describe what each helper computes.
- Add concise one-line docstrings to the public-ish functions
(readmsr/writemsr, get_value_for_bits, is_on_battery, the various
MSR getters/setters, load_config, calc_reg_values, power_thread,
monitor, main, etc.) so a reader can navigate without reading the
body.
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
- Replace bare `except:` clauses in set_msr_allow_writes, check_cpu,
and the --log file open with specific exception types so we no
longer swallow KeyboardInterrupt/SystemExit and we surface the
actual error in the log.
- check_cpu now re-raises SystemExit instead of calling sys.exit
again, and includes the underlying error in the fatal message.
- power_thread skips the PKG_POWER_LIMIT (and matching MCHBAR) write
if no package power limit was computed, instead of KeyError'ing
when all PL1/PL2 entries are commented out in the config.
- Strip ANSI color escapes when writing to the --log file. The
OK/ERR/LIM constants embed ANSI codes intended for terminals and
were leaking into log files.
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
- get_msr_list(): sort numerically and skip non-digit entries (like
/dev/cpu/microcode). os.listdir() ordering is arbitrary, so the
previous code returned readmsr() results indexed by enumeration
order rather than CPU number, breaking the cpu= and flatten=True
paths on systems where listdir didn't happen to return CPUs in
order; it would also crash with ValueError when /dev/cpu contained
any non-CPU entry.
- readmsr/writemsr: close MSR file descriptors via try/finally so a
failed read/write doesn't leak the fd.
- is_on_battery(): replace bare `raise` (no active exception) and
catch-all `except:` with specific exceptions; restore the intended
fall-through to the upower fallback.
- test_msr_rw_capabilities(): declare TESTMSR global. The previous
`TESTMSR = True` only created a local, so the in-flight detection
could not actually catch MSR errors and would call fatal() instead.
- power_thread(): always sleep at end of loop. Previously the
exit_event.wait was only reached in the else-branch of the HWP
check, so when HWP fired the thread spun without sleeping.
- set_disable_bdprochot(): use `read_value == 0` for the debug
match check; `~read_value` was always truthy.
- main(): initialize cpuid = None so --force does not raise
UnboundLocalError when starting the power thread.
- mmio.py: map /dev/mem with PROT_READ | PROT_WRITE so read32 is
defined and portable; close fd if mmap.mmap raises; fix __str__
which referenced nonexistent self.base/self.size; drop dead
self._fd assignment.
Signed-off-by: ooonea <35407790+ooonea@users.noreply.github.com>
Added Precision 7720 to tested hardware list, it works for me best with thermald --adaptive; also setted both HWP to enabled and cTDP to be down and while with thermald it still reached 99 C and more :((; both combined and the rest are amazing, even having my cpu when idle down to 40 C which i barely managed to do.
On some systems, the name of the battery or the adapter may be different. The code assumes
the adapter is called "line_power_AC" and the battery "BAT0" but in my system both are different.
UPower has the OnBattery property which we can query and this is more robust. Additionally, we
can do it directly throuth the dbus API without invoking a sub-process.
This fixes a problem with my recent commit. I used `[ "$INIT" == "systemd" ]` (and similar), which works in bash, but not in `/usr/bin/sh`. I changed it to `[ "$INIT" = "systemd" ]` (and similar) to correct this issue.