summaryrefslogtreecommitdiffstats
path: root/convert/extract-nvidia-pcitable.sh
blob: d9b67dc639b312ac2fe52a6f9fb09614ee7fcaf9 (plain)
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/bin/sh

#
# author: ghibo
# release: 1.0 (2022-10-14)
#
# - This script builds a newer version of the pcitable and pcitable.x86_64 files according to
#   newer nvidia drivers.
#
# Instructions:
#
# - Copy this file to your workdir and run from there.
#
# - Set the appropriate driver version number for both nvidia470 and nvidia-current in
# the variables $nvidia470_ver and $nvidiacur_ver below. The latest nvidia drivers
# are listed here: https://www.nvidia.com/en-us/drivers/unix/.
#
# - The script downloads the drivers, and extracts the pcitables. The changes for
# pcitable and pcitable.x86_64 are shown into ldetect-lst.patch, or inside the
# git tree of the local dir ldetect-lst (which is an anonymous tree). Then the changes should be
# copied manually to the real (non-anonymous) ldetect-lst tree.
#

# driver version
#
# Note that drivers nvidia470.xx and beyond are 64-bit only.
nvidia470_ver=470.182.03
nvidiacur_ver=525.116.03

GET=aria2c
GETOPT="-c"
WORKDIR="./workdir"

if [ "$(type -p ${GET})" == "" ]; then
	echo "${GET} not found, please install the ${GET} package"
	exit 1
fi

if [ "$(type -p jq)" == "" ]; then
	echo "jq not found, please install the jq package"
	exit 1
fi

if [ "$(type -p git)" == "" ]; then
	echo "git not found, please install the git package"
	exit 1
fi

nvidia470_name=NVIDIA-Linux-x86_64-${nvidia470_ver}.run
nvidia470_dir=NVIDIA-Linux-x86_64-${nvidia470_ver}
export nvidia470_card_string="Card:NVIDIA GeForce 635 to GeForce 920"

nvidiacur_name=NVIDIA-Linux-x86_64-${nvidiacur_ver}.run
nvidiacur_dir=NVIDIA-Linux-x86_64-${nvidiacur_ver}
export nvidiacur_card_string="Card:NVIDIA GeForce 745 series and later"

export nvidia390_card_string="Card:NVIDIA GeForce 420 to GeForce 630"

if [ ! -d "$WORKDIR}" ]; then
	mkdir -p ${WORKDIR}
fi

pushd ${WORKDIR} > /dev/null

# ------ nvidia 470.xx drivers ------
if [ ! -e README_${nvidia470_ver}.txt -a ! -e supported-gpus-${nvidia470_ver}.json ]; then
	if [ ! -e "${nvidia470_name}" ]; then
        	${GET} ${GETOPT} https://us.download.nvidia.com/XFree86/Linux-x86_64/${nvidia470_ver}/${nvidia470_name}
	fi
	if [ ! -d ${nvidia470_dir} ]; then
		sh ${nvidia470_name} --extract-only .
	fi
	cp -pf ${nvidia470_dir}/README.txt README_orig_${nvidia470_ver}.txt
	cp -pf ${nvidia470_dir}/supported-gpus/supported-gpus.json supported-gpus-${nvidia470_ver}.json
	# clean-up driver dir, not needed anymore
	if [ -d ./${nvidia470_dir} ]; then
		rm -rf ./${nvidia470_dir}
	fi
fi	
echo "\"DeviceId\",\"SubVendorId\",\"SubDeviceId\",\"Card Name\"" > pcitable-nvidia470-from-json-extended.csv
cat supported-gpus-${nvidia470_ver}.json | \
	jq -r '.chips[] | select (.legacybranch == null) | [.devid,.subvendorid,.subdevid,.name] | @text'| \
	sed -e 's@^\[@@g' -e 's@\]$@@g' | \
	awk -F, '{      devid=tolower($1); gsub(/"/, "", devid);
	          subvendorid=tolower($2); gsub(/"/, "", subvendorid);
	             subdevid=tolower($3); gsub(/"/, "", subdevid);
	             print(devid "," subvendorid "," subdevid "," $4)}' | \
	sort -u >> pcitable-nvidia470-from-json-extended.csv

cat supported-gpus-${nvidia470_ver}.json | \
	jq -r '.chips[] | select (.legacybranch == null) | [.devid] | @text'| \
	sed -e 's@^\[@@g' -e 's@\]$@@g' -e 's@"@@g' | \
	awk -F, '{print("0x10de" "\t" tolower($1) "\t" "\"" ENVIRON["nvidia470_card_string"] "\"")}' | \
	sort -u > pcitable-nvidia470-from-json.txt

cat supported-gpus-${nvidia470_ver}.json | \
	jq -r '.chips[] | select (.legacybranch == null) | [.devid,.subvendorid,.subdevid] | @text'| \
	sed -e 's@^\[@@g' -e 's@\]$@@g' | \
	awk -F, '{      devid=tolower($1); gsub(/"/, "", devid);
	          subvendorid=tolower($2); gsub(/"/, "", subvendorid);
	             subdevid=tolower($3); gsub(/"/, "", subdevid);
	             print("0x10de" "\t" devid "\t" subvendorid "\t" subdevid "\t" "\"" ENVIRON["nvidia470_card_string"] "\"")}' | \
	sed -e 's@\tnull@@g' | \
	sort -u > pcitable-nvidia470-from-json-withsubdev.txt
# ------------------------------------

# ------ nvidia current drivers ------
if [ ! -e README_${nvidiacur_ver}.txt -a ! -e supported-gpus-${nvidiacur_ver}.json ]; then
	if [ ! -e "${nvidiacur_name}" ]; then
		${GET} ${GETOPT} https://us.download.nvidia.com/XFree86/Linux-x86_64/${nvidiacur_ver}/${nvidiacur_name}
	fi 
	if [ ! -d ${nvidiacur_dir} ]; then
		sh ${nvidiacur_name} --extract-only .
	fi
	cp -pf ${nvidiacur_dir}/README.txt README_orig_${nvidiacur_ver}.txt
	cp -pf ${nvidiacur_dir}/supported-gpus/supported-gpus.json supported-gpus-${nvidiacur_ver}.json
	# clean-up driver dir, not needed anymore
	if [ -d ./${nvidiacur_dir} ]; then
		rm -rf ./${nvidiacur_dir}
	fi
fi
echo "\"DeviceId\",\"SubVendorId\",\"SubDeviceId\",\"Card Name\"" > pcitable-nvidiacurrent-from-json-extended.csv
cat supported-gpus-${nvidiacur_ver}.json | \
	jq -r '.chips[] | select (.legacybranch == null) | [.devid,.subvendorid,.subdevid,.name] | @text'| \
	sed -e 's@^\[@@g' -e 's@\]$@@g' | \
	awk -F, '{      devid=tolower($1); gsub(/"/, "", devid);
	          subvendorid=tolower($2); gsub(/"/, "", subvendorid);
	             subdevid=tolower($3); gsub(/"/, "", subdevid);
	             print(devid "," subvendorid "," subdevid "," $4)}' | \
	sort -u >> pcitable-nvidiacurrent-from-json-extended.csv

cat supported-gpus-${nvidiacur_ver}.json | \
	jq -r '.chips[] | select (.legacybranch == null) | [.devid] | @text'| \
	sed -e 's@^\[@@g' -e 's@\]$@@g' -e 's@"@@g' | \
	awk -F, '{print("0x10de" "\t" tolower($1) "\t" "\"" ENVIRON["nvidiacur_card_string"] "\"")}' | \
	sort -u > pcitable-nvidiacurrent-from-json.txt

cat supported-gpus-${nvidiacur_ver}.json | \
	jq -r '.chips[] | select (.legacybranch == null) | [.devid,.subvendorid,.subdevid] | @text'| \
	sed -e 's@^\[@@g' -e 's@\]$@@g' | \
	awk -F, '{      devid=tolower($1); gsub(/"/, "", devid);
	          subvendorid=tolower($2); gsub(/"/, "", subvendorid);
	             subdevid=tolower($3); gsub(/"/, "", subdevid);
	             print("0x10de" "\t" devid "\t" subvendorid "\t" subdevid "\t" "\"" ENVIRON["nvidiacur_card_string"] "\"")}' | \
	sed -e 's@\tnull@@g' | \
	sort -u > pcitable-nvidiacurrent-from-json-withsubdev.txt

# -----------------------------------------------------

cp pcitable-nvidiacurrent-from-json.txt pcitable-nvidiacurrent-nvidia470-from-json-temp.txt
perl -pi -e "s@${nvidiacur_card_string}@${nvidia470_card_string}@g" pcitable-nvidiacurrent-nvidia470-from-json-temp.txt

# pcitable-nvidia470-from-json-residual.txt contains the list of the cards supported by driver nvidia470, which are
# not already supported by driver nvidia-current.
comm -1 -3 pcitable-nvidiacurrent-nvidia470-from-json-temp.txt \
	pcitable-nvidia470-from-json.txt > pcitable-nvidia470-from-json-residual.txt
rm -f pcitable-nvidiacurrent-nvidia470-from-json-temp.txt

popd > /dev/null

# download ldetect-lst from git
if [ ! -e ldetect-lst ]; then
	git clone git://git.mageia.org/software/ldetect-lst
else
	(cd ldetect-lst
	 git pull --quiet
	)
fi

cp -pf ldetect-lst/lst/pcitable ${WORKDIR}/
cp -pf ldetect-lst/lst/pcitable.x86_64 ${WORKDIR}/

pushd ${WORKDIR} > /dev/null

cat pcitable | grep -E "${nvidia390_card_string}" | sort -u > pcitable-nvidia390.txt
cp -p pcitable-nvidia470-from-json-residual.txt pcitable-nvidia470-nvidia390-temp.txt
perl -pi -e "s@${nvidia470_card_string}@${nvidia390_card_string}@g" pcitable-nvidia470-nvidia390-temp.txt

# pcitable-nvidia390-residual.txt contains the list of the cards supported by the driver for
# ${nvidia390_card_string} (now supposed to be nouveau) which are not already supported by
# the driver nvidia470.
comm -1 -3 pcitable-nvidia470-nvidia390-temp.txt \
	pcitable-nvidia390.txt > pcitable-nvidia390-residual.txt
rm -f pcitable-nvidia470-nvidia390-temp.txt

cat pcitable.x86_64 | \
	grep -E -v "${nvidia470_card_string}|${nvidiacur_card_string}" > pcitable.x86_64.skel
cat pcitable-nvidiacurrent-from-json.txt >> pcitable.x86_64.skel

# $nvidia470_card_string is listed on pcitable (though nvidia470 is x86_64 only). Is that the right place for it
# or should it be moved to pcitable.x86_64? To review in ldetect-lst.
cat pcitable | \
	grep -E -v "${nvidia470_card_string}" > pcitable.skel
# append cards for nvidia470 not supported by nvidia-current.
cat pcitable-nvidia470-from-json-residual.txt >> pcitable.skel

# cleanup pcitables against older $nvidia390_card_string entries, to avoid "multiple entry" errors during
# ldetect-lst package building
cat pcitable.x86_64.skel | \
	grep -E -v "$nvidia390_card_string" > pcitable_cleaned.x86_64.skel
	
cat pcitable.skel | \
	grep -E -v "$nvidia390_card_string" > pcitable_cleaned.skel

# append older nvidia390's residual pcitable (now used by nouveau) to pcitable
cat pcitable_cleaned.skel pcitable-nvidia390-residual.txt | sort > pcitable
cat pcitable_cleaned.x86_64.skel | sort > pcitable.x86_64

popd > /dev/null

cp -pf ${WORKDIR}/{pcitable,pcitable.x86_64} ldetect-lst/lst/

(cd ldetect-lst
 git diff > ../ldetect-lst.patch
)

echo "-----------------------------"
echo "ldetect-lst diffs:"
cat ldetect-lst.patch

echo "-----------------------------"
pushd ${WORKDIR} > /dev/null
	echo "new card entries added or moved (approximate list)"
	newcards=$(cat ../ldetect-lst.patch | grep ^+0 | awk '{print $2}')
	for i in ${newcards}; do \
		grep -F -i $i pcitable-nvidiacurrent-from-json-extended.csv pcitable-nvidia470-from-json-extended.csv
	done
	echo
	echo "older entries removed or moved (approximate list)"
	oldcards=$(cat ../ldetect-lst.patch | grep ^\-0 | awk '{print $2}')
	for i in ${oldcards}; do \
		grep -F -i $i pcitable-nvidiacurrent-from-json-extended.csv pcitable-nvidia470-from-json-extended.csv
	done
popd > /dev/null