10cb256c0SMichal Berger#!/usr/bin/env bash 2eb53c232Spaul luse# SPDX-License-Identifier: BSD-3-Clause 3eb53c232Spaul luse# Copyright (C) 2021 Intel Corporation 4eb53c232Spaul luse# All rights reserved. 5eb53c232Spaul luse 68d7abaf5SMichal Berger# We simply check if BAR2, BAR4 are present as that's where PMR or CMB is 70cb256c0SMichal Berger# meant to be located under qemu. If found, print some stats then exit. 8eb4b7991SMichal Bergershopt -s nullglob 90cb256c0SMichal Berger 100cb256c0SMichal Berger[[ $(uname -s) == Linux ]] || exit 0 110cb256c0SMichal Berger# Use MSR instead? 120cb256c0SMichal Berger[[ $(< /sys/class/dmi/id/chassis_vendor) == QEMU ]] || exit 0 130cb256c0SMichal Berger 14b0107e8cSMichal Bergercurdir=$(readlink -f "$(dirname "$0")") 15b0107e8cSMichal Bergersource "$curdir/common.sh" 16b0107e8cSMichal Berger 17eb4b7991SMichal Bergerget_bar() { 18843606d7SMichal Berger echo "0x$(setpci -s "$1" "$2.${3:-L}")" 190cb256c0SMichal Berger} 200cb256c0SMichal Berger 210cb256c0SMichal Bergerget_size() { 220cb256c0SMichal Berger local addr=$1 230cb256c0SMichal Berger local start end type 240cb256c0SMichal Berger 250cb256c0SMichal Berger while IFS="- " read -r start end type; do 260cb256c0SMichal Berger start=0x$start end=0x$end 270cb256c0SMichal Berger if ((start == addr)) && [[ $type == *"$pci"* ]]; then 280cb256c0SMichal Berger printf '0x%08x:0x%08x:0x%08x\n' \ 290cb256c0SMichal Berger "$start" "$end" $((end - start + 1)) 300cb256c0SMichal Berger return 0 310cb256c0SMichal Berger fi 320cb256c0SMichal Berger done < /proc/iomem 33eb4b7991SMichal Berger echo "unknown/unassigned" 340cb256c0SMichal Berger} 350cb256c0SMichal Berger 360cb256c0SMichal Bergerinfo() { 37eb4b7991SMichal Berger local dev=$1 380cb256c0SMichal Berger 398d7abaf5SMichal Berger local pref 40843606d7SMichal Berger local head 410cb256c0SMichal Berger 42eb4b7991SMichal Berger local base_addr2 43eb4b7991SMichal Berger local base_addr4 44eb4b7991SMichal Berger 45843606d7SMichal Berger local bar2 bar3 bar4 bar5 46eb4b7991SMichal Berger 470cb256c0SMichal Berger pref[0]=non-prefetchable 480cb256c0SMichal Berger pref[1]=prefetchable 490cb256c0SMichal Berger 50eb4b7991SMichal Berger print_info() { 51eb4b7991SMichal Berger local bar=$1 base_addr=$2 bar_type=$3 520cb256c0SMichal Berger 53b0107e8cSMichal Berger printf '%s:%s:%s:%s:%s\n' \ 54eb4b7991SMichal Berger "$dev" \ 55eb4b7991SMichal Berger "64-bit" \ 56eb4b7991SMichal Berger "${pref[bar & 1 << 3 ? 1 : 0]}" \ 57eb4b7991SMichal Berger "$(get_size "$base_addr")" \ 58eb4b7991SMichal Berger "$bar_type" 59eb4b7991SMichal Berger } 60eb4b7991SMichal Berger 61843606d7SMichal Berger head=$(get_bar "$dev" 0x0e B) 62eb4b7991SMichal Berger bar2=$(get_bar "$dev" 0x18) 63eb4b7991SMichal Berger bar3=$(get_bar "$dev" 0x1c) 64eb4b7991SMichal Berger bar4=$(get_bar "$dev" 0x20) 65eb4b7991SMichal Berger bar5=$(get_bar "$dev" 0x24) 66eb4b7991SMichal Berger 67843606d7SMichal Berger if ((head != 0)); then 68*34edd9f1SKamil Godzwon echo "Wrong header type under $dev" >&2 69843606d7SMichal Berger return 1 70843606d7SMichal Berger fi 71843606d7SMichal Berger 7229756d4cSMichal Berger # QEMU uses 64-bit BARs. If there is no CMB or PMR present, report 7329756d4cSMichal Berger # that to the user and signal failure. 7429756d4cSMichal Berger if ((!(bar2 & 1 << 2) && !(bar4 & 1 << 2))); then 7529756d4cSMichal Berger echo "No CMB|PMR present under $dev" >&2 7629756d4cSMichal Berger return 1 7729756d4cSMichal Berger fi 7829756d4cSMichal Berger 79eb4b7991SMichal Berger if ((bar2 & 1 << 2)); then 80eb4b7991SMichal Berger base_addr2=$(((bar2 & ~0xf) + (bar3 << 32))) 81843606d7SMichal Berger print_info "$bar2" "$base_addr2" cmb 82eb4b7991SMichal Berger fi 8329756d4cSMichal Berger 84eb4b7991SMichal Berger if ((bar4 & 1 << 2)); then 85eb4b7991SMichal Berger base_addr4=$(((bar4 & ~0xf) + (bar5 << 32))) 86eb4b7991SMichal Berger print_info "$bar4" "$base_addr4" pmr 87eb4b7991SMichal Berger fi 880cb256c0SMichal Berger} 890cb256c0SMichal Berger 9029756d4cSMichal Bergermissing_buf=0 91b0107e8cSMichal Bergercache_pci_bus 92b0107e8cSMichal Berger 93b0107e8cSMichal Bergerfor pci in ${pci_bus_cache[0x010802]}; do 9429756d4cSMichal Berger info "$pci" || ((++missing_buf)) 950cb256c0SMichal Bergerdone 9629756d4cSMichal Berger((missing_buf == 0)) 97