1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2021 Intel Corporation 4# All rights reserved. 5 6# We simply check if BAR2, BAR4 are present as that's where PMR or CMB is 7# meant to be located under qemu. If found, print some stats then exit. 8shopt -s nullglob 9 10[[ $(uname -s) == Linux ]] || exit 0 11# Use MSR instead? 12[[ $(< /sys/class/dmi/id/chassis_vendor) == QEMU ]] || exit 0 13 14curdir=$(readlink -f "$(dirname "$0")") 15source "$curdir/common.sh" 16 17get_bar() { 18 echo "0x$(setpci -s "$1" "$2.${3:-L}")" 19} 20 21get_size() { 22 local addr=$1 23 local start end type 24 25 while IFS="- " read -r start end type; do 26 start=0x$start end=0x$end 27 if ((start == addr)) && [[ $type == *"$pci"* ]]; then 28 printf '0x%08x:0x%08x:0x%08x\n' \ 29 "$start" "$end" $((end - start + 1)) 30 return 0 31 fi 32 done < /proc/iomem 33 echo "unknown/unassigned" 34} 35 36info() { 37 local dev=$1 38 39 local pref 40 local head 41 42 local base_addr2 43 local base_addr4 44 45 local bar2 bar3 bar4 bar5 46 47 pref[0]=non-prefetchable 48 pref[1]=prefetchable 49 50 print_info() { 51 local bar=$1 base_addr=$2 bar_type=$3 52 53 printf '%s:%s:%s:%s:%s\n' \ 54 "$dev" \ 55 "64-bit" \ 56 "${pref[bar & 1 << 3 ? 1 : 0]}" \ 57 "$(get_size "$base_addr")" \ 58 "$bar_type" 59 } 60 61 head=$(get_bar "$dev" 0x0e B) 62 bar2=$(get_bar "$dev" 0x18) 63 bar3=$(get_bar "$dev" 0x1c) 64 bar4=$(get_bar "$dev" 0x20) 65 bar5=$(get_bar "$dev" 0x24) 66 67 if ((head != 0)); then 68 echo "Wrong header type under $dev" >&2 69 return 1 70 fi 71 72 # QEMU uses 64-bit BARs. If there is no CMB or PMR present, report 73 # that to the user and signal failure. 74 if ((!(bar2 & 1 << 2) && !(bar4 & 1 << 2))); then 75 echo "No CMB|PMR present under $dev" >&2 76 return 1 77 fi 78 79 if ((bar2 & 1 << 2)); then 80 base_addr2=$(((bar2 & ~0xf) + (bar3 << 32))) 81 print_info "$bar2" "$base_addr2" cmb 82 fi 83 84 if ((bar4 & 1 << 2)); then 85 base_addr4=$(((bar4 & ~0xf) + (bar5 << 32))) 86 print_info "$bar4" "$base_addr4" pmr 87 fi 88} 89 90missing_buf=0 91cache_pci_bus 92 93for pci in ${pci_bus_cache[0x010802]}; do 94 info "$pci" || ((++missing_buf)) 95done 96((missing_buf == 0)) 97