diff --git a/CMake/pkg.cmake b/CMake/pkg.cmake index d41199d9..b590c1f3 100644 --- a/CMake/pkg.cmake +++ b/CMake/pkg.cmake @@ -28,11 +28,15 @@ execute_process( OUTPUT_VARIABLE XDNA_CPACK_LINUX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) -execute_process( - COMMAND bash -c "source /etc/os-release && echo \"\$ID \$ID_LIKE\"" - OUTPUT_VARIABLE XDNA_CPACK_LINUX_PKG_FLAVOR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) +if (EXISTS "/etc/arch-release") + set(XDNA_CPACK_LINUX_PKG_FLAVOR "arch") +else() + execute_process( + COMMAND bash -c "source /etc/os-release && echo \"\$ID \$ID_LIKE\"" + OUTPUT_VARIABLE XDNA_CPACK_LINUX_PKG_FLAVOR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() execute_process( COMMAND echo ${XRT_VERSION_STRING} COMMAND awk -F. "{print $1}" @@ -129,8 +133,22 @@ elseif("${XDNA_CPACK_LINUX_PKG_FLAVOR}" MATCHES "fedora") set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/package/postinst") set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/package/prerm") endif() -else("${XDNA_CPACK_LINUX_PKG_FLAVOR}" MATCHES "debian") - message(WARNING "Unknown Linux package flavor: ${XDNA_CPACK_LINUX_PKG_FLAVOR}") -endif("${XDNA_CPACK_LINUX_PKG_FLAVOR}" MATCHES "debian") +elseif("${XDNA_CPACK_LINUX_PKG_FLAVOR}" MATCHES "arch") + set(CPACK_GENERATOR "TGZ") + # For Arch Linux, we generate a tarball that can be repackaged into a proper + # Arch package using the provided PKGBUILD. When using the PKGBUILD, install + # hooks handle post-install/pre-remove automatically via pacman. + set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) + message(STATUS "Arch Linux detected - generating TGZ package") + if(NOT SKIP_KMOD) + message(STATUS "Post-install script: ${CMAKE_CURRENT_BINARY_DIR}/package/postinst") + message(STATUS "Pre-remove script: ${CMAKE_CURRENT_BINARY_DIR}/package/prerm") + message(STATUS "Note: Use the provided PKGBUILD to create an Arch package with proper install hooks") + endif() +else() + message(FATAL_ERROR "Unknown Linux package flavor: ${XDNA_CPACK_LINUX_PKG_FLAVOR}. " + "Supported distributions: Debian/Ubuntu (deb), Fedora/RHEL (rpm), Arch Linux (TGZ). " + "To add support for your distribution, please open an issue at https://github.com/amd/xdna-driver/issues") +endif() include(CPack) diff --git a/README.md b/README.md index faa4d1bf..448a8e03 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ cd exit ``` -### Steps to create release build DEB package: +### Steps to create release build DEB package (Ubuntu/Debian): ``` bash cd /build @@ -121,7 +121,53 @@ cd ../../build # To adapt according to your OS & version sudo apt reinstall ./Release/xrt_plugin.2.19.0_ubuntu22.04-x86_64-amdxdna.deb ``` -You will find `xrt_plugin\*-amdxdna.deb` in Release/ folder. This package includes: + +### Steps to create release build packages (Arch Linux): + +``` bash +cd + +# Install dependencies (requires sudo) +sudo ./tools/amdxdna_deps.sh + +# Get submodules +git submodule update --init --recursive + +# Build XRT +cd xrt/build +./build.sh -npu -opt + +# Build and install XRT packages using pacman +# PKGBUILDs are in xrt/build/arch/ +cd arch +makepkg -p PKGBUILD-xrt-base +sudo pacman -U xrt-base-*.pkg.tar.zst + +makepkg -p PKGBUILD-xrt-npu +sudo pacman -U xrt-npu-*.pkg.tar.zst + +# Build XDNA driver +cd ../../../build +./build.sh -release + +# Build and install XDNA plugin package +makepkg -p PKGBUILD-xrt-plugin +sudo pacman -U xrt-plugin-amdxdna-*.pkg.tar.zst + +# Configure memory limits (required for NPU access) +sudo bash -c 'echo "* soft memlock unlimited" >> /etc/security/limits.conf' +sudo bash -c 'echo "* hard memlock unlimited" >> /etc/security/limits.conf' + +# Log out and log back in (or reboot) for memory limit changes to take effect +``` + +**Note for Arch Linux users**: The build system generates `.tar.gz` packages which are repackaged into proper Arch packages (`.pkg.tar.zst`) using the provided PKGBUILDs: +- XRT packages: `xrt/build/arch/` (PKGBUILD-xrt-base, PKGBUILD-xrt-npu) +- XDNA driver: `build/` directory (PKGBUILD-xrt-plugin) + +This ensures proper integration with pacman for installation, upgrades, and removal. + +You will find `xrt_plugin*-amdxdna.deb` (Ubuntu/Debian) or `xrt_plugin*.tar.gz` (Arch Linux) in Release/ folder. This package includes: * The `.so` library files, which will be installed into `/opt/xilinx/xrt/lib` folder * The XDNA driver and DKMS script, which build, install and load `amdxdna.ko` driver when installing the .DEB package on target machine diff --git a/build/PKGBUILD-xrt-plugin b/build/PKGBUILD-xrt-plugin new file mode 100644 index 00000000..f9bf3ec4 --- /dev/null +++ b/build/PKGBUILD-xrt-plugin @@ -0,0 +1,43 @@ +# Maintainer: Your Name +pkgname=xrt-plugin-amdxdna +pkgver=2.21.0 +pkgrel=1 +pkgdesc="AMD XDNA Driver plugin for Xilinx RunTime" +arch=('x86_64') +url="https://github.com/amd/xdna-driver" +license=('Apache-2.0') +depends=('xrt-base' 'xrt-npu' 'dkms' 'linux-headers') +provides=('xrt-plugin-amdxdna') +conflicts=('amdxdna-driver' 'amdxdna-driver-bin') +install=xrt-plugin-amdxdna.install + +# Set this to your xdna-driver build output directory (relative to $startdir, the PKGBUILD's directory) +: ${XDNA_BUILD_DIR:="Release"} + +package() { + cd "$srcdir" + + # Extract the tarball directly into the package directory + # The tarball should be at $startdir/$XDNA_BUILD_DIR/xrt_plugin*.tar.gz + # Use nullglob to handle case where no files match the glob pattern + local _nullglob_set=$(shopt -p nullglob) + shopt -s nullglob + local tarballs=("$startdir/${XDNA_BUILD_DIR}"/xrt_plugin*-amdxdna.tar.gz) + $_nullglob_set + if [ ${#tarballs[@]} -eq 0 ] || [ ! -f "${tarballs[0]}" ]; then + error "XDNA plugin tarball not found in ${XDNA_BUILD_DIR}" + error "Please build XDNA driver first: cd build && ./build.sh -release" + return 1 + fi + + local tarball="${tarballs[0]}" + msg2 "Extracting $tarball" + tar -xzf "$tarball" -C "$pkgdir" + + # Copy the install scripts for reference (they'll be called from .install file) + mkdir -p "$pkgdir/opt/xilinx/xrt/share/amdxdna/package" + install -Dm755 "$startdir/${XDNA_BUILD_DIR}/package/postinst" \ + "$pkgdir/opt/xilinx/xrt/share/amdxdna/package/postinst" + install -Dm755 "$startdir/${XDNA_BUILD_DIR}/package/prerm" \ + "$pkgdir/opt/xilinx/xrt/share/amdxdna/package/prerm" +} diff --git a/build/xrt-plugin-amdxdna.install b/build/xrt-plugin-amdxdna.install new file mode 100644 index 00000000..20bea020 --- /dev/null +++ b/build/xrt-plugin-amdxdna.install @@ -0,0 +1,75 @@ +post_install() { + echo "Installing AMD XDNA driver via DKMS..." + + install_datadir=/opt/xilinx/xrt/share/amdxdna + udev_rules_d=/etc/udev/rules.d + amdxdna_rules_file=99-amdxdna.rules + dracut_conf_d=/etc/dracut.conf.d + dracut_conf_file=amdxdna.dracut.conf + + # On systems with dracut, exclude driver from initramfs + if [ -d ${dracut_conf_d} ]; then + if [ ! -f ${dracut_conf_d}/${dracut_conf_file} ]; then + touch ${dracut_conf_d}/${dracut_conf_file} + fi + grep -q '^omit_drivers\+=\" amdxdna \"' "${dracut_conf_d}/${dracut_conf_file}" || echo 'omit_drivers+=" amdxdna "' >> "${dracut_conf_d}/${dracut_conf_file}" + fi + + # Install DKMS module + echo "Installing amdxdna Linux kernel module via DKMS..." + if [ ! -x "$install_datadir/dkms_driver.sh" ]; then + echo "Error: $install_datadir/dkms_driver.sh not found or not executable." >&2 + return 1 + fi + "$install_datadir/dkms_driver.sh" --install + + # Setup udev rules + echo "Setting up udev rules..." + if [ ! -f ${udev_rules_d}/${amdxdna_rules_file} ]; then + touch ${udev_rules_d}/${amdxdna_rules_file} + fi + grep -q '^KERNEL=="accel\*",DRIVERS=="amdxdna",MODE="0666"$' ${udev_rules_d}/${amdxdna_rules_file} || \ + echo 'KERNEL=="accel*",DRIVERS=="amdxdna",MODE="0666"' >> ${udev_rules_d}/${amdxdna_rules_file} + + # Load the kernel module + echo "Loading amdxdna kernel module..." + rmmod amdxdna > /dev/null 2>&1 || true + modprobe amdxdna || echo "Warning: Failed to load amdxdna module. Check dmesg for details." + + echo "AMD XDNA driver installation complete!" + echo "You can test it with: source /opt/xilinx/xrt/setup.sh && xrt-smi validate" +} + +post_upgrade() { + post_install +} + +pre_remove() { + echo "Removing AMD XDNA driver..." + + install_datadir=/opt/xilinx/xrt/share/amdxdna + udev_rules_d=/etc/udev/rules.d + amdxdna_rules_file=99-amdxdna.rules + dracut_conf_d=/etc/dracut.conf.d + dracut_conf_file=amdxdna.dracut.conf + + # Unload kernel module + if lsmod | grep -q "amdxdna"; then + rmmod amdxdna + fi + + # Remove dracut config + if [ -f ${dracut_conf_d}/${dracut_conf_file} ]; then + rm -f ${dracut_conf_d}/${dracut_conf_file} + fi + + # Remove udev rules + if [ -f ${udev_rules_d}/${amdxdna_rules_file} ]; then + rm -f ${udev_rules_d}/${amdxdna_rules_file} + fi + + # Remove DKMS module + $install_datadir/dkms_driver.sh --remove + + echo "AMD XDNA driver removed!" +} diff --git a/src/driver/amdxdna/Makefile b/src/driver/amdxdna/Makefile index caa0d670..c534a58f 100644 --- a/src/driver/amdxdna/Makefile +++ b/src/driver/amdxdna/Makefile @@ -41,6 +41,13 @@ endif XDNA_DRIVER_VERSION ?= 2.21.0 XDNA_DATE ?= $(shell date +%Y%m%d) XDNA_HASH ?= $(shell git rev-parse HEAD) +# Detect if kernel was built with Clang - check /proc/config.gz first, then /boot/config-* +USE_LLVM ?= $(shell \ + if [ -e /proc/config.gz ]; then \ + zgrep -q "CONFIG_CC_IS_CLANG=y" /proc/config.gz 2>/dev/null && echo -n "LLVM=1"; \ + elif [ -e /boot/config-$(KERNEL_VER) ]; then \ + grep -q "CONFIG_CC_IS_CLANG=y" /boot/config-$(KERNEL_VER) 2>/dev/null && echo -n "LLVM=1"; \ + fi) ifndef MODULE_VER_STR MODULE_VER_STR := $(XDNA_DRIVER_VERSION)_$(XDNA_DATE),$(XDNA_HASH) @@ -49,7 +56,7 @@ endif DEFINES += -DMODULE_VER_STR='\"$(MODULE_VER_STR)\"' modules: - $(MAKE) -C $(KERNEL_SRC) M=$(SRC_DIR) CFLAGS_MODULE="$(DEFINES)" OFT_CONFIG_AMDXDNA_PCI=$(PCI) OFT_CONFIG_AMDXDNA_OF=$(OF) modules + $(MAKE) -C $(KERNEL_SRC) M=$(SRC_DIR) CFLAGS_MODULE="$(DEFINES)" OFT_CONFIG_AMDXDNA_PCI=$(PCI) OFT_CONFIG_AMDXDNA_OF=$(OF) $(USE_LLVM) modules modules_install: $(MAKE) -C $(KERNEL_SRC) M=$(SRC_DIR) modules_install diff --git a/src/driver/amdxdna/aie2_pci.c b/src/driver/amdxdna/aie2_pci.c index 9dec6bff..10c3218c 100644 --- a/src/driver/amdxdna/aie2_pci.c +++ b/src/driver/amdxdna/aie2_pci.c @@ -1519,6 +1519,7 @@ static int aie2_get_coredump(struct amdxdna_client *client, struct amdxdna_drm_g static int aie2_get_array_hwctx(struct amdxdna_client *client, struct amdxdna_drm_get_array *args) { struct amdxdna_dev *xdna = client->xdna; + struct amdxdna_drm_hwctx_entry input = {}; struct amdxdna_drm_hwctx_entry *tmp; int ctx_limit, ctx_cnt, ret; u32 buf_size; @@ -1551,8 +1552,6 @@ static int aie2_get_array_hwctx(struct amdxdna_client *client, struct amdxdna_dr break; case DRM_AMDXDNA_HW_CONTEXT_BY_ID: - struct amdxdna_drm_hwctx_entry input = {}; - ret = amdxdna_drm_copy_array_from_user(args, &input, sizeof(input), 1); if (ret) goto exit; diff --git a/src/driver/tools/configure_kernel.sh b/src/driver/tools/configure_kernel.sh index bf4b5083..b89b3f1a 100755 --- a/src/driver/tools/configure_kernel.sh +++ b/src/driver/tools/configure_kernel.sh @@ -41,6 +41,13 @@ try_compile() { tmpdir=$(mktemp -d /tmp/conftest-XXXXXX) conftest_c="$tmpdir/conftest.c" conftest_mk="$tmpdir/Makefile" + USE_LLVM="" + if [ -e /proc/config.gz ]; then + USE_LLVM=$(zgrep -q "CONFIG_CC_IS_CLANG=y" /proc/config.gz 2>/dev/null && echo -n "LLVM=1"); + elif [ -e /boot/config-$(KERNEL_VER) ]; then + USE_LLVM=$(grep -q "CONFIG_CC_IS_CLANG=y" /boot/config-$(KERNEL_VER) 2>/dev/null && echo -n "LLVM=1"); + fi + # Minimal Kbuild for an external module cat > "$conftest_mk" <> "$conftest_c" # Now build it like your real driver - if make -s -C "$KERNEL_SRC" M="$tmpdir" modules >/dev/null 2>&1; then + if make -s -C "$KERNEL_SRC" M="$tmpdir" modules "$USE_LLVM" >/dev/null 2>&1; then echo "#define $macro 1" >> "$OUT" echo ">>> + $macro: yes" >&2 else diff --git a/tools/amdxdna_deps.sh b/tools/amdxdna_deps.sh index 35dca97b..9560b8be 100755 --- a/tools/amdxdna_deps.sh +++ b/tools/amdxdna_deps.sh @@ -10,6 +10,8 @@ if [ -x "$(command -v apt-get)" ]; then apt-get install -y jq elif [ -x "$(command -v dnf)" ]; then dnf install -y jq +elif [ -x "$(command -v pacman)" ]; then + pacman -S --needed --noconfirm jq fi $SCRIPT_DIR/../xrt/src/runtime_src/tools/scripts/xrtdeps.sh