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
119
120
121
122
123
124
125
|
# SPDX-License-Identifier: MIT
from ...utils import *
from .crash import ASCCrashLogEndpoint
from .syslog import ASCSysLogEndpoint
from .mgmt import ASCManagementEndpoint
from .kdebug import ASCKDebugEndpoint
from .ioreporting import ASCIOReportingEndpoint
from .oslog import ASCOSLogEndpoint
from .base import ASCBaseEndpoint, ASCTimeout
from ...hw.asc import ASC
__all__ = []
class ASCDummyEndpoint(ASCBaseEndpoint):
SHORT = "dummy"
class StandardASC(ASC):
ENDPOINTS = {
0: ASCManagementEndpoint,
1: ASCCrashLogEndpoint,
2: ASCSysLogEndpoint,
3: ASCKDebugEndpoint,
4: ASCIOReportingEndpoint,
8: ASCOSLogEndpoint,
0xa: ASCDummyEndpoint, # tracekit
}
def __init__(self, u, asc_base, dart=None, stream=0):
super().__init__(u, asc_base)
self.remote_eps = set()
self.add_ep(0, ASCManagementEndpoint(self, 0))
self.dart = dart
self.stream = stream
self.eps = []
self.epcls = {}
self.dva_offset = 0
self.dva_size = 1 << 32
self.allow_phys = False
for cls in type(self).mro():
eps = getattr(cls, "ENDPOINTS", None)
if eps is None:
break
for k, v in eps.items():
if k not in self.epcls:
self.epcls[k] = v
def addr(self, addr):
return f"{addr:#x}"
def iomap(self, addr, size):
if self.dart is None:
return addr
dva = self.dva_offset | self.dart.iomap(self.stream, addr, size)
self.dart.invalidate_streams(1)
return dva
def ioalloc(self, size):
paddr = self.u.memalign(0x4000, size)
dva = self.iomap(paddr, size)
return paddr, dva
def ioread(self, dva, size):
if self.allow_phys and dva < self.dva_offset or dva >= (self.dva_offset + self.dva_size):
return self.iface.readmem(dva, size)
if self.dart:
return self.dart.ioread(self.stream, dva & 0xFFFFFFFFF, size)
else:
return self.iface.readmem(dva, size)
def iowrite(self, dva, data):
if self.allow_phys and dva < self.dva_offset or dva >= (self.dva_offset + self.dva_size):
return self.iface.writemem(dva, data)
if self.dart:
return self.dart.iowrite(self.stream, dva & 0xFFFFFFFFF, data)
else:
return self.iface.writemem(dva, data)
def iotranslate(self, dva, size):
if self.allow_phys and dva < self.dva_offset or dva >= (self.dva_offset + self.dva_size):
return [(dva, size)]
if self.dart:
return self.dart.iotranslate(self.stream, dva & 0xFFFFFFFFF, size)
else:
return [(dva, size)]
def start_ep(self, epno):
if epno not in self.epcls:
raise Exception(f"Unknown endpoint {epno:#x}")
epcls = self.epcls[epno]
ep = epcls(self, epno)
self.add_ep(epno, ep)
print(f"Starting endpoint #{epno:#x} ({ep.name})")
self.mgmt.start_ep(epno)
ep.start()
def start(self):
super().boot()
self.mgmt.start()
self.mgmt.wait_boot(3)
def stop(self, state=0x10):
for ep in list(self.epmap.values())[::-1]:
if ep.epnum < 0x10:
continue
ep.stop()
self.mgmt.stop(state=state)
self.epmap = {}
self.add_ep(0, ASCManagementEndpoint(self, 0))
if state < 0x10:
self.shutdown()
def boot(self):
print("Booting ASC...")
super().boot()
self.mgmt.wait_boot(1)
__all__.extend(k for k, v in globals().items()
if (callable(v) or isinstance(v, type)) and v.__module__ == __name__)
|