Skip to content

Commit

Permalink
[ot] scripts/opentitan: pyot: add configurable startup delay
Browse files Browse the repository at this point in the history
Signed-off-by: Emmanuel Blot <[email protected]>
  • Loading branch information
rivos-eblot authored and loiclefort committed Feb 8, 2024
1 parent 08500ba commit abe6f32
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
6 changes: 5 additions & 1 deletion docs/opentitan/pyot.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

````text
usage: pyot.py [-h] [-q QEMU] [-Q OPTS] [-m MACHINE] [-p DEVICE] [-L LOG_FILE]
[-M LOG] [-t TRACE] [-i N] [-s] [-T SECS] [-U] [-c JSON]
[-M LOG] [-t TRACE] [-i N] [-s] [-T SECS] [-U] [-D] [-c JSON]
[-w CSV] [-K] [-r ELF] [-O RAW] [-o VMEM] [-f RAW] [-x file]
[-b file] [-R] [-k SECONDS] [-F TEST] [-v] [-d]
Expand Down Expand Up @@ -35,6 +35,8 @@ Virtual machine:
timeout factor
-U, --muxserial enable multiple virtual UARTs to be muxed into same
host output channel
-D DELAY, --start-delay DELAY
QEMU start up delay before initial comm
Files:
-c JSON, --config JSON
Expand Down Expand Up @@ -118,6 +120,8 @@ This tool may be used in two ways, which can be combined:
it can be greater to increase timeouts or lower than 1 to decrease timeouts.
* `-U` / `--muxserial` enable muxing QEMU VCP. This option is required when several virtual UARTs
are routed to the same host output channel.
* `-D` / `--start-delay` VM start up delay. Grace period to wait for the VM to start up before
attempting to communicate with its char devices.

### File options:

Expand Down
39 changes: 26 additions & 13 deletions scripts/opentitan/pyot.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def __init__(self, tcpdev: Tuple[str, int], debug: bool):
self._otlog = getLogger('pyot.ot')

def run(self, qemu_args: List[str], timeout: int, name: str,
ctx: Optional['QEMUContext']) -> Tuple[int, ExecTime, str]:
ctx: Optional['QEMUContext'], start_delay: float) -> \
Tuple[int, ExecTime, str]:
"""Execute the specified QEMU command, aborting execution if QEMU does
not exit after the specified timeout.
Expand All @@ -186,10 +187,12 @@ def run(self, qemu_args: List[str], timeout: int, name: str,
is aborted
:param name: the tested application name
:param ctx: execution context, if any
:param start_delay: start up delay
:return: a 3-uple of exit code, execution time, and last guest error
"""
# pylint: disable=too-many-locals
# pylint: disable=too-many-arguments
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements

# stdout and stderr belongs to QEMU VM
Expand All @@ -216,7 +219,8 @@ def run(self, qemu_args: List[str], timeout: int, name: str,
try:
# ensure that QEMU starts and give some time for it to set up
# its VCP before attempting to connect to it
proc.wait(0.9)
self._log.debug(f'Waiting {start_delay:.1f}s for VM init')
proc.wait(start_delay)
except TimeoutExpired:
pass
else:
Expand Down Expand Up @@ -973,7 +977,7 @@ def build(self) -> None:
:raise ValueError: if some argument is invalid
"""
self._qemu_cmd, self._vcp, _ = self._build_qemu_command(self._args)
self._qemu_cmd, self._vcp = self._build_qemu_command(self._args)[:2]
self._argdict = dict(self._args.__dict__)
self._suffixes = []
suffixes = self._config.get('suffixes', [])
Expand Down Expand Up @@ -1024,12 +1028,12 @@ def run(self, debug: bool) -> int:
'UTDIR': normpath(dirname(test)),
'UTFILE': basename(test),
})
qemu_cmd, targs, timeout, temp_files, ctx = \
qemu_cmd, targs, timeout, temp_files, ctx, sdelay = \
self._build_qemu_test_command(test)
test_name = self.get_test_radix(test)
ctx.execute('pre')
tret, xtime, err = qot.run(qemu_cmd, timeout, test_name,
ctx)
ctx, sdelay)
cret = ctx.finalize()
ctx.execute('post', tret)
if tret == 0 and cret != 0:
Expand Down Expand Up @@ -1118,14 +1122,15 @@ def _cleanup_temp_files(self, storage: Dict[str, Set[str]]) -> None:

def _build_qemu_command(self, args: Namespace,
opts: Optional[List[str]] = None) \
-> Tuple[List[str], Tuple[str, int], Dict[str, Set[str]]]:
-> Tuple[List[str], Tuple[str, int], Dict[str, Set[str]], float]:
"""Build QEMU command line from argparser values.
:param args: the parsed arguments
:param opts: any QEMU-specific additional options
:return: a tuple of a list of QEMU command line,
the TCP device descriptor to connect to the QEMU VCP, and
a dictionary of generated temporary files
the TCP device descriptor to connect to the QEMU VCP,
a dictionary of generated temporary files and the start
delay
"""
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals
Expand Down Expand Up @@ -1200,6 +1205,11 @@ def _build_qemu_command(self, args: Namespace,
if args.icount is not None:
qemu_args.extend(('-icount', f'{args.icount}'))
mux = f'mux={"on" if args.muxserial else "off"}'
try:
start_delay = float(getattr(args, 'start_delay', 1.0))
except ValueError as exc:
raise ValueError(f'Invalid start up delay {args.start_delay}') \
from exc
device = args.device
devdesc = device.split(':')
try:
Expand All @@ -1216,16 +1226,17 @@ def _build_qemu_command(self, args: Namespace,
raise ValueError('Invalid TCP serial device') from exc
if opts:
qemu_args.extend((str(o) for o in opts))
return qemu_args, tcpdev, temp_files
return qemu_args, tcpdev, temp_files, start_delay

def _build_qemu_test_command(self, filename: str) -> \
Tuple[List[str], Namespace, int, Dict[str, Set[str]], QEMUContext]:
Tuple[List[str], Namespace, int, Dict[str, Set[str]], QEMUContext,
float]:
test_name = self.get_test_radix(filename)
args, opts, timeout = self._build_test_args(test_name)
setattr(args, 'exec', filename)
qemu_cmd, _, temp_files = self._build_qemu_command(args, opts)
qemu_cmd, _, temp_files, sdelay = self._build_qemu_command(args, opts)
ctx = self._build_test_context(test_name)
return qemu_cmd, args, timeout, temp_files, ctx
return qemu_cmd, args, timeout, temp_files, ctx, sdelay

def _build_test_list(self, alphasort: bool = True) -> List[str]:
# pylint: disable=too-many-branches
Expand Down Expand Up @@ -1430,6 +1441,8 @@ def main():
default=None,
help='enable multiple virtual UARTs to be muxed into '
'same host output channel')
qvm.add_argument('-D', '--start-delay', type=float, metavar='DELAY',
help='QEMU start up delay before initial comm')
files = argparser.add_argument_group(title='Files')
files.add_argument('-c', '--config', metavar='JSON',
type=FileType('rt', encoding='utf-8'),
Expand Down

0 comments on commit abe6f32

Please sign in to comment.