Add FPGA u280 firmware (working ok)

This commit is contained in:
Rodrigo Arias 2025-02-25 17:08:13 +01:00
parent e81b7cc158
commit 82ed40d386
4 changed files with 416 additions and 0 deletions

View File

@ -37,6 +37,7 @@
nixpkgs.overlays = [
(final: prev: {
xilinx-xrt = prev.callPackage ./xilinx-xrt.nix { };
xilinx-fw = prev.callPackage ./xilinx-fw.nix { };
xilinx-xocl = prev.callPackage ./xilinx-xocl.nix {
kernel = config.boot.kernelPackages.kernel;
};

335
m/raccoon/xilinx-create-xsabin.sh Executable file
View File

@ -0,0 +1,335 @@
#!/bin/bash
## (c) Copyright 2020 Xilinx, Inc. All rights reserved.
##
## This file contains confidential and proprietary information
## of Xilinx, Inc. and is protected under U.S. and
## international copyright and other intellectual property
## laws.
##
## DISCLAIMER
## This disclaimer is not a license and does not grant any
## rights to the materials distributed herewith. Except as
## otherwise provided in a valid license issued to you by
## Xilinx, and to the maximum extent permitted by applicable
## law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
## WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
## AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
## BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
## INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
## (2) Xilinx shall not be liable (whether in contract or tort,
## including negligence, or under any other theory of
## liability) for any loss or damage of any kind or nature
## related to, arising under or in connection with these
## materials, including for any direct, or any indirect,
## special, incidental, or consequential loss or damage
## (including loss of data, profits, goodwill, or any type of
## loss or damage suffered as a result of any action brought
## by a third party) even if such damage or loss was
## reasonably foreseeable or Xilinx had been advised of the
## possibility of the same.
##
## CRITICAL APPLICATIONS
## Xilinx products are not designed or intended to be fail-
## safe, or for use in any application requiring fail-safe
## performance, such as life-support or safety devices or
## systems, Class III medical devices, nuclear facilities,
## applications related to the deployment of airbags, or any
## other applications that could lead to death, personal
## injury, or severe property or environmental damage
## (individually and collectively, "Critical
## Applications"). Customer assumes the sole risk and
## liability of any use of Xilinx products in Critical
## Applications, subject only to applicable laws and
## regulations governing limitations on product liability.
##
## THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
## PART OF THIS FILE AT ALL TIMES.
# This script must be run with root permissions
# if [[ "$EUID" -ne 0 ]]; then
# echo "This script must be run as root."
# exit
# fi
# Get absolute path to this script with any symlinks resolved
realme=$(realpath $0)
scriptpath="${realme%/*}"
echo "This is create_xsabin.sh running from $scriptpath on $(date)"
# The directory above that is the human-readable installation path - probably /opt/xilinx/firmware/<card>/<family>/<partition>/
humanpath=${scriptpath%/*}
pushd $humanpath > /dev/null
# This script may be called during firmware upgrade, in which case the firmware product, branch, version and release
# are provided as script arguments, to help this script to select the new firmware file
if [[ "$#" -ge 4 ]]; then
firmware_upgrade_product=$1
firmware_upgrade_branch=$2
firmware_upgrade_version=$3
firmware_upgrade_release=$4
echo "Run for install of firmware $firmware_upgrade_product-$firmware_upgrade_branch version $firmware_upgrade_version release $firmware_upgrade_release"
elif [[ "$#" -eq 3 ]]; then
# If 3 script arguments, these are the partition name, version and release, so that this script can report them for debug
echo "Run for install of partition $1 version $2 release $3"
fi
# Find the partition_metadata.json link in the install directory
jsonlink="partition_metadata.json"
if [[ ! -e "$jsonlink" ]]; then
echo "Cannot find $jsonlink file in $humanpath - install failed"
exit 1
fi
# Find the machine-readable directory for this partition:
# this is the target of the partition_metadata.json link
if [[ ! -h "$jsonlink" ]]; then
echo "$jsonlink in $humanpath should be a symlink, but it is not - install failed"
exit 1
fi
jsonpath=$(readlink $jsonlink)
if [[ $? -ne 0 ]]; then
echo "Failed to read target of symlink $jsonlink in $humanpath - install failed"
exit 1
fi
if [[ ! -e "$jsonpath" ]]; then
echo "Target of symlink $jsonlink in $humanpath is $jsonpath, which does not exist - install failed"
exit 1
fi
echo "Metadata file is $jsonpath"
machinepath=${jsonpath%/*}
json=${jsonpath##*/}
echo "User install path is $humanpath"
echo "Machine-readable path is $machinepath"
pushd $machinepath > /dev/null
# Parse the partition_metadata.json file to find the required firmware
declare -A firmware
firmware_products=()
product=""
branch="mainline"
major="*"
minor="*"
revision="*"
while IFS= read -r line; do
key=${line#*\"}
key=${key%%\"*}
value=${line%\"*}
value=${value##*\"}
numvalue=$value
if [[ "$numvalue" =~ ^0x ]]; then
numvalue=$(($numvalue))
fi
case "$key" in
"firmware")
# Starts a new section: record current one (except if before the first section)
if [[ -n "$product" ]]; then
firmware_products+=($product)
firmware["$product.branch"]=$branch
firmware["$product.version"]="$major.$minor.$revision"
product=""
branch="mainline"
major="*"
minor="*"
revision="*"
fi
;;
"firmware_product_name")
product=${value,,}
;;
"firmware_branch_name")
branch=${value,,}
;;
"firmware_version_major")
major=$numvalue
;;
"firmware_version_minor")
minor=$numvalue
;;
"firmware_version_revision")
revision=$numvalue
;;
esac
done <<< "$(grep '\"firmware' $json)"
# Record last section
firmware_products+=($product)
firmware["$product.branch"]=$branch
firmware["$product.version"]="$major.$minor.$revision"
# Locate the required firmware in existing installed directories, and build xclbinutil options to add firmware
# For each firmware, there is already a symlink in the human-readable directory's firmware directory
# which points to the existing firmware install directory
firmware_opts=""
for product in "${firmware_products[@]}"; do
uc_product=${product^^}
branch=${firmware[$product.branch]}
version=${firmware[$product.version]}
link="$humanpath/firmware/$product-$branch"
if [[ ! -L "$link" ]]; then
echo "Expected symlink $link for required $product firmware, but this either does not exist or is not a symlink - install failed"
exit 1
fi
firmware_path=$(readlink -f $humanpath/firmware/$product-$branch)
if [[ ! -e "$firmware_path" ]]; then
echo "Required $product firmware install directory not found at $firmware_path. Unable to build xsabin files"
exit 1
fi
# Locate the required firmware binary file
case "$product" in
"ert")
# ERT firmware is deployed within XRT and has its own file naming rule
if [[ "$branch" == "mainline" ]] || [[ "$branch" == "legacy" ]] || [[ "$branch" == "" ]]; then
ert_name="sched.bin"
else
ert_name="sched_$branch.bin"
fi
firmware_file="$firmware_path/$ert_name"
if [[ ! -e "$firmware_file" ]]; then
echo "Cannot locate required $product firmware: not found at $firmware_file. Unable to build xsabin files"
exit 1
fi
firmware_opts+=" --add-section SCHED_FIRMWARE:RAW:${firmware_file}"
;;
*)
# All other firmware is deployed in its own package
# Accommodate possible variations in firmware file name, as long as the file name contains the product name
# During firmware upgrade, it is possible that both the old and the new firmware files are both present
# (the old one may not be removed until after this script has run).
# In this situation, the new firmware product, branch and version are provided as script arguments:
# select the appropriate file here (if multiple files are found).
firmware_files=()
for globfile in $firmware_path/*; do
if [[ -e "$globfile" ]] && [[ ! -d "$globfile" ]]; then
globfilename=${globfile##*/}
if [[ "$globfilename" == *"$product"* ]] || [[ "$globfilename" == *"$uc_product"* ]]; then
firmware_files+=($globfile)
fi
fi
done
if [[ "${#firmware_files[@]}" -eq 0 ]]; then
echo "Cannot locate required $product firmware: not found at $firmware_path. Unable to build xsabin files"
exit 1
fi
firmware_file=""
if [[ "${#firmware_files[@]}" -gt 1 ]]; then
IFS=$'\n'
firmware_files=( $(sort -V <<<"${firmware_files[*]}") )
unset IFS
if [[ "$firmware_upgrade_product" == "$product" ]]; then
firmware_file=""
for fw_file in "${firmware_files[@]}"; do
fw_filename=${fw_file##*/}
if [[ "$fw_filename" == *"$firmware_upgrade_version"* ]]; then
firmware_file=$fw_file
fi
done
fi
fi
if [[ -z "$firmware_file" ]]; then
firmware_file="${firmware_files[-1]}"
fi
# Select the correct xsabin section name, depending on the firmware product
section=""
case "$product" in
"cmc")
section="FIRMWARE"
;;
"sc-fw" | "sc")
section="BMC-FW"
;;
*)
echo "Unrecognised firmware product name '$product', unable to select the correct xsabin section name"
exit 1
;;
esac
firmware_opts+=" --add-section ${section}:RAW:${firmware_file}"
# The SC firmware (BMC-FW section) may have a metadata JSON file also to be added
if [[ "$section" == "BMC-FW" && -e "$firmware_path/metadata.json" ]]; then
firmware_opts+=" --add-section BMC-METADATA:JSON:${firmware_path}/metadata.json"
fi
;;
esac
done
# Extract vendor, board, name and version from partition_metadata.json, to build PlatformVBNV
declare -A vbnv
for element in {partition_vendor,partition_card,partition_family,partition_name,installed_package_version}; do
line="$(grep $element $json)"
if [[ -n "$line" ]]; then
value=${line%\"*}
value=${value##*\"}
if [[ "$element" != "partition_vendor" ]] && [[ "$element" != "partition_card" ]]; then
value=${value//-/_}
fi
else
value="UNKNOWN"
fi
vbnv[$element]=$value
done
platform_vbnv="${vbnv[partition_vendor]}:${vbnv[partition_card]}:${vbnv[partition_family]}_${vbnv[partition_name]}:${vbnv[installed_package_version]}"
# Check for VBNV override in partition_metadata.json
line="$(grep vbnv_override $json)"
if [[ -n "$line" ]]; then
value=${line%\"*}
value=${value##*\"}
# Check VBNV override value is correctly formatted (4 fields separated by colons)
fields="$(echo "$value" | tr ':' ' ' | wc -w)"
if [[ "$fields" == "4" ]]; then
platform_vbnv=$value
fi
fi
# Use the XRT standard install path to find xclbinutil
xclbinutil="${xclbinutil:-/opt/xilinx/xrt/bin/xclbinutil}"
if [[ ! -e "$xclbinutil" ]]; then
echo "xclbinutil tool not found at $xclbinutil, unable to build xsabin files"
exit 1
fi
## Must source XRT's setup.sh to set up environment correctly
#if [[ ! -e /opt/xilinx/xrt/setup.sh ]]; then
# echo "XRT setup.sh not found at /opt/xilinx/xrt/setup.sh, XRT installation is bad. Cannot build xsabin files"
# exit 1
#fi
#source /opt/xilinx/xrt/setup.sh
# Build xclbinutil options for creating xsabin files
xclbinopts=" --force"
if [[ -e "partition.mcs" ]]; then
xclbinopts+=" --add-section MCS-PRIMARY:RAW:partition.mcs"
fi
if [[ -e "partition_secondary.mcs" ]]; then
xclbinopts+=" --add-section MCS-SECONDARY:RAW:partition_secondary.mcs"
fi
if [[ -e "partition.bin" ]]; then
xclbinopts+=" --add-section FLASH[BIN]-DATA:RAW:partition.bin"
fi
if [[ -e "bin_metadata.json" ]]; then
xclbinopts+=" --add-section FLASH[BIN]-METADATA:JSON:bin_metadata.json"
fi
if [[ -e "partition.bit" ]]; then
xclbinopts+=" --add-section BITSTREAM:RAW:partition.bit"
fi
if [[ -e "partition.pdi" ]]; then
xclbinopts+=" --add-section PDI:RAW:partition.pdi"
fi
xclbinopts+=" --add-section PARTITION_METADATA:JSON:${json}"
xclbinopts+=$firmware_opts
xclbinopts+=" --key-value SYS:PlatformVBNV:${platform_vbnv}"
# Create partition.xsabin
xsabin="partition.xsabin"
xclbincmd="${xclbinutil} ${xclbinopts} --output $xsabin"
echo $xclbincmd
$xclbincmd
if [[ $? -ne 0 ]]; then
echo "An error occurred while running xclbinutil"
exit 1
fi
if [[ ! -e "$xsabin" ]]; then
echo "xclbinutil did not create output file $xsabin"
exit 1
fi
# And we're done
echo "create_xsabin.sh completed successfully"

75
m/raccoon/xilinx-fw.nix Normal file
View File

@ -0,0 +1,75 @@
{
stdenv
, lib
, dpkg
, fetchurl
, xilinx-xrt
}:
with lib;
# Must read: https://xilinx.github.io/XRT/master/html/platforms_partitions.html#shell
# Taken from:
# - https://aur.archlinux.org/packages/xilinx-sc-fw-u280
# - https://aur.archlinux.org/packages/xilinx-u280-gen3x16-xdma-base
stdenv.mkDerivation rec {
pname = "xilinx-fw";
version = "1.3.5-3592445";
srcs = [
# List packages with: curl https://packages.xilinx.com/artifactory/debian-packages-cache/pool/
(fetchurl {
url = "https://packages.xilinx.com/artifactory/debian-packages-cache/pool/xilinx-cmc-u280_1.3.5-3592445_all.deb";
hash = "sha256-H48bdeuBc9dK6LExMnw1RCfY85PKntBk/X8CMcAI+zI=";
})
(fetchurl {
url = "https://packages.xilinx.com/artifactory/debian-packages-cache/pool/xilinx-sc-fw-u280_4.3.28-1.ea1b92f_all.deb";
hash = "sha256-JxQal2IqYAgebAgfjs2noFG5ghxC9sJQFppJFUCx6jA=";
})
(fetchurl {
url = "https://packages.xilinx.com/artifactory/debian-packages-cache/pool/xilinx-u280-gen3x16-xdma-base_1-3585717_all.deb";
hash = "sha256-oe84YgmmRFZjNa63j0pIneuFUG0Bb4aA7wulyU4bCrY=";
})
(fetchurl {
url = "https://packages.xilinx.com/artifactory/debian-packages-cache/pool/xilinx-u280-gen3x16-xdma-validate_1-3585755_all.deb";
hash = "sha256-F+IAzR8NVc9FDsgQstpBcKeq3ogH1PI8nuq94sEExCg=";
})
# Needed for the ERT firmware
(fetchurl {
url = "https://packages.xilinx.com/artifactory/debian-packages-cache/pool/xrt_202320.2.16.204_22.04-amd64-xrt.deb";
hash = "sha256-FEhzx2KlIYpunXmTSBjtyAtblbuz5tkvnt2qp21gUho=";
})
];
dontStrip = true;
hardeningDisable = [ "all" ];
nativeBuildInputs = [ dpkg ];
unpackPhase = ''
for f in $srcs; do
dpkg-deb -x "$f" deb
done
sourceRoot=deb
'';
# Generate the xsabin firmware file by fixing the original script
buildPhase = ''
set -x
ln -rs lib/firmware/xilinx/283bab8f654d8674968f4da57f7fa5d7 lib/firmware/xilinx/fb2b2c5a19ed63593fea95f51fbc8eb9
ln -rs lib/firmware/xilinx/283bab8f654d8674968f4da57f7fa5d7/partition_metadata.json opt/xilinx/firmware/u280/gen3x16-xdma/base/partition_metadata.json
ln -rs lib/firmware/xilinx/283bab8f654d8674968f4da57f7fa5d7/partition.xsabin opt/xilinx/firmware/u280/gen3x16-xdma/base/partition.xsabin
ln -rs opt/xilinx/xrt/share/fw opt/xilinx/firmware/u280/gen3x16-xdma/base/firmware/ert-v30
ln -rs opt/xilinx/firmware/cmc/u280 opt/xilinx/firmware/u280/gen3x16-xdma/base/firmware/cmc-u280
ln -rs opt/xilinx/firmware/sc-fw/u280 opt/xilinx/firmware/u280/gen3x16-xdma/base/firmware/sc-fw-u280
find
export xclbinutil=${xilinx-xrt}/xrt/bin/xclbinutil
cp -a ${./xilinx-create-xsabin.sh} opt/xilinx/firmware/u280/gen3x16-xdma/base/scripts/create_xsabin.sh
bash -x opt/xilinx/firmware/u280/gen3x16-xdma/base/scripts/create_xsabin.sh xilinx-u280-gen3x16-xdma-base 1 3585717
set +x
'';
installPhase = ''
mkdir -p $out
cp -a * $out
'';
}

View File

@ -46,6 +46,11 @@ stdenv.mkDerivation rec {
"-DXRT_INSTALL_DIR=${placeholder "out"}"
"-DXRT_NATIVE_BUILD=yes"
"-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON"
# Enable debug
"-DCMAKE_BUILD_TYPE=RelWithDebInfo"
#"-DCMAKE_BUILD_TYPE=Debug"
#"-DXOCL_VERBOSE=1"
#"-DXRT_VERBOSE=1"
];
# A directory named "build" already exists
cmakeBuildDir = "the-build";