Skip to content

Commit 232455e

Browse files
committed
Add nushell port of autoaspm
1 parent 61bb4f6 commit 232455e

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

sourced/auto_aspm.nu

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env nu
2+
3+
const aspm = {
4+
DISABLED: 0b00
5+
L0s: 0b01
6+
L1: 0b10
7+
L0sL1: 0b11
8+
}
9+
10+
def get-bytes-for-device [
11+
device: string
12+
]: nothing -> binary {
13+
sudo lspci -s $device -xxx
14+
| lines
15+
| skip
16+
| compact -e
17+
| split column -c ':'
18+
| get column2
19+
| split row ' '
20+
| compact -e
21+
| str join
22+
| decode hex
23+
| if ($in|bytes length) < 256 {
24+
print $"Invalid byte length detected for device ($device) aborting"
25+
exit
26+
} else {
27+
$in
28+
}
29+
}
30+
31+
def find-bytes [
32+
bytes: binary
33+
pos: int
34+
]: nothing -> int {
35+
# absolute black magic
36+
let result = ($bytes|bytes at $pos..$pos|into int)
37+
if $result != 0x10 {
38+
find-bytes $bytes ($result + 0x1)
39+
} else {
40+
return ($result + 0x10)
41+
}
42+
}
43+
44+
def patch-device [
45+
device: string
46+
aspm_value: string
47+
] {
48+
let bytes = (get-bytes-for-device $device)
49+
let byte_position = (find-bytes $bytes 0x34) #no one really knows where this value comes from
50+
let byte_to_patch = (
51+
$bytes
52+
| bytes at $byte_position..$byte_position
53+
| into int
54+
)
55+
# no idea
56+
if ($byte_to_patch| bits and 0b11) == ($aspm|get $aspm_value) {
57+
print $"($device) already has ASPM ($aspm_value) enabled"
58+
} else {
59+
print $"Enabling ASPM ($aspm_value) for device ($device)"
60+
let new_byte_value = (
61+
$byte_to_patch
62+
| bits shr 2 #no idea why we bitshift right and left
63+
| bits shl 2
64+
| bits or ($aspm|get $aspm_value)
65+
)
66+
patch-byte $device $byte_position $new_byte_value
67+
print $"Enabled ASPM ($aspm_value) for device ($device)"
68+
}
69+
}
70+
71+
def patch-byte [
72+
device: string
73+
position: int
74+
value: int
75+
] {
76+
setpci -s $device $"($position|format number|get upperhex).B=($value|format number|get upperhex)"
77+
}
78+
79+
def get-supported-devices []: nothing -> table<address: string, supported_aspm: string> {
80+
lspci -vv
81+
| lines
82+
| split list ''
83+
| each {|device|
84+
85+
let address = (
86+
$device
87+
| first
88+
| split row ' '
89+
| first
90+
)
91+
92+
let params = ($device|skip)
93+
94+
if ($params|find "ASPM"|is-empty) or ($params|find "ASPM not supported"|is-not-empty) {
95+
null
96+
} else {
97+
let supported_aspm = (
98+
$params
99+
| parse -r "ASPM (L[L0-1s ]*),"
100+
| get capture0.0
101+
| str replace " " ""
102+
)
103+
{address: $address, supported_aspm: $supported_aspm}
104+
}
105+
}
106+
}
107+
108+
if not (is-admin) {
109+
error make -u {
110+
msg: "This script needs to be run as root"
111+
}
112+
}
113+
if $nu.os-info.name != "linux" {
114+
error make -u {
115+
msg: "This script needs to run under Linux"
116+
}
117+
}
118+
if (which lspci setpci|length) < 2 {
119+
error make -u {
120+
msg: "lspci and setpci need to be available in PATH"
121+
}
122+
}
123+
124+
for device in (get-supported-devices) {
125+
patch-device $device.address $device.supported_aspm
126+
}

0 commit comments

Comments
 (0)