Skip to content

Commit 2a62a6c

Browse files
committed
vcu118-run.py: Adapt to accommodate GDB/cheri-14
This is also more resilient against newer OpenOCD that spews errors due to GDB trying to read the first 0x64 bytes of memory for some reason. Note that due to a combination of OpenOCD and Bluespec Debug Module bugs newer OpenOCD requires fixes and workarounds.
1 parent 3d5d136 commit 2a62a6c

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

vcu118-run.py

+33-7
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import typing
3939
from abc import abstractmethod
4040
from pathlib import Path
41+
from threading import Thread
4142
from typing import Optional
4243

4344
_cheribuild_root = Path(__file__).resolve().parent
@@ -268,6 +269,16 @@ def __init__(self, gdb: pexpect.spawn, openocd: pexpect.spawn, serial: SerialCon
268269
self.serial = serial
269270

270271

272+
class BackgroundExpectEOF(Thread):
273+
def __init__(self, child):
274+
Thread.__init__(self)
275+
self.child = child
276+
self.daemon = True
277+
278+
def run(self):
279+
self.child.expect(pexpect.EOF, timeout=None)
280+
281+
271282
def reset_soc(conn: FpgaConnection):
272283
# On the rare occasion you need to reset SoC stuff not just the core, set *(0x6fff0000)=1 does a write to a GPIO
273284
# block whose output is connected to the SoC's reset so that lets you reset the whole SoC
@@ -327,12 +338,26 @@ def load_and_start_kernel(
327338
gdb_start_time = datetime.datetime.utcnow()
328339
openocd, openocd_gdb_port = start_openocd(openocd_cmd, num_cores)
329340
# openocd is running, now start GDB
330-
args = [str(Path(bios_image).absolute()), "-ex", "target extended-remote :" + str(openocd_gdb_port)]
341+
# NB: Cannot set the actual file since GDB will then expect OpenOCD's
342+
# gdbserver to provide capabilities and fail to read the PC (PCC).
343+
args = ["-ex", "set architecture riscv"]
344+
# NB: Avoids software single stepping as writing ebreak to the bootrom
345+
# doesn't work (silently fails at least with Toooba at time of writing).
346+
args += ["-ex", "set os none"]
347+
args += ["-ex", "symbol-file " + str(Path(bios_image).absolute())]
348+
args += ["-ex", "target extended-remote :" + str(openocd_gdb_port)]
331349
args += ["-ex", "set confirm off"] # avoid interactive prompts
332350
args += ["-ex", "set pagination off"] # avoid paginating output, requiring input
333351
args += ["-ex", "set style enabled off"] # disable colours since they break the matcher strings
334352
args += ["-ex", "monitor reset init"] # reset and go back to boot room
353+
if num_cores > 1:
354+
args += ["-ex", "thread 1"] # ensure we're on core 0
335355
args += ["-ex", "si 5"] # we need to run the first few instructions to get a valid DTB
356+
if num_cores > 1:
357+
for core in range(1, num_cores):
358+
args += ["-ex", f"thread {core + 1:d}"] # switch to thread (core + 1) (GDB counts from 1)
359+
args += ["-ex", "si 5"] # execute bootrom on every other core
360+
args += ["-ex", "thread 1"] # switch back to core 0
336361
args += ["-ex", "set disassemble-next-line on"]
337362
# Load the kernel image first since load changes the next PC to the entry point
338363
if kernel_image is not None:
@@ -351,8 +376,6 @@ def load_and_start_kernel(
351376
if num_cores > 1:
352377
args += ["-ex", "set $entry_point = $pc"] # Record the entry point to the bios
353378
for core in range(1, num_cores):
354-
args += ["-ex", f"thread {core + 1:d}"] # switch to thread (core + 1) (GDB counts from 1)
355-
args += ["-ex", "si 5"] # execute bootrom on every other core
356379
args += ["-ex", "set $pc=$entry_point"] # set every other core to the start of the bios
357380
args += ["-ex", "thread 1"] # switch back to core 0
358381
if extra_gdb_commands is not None:
@@ -368,6 +391,9 @@ def load_and_start_kernel(
368391
# openOCD should acknowledge the GDB connection:
369392
openocd.expect_exact([f"Info : accepting 'gdb' connection on tcp/{openocd_gdb_port}"])
370393
success("openocd accepted GDB connection")
394+
# Now we're done with OpenOCD and want to ensure anything it logs doesn't
395+
# lead to backpressure and block it
396+
BackgroundExpectEOF(openocd).start()
371397
gdb.expect_exact(["Remote debugging using :" + str(openocd_gdb_port)])
372398
success("GDB connected to openocd")
373399
# XXX: doesn't match with recent GDB: gdb.expect_exact(["0x0000000070000000 in ??"])
@@ -376,6 +402,10 @@ def load_and_start_kernel(
376402
# XXX: doesn't match with recent GDB: gdb.expect_exact(["0x0000000044000000 in ??"])
377403
gdb.expect_exact(["0x0000000044000000"])
378404
success("Done executing bootrom")
405+
if num_cores > 1:
406+
for core in range(1, num_cores):
407+
gdb.expect_exact(["0x0000000044000000"])
408+
success("Done executing bootrom on all other cores")
379409
if kernel_image is not None:
380410
gdb.expect_exact(["Loading section .text"])
381411
load_start_time = datetime.datetime.utcnow()
@@ -391,10 +421,6 @@ def load_and_start_kernel(
391421
load_end_time = datetime.datetime.utcnow()
392422
success("Finished loading bootloader image in ", load_end_time - load_start_time)
393423
gdb_finish_time = load_end_time
394-
if num_cores > 1:
395-
for core in range(1, num_cores):
396-
gdb.expect_exact(["0x0000000044000000"])
397-
success("Done executing bootrom on all other cores")
398424
gdb.expect_exact(["ready to continue"])
399425
gdb.sendline("continue")
400426
success("Starting CheriBSD after ", datetime.datetime.utcnow() - gdb_start_time)

0 commit comments

Comments
 (0)