detached f671f7d

feat(base): add AMD CPU-specific kernel parameters

commit
f671f7d32205cc3f2ca6aaf866b05389f3b26a00
author
bnema · · 2025-10-20 18:45 UTC
parent
5c93522
signature
unsigned
1 file · +256 -0
A install/base/amd-cpu.sh +256 -0
@@ -0,0 +1,256 @@
1+#!/bin/bash
2+# AMD CPU detection and P-State configuration
3+# Detects Zen generation and recommends appropriate AMD P-State modes
4+
5+# This script should only be called for AMD CPUs
6+# Requires: gum, /proc/cpuinfo
7+
8+detect_zen_generation() {
9+ local cpu_family
10+ local cpu_model
11+
12+ # Get CPU family and model from /proc/cpuinfo
13+ cpu_family=$(grep -m1 'cpu family' /proc/cpuinfo | awk '{print $4}')
14+ cpu_model=$(grep -m1 'model' /proc/cpuinfo | awk '{print $3}')
15+
16+ # Convert to hex for easier comparison (though we'll use decimal)
17+ local family_dec=$((cpu_family))
18+ local model_dec=$((cpu_model))
19+
20+ # Detect Zen generation based on CPU family and model
21+ # Reference: https://en.wikichip.org/wiki/amd/cpuid
22+
23+ local zen_gen=""
24+ local zen_label=""
25+
26+ case $family_dec in
27+ 23) # Family 17h
28+ if [ $model_dec -ge 0 ] && [ $model_dec -le 15 ]; then
29+ zen_gen="1"
30+ zen_label="Zen 1"
31+ elif [ $model_dec -ge 16 ] && [ $model_dec -le 31 ]; then
32+ zen_gen="1+"
33+ zen_label="Zen+"
34+ elif [ $model_dec -ge 48 ] && [ $model_dec -le 127 ]; then
35+ zen_gen="2"
36+ zen_label="Zen 2"
37+ else
38+ zen_gen="2"
39+ zen_label="Zen 2 (assumed)"
40+ fi
41+ ;;
42+ 25) # Family 19h
43+ if [ $model_dec -ge 0 ] && [ $model_dec -le 15 ]; then
44+ zen_gen="3"
45+ zen_label="Zen 3"
46+ elif [ $model_dec -ge 32 ] && [ $model_dec -le 47 ]; then
47+ zen_gen="3"
48+ zen_label="Zen 3"
49+ elif [ $model_dec -ge 80 ] && [ $model_dec -le 95 ]; then
50+ zen_gen="3+"
51+ zen_label="Zen 3+"
52+ elif [ $model_dec -ge 96 ] && [ $model_dec -le 175 ]; then
53+ zen_gen="4"
54+ zen_label="Zen 4"
55+ else
56+ zen_gen="3"
57+ zen_label="Zen 3 (assumed)"
58+ fi
59+ ;;
60+ 26) # Family 1Ah
61+ zen_gen="5"
62+ zen_label="Zen 5"
63+ ;;
64+ *)
65+ zen_gen="unknown"
66+ zen_label="Unknown"
67+ ;;
68+ esac
69+
70+ echo "${zen_gen}|${zen_label}"
71+}
72+
73+get_recommended_pstate_modes() {
74+ local zen_gen=$1
75+ local kernel_version
76+
77+ # Get kernel version
78+ kernel_version=$(uname -r | cut -d'.' -f1,2)
79+ local major=$(echo "$kernel_version" | cut -d'.' -f1)
80+ local minor=$(echo "$kernel_version" | cut -d'.' -f2)
81+
82+ # Calculate kernel version as single number for comparison
83+ local kernel_num=$((major * 100 + minor))
84+
85+ # Determine available modes based on Zen generation and kernel version
86+ # Reference: https://docs.kernel.org/admin-guide/pm/amd-pstate.html
87+ # Active: CPPC autonomous (amd_pstate_epp) - kernel 6.3+
88+ # Passive: CPPC non-autonomous (amd_pstate) - all kernels
89+ # Guided: CPPC guided autonomous (amd_pstate) - kernel 6.4+
90+
91+ case $zen_gen in
92+ "1"|"1+")
93+ # Zen 1 and Zen+: No CPPC support, use acpi-cpufreq
94+ echo "none"
95+ ;;
96+ "2")
97+ # Zen 2: Basic CPPC support, may need shared_mem=1 parameter
98+ # Passive: available, Active: 6.3+
99+ if [ $kernel_num -ge 603 ]; then
100+ echo "passive|active"
101+ else
102+ echo "passive"
103+ fi
104+ ;;
105+ "3"|"3+"|"4"|"5")
106+ # Zen 3+: Full CPPC support for all modes
107+ # Passive: available, Active: 6.3+, Guided: 6.4+
108+ local modes="passive"
109+ if [ $kernel_num -ge 603 ]; then
110+ modes="${modes}|active"
111+ fi
112+ if [ $kernel_num -ge 604 ]; then
113+ modes="${modes}|guided"
114+ fi
115+ echo "$modes"
116+ ;;
117+ *)
118+ echo "passive"
119+ ;;
120+ esac
121+}
122+
123+get_pstate_recommendation() {
124+ local zen_gen=$1
125+
126+ # Return the best recommended mode for each Zen generation
127+ case $zen_gen in
128+ "1"|"1+")
129+ echo "none" # Use default acpi-cpufreq
130+ ;;
131+ "2")
132+ echo "passive" # Conservative choice for Zen 2
133+ ;;
134+ "3"|"3+")
135+ echo "active" # Best for Zen 3/3+
136+ ;;
137+ "4"|"5")
138+ echo "active" # Best for Zen 4/5
139+ ;;
140+ *)
141+ echo "passive"
142+ ;;
143+ esac
144+}
145+
146+get_additional_params() {
147+ local zen_gen=$1
148+ local mode=$2
149+
150+ # Some Zen 2 CPUs need shared_mem parameter
151+ if [ "$zen_gen" = "2" ] && [ "$mode" = "active" ]; then
152+ echo "amd_pstate.shared_mem=1"
153+ else
154+ echo ""
155+ fi
156+}
157+
158+# Main execution
159+main() {
160+ gum style --foreground 6 --padding "1 0 0 $PADDING_LEFT" "AMD CPU Detection"
161+
162+ # Detect Zen generation
163+ local zen_info
164+ zen_info=$(detect_zen_generation)
165+ local zen_gen=$(echo "$zen_info" | cut -d'|' -f1)
166+ local zen_label=$(echo "$zen_info" | cut -d'|' -f2)
167+
168+ # Get CPU model name for display
169+ local cpu_model_name
170+ cpu_model_name=$(grep -m1 'model name' /proc/cpuinfo | cut -d':' -f2 | sed 's/^[ \t]*//')
171+
172+ gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "[OK] Detected: $zen_label"
173+ gum style --padding "0 0 0 $PADDING_LEFT" " CPU: $cpu_model_name"
174+
175+ # Check if Zen generation supports AMD pstate
176+ if [ "$zen_gen" = "1" ] || [ "$zen_gen" = "1+" ]; then
177+ gum style --foreground 3 --padding "0 0 1 $PADDING_LEFT" "[WARN] $zen_label does not support AMD P-State driver"
178+ gum style --padding "0 0 1 $PADDING_LEFT" " Using default acpi-cpufreq driver"
179+ export ARCHUP_AMD_PSTATE=""
180+ export ARCHUP_AMD_KERNEL_PARAMS=""
181+ echo "AMD CPU: $zen_label (no P-State support)" >> "$ARCHUP_INSTALL_LOG_FILE"
182+ return 0
183+ fi
184+
185+ # Get available modes for this Zen generation
186+ local available_modes
187+ available_modes=$(get_recommended_pstate_modes "$zen_gen")
188+
189+ echo
190+ gum style --foreground 6 --padding "1 0 0 $PADDING_LEFT" "AMD P-State Configuration"
191+ gum style --padding "0 0 0 $PADDING_LEFT" "Select AMD P-State driver mode for CPU frequency scaling"
192+ gum style --foreground 8 --padding "0 0 0 $PADDING_LEFT" "Note: Requires CPPC enabled in UEFI (AMD CBS > NBIO > SMU > CPPC)"
193+ echo
194+
195+ # Build choice menu based on available modes
196+ declare -a MODE_CHOICES
197+
198+ if echo "$available_modes" | grep -q "active"; then
199+ MODE_CHOICES+=("active - CPPC autonomous with EPP hints (best performance, desktop/gaming)")
200+ fi
201+
202+ if echo "$available_modes" | grep -q "guided"; then
203+ MODE_CHOICES+=("guided - CPPC guided autonomous (balanced, laptop/hybrid)")
204+ fi
205+
206+ if echo "$available_modes" | grep -q "passive"; then
207+ MODE_CHOICES+=("passive - CPPC non-autonomous (compatibility, manual governor control)")
208+ fi
209+
210+ # Show recommendation
211+ local recommended
212+ recommended=$(get_pstate_recommendation "$zen_gen")
213+
214+ if [ "$recommended" != "none" ]; then
215+ gum style --foreground 3 --padding "0 0 0 $PADDING_LEFT" "Recommended for $zen_label: $recommended"
216+ echo
217+ fi
218+
219+ # Let user choose
220+ local choice
221+ choice=$(gum choose --padding "0 0 1 $PADDING_LEFT" "${MODE_CHOICES[@]}")
222+
223+ # Extract mode name
224+ local selected_mode
225+ selected_mode=$(echo "$choice" | awk '{print $1}')
226+
227+ # Get any additional kernel parameters needed
228+ local extra_params
229+ extra_params=$(get_additional_params "$zen_gen" "$selected_mode")
230+
231+ # Export configuration
232+ export ARCHUP_AMD_PSTATE="$selected_mode"
233+
234+ if [ -n "$extra_params" ]; then
235+ export ARCHUP_AMD_KERNEL_PARAMS="amd_pstate=$selected_mode $extra_params"
236+ else
237+ export ARCHUP_AMD_KERNEL_PARAMS="amd_pstate=$selected_mode"
238+ fi
239+
240+ gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "[OK] P-State mode: $selected_mode"
241+
242+ if [ -n "$extra_params" ]; then
243+ gum style --padding "0 0 1 $PADDING_LEFT" " Additional params: $extra_params"
244+ fi
245+
246+ echo "AMD CPU: $zen_label, P-State: $selected_mode" >> "$ARCHUP_INSTALL_LOG_FILE"
247+
248+ if [ -n "$extra_params" ]; then
249+ echo " Extra params: $extra_params" >> "$ARCHUP_INSTALL_LOG_FILE"
250+ fi
251+}
252+
253+# Run if executed directly (not sourced)
254+if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
255+ main
256+fi
@@ -0,0 +1,256 @@
1+#!/bin/bash
2+# AMD CPU detection and P-State configuration
3+# Detects Zen generation and recommends appropriate AMD P-State modes
4+
5+# This script should only be called for AMD CPUs
6+# Requires: gum, /proc/cpuinfo
7+
8+detect_zen_generation() {
9+ local cpu_family
10+ local cpu_model
11+
12+ # Get CPU family and model from /proc/cpuinfo
13+ cpu_family=$(grep -m1 'cpu family' /proc/cpuinfo | awk '{print $4}')
14+ cpu_model=$(grep -m1 'model' /proc/cpuinfo | awk '{print $3}')
15+
16+ # Convert to hex for easier comparison (though we'll use decimal)
17+ local family_dec=$((cpu_family))
18+ local model_dec=$((cpu_model))
19+
20+ # Detect Zen generation based on CPU family and model
21+ # Reference: https://en.wikichip.org/wiki/amd/cpuid
22+
23+ local zen_gen=""
24+ local zen_label=""
25+
26+ case $family_dec in
27+ 23) # Family 17h
28+ if [ $model_dec -ge 0 ] && [ $model_dec -le 15 ]; then
29+ zen_gen="1"
30+ zen_label="Zen 1"
31+ elif [ $model_dec -ge 16 ] && [ $model_dec -le 31 ]; then
32+ zen_gen="1+"
33+ zen_label="Zen+"
34+ elif [ $model_dec -ge 48 ] && [ $model_dec -le 127 ]; then
35+ zen_gen="2"
36+ zen_label="Zen 2"
37+ else
38+ zen_gen="2"
39+ zen_label="Zen 2 (assumed)"
40+ fi
41+ ;;
42+ 25) # Family 19h
43+ if [ $model_dec -ge 0 ] && [ $model_dec -le 15 ]; then
44+ zen_gen="3"
45+ zen_label="Zen 3"
46+ elif [ $model_dec -ge 32 ] && [ $model_dec -le 47 ]; then
47+ zen_gen="3"
48+ zen_label="Zen 3"
49+ elif [ $model_dec -ge 80 ] && [ $model_dec -le 95 ]; then
50+ zen_gen="3+"
51+ zen_label="Zen 3+"
52+ elif [ $model_dec -ge 96 ] && [ $model_dec -le 175 ]; then
53+ zen_gen="4"
54+ zen_label="Zen 4"
55+ else
56+ zen_gen="3"
57+ zen_label="Zen 3 (assumed)"
58+ fi
59+ ;;
60+ 26) # Family 1Ah
61+ zen_gen="5"
62+ zen_label="Zen 5"
63+ ;;
64+ *)
65+ zen_gen="unknown"
66+ zen_label="Unknown"
67+ ;;
68+ esac
69+
70+ echo "${zen_gen}|${zen_label}"
71+}
72+
73+get_recommended_pstate_modes() {
74+ local zen_gen=$1
75+ local kernel_version
76+
77+ # Get kernel version
78+ kernel_version=$(uname -r | cut -d'.' -f1,2)
79+ local major=$(echo "$kernel_version" | cut -d'.' -f1)
80+ local minor=$(echo "$kernel_version" | cut -d'.' -f2)
81+
82+ # Calculate kernel version as single number for comparison
83+ local kernel_num=$((major * 100 + minor))
84+
85+ # Determine available modes based on Zen generation and kernel version
86+ # Reference: https://docs.kernel.org/admin-guide/pm/amd-pstate.html
87+ # Active: CPPC autonomous (amd_pstate_epp) - kernel 6.3+
88+ # Passive: CPPC non-autonomous (amd_pstate) - all kernels
89+ # Guided: CPPC guided autonomous (amd_pstate) - kernel 6.4+
90+
91+ case $zen_gen in
92+ "1"|"1+")
93+ # Zen 1 and Zen+: No CPPC support, use acpi-cpufreq
94+ echo "none"
95+ ;;
96+ "2")
97+ # Zen 2: Basic CPPC support, may need shared_mem=1 parameter
98+ # Passive: available, Active: 6.3+
99+ if [ $kernel_num -ge 603 ]; then
100+ echo "passive|active"
101+ else
102+ echo "passive"
103+ fi
104+ ;;
105+ "3"|"3+"|"4"|"5")
106+ # Zen 3+: Full CPPC support for all modes
107+ # Passive: available, Active: 6.3+, Guided: 6.4+
108+ local modes="passive"
109+ if [ $kernel_num -ge 603 ]; then
110+ modes="${modes}|active"
111+ fi
112+ if [ $kernel_num -ge 604 ]; then
113+ modes="${modes}|guided"
114+ fi
115+ echo "$modes"
116+ ;;
117+ *)
118+ echo "passive"
119+ ;;
120+ esac
121+}
122+
123+get_pstate_recommendation() {
124+ local zen_gen=$1
125+
126+ # Return the best recommended mode for each Zen generation
127+ case $zen_gen in
128+ "1"|"1+")
129+ echo "none" # Use default acpi-cpufreq
130+ ;;
131+ "2")
132+ echo "passive" # Conservative choice for Zen 2
133+ ;;
134+ "3"|"3+")
135+ echo "active" # Best for Zen 3/3+
136+ ;;
137+ "4"|"5")
138+ echo "active" # Best for Zen 4/5
139+ ;;
140+ *)
141+ echo "passive"
142+ ;;
143+ esac
144+}
145+
146+get_additional_params() {
147+ local zen_gen=$1
148+ local mode=$2
149+
150+ # Some Zen 2 CPUs need shared_mem parameter
151+ if [ "$zen_gen" = "2" ] && [ "$mode" = "active" ]; then
152+ echo "amd_pstate.shared_mem=1"
153+ else
154+ echo ""
155+ fi
156+}
157+
158+# Main execution
159+main() {
160+ gum style --foreground 6 --padding "1 0 0 $PADDING_LEFT" "AMD CPU Detection"
161+
162+ # Detect Zen generation
163+ local zen_info
164+ zen_info=$(detect_zen_generation)
165+ local zen_gen=$(echo "$zen_info" | cut -d'|' -f1)
166+ local zen_label=$(echo "$zen_info" | cut -d'|' -f2)
167+
168+ # Get CPU model name for display
169+ local cpu_model_name
170+ cpu_model_name=$(grep -m1 'model name' /proc/cpuinfo | cut -d':' -f2 | sed 's/^[ \t]*//')
171+
172+ gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "[OK] Detected: $zen_label"
173+ gum style --padding "0 0 0 $PADDING_LEFT" " CPU: $cpu_model_name"
174+
175+ # Check if Zen generation supports AMD pstate
176+ if [ "$zen_gen" = "1" ] || [ "$zen_gen" = "1+" ]; then
177+ gum style --foreground 3 --padding "0 0 1 $PADDING_LEFT" "[WARN] $zen_label does not support AMD P-State driver"
178+ gum style --padding "0 0 1 $PADDING_LEFT" " Using default acpi-cpufreq driver"
179+ export ARCHUP_AMD_PSTATE=""
180+ export ARCHUP_AMD_KERNEL_PARAMS=""
181+ echo "AMD CPU: $zen_label (no P-State support)" >> "$ARCHUP_INSTALL_LOG_FILE"
182+ return 0
183+ fi
184+
185+ # Get available modes for this Zen generation
186+ local available_modes
187+ available_modes=$(get_recommended_pstate_modes "$zen_gen")
188+
189+ echo
190+ gum style --foreground 6 --padding "1 0 0 $PADDING_LEFT" "AMD P-State Configuration"
191+ gum style --padding "0 0 0 $PADDING_LEFT" "Select AMD P-State driver mode for CPU frequency scaling"
192+ gum style --foreground 8 --padding "0 0 0 $PADDING_LEFT" "Note: Requires CPPC enabled in UEFI (AMD CBS > NBIO > SMU > CPPC)"
193+ echo
194+
195+ # Build choice menu based on available modes
196+ declare -a MODE_CHOICES
197+
198+ if echo "$available_modes" | grep -q "active"; then
199+ MODE_CHOICES+=("active - CPPC autonomous with EPP hints (best performance, desktop/gaming)")
200+ fi
201+
202+ if echo "$available_modes" | grep -q "guided"; then
203+ MODE_CHOICES+=("guided - CPPC guided autonomous (balanced, laptop/hybrid)")
204+ fi
205+
206+ if echo "$available_modes" | grep -q "passive"; then
207+ MODE_CHOICES+=("passive - CPPC non-autonomous (compatibility, manual governor control)")
208+ fi
209+
210+ # Show recommendation
211+ local recommended
212+ recommended=$(get_pstate_recommendation "$zen_gen")
213+
214+ if [ "$recommended" != "none" ]; then
215+ gum style --foreground 3 --padding "0 0 0 $PADDING_LEFT" "Recommended for $zen_label: $recommended"
216+ echo
217+ fi
218+
219+ # Let user choose
220+ local choice
221+ choice=$(gum choose --padding "0 0 1 $PADDING_LEFT" "${MODE_CHOICES[@]}")
222+
223+ # Extract mode name
224+ local selected_mode
225+ selected_mode=$(echo "$choice" | awk '{print $1}')
226+
227+ # Get any additional kernel parameters needed
228+ local extra_params
229+ extra_params=$(get_additional_params "$zen_gen" "$selected_mode")
230+
231+ # Export configuration
232+ export ARCHUP_AMD_PSTATE="$selected_mode"
233+
234+ if [ -n "$extra_params" ]; then
235+ export ARCHUP_AMD_KERNEL_PARAMS="amd_pstate=$selected_mode $extra_params"
236+ else
237+ export ARCHUP_AMD_KERNEL_PARAMS="amd_pstate=$selected_mode"
238+ fi
239+
240+ gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "[OK] P-State mode: $selected_mode"
241+
242+ if [ -n "$extra_params" ]; then
243+ gum style --padding "0 0 1 $PADDING_LEFT" " Additional params: $extra_params"
244+ fi
245+
246+ echo "AMD CPU: $zen_label, P-State: $selected_mode" >> "$ARCHUP_INSTALL_LOG_FILE"
247+
248+ if [ -n "$extra_params" ]; then
249+ echo " Extra params: $extra_params" >> "$ARCHUP_INSTALL_LOG_FILE"
250+ fi
251+}
252+
253+# Run if executed directly (not sourced)
254+if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
255+ main
256+fi

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close