summaryrefslogtreecommitdiff
path: root/tools/proxyclient/m1n1/trace/pcie.py
diff options
context:
space:
mode:
authormagh <magh@maghmogh.com>2023-03-06 18:44:55 -0600
committermagh <magh@maghmogh.com>2023-03-06 18:44:55 -0600
commite80d9d8871b325a04b18f90a9ea4bb7fd148fb25 (patch)
tree79dbdb8506b7ff1e92549188d1b94cfc0b3503ae /tools/proxyclient/m1n1/trace/pcie.py
add m1n1HEADmaster
Diffstat (limited to 'tools/proxyclient/m1n1/trace/pcie.py')
-rw-r--r--tools/proxyclient/m1n1/trace/pcie.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/tools/proxyclient/m1n1/trace/pcie.py b/tools/proxyclient/m1n1/trace/pcie.py
new file mode 100644
index 0000000..191da84
--- /dev/null
+++ b/tools/proxyclient/m1n1/trace/pcie.py
@@ -0,0 +1,108 @@
+from . import Tracer, TraceMode
+from ..utils import *
+
+class R_BAR(Register32):
+ BASE = 31, 4
+ PREFETCH = 3
+ ADDR64 = 2
+ BELOW_1M = 1
+ SPACE = 0
+
+class PCICfgSpace(RegMap):
+ VENDOR_ID = 0x00, Register16
+ PRODUCT_ID = 0x02, Register16
+ COMMAND = 0x04, Register16
+ STATUS = 0x06, Register16
+
+ BAR = irange(0x10, 6, 4), R_BAR
+ ROMADDR = 0x30, Register32
+
+class PCIeDevTracer(Tracer):
+ CFGMAP = PCICfgSpace
+ BARMAPS = []
+ NAMES = []
+ PREFIXES = []
+
+ def __init__(self, hv, apcie, bus, dev, fn, verbose=False):
+ super().__init__(hv, verbose=verbose, ident=f"{type(self).__name__}@{apcie}/{bus:02x}:{dev:02x}.{fn:1x}")
+ self.busn = bus
+ self.devn = dev
+ self.fn = fn
+ self.ecam_off = (bus << 20) | (dev << 15) | (fn << 12)
+ self.apcie = hv.adt[apcie]
+ self.bars = [0] * 6
+ self.bar_ranges = [None] * 6
+ self.cfg_space = self.CFGMAP(hv.u, self.apcie.get_reg(0)[0] + self.ecam_off)
+ self.verbose = 3
+
+ def init_state(self):
+ self.state.bars = [R_BAR(0) for i in range(6)]
+ self.state.barsize = [None] * 6
+
+ @classmethod
+ def _reloadcls(cls, force=False):
+ cls.BARMAPS = [i._reloadcls(force) if i else None for i in cls.BARMAPS]
+ return super()._reloadcls(force)
+
+ def r_cfg_BAR(self, val, index):
+ if self.state.bars[index].BASE == 0xfffffff:
+ size = (0x10000000 - val.BASE) << 4
+ self.log(f"BAR{index} size = {size:#x}")
+ self.state.barsize[index] = size
+
+ def w_cfg_BAR(self, val, index):
+ self.state.bars[index] = val
+ self.update_tracers(val, index)
+
+ def update_tracers(self, val = None, index = None):
+ self.hv.clear_tracers(self.ident)
+ ecam = self.apcie.get_reg(0)[0]
+ self.trace_regmap(ecam + self.ecam_off, 0x1000, self.CFGMAP, prefix="cfg",
+ mode=TraceMode.WSYNC)
+ i = 0
+ while i < 6:
+ idx = i
+ if i == index:
+ bar = val
+ else:
+ bar = self.cfg_space.BAR[i].reg
+ addr = bar.BASE << 4
+ if bar.ADDR64 and i != 5:
+ if i + 1 == index:
+ barh = val
+ else:
+ barh = self.cfg_space.BAR[i + 1].reg
+ addr |= barh.value << 32
+ i += 2
+ else:
+ i += 1
+
+ if addr in (0, 0xfffffff0, 0xffffffff00000000, 0xfffffffffffffff0):
+ continue
+
+ size = self.state.barsize[idx]
+
+ if not size:
+ self.log(f"BAR{idx} size is unknown!")
+ continue
+
+ # Add in PCIe DT addr flags to get the correct translation
+ start = self.apcie.translate(addr | (0x02 << 88))
+
+ self.log(f"Tracing BAR{idx} : {addr:#x} -> {start:#x}..{start+size-1:#x}")
+ self.bar_ranges[idx] = irange(start, size)
+ self.trace_bar(idx, start, size)
+
+ def trace_bar(self, idx, start, size):
+ if idx >= len(self.BARMAPS) or (regmap := self.BARMAPS[idx]) is None:
+ return
+ prefix = name = None
+ if idx < len(self.NAMES):
+ name = self.NAMES[i]
+ if idx < len(self.PREFIXES):
+ prefix = self.PREFIXES[i]
+
+ self.trace_regmap(start, size, regmap, name=name, prefix=prefix)
+
+ def start(self):
+ self.update_tracers()