1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
from . import ADTDevTracer
from .dart import DARTTracer
from ..hv import TraceMode
from ..hw.dart import DART, DARTRegs
from ..hw.isp import *
class ISPTracer(ADTDevTracer):
DEFAULT_MODE = TraceMode.SYNC
REGMAPS = [ISPRegs, PSReg, SPMIReg, SPMIReg, SPMIReg]
NAMES = ["isp", "ps", "spmi0", "spmi1", "spmi2"]
ALLOWLISTED_CHANNELS = ["TERMINAL", "IO", "BUF_H2T", "BUF_T2H", "SHAREDMALLOC", "IO_T2H"]
def __init__(self, hv, dev_path, dart_dev_path, verbose):
super().__init__(hv, dev_path, verbose)
hv.p.pmgr_adt_clocks_enable("/arm-io/dart-isp")
self.dart_tracer = DARTTracer(hv, "/arm-io/dart-isp")
self.dart_tracer.start()
self.dart = self.dart_tracer.dart
self.ignored_ranges = [
# -----------------------------------------------------------------
# ## System clock counter (24 mhz)
(0x23b734004, 4),
(0x23b734008, 4),
# ## Noisy memory addresses that are always zero
(0x23b734868, 4),
(0x23b73486c, 4),
(0x23b734b38, 4),
(0x23b734b3c, 4),
(0x23b734b58, 4),
(0x23b734b5c, 4),
(0x23b734bd8, 4),
(0x23b734bdc, 4),
(0x23b734c18, 4),
(0x23b734c1c, 4),
(0x23b778128, 4),
(0x23b77812c, 4),
(0x23b77c128, 4),
(0x23b77c12c, 4),
# # Noisy memory addresses that change value
(0x23b700248, 4),
(0x23b700258, 4),
(0x23b7003f8, 4),
(0x23b700470, 4),
# # ECPU/PCPU state report
(0x23b738004, 4), # ecpu state report
(0x23b738008, 4), # pcpu state report
# -----------------------------------------------------------------
]
def r_ISP_GPR0(self, val):
# I have no idea how many channels may be available in other platforms
# but, at least for M1 I know they are seven (7), so using 64 as safe value here
if val.value == 0x8042006:
self.log(f"ISP_GPR0 = ACK")
elif val.value < 64:
self.log(f"ISP_IPC_CHANNELS = {val!s}")
self.number_of_channels = val.value
elif val.value > 0:
self.log(f"ISP_IPC_CHANNEL_TABLE_IOVA = {val!s}")
self.channel_table = ISPChannelTable(self, self.number_of_channels, val.value)
self.log(f"{str(self.channel_table)}")
def r_ISP_IRQ_INTERRUPT(self, val):
pending_irq = int(val.value)
self.log(f"======== BEGIN IRQ ========")
#self.channel_table.dump()
self.channel_table.get_last_read_command(pending_irq)
self.log(f"======== END IRQ ========")
def w_ISP_DOORBELL_RING0(self, val):
doorbell_value = int(val.value)
self.log(f"======== BEGIN DOORBELL ========")
#self.channel_table.dump()
self.channel_table.get_last_write_command(doorbell_value)
self.log(f"======== END DOORBELL ========")
def w_ISP_GPR0(self, val):
self.log(f"ISP_GPR0 = ({val!s})")
if val.value == 0x1812f80:
if self.dart:
self.init_struct = self.dart.ioread(0, val.value & 0xFFFFFFFF, 0x190)
def w_ISP_IRQ_INTERRUPT(self, val):
self.log(f"IRQ_INTERRUPT = ({val!s}).")
if val.value == 0xf:
self.log(f"ISP Interrupts enabled")
def ioread(self, dva, size):
if self.dart:
return self.dart.ioread(0, dva & 0xFFFFFFFF, size)
else:
return self.hv.iface.readmem(dva, size)
def iowrite(self, dva, data):
if self.dart:
return self.dart.iowrite(0, dva & 0xFFFFFFFF, data)
else:
return self.hv.iface.writemem(dva, data)
def start(self):
super().start()
self.msgmap = {}
for name in dir(self):
arg = getattr(self, name)
if not callable(arg) or not getattr(arg, "is_message", False):
continue
self.msgmap[arg.direction, arg.endpoint, arg.message] = getattr(self, name), name, arg.regtype
# Disable trace of memory regions
for addr, size in self.ignored_ranges:
self.trace(addr, size, TraceMode.OFF)
|