diff --git a/pkgs/default.nix b/pkgs/default.nix index 8e55a37..81d9e04 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -8,6 +8,7 @@ }: { ncurses5-fhs = pkgs.callPackage ./ncurses5-fhs.nix {}; + fpga-udev-rules = pkgs.callPackage ./fpga-udev-rules {}; # OpenTitan packages verilator_ot = import ./verilator {inherit pkgs;}; diff --git a/pkgs/fpga-udev-rules/62-lowrisc.rules b/pkgs/fpga-udev-rules/62-lowrisc.rules new file mode 100644 index 0000000..ff5cf99 --- /dev/null +++ b/pkgs/fpga-udev-rules/62-lowrisc.rules @@ -0,0 +1,34 @@ +# Copyright lowRISC contributors. +# +# SPDX-License-Identifier: MIT + +# This list is taken from the OpenTitan documentation +# * https://opentitan.org/book/doc/getting_started/install_vivado/index.html?highlight=udev#device-permissions-udev-rules +# and HyperDebug documentation +# * https://github.com/lowRISC/hyperdebug-firmware/blob/main/90-hyperdebug.rules + +# 90-lowrisc.rules + +# NewAE Technology Inc. ChipWhisperer boards e.g. CW310, CW305, CW-Lite, CW-Husky +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="2b3e", ATTRS{idProduct}=="ace[0-9]|c[3-6][0-9][0-9]", ENV{ID_FPGA}="1" + +# Digilent rule removed because it's covered by Xilinx rules. + +# Future Technology Devices International, Ltd FT232 Serial (UART) IC +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ENV{ID_FPGA}="1" + +# Future Technology Devices International, Ltd FT4232H Quad HS USB-UART/FIFO IC +# used on the CW340 +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6011", ENV{ID_FPGA}="1" + +# HyperDebug +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="520e", ENV{ID_FPGA}="1" + +# HyperDebug DFU (actually, any ST microcontroller in DFU mode) +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", ENV{ID_FPGA}="1" + +# Olimex ARM-USB-TINY-H +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002a", ENV{ID_FPGA}="1" + +# USB device under test: uses Google as VID and a google allocated PID +SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="503a", ENV{ID_FPGA}="1" diff --git a/pkgs/fpga-udev-rules/62-xilinx.rules b/pkgs/fpga-udev-rules/62-xilinx.rules new file mode 100644 index 0000000..6045671 --- /dev/null +++ b/pkgs/fpga-udev-rules/62-xilinx.rules @@ -0,0 +1,27 @@ +# Copyright lowRISC contributors. +# +# SPDX-License-Identifier: MIT + +# This list is taken from xilinx UG973. +# * https://docs.amd.com/r/en-US/ug973-vivado-release-notes-install-license/Installing-Cable-Drivers +# * https://digilent.com/reference/programmable-logic/guides/install-cable-drivers + +# 52-xilinx-digilent-usb.rules + +ATTRS{idVendor}=="1443", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="0403", ATTRS{manufacturer}=="Digilent", ENV{ID_FPGA}="1" + +# 52-xilinx-ftdi-usb.rules + +ATTRS{idVendor}=="0403", ATTRS{manufacturer}=="Xilinx", ENV{ID_FPGA}="1" + +# 52-xilinx-pcusb.rules + +# These rules are changed from `ATTR` to `ATTRS`, see https://support.xilinx.com/s/question/0D52E000074LyuDSAS/bug-udev-rules-badly-written +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0008", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0007", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0009", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="000d", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="000f", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0013", ENV{ID_FPGA}="1" +ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0015", ENV{ID_FPGA}="1" diff --git a/pkgs/fpga-udev-rules/70-fpga-uaccess.rules b/pkgs/fpga-udev-rules/70-fpga-uaccess.rules new file mode 100644 index 0000000..f4722d5 --- /dev/null +++ b/pkgs/fpga-udev-rules/70-fpga-uaccess.rules @@ -0,0 +1,24 @@ +# Copyright lowRISC contributors. +# +# SPDX-License-Identifier: MIT + +# Most FPGA rules set mode to 666 makes it globally writable, and this is not secure. Ubuntu uses a plugdev group, +# which is considered a bad practice by Arch Linux and systemd developers. +# See https://wiki.archlinux.org/title/Udev and https://bugzilla.redhat.com/show_bug.cgi?id=815093. +# +# The modern approach is to first, identify which type a device is, and then assign it to a specific group (e.g. +# disk, cdrom, dialout) or set the "uaccess" tag. "uaccess" tag allows all users with seats allocated (i.e. have physical +# access) to access the device with dynamic ACL. This is both zero-configuration and more secure. +# +# We replicate this approach and have FPGA rules that just set an identification tag, and this file will give it "uaccess" +# flag. The identication rules should have priority between 61 and 69 so they takes priority over systemd-provided device +# identiciation rules which all uses 60- prefix, and before this rule. +# +# This rule uses 70- priority which matches systemd 70-uaccess.rules, and it must be smaller than 73-seat-late.rules. + +# We do not set group here becuase `plugdev` group is non-standard, and as mentioned above, discouraged. +# For FPGA machines that need user to SSH into them to use, one can add another rule like: +# ``` +# ACTION="add|change", ENV{ID_FPGA}=="1", GROUP="plugdev", MODE="0660" +# ``` +ACTION=="add|change", ENV{ID_FPGA}=="1", TAG+="uaccess" diff --git a/pkgs/fpga-udev-rules/default.nix b/pkgs/fpga-udev-rules/default.nix new file mode 100644 index 0000000..1325730 --- /dev/null +++ b/pkgs/fpga-udev-rules/default.nix @@ -0,0 +1,8 @@ +# Copyright lowRISC contributors. +# +# SPDX-License-Identifier: MIT +{runCommand}: +runCommand "fpga-udev-rules" {} '' + mkdir -p $out/etc/udev/rules.d + cp ${./.}/*.rules $out/etc/udev/rules.d/ +''