2021-03-23 20:30:57 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
# We simply check if BAR2 is present as that's where PMR or CMB is
|
|
|
|
# meant to be located under qemu. If found, print some stats then exit.
|
2021-04-21 18:20:31 +00:00
|
|
|
shopt -s nullglob
|
2021-03-23 20:30:57 +00:00
|
|
|
|
|
|
|
[[ $(uname -s) == Linux ]] || exit 0
|
|
|
|
# Use MSR instead?
|
|
|
|
[[ $(< /sys/class/dmi/id/chassis_vendor) == QEMU ]] || exit 0
|
|
|
|
|
2021-04-21 18:20:31 +00:00
|
|
|
get_bar() {
|
|
|
|
echo "0x$(setpci -s "$1" "$2.L")"
|
2021-03-23 20:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get_size() {
|
|
|
|
local addr=$1
|
|
|
|
local start end type
|
|
|
|
|
|
|
|
while IFS="- " read -r start end type; do
|
|
|
|
start=0x$start end=0x$end
|
|
|
|
if ((start == addr)) && [[ $type == *"$pci"* ]]; then
|
|
|
|
printf '0x%08x:0x%08x:0x%08x\n' \
|
|
|
|
"$start" "$end" $((end - start + 1))
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done < /proc/iomem
|
2021-04-21 18:20:31 +00:00
|
|
|
echo "unknown/unassigned"
|
2021-03-23 20:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
info() {
|
2021-04-21 18:20:31 +00:00
|
|
|
local dev=$1
|
2021-03-23 20:30:57 +00:00
|
|
|
|
|
|
|
local pref loc
|
|
|
|
|
2021-04-21 18:20:31 +00:00
|
|
|
local base_addr2
|
|
|
|
local base_addr4
|
|
|
|
|
|
|
|
local bar local bar2 bar3 bar4 bar5
|
|
|
|
local bar_type2
|
|
|
|
|
2021-03-23 20:30:57 +00:00
|
|
|
pref[0]=non-prefetchable
|
|
|
|
pref[1]=prefetchable
|
|
|
|
|
2021-04-21 18:20:31 +00:00
|
|
|
print_info() {
|
|
|
|
local bar=$1 base_addr=$2 bar_type=$3
|
|
|
|
|
|
|
|
printf '%s:%s:%s:%s:%s:%s\n' \
|
|
|
|
"${nvme##*/}" \
|
|
|
|
"$dev" \
|
|
|
|
"64-bit" \
|
|
|
|
"${pref[bar & 1 << 3 ? 1 : 0]}" \
|
|
|
|
"$(get_size "$base_addr")" \
|
|
|
|
"$bar_type"
|
|
|
|
}
|
2021-03-23 20:30:57 +00:00
|
|
|
|
2021-04-21 18:20:31 +00:00
|
|
|
bar2=$(get_bar "$dev" 0x18)
|
|
|
|
bar3=$(get_bar "$dev" 0x1c)
|
|
|
|
bar4=$(get_bar "$dev" 0x20)
|
|
|
|
bar5=$(get_bar "$dev" 0x24)
|
|
|
|
|
|
|
|
# QEMU uses 64-bit BARs
|
|
|
|
if ((bar2 & 1 << 2)); then
|
|
|
|
bar_type2=pmr
|
|
|
|
if [[ -e $nvme/cmb ]]; then
|
|
|
|
bar_type2=cmb
|
|
|
|
fi
|
|
|
|
base_addr2=$(((bar2 & ~0xf) + (bar3 << 32)))
|
|
|
|
print_info "$bar2" "$base_addr2" "$bar_type2"
|
|
|
|
fi
|
|
|
|
# QEMU uses 64-bit BARs
|
|
|
|
if ((bar4 & 1 << 2)); then
|
|
|
|
base_addr4=$(((bar4 & ~0xf) + (bar5 << 32)))
|
|
|
|
print_info "$bar4" "$base_addr4" pmr
|
|
|
|
fi
|
2021-03-23 20:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for nvme in /sys/class/nvme/nvme*; do
|
|
|
|
pci=$(readlink -f "$nvme/device") pci=${pci##*/}
|
2021-04-21 18:20:31 +00:00
|
|
|
info "$pci"
|
2021-03-23 20:30:57 +00:00
|
|
|
done
|