fwt_software/tools/thermal-sim/fake-temp.sh

78 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# A fake /sys for the CPU guard, so heat can be simulated without heat. Point the
# program at it with [Thermal] sysfs_root = <root> (config.ini or hardware.ini)
# and change the temperature while it runs.
#
# tools/thermal-sim/fake-temp.sh <root> init # build the tree (4 cores, 3.6 GHz, 70 C)
# tools/thermal-sim/fake-temp.sh <root> <C> # set the CPU temperature
# tools/thermal-sim/fake-temp.sh <root> <C> throttle # ...and count one throttle event
# tools/thermal-sim/fake-temp.sh <root> clock <MHz> # set every core's clock
# tools/thermal-sim/fake-temp.sh <root> ramp <C> <C> <step> <secs-per-step>
# # walk the temperature, throttling
# # at 90 C and above
#
# The tree has no proc/stat, so the program reads the real /proc/stat: how busy
# the CPU is stays real (raise it with heat-load.sh).
set -euo pipefail
usage() { sed -n '2,15p' "$0" >&2; exit 2; }
[[ $# -ge 2 ]] || usage
root=$1; shift
cpu=$root/sys/devices/system/cpu
zone=$root/sys/class/thermal/thermal_zone0
init() {
rm -f "$root/proc/stat" # an older tree's frozen copy would hide the real one
mkdir -p "$zone"
echo x86_pkg_temp > "$zone/type"
echo 70000 > "$zone/temp"
for c in 0 1 2 3; do
mkdir -p "$cpu/cpu$c/cpufreq" "$cpu/cpu$c/thermal_throttle"
echo 2800000 > "$cpu/cpu$c/cpufreq/scaling_cur_freq"
echo 3600000 > "$cpu/cpu$c/cpufreq/cpuinfo_max_freq"
echo 3600000 > "$cpu/cpu$c/cpufreq/scaling_max_freq"
echo 0 > "$cpu/cpu$c/thermal_throttle/package_throttle_count"
echo 0 > "$cpu/cpu$c/thermal_throttle/core_throttle_count"
done
echo "fake tree ready at $root: 70 C, 2.8 of 3.6 GHz"
}
set_temp() { # <C> [throttle]
echo $(( $1 * 1000 )) > "$zone/temp"
if [[ ${2:-} == throttle ]]; then
f=$cpu/cpu0/thermal_throttle/package_throttle_count
echo $(( $(cat "$f") + 1 )) > "$f"
fi
}
[[ $1 == init ]] && { init; exit 0; }
[[ -d $zone ]] || { echo "$0: no tree at $root - run '$0 $root init' first" >&2; exit 1; }
case $1 in
clock)
[[ $# -eq 2 ]] || usage
for c in "$cpu"/cpu[0-9]*; do echo $(( $2 * 1000 )) > "$c/cpufreq/scaling_cur_freq"; done
echo "clock $2 MHz" ;;
ramp)
[[ $# -eq 5 ]] || usage
from=$2 to=$3 step=$4 secs=$5
(( from > to )) && step=$(( -step ))
t=$from
while :; do
echo "$(date +%T) $t C"
# Hold the step; at 90 C and up the CPU throttles, one counted
# event every 2 s.
for (( i = 0; i < secs; i += 2 )); do
if (( t >= 90 )); then set_temp "$t" throttle; else set_temp "$t"; fi
sleep 2
done
(( t == to )) && break
t=$(( t + step ))
(( (step > 0 && t > to) || (step < 0 && t < to) )) && t=$to
done ;;
*)
[[ $1 =~ ^[0-9]+$ ]] || usage
set_temp "$1" "${2:-}"
echo "CPU $1 C${2:+, one throttle event}" ;;
esac