Fix race when finding the port OpenOCD is using.
[riscv-tests.git] / debug / targets.py
1 import os.path
2 import tempfile
3
4 import testlib
5
6 class Target(object):
7 name = "name"
8 xlen = 0
9 directory = None
10 timeout_sec = 2
11 temporary_files = []
12 temporary_binary = None
13 openocd_config = []
14
15 def __init__(self, cmd, run, isolate):
16 self.cmd = cmd
17 self.run = run
18 self.isolate = isolate
19
20 def target(self):
21 """Start the target, eg. a simulator."""
22 pass
23
24 def server(self):
25 """Start the debug server that gdb connects to, eg. OpenOCD."""
26 if self.openocd_config:
27 return testlib.Openocd(cmd=self.cmd, config=self.openocd_config)
28 else:
29 raise NotImplementedError
30
31 def compile(self, *sources):
32 binary_name = "%s_%s-%d" % (
33 self.name,
34 os.path.basename(os.path.splitext(sources[0])[0]),
35 self.xlen)
36 if self.isolate:
37 self.temporary_binary = tempfile.NamedTemporaryFile(
38 prefix=binary_name + "_")
39 binary_name = self.temporary_binary.name
40 Target.temporary_files.append(self.temporary_binary)
41 testlib.compile(sources +
42 ("programs/entry.S", "programs/init.c",
43 "-I", "../env",
44 "-march=RV%dIMAFD" % self.xlen,
45 "-T", "targets/%s/link.lds" % (self.directory or self.name),
46 "-nostartfiles",
47 "-mcmodel=medany",
48 "-o", binary_name),
49 xlen=self.xlen)
50 return binary_name
51
52 class SpikeTarget(Target):
53 # pylint: disable=abstract-method
54 directory = "spike"
55 ram = 0x80010000
56 ram_size = 5 * 1024 * 1024
57 instruction_hardware_breakpoint_count = 4
58 reset_vector = 0x1000
59
60 class Spike64Target(SpikeTarget):
61 name = "spike64"
62 xlen = 64
63
64 def server(self):
65 return testlib.Spike(self.cmd, halted=True)
66
67 class Spike32Target(SpikeTarget):
68 name = "spike32"
69 xlen = 32
70
71 def server(self):
72 return testlib.Spike(self.cmd, halted=True, xlen=32)
73
74 class FreedomE300Target(Target):
75 name = "freedom-e300"
76 xlen = 32
77 ram = 0x80000000
78 ram_size = 16 * 1024
79 instruction_hardware_breakpoint_count = 2
80 openocd_config = "targets/%s/openocd.cfg" % name
81
82 class FreedomE300SimTarget(Target):
83 name = "freedom-e300-sim"
84 xlen = 32
85 timeout_sec = 240
86 ram = 0x80000000
87 ram_size = 256 * 1024 * 1024
88 instruction_hardware_breakpoint_count = 2
89 openocd_config = "targets/%s/openocd.cfg" % name
90
91 def target(self):
92 return testlib.VcsSim(simv=self.run, debug=False)
93
94 class FreedomU500Target(Target):
95 name = "freedom-u500"
96 xlen = 64
97 ram = 0x80000000
98 ram_size = 16 * 1024
99 instruction_hardware_breakpoint_count = 2
100 openocd_config = "targets/%s/openocd.cfg" % name
101
102 class FreedomU500SimTarget(Target):
103 name = "freedom-u500-sim"
104 xlen = 64
105 timeout_sec = 240
106 ram = 0x80000000
107 ram_size = 256 * 1024 * 1024
108 instruction_hardware_breakpoint_count = 2
109 openocd_config = "targets/%s/openocd.cfg" % name
110
111 def target(self):
112 return testlib.VcsSim(simv=self.run, debug=False)
113
114 targets = [
115 Spike32Target,
116 Spike64Target,
117 FreedomE300Target,
118 FreedomU500Target,
119 FreedomE300SimTarget,
120 FreedomU500SimTarget]
121
122 def add_target_options(parser):
123 group = parser.add_mutually_exclusive_group(required=True)
124 for t in targets:
125 group.add_argument("--%s" % t.name, action="store_const", const=t,
126 dest="target")
127 parser.add_argument("--run",
128 help="The command to use to start the actual target (e.g. "
129 "simulation)")
130 parser.add_argument("--cmd",
131 help="The command to use to start the debug server.")
132
133 xlen_group = parser.add_mutually_exclusive_group()
134 xlen_group.add_argument("--32", action="store_const", const=32, dest="xlen",
135 help="Force the target to be 32-bit.")
136 xlen_group.add_argument("--64", action="store_const", const=64, dest="xlen",
137 help="Force the target to be 64-bit.")
138
139 parser.add_argument("--isolate", action="store_true",
140 help="Try to run in such a way that multiple instances can run at "
141 "the same time. This may make it harder to debug a failure if it "
142 "does occur.")