xref: /spdk/scripts/get-pmr (revision 34edd9f1bf5fda4c987f4500ddc3c9f50be32e7d)
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