m1n1.trace.gpio: convert GPIOTracer to new framework

Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
Janne Grunau 2021-06-17 22:53:09 +02:00 committed by Hector Martin
parent ccd765464d
commit de82209079
2 changed files with 112 additions and 98 deletions

View file

@ -1,101 +1,8 @@
# SPDX-License-Identifier: MIT
from construct import *
GpioPin = BitStruct(
"u_top" / BitsInteger(13),
"group" / BitsInteger(3),
"u15" / Bit,
"u14" / Bit,
"u13" / Bit,
"u12" / Bit,
"u11" / Bit,
"u10" / Bit,
"cfg_done" / Bit,
"u8" / Bit,
"u7" / Bit,
"u6" / Bit,
"periph" / Bit,
"u4" / Bit,
"irq" / BitsInteger(3),
"value" / Bit,
)
class MmioTraceGpio:
def __init__(self, name, nr_pins):
self.name = name
self.nr_pins = nr_pins
self.pins = [0 for x in range(nr_pins)]
self.pn = {
0xc0: "i2c0:scl",
0xbc: "i2c0:sda",
0xc9: "i2c1:scl",
0xc7: "i2c1:sda",
0xa3: "i2c2:scl",
0xa2: "i2c2:sda",
106: "hpm:irq",
136: "bluetooth:irq",
196: "wlan:irq",
183: "cs42l83:irq",
182: "tas5770:irq",
152: "pci@0,0",
153: "pci@1,0",
33: "pci@2,0",
}
self.IRQ_ACT = 0x800
self.IRQ_GRP_SZ = 0x40
def handle_pin(self, pin, data, write):
# ignore noisy SPI NOR chip select?
if pin == 45:
return
if data != self.pins[pin]:
p = GpioPin.parse(Int32ub.build(data))
if not write and not p.cfg_done:
return
config = f"top:{p.u_top:#04x} group:{p.group} u15:{p.u15} u14:{p.u14} " + \
f"u13:{p.u13} u12:{p.u12} u11:{p.u11} u10:{p.u10} " + \
f"cfg_done:{p.cfg_done} u8:{p.u8} u7:{p.u7} u6:{p.u6} " + \
f"periph:{p.periph} u4:{p.u4} irq:{p.irq:#3x} val:{p.value}"
t = "W" if write else "R"
print(f"{self.name} {self.pn.get(pin, pin):>15}: {t} {config}")
self.pins[pin] = data
def handle_irq(self, group, start, data, write):
desc = "masking" if write else "active"
if data == 0xFFFFFFFF:
print(f"{self.name}: IRQ group {group} {desc:>7}: {start:>3} - {start + 31:>3}")
else:
irqs = [self.pn.get(start + i, start + i) for i in range(32) if (data >> i) & 0x1]
print(f"{self.name}: IRQ group {group} {desc:>7}: " + " ".join(irqs))
def handle_mmiotrace(self, evt, zone):
offset = evt.addr - zone.start
if evt.flags.WIDTH != 2:
print(f"GPIO: unexpected width {evt.flags.WIDTH}")
return
if offset >= 0 and offset < 4 * self.nr_pins:
self.handle_pin(offset // 4, int(evt.data), evt.flags.WRITE)
elif offset >= self.IRQ_ACT and offset < self.IRQ_ACT + 7 * self.IRQ_GRP_SZ:
if evt.data:
group = (offset - self.IRQ_ACT) // self.IRQ_GRP_SZ
start = (offset & (self.IRQ_GRP_SZ - 1)) * 8
self.handle_irq(group, start, evt.data, evt.flags.WRITE)
else:
t = "W" if evt.flags.WRITE else "R"
m = "+" if evt.flags.MULTI else " "
print(f"{self.name}: {t}.{1<<evt.flags.WIDTH:<2}{m} unknown offset {offset:#06x}) = {evt.data:#x}")
from m1n1.trace.gpio import GPIOTracer
#trace_device("/arm-io/gpio", True)
# trace gpio interrups, useful to follow the cascaded interrupts
aic_phandle = getattr(hv.adt["/arm-io/aic"], "AAPL,phandle")
@ -104,6 +11,6 @@ if getattr(node, "interrupt-parent") == aic_phandle:
for irq in getattr(node, "interrupts"):
hv.trace_irq(node.name, irq, 1, hv.IRQTRACE_IRQ)
gpio_trace = MmioTraceGpio(node.name, getattr(node, "#gpio-pins"))
hv.trace_device("/arm-io/gpio", handler=gpio_trace)
GPIOTracer = GPIOTracer._reloadcls()
gpio_tracer = GPIOTracer(hv, "/arm-io/gpio", verbose=0)
gpio_tracer.start()

View file

@ -0,0 +1,107 @@
# SPDX-License-Identifier: MIT
from ..hv import TraceMode
from ..utils import *
from . import ADTDevTracer
class R_PIN(Register32):
GROUP = 18, 16
CFG_DONE = 9
PERIPH = 5
CONFIG = 3, 1
VALUE = 0
class GPIORegs(RegMap):
IRQ_ACT = 0x800
IRQ_GRP_SZ = 0x40
PIN = irange(0x000, 212, 4), R_PIN
IRQ_GROUP0 = irange(IRQ_ACT + 0 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
IRQ_GROUP1 = irange(IRQ_ACT + 1 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
IRQ_GROUP2 = irange(IRQ_ACT + 2 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
IRQ_GROUP3 = irange(IRQ_ACT + 3 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
IRQ_GROUP4 = irange(IRQ_ACT + 4 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
IRQ_GROUP5 = irange(IRQ_ACT + 5 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
IRQ_GROUP6 = irange(IRQ_ACT + 6 * IRQ_GRP_SZ, (212 + 31) // 32, 4), Register32
def bits32(val, start):
return [start + i for i in range(0, 32) if int(val) & (1 << i)]
class GPIOTracer(ADTDevTracer):
DEFAULT_MODE = TraceMode.UNBUF
REGMAPS = [GPIORegs]
NAMES = ["gpio"]
PIN_NAMES = {
0xC0: "i2c0:scl",
0xBC: "i2c0:sda",
0xC9: "i2c1:scl",
0xC7: "i2c1:sda",
0xA3: "i2c2:scl",
0xA2: "i2c2:sda",
106: "hpm:irq",
136: "bluetooth:irq",
196: "wlan:irq",
183: "cs42l83:irq",
182: "tas5770:irq",
152: "pci@0,0",
153: "pci@1,0",
33: "pci@2,0",
0x2D: "spi_nor:CS"
}
def pn(self, pin):
return self.PIN_NAMES.get(pin, f"Pin-{pin}")
def r_PIN(self, val, index):
if index == 0x2D and self.verbose < 2:
return # ignore noisy SPI NOR CS
self.log(f"{self.pn(index):14} R {val!s} ")
def w_PIN(self, val, index):
if index == 0x2D and self.verbose < 2:
return # ignore noisy SPI NOR CS
self.log(f"{self.pn(index):14} W {val!s} ")
def r_IRQ_GROUP(self, val, index, grp):
if int(val) != 0:
self.log(f"IRQ[{grp}] ACT {[self.pn(x) for x in bits32(val, index * 32)]}")
def r_IRQ_GROUP0(self, val, index):
self.r_IRQ_GROUP(val, index, 0)
def r_IRQ_GROUP1(self, val, index):
self.r_IRQ_GROUP(val, index, 1)
def r_IRQ_GROUP2(self, val, index):
self.r_IRQ_GROUP(val, index, 2)
def r_IRQ_GROUP3(self, val, index):
self.r_IRQ_GROUP(val, index, 3)
def r_IRQ_GROUP4(self, val, index):
self.r_IRQ_GROUP(val, index, 4)
def r_IRQ_GROUP5(self, val, index):
self.r_IRQ_GROUP(val, index, 5)
def r_IRQ_GROUP6(self, val, index):
self.r_IRQ_GROUP(val, index, 6)
def w_IRQ_GROUP(self, val, index, grp):
if int(val) == (1 << 32) - 1:
self.log(f"IRQ[{grp}] ACK {index * 32} - {index * 32 + 31}")
elif int(val) != 0:
self.log(f"IRQ[{grp}] ACK {[self.pn(x) for x in bits32(val, index * 32)]}")
def w_IRQ_GROUP0(self, val, index):
self.w_IRQ_GROUP(val, index, 0)
def w_IRQ_GROUP1(self, val, index):
self.w_IRQ_GROUP(val, index, 1)
def w_IRQ_GROUP2(self, val, index):
self.w_IRQ_GROUP(val, index, 2)
def w_IRQ_GROUP3(self, val, index):
self.w_IRQ_GROUP(val, index, 3)
def w_IRQ_GROUP4(self, val, index):
self.w_IRQ_GROUP(val, index, 4)
def w_IRQ_GROUP5(self, val, index):
self.w_IRQ_GROUP(val, index, 5)
def w_IRQ_GROUP6(self, val, index):
self.w_IRQ_GROUP(val, index, 6)