feat(fpga): Auto-detect CB FPGA BDF at source time
blanton_fpga_pcimem.sh V1.5.0. The four FUNCT0..3_RES sysfs paths were hard-coded and had to be edited for every DUT, because the CB FPGA's BDF changes with the PCIe enumeration (0000:03:00.x / 0000:05:00.x seen so far). Detection order at source time: FPGA_BDF override -> sysfs scan for vendor 0x1590 with all four functions exposing resource0 -> lspci -Dnn name/id match -> FPGA_BDF_FALLBACK. Adds fpga_rescan for a DUT swap, FPGA_BDF / FPGA_VENDOR_ID / FPGA_LSPCI_MATCH overrides, FPGA_BDF_ACTIVE reporting and FPGA_QUIET. Detection runs once, so cb_fpga / pmc / icb / swb keep zero per-command overhead.
This commit is contained in:
@@ -17,10 +17,21 @@
|
|||||||
# V1.4.2 2026-08-10 Change: FUNCT0..3_RES BDF updated 0000:04:00.x -> 0000:03:00.x (current unit's enumeration).
|
# V1.4.2 2026-08-10 Change: FUNCT0..3_RES BDF updated 0000:04:00.x -> 0000:03:00.x (current unit's enumeration).
|
||||||
# V1.4.3 2026-08-12 Change: FUNCT0..3_RES BDF updated 0000:03:00.x -> 0000:05:00.x (current unit's enumeration).
|
# V1.4.3 2026-08-12 Change: FUNCT0..3_RES BDF updated 0000:03:00.x -> 0000:05:00.x (current unit's enumeration).
|
||||||
# V1.4.4 2026-08-12 Change: FUNCT0..3_RES BDF back to 0000:03:00.x for the DUT on COM36.
|
# V1.4.4 2026-08-12 Change: FUNCT0..3_RES BDF back to 0000:03:00.x for the DUT on COM36.
|
||||||
# NOTE: this BDF is per-unit. Check with
|
# V1.5.0 2026-08-17 Change: BDF is no longer hard-coded. FUNCT0..3_RES are now
|
||||||
# lspci -Dnn | grep -i fpga or
|
# auto-detected at source time by scanning sysfs for the HPE
|
||||||
# ls -d /sys/bus/pci/devices/0000:*:00.3
|
# vendor id (0x1590) with all four functions .0-.3 present,
|
||||||
# and edit the four lines below if it differs.
|
# falling back to `lspci -Dnn` name/id match, then to
|
||||||
|
# FPGA_BDF_FALLBACK. No more editing this file per DUT.
|
||||||
|
# Add: fpga_rescan (re-detect after DUT swap / re-enumeration),
|
||||||
|
# FPGA_BDF / FPGA_VENDOR_ID / FPGA_LSPCI_MATCH overrides,
|
||||||
|
# FPGA_BDF_ACTIVE reporting the BDF in use.
|
||||||
|
# Note: detection runs ONCE at source time (one INFO line on
|
||||||
|
# stdout, WARN/FAIL on stderr). FPGA_QUIET=1 silences the
|
||||||
|
# INFO line. cb_fpga/pmc/icb/swb never re-scan, so there is
|
||||||
|
# no per-command output and no per-command overhead.
|
||||||
|
# NOTE: the old per-unit NOTE ("edit the four lines below")
|
||||||
|
# no longer applies - detection handles it. To pin a BDF
|
||||||
|
# manually: FPGA_BDF=0000:05:00 fpga_rescan
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
#
|
#
|
||||||
# SONiC hardware has no memtool / devmem, but it has pcimem. pcimem mmaps the PCI
|
# SONiC hardware has no memtool / devmem, but it has pcimem. pcimem mmaps the PCI
|
||||||
@@ -42,26 +53,112 @@
|
|||||||
# icb_fpga <addr> [data]
|
# icb_fpga <addr> [data]
|
||||||
# swb0_fpga <addr> [data]
|
# swb0_fpga <addr> [data]
|
||||||
# swb1_fpga <addr> [data]
|
# swb1_fpga <addr> [data]
|
||||||
|
# fpga_rescan re-detect the CB FPGA BDF (after a DUT swap)
|
||||||
#
|
#
|
||||||
# data present = write, absent = read.
|
# data present = write, absent = read.
|
||||||
# Usage: source blanton_fpga_pcimem.sh
|
# Usage: source blanton_fpga_pcimem.sh
|
||||||
|
|
||||||
# === CB FPGA PCIe resource file (sysfs) ===
|
# === CB FPGA PCIe resource file (sysfs) - AUTO-DETECTED ===
|
||||||
# Use lspci -D to find the BDF (domain:bus:dev.fn); resource0 is the sysfs mapping of BAR0.
|
# The CB FPGA's BDF (domain:bus:dev.fn) changes per unit / per enumeration, so it is
|
||||||
# e.g. lspci -Dnn | grep -i fpga -> 0000:02:00.0 ...
|
# detected at source time instead of being hard-coded. resource0 is the sysfs mapping
|
||||||
# memtool variant fills in the BAR value; pcimem variant fills in the resource file
|
# of BAR0. (memtool variant fills in the BAR value; pcimem variant fills in the
|
||||||
# path instead (offset becomes relative to BAR).
|
# resource file path instead, so offsets become relative to BAR.)
|
||||||
FUNCT0_RES=/sys/bus/pci/devices/0000:03:00.0/resource0
|
#
|
||||||
FUNCT1_RES=/sys/bus/pci/devices/0000:03:00.1/resource0
|
# Detection order:
|
||||||
FUNCT2_RES=/sys/bus/pci/devices/0000:03:00.2/resource0
|
# 1. FPGA_BDF override e.g. FPGA_BDF=0000:05:00 (domain:bus:dev, WITHOUT .fn)
|
||||||
FUNCT3_RES=/sys/bus/pci/devices/0000:03:00.3/resource0
|
# 2. sysfs vendor scan /sys/bus/pci/devices/*.0 whose vendor == FPGA_VENDOR_ID
|
||||||
|
# (0x1590 = Hewlett Packard Enterprise) and that has all
|
||||||
|
# four functions .0 .1 .2 .3 exposing resource0
|
||||||
|
# 3. lspci -Dnn fallback lines matching FPGA_LSPCI_MATCH
|
||||||
|
# ("Hewlett Packard Enterprise" or vendor id "[1590:")
|
||||||
|
# 4. FPGA_BDF_FALLBACK last-known BDF, only if 1-3 all fail
|
||||||
|
#
|
||||||
|
# Overrides (export before sourcing, or set and call fpga_rescan afterwards):
|
||||||
|
# FPGA_BDF=0000:05:00 pin a specific device, skip detection
|
||||||
|
# FPGA_VENDOR_ID=0x10ee different vendor (e.g. a Xilinx-branded board)
|
||||||
|
# FPGA_LSPCI_MATCH='...' custom lspci grep -iE pattern
|
||||||
|
FPGA_VENDOR_ID="${FPGA_VENDOR_ID:-0x1590}"
|
||||||
|
FPGA_LSPCI_MATCH="${FPGA_LSPCI_MATCH:-Hewlett Packard Enterprise|\[1590:}"
|
||||||
|
FPGA_BDF_FALLBACK="${FPGA_BDF_FALLBACK:-0000:03:00}"
|
||||||
|
|
||||||
# Auto-detect example (uncomment to use; needs the FPGA's BDF prefix):
|
# True if all four functions of <bdf> exist and expose resource0.
|
||||||
# _BDF=0000:02:00
|
# Usage: _fpga_bdf_ok <domain:bus:dev>
|
||||||
# FUNCT0_RES=/sys/bus/pci/devices/${_BDF}.0/resource0
|
_fpga_bdf_ok() {
|
||||||
# FUNCT1_RES=/sys/bus/pci/devices/${_BDF}.1/resource0
|
local bdf="$1" fn
|
||||||
# FUNCT2_RES=/sys/bus/pci/devices/${_BDF}.2/resource0
|
for fn in 0 1 2 3; do
|
||||||
# FUNCT3_RES=/sys/bus/pci/devices/${_BDF}.3/resource0
|
[ -e "/sys/bus/pci/devices/${bdf}.${fn}/resource0" ] || return 1
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print the detected FPGA BDF prefix (domain:bus:dev) on stdout; non-zero if none.
|
||||||
|
_fpga_detect_bdf() {
|
||||||
|
local cands="" bdf dir vend want
|
||||||
|
|
||||||
|
# 1. explicit override wins (tolerate a trailing ".fn" being included)
|
||||||
|
if [ -n "${FPGA_BDF:-}" ]; then
|
||||||
|
bdf="$FPGA_BDF"
|
||||||
|
case "$bdf" in *.[0-7]) bdf="${bdf%.*}" ;; esac
|
||||||
|
echo "$bdf"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
want=$(echo "$FPGA_VENDOR_ID" | tr 'A-Z' 'a-z')
|
||||||
|
|
||||||
|
# 2. sysfs vendor-ID scan (no lspci / pci.ids needed)
|
||||||
|
for dir in /sys/bus/pci/devices/*:*.0; do
|
||||||
|
[ -e "$dir/vendor" ] || continue
|
||||||
|
vend=$(tr 'A-Z' 'a-z' < "$dir/vendor" 2>/dev/null)
|
||||||
|
[ "$vend" = "$want" ] || continue
|
||||||
|
bdf="${dir##*/}"; bdf="${bdf%.0}"
|
||||||
|
_fpga_bdf_ok "$bdf" && cands="$cands $bdf"
|
||||||
|
done
|
||||||
|
|
||||||
|
# 3. lspci fallback (device name match, in case the vendor id differs)
|
||||||
|
if [ -z "$cands" ] && command -v lspci >/dev/null 2>&1; then
|
||||||
|
for bdf in $(lspci -Dnn 2>/dev/null | grep -iE "$FPGA_LSPCI_MATCH" \
|
||||||
|
| awk '{print $1}' | sed 's/\.[0-9a-f]*$//' | sort -u); do
|
||||||
|
_fpga_bdf_ok "$bdf" && cands="$cands $bdf"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -- $cands
|
||||||
|
[ $# -eq 0 ] && return 1
|
||||||
|
if [ $# -gt 1 ]; then
|
||||||
|
echo -e "[\033[33mWARN\033[0m] multiple candidate FPGAs found:$cands -> using $1" >&2
|
||||||
|
echo -e " set FPGA_BDF=<domain:bus:dev> and run fpga_rescan to pick another." >&2
|
||||||
|
fi
|
||||||
|
echo "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# (Re)detect the FPGA BDF and refresh FUNCT0..3_RES. Called once at source time;
|
||||||
|
# call again by hand after swapping/re-enumerating a DUT.
|
||||||
|
# The one-line INFO goes to STDOUT (so wrappers that already do
|
||||||
|
# `source ... >/dev/null` stay silent); WARN/FAIL go to STDERR.
|
||||||
|
# Set FPGA_QUIET=1 to suppress the INFO line entirely.
|
||||||
|
fpga_rescan() {
|
||||||
|
local bdf
|
||||||
|
bdf=$(_fpga_detect_bdf)
|
||||||
|
if [ -z "$bdf" ]; then
|
||||||
|
bdf="$FPGA_BDF_FALLBACK"
|
||||||
|
echo -e "[\033[33mWARN\033[0m] no FPGA found (vendor $FPGA_VENDOR_ID / '$FPGA_LSPCI_MATCH');" >&2
|
||||||
|
echo -e " falling back to $bdf. Check with: lspci -Dnn | grep -iE 'Hewlett|fpga'" >&2
|
||||||
|
fi
|
||||||
|
FPGA_BDF_ACTIVE="$bdf"
|
||||||
|
FUNCT0_RES=/sys/bus/pci/devices/${bdf}.0/resource0
|
||||||
|
FUNCT1_RES=/sys/bus/pci/devices/${bdf}.1/resource0
|
||||||
|
FUNCT2_RES=/sys/bus/pci/devices/${bdf}.2/resource0
|
||||||
|
FUNCT3_RES=/sys/bus/pci/devices/${bdf}.3/resource0
|
||||||
|
if _fpga_bdf_ok "$bdf"; then
|
||||||
|
[ "${FPGA_QUIET:-0}" = "1" ] || \
|
||||||
|
echo -e "[\033[34mINFO\033[0m] CB FPGA BDF = \033[36m${bdf}.0-.3\033[0m (resource0)"
|
||||||
|
else
|
||||||
|
echo -e "[\033[31mFAIL\033[0m] ${bdf}.0-.3 resource0 not all present - register access will fail." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fpga_rescan
|
||||||
|
|
||||||
# === VSPI window base offset (relative to CB Function 2 resource0 start) ===
|
# === VSPI window base offset (relative to CB Function 2 resource0 start) ===
|
||||||
# NOTE: CB.F2 has TWO near-identical VSPI register blocks (see spec register map):
|
# NOTE: CB.F2 has TWO near-identical VSPI register blocks (see spec register map):
|
||||||
@@ -268,6 +365,9 @@ blanton_fpga_help() {
|
|||||||
echo -e " \033[33mswb0_fpga\033[0m <addr> [data] SWB0 FPGA via VSPI"
|
echo -e " \033[33mswb0_fpga\033[0m <addr> [data] SWB0 FPGA via VSPI"
|
||||||
echo -e " \033[33mswb1_fpga\033[0m <addr> [data] SWB1 FPGA via VSPI"
|
echo -e " \033[33mswb1_fpga\033[0m <addr> [data] SWB1 FPGA via VSPI"
|
||||||
echo -e " \033[33mfpga_debug\033[0m on|off Toggle debug mode (print commands and execute)"
|
echo -e " \033[33mfpga_debug\033[0m on|off Toggle debug mode (print commands and execute)"
|
||||||
|
echo -e " \033[33mfpga_rescan\033[0m Re-detect CB FPGA BDF (after DUT swap / re-enum)"
|
||||||
|
echo ""
|
||||||
|
echo -e " Active CB FPGA BDF: \033[36m${FPGA_BDF_ACTIVE:-unknown}\033[0m .0-.3 (pin with: FPGA_BDF=0000:05:00 fpga_rescan)"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " Omit [data] to \033[32mread\033[0m, provide [data] to \033[31mwrite\033[0m."
|
echo -e " Omit [data] to \033[32mread\033[0m, provide [data] to \033[31mwrite\033[0m."
|
||||||
echo -e " Backend: \033[36mpcimem\033[0m (sysfs resource file + relative offset)."
|
echo -e " Backend: \033[36mpcimem\033[0m (sysfs resource file + relative offset)."
|
||||||
|
|||||||
Reference in New Issue
Block a user