diff options
-rwxr-xr-x | convert/extract-nvidia-pcitable.sh | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/convert/extract-nvidia-pcitable.sh b/convert/extract-nvidia-pcitable.sh new file mode 100755 index 00000000..caa1b4ef --- /dev/null +++ b/convert/extract-nvidia-pcitable.sh @@ -0,0 +1,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.141.03 +nvidiacur_ver=515.76 + +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 |