#!/bin/sh
readfns='
pci_bus_read_config_byte
pci_bus_read_config_word
pci_bus_read_config_dword
'
writefns='
pci_bus_write_config_byte 8
pci_bus_write_config_word 16
pci_bus_write_config_dword 32
'
# for access via sysfs
ureadfns="${readfns//bus/user}"
uwritefns="${writefns//bus/user}"

# Cannot use local vars in kretprobe.
#printf "perf probe -a '%s%%return bus=bus->number devfn:u pos:u value[0]'\n" $readfns
# These somehow do not universally work because of inlines functions... see
# perf probe -V pci_bus_config_write_dword.
#printf "perf probe -a '%s bus:u devfn:u pos:u'\n" $readfns
#printf "perf probe -a '%s bus:u devfn:u pos:u value:u%d'\n" $writefns
# for bus->number "bus(type:pci_bus) has no member number." for some reason...

# printf "perf probe -a '%s ${bus}:u devfn:u pos:u'\n" $readfns
# printf "perf probe -a '%s ${bus}:u devfn:u pos:u value[0]:u'\n" $writefns

# should work also for inlined functions where variable name is unknown.
printf "perf probe -a '%s bus=%%di:x64 devfn=%%si:x32 pos=%%dx:x32'\n" $readfns
printf "perf probe -a '%s bus=%%di:x64 devfn=%%si:x32 pos=%%dx:x32 value=%%cx:x%d'\n" $writefns

printf "perf probe -a '%s dev=%%di:x64 pos=%%si:x32'\n" $ureadfns
printf "perf probe -a '%s dev=%%di:x64 pos=%%si:x32 value=%%dx:x%d'\n" $uwritefns
# TODO somehow get dev->bus and dev->devfn working?
#printf "perf probe -a '%s bus=dev->bus:x64 pos:x32'\n" $ureadfns
#printf "perf probe -a '%s bus=dev->bus:x64 pos:x32 value:x%d'\n" $uwritefns

# Alternative, lower-level
#printf "perf probe -a 'raw_pci_write bus:x32 devfn:x32 reg:x32 len:x32 val:x32'\n"
#printf "perf probe -a 'raw_pci_read  bus:x32 devfn:x32 reg:x32 len:x32'\n"

cat <<EOF
# perf record -e 'probe:*' -aR bash
# perf script
# perf probe -d '*'
EOF

# list all probes:
# perf probe -l

# di si dx cx r8 r9
# arch/x86/pci/common.c
# int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
#                                                 int reg, int len, u32 *val)
# int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
#                                                 int reg, int len, u32 val)
