mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-11 02:04:11 +00:00
m1n1.trace.gpio: convert GPIOTracer to new framework
Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
parent
ccd765464d
commit
de82209079
2 changed files with 112 additions and 98 deletions
|
@ -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()
|
||||
|
|
107
proxyclient/m1n1/trace/gpio.py
Normal file
107
proxyclient/m1n1/trace/gpio.py
Normal 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)
|
Loading…
Reference in a new issue