Skip to content

Commit 75629d4

Browse files
committed
[ot] scripts/opentitan: cfggen.py: use more flexible option switches
it is noe possible to either: - specify the path to the top configuration file, or - specify the path to the OT directory and the top name Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
1 parent 926faf1 commit 75629d4

File tree

2 files changed

+64
-21
lines changed

2 files changed

+64
-21
lines changed

docs/opentitan/cfggen.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ parse, each of which can be overidden with options `-c`, `-l` and `-t`.
5858
* `-s` specify a SoC identifier for OT platforms with mulitple SoCs
5959

6060
* `-T` specify the OpenTitan _top_ name, such as `Darjeeling`, `EarlGrey`, ... This option is
61-
mandatory.
61+
mandatory if `-t` is not specified. Requires a TOPDIR path
6262

63-
* `-t` alternative path to the `top_<top>.gen.hjson` file
63+
* `-t` path to the `top_<top>.gen.hjson` file. This option is mandatory is `-T` is not specified.
6464

6565
* `-v` can be repeated to increase verbosity of the script, mostly for debug purpose.
6666

scripts/opentitan/cfggen.py

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from argparse import ArgumentParser
1313
from configparser import ConfigParser
1414
from logging import getLogger
15-
from os.path import dirname, isdir, isfile, join as joinpath, normpath
15+
from os.path import abspath, dirname, isdir, isfile, join as joinpath, normpath
1616
from traceback import format_exc
1717
from typing import Optional
1818
import re
@@ -53,12 +53,18 @@ def __init__(self):
5353
self._roms: dict[Optional[int], dict[str, str]] = {}
5454
self._otp: dict[str, str] = {}
5555
self._lc: dict[str, str] = {}
56+
self._top_name: Optional[str] = None
57+
58+
@property
59+
def top_name(self) -> Optional[str]:
60+
return self._top_name
5661

5762
def load_top_config(self, toppath: str) -> None:
5863
"""Load data from HJSON top configuration file."""
5964
assert not _HJSON_ERROR
6065
with open(toppath, 'rt') as tfp:
6166
cfg = hjload(tfp)
67+
self._top_name = cfg.get('name')
6268
for module in cfg.get('module') or []:
6369
modtype = module.get('type')
6470
if modtype == 'rom_ctrl':
@@ -232,9 +238,9 @@ def main():
232238
desc = sys.modules[__name__].__doc__.split('.', 1)[0].strip()
233239
argparser = ArgumentParser(description=f'{desc}.')
234240
files = argparser.add_argument_group(title='Files')
235-
files.add_argument('opentitan', nargs=1, metavar='TOPDIR',
241+
files.add_argument('opentitan', nargs='*', metavar='OTDIR',
236242
help='OpenTitan top directory')
237-
files.add_argument('-T', '--top', choices=top_map.keys(), required=True,
243+
files.add_argument('-T', '--top', choices=top_map.keys(),
238244
help='OpenTitan top name')
239245
files.add_argument('-o', '--out', metavar='CFG',
240246
help='Filename of the config file to generate')
@@ -258,25 +264,63 @@ def main():
258264
args = argparser.parse_args()
259265
debug = args.debug
260266

261-
configure_loggers(args.verbose, 'cfggen', 'otp')
267+
log = configure_loggers(args.verbose, 'cfggen', 'otp')[0]
262268

263269
if _HJSON_ERROR:
264270
argparser.error('Missing HJSON module: {_HJSON_ERROR}')
265271

266-
topdir = args.opentitan[0]
267-
if not isdir(topdir):
268-
argparser.error('Invalid OpenTitan top directory')
269-
ot_dir = normpath(topdir)
270-
ltop = args.top.lower()
271-
top = f'top_{ltop}'
272-
var = top_map[args.top]
273-
if not args.topcfg:
274-
cfgpath = joinpath(ot_dir, f'hw/{top}/data/autogen/{top}.gen.hjson')
275-
else:
276-
cfgpath = args.topcfg
277-
if not isfile(cfgpath):
278-
argparser.error(f"No such file '{cfgpath}'")
272+
cfg = OtConfiguration()
279273

274+
topcfg = args.topcfg
275+
if not topcfg:
276+
if not args.opentitan:
277+
argparser.error('TOPDIR is required is no top file is '
278+
'specified')
279+
ot_dir = args.opentitan[0]
280+
if not isdir(ot_dir):
281+
argparser.error('Invalid OpenTitan top directory')
282+
ot_dir = abspath(ot_dir)
283+
if not args.top:
284+
argparser.error('Top name is required if no top file is '
285+
'specified')
286+
ltop = args.top.lower()
287+
top = f'top_{ltop}'
288+
topvar = top_map[args.top]
289+
topcfg = joinpath(ot_dir, f'hw/{top}/data/autogen/{top}.gen.hjson')
290+
if not isfile(topcfg):
291+
argparser.error(f"No such file '{topcfg}'")
292+
log.info("Top config: '%s'", topcfg)
293+
cfg.load_top_config(topcfg)
294+
else:
295+
if not isfile(topcfg):
296+
argparser.error(f'No such top file: {topcfg}')
297+
cfg.load_top_config(topcfg)
298+
ltop = cfg.top_name
299+
if not ltop:
300+
argparser.error('Unknown top name')
301+
log.info("Top: '%s'", cfg.top_name)
302+
ltop = ltop.lower()
303+
topvar = {k.lower(): v for k, v in top_map.items()}.get(ltop)
304+
if not topvar:
305+
argparser.error(f'Unsupported top name: {cfg.top_name}')
306+
top = f'top_{ltop}'
307+
ot_dir = args.opentitan[0] if args.opentitan else None
308+
if not ot_dir:
309+
check_dir = f'hw/{top}/data'
310+
cur_dir = dirname(topcfg)
311+
while cur_dir:
312+
check_path = joinpath(cur_dir, check_dir)
313+
if isdir(check_path):
314+
ot_dir = cur_dir
315+
break
316+
cur_dir = dirname(cur_dir)
317+
if not ot_dir:
318+
argparser.error('Cannot find OT directory')
319+
elif not isdir(ot_dir):
320+
argparser.error('Invalid OpenTitan top directory')
321+
ot_dir = abspath(ot_dir)
322+
log.info("OT directory: '%s'", ot_dir)
323+
log.info("Variant: '%s'", topvar)
280324
if not args.lifecycle:
281325
lcpath = joinpath(ot_dir, 'hw/ip/lc_ctrl/rtl/lc_ctrl_state_pkg.sv')
282326
else:
@@ -293,10 +337,9 @@ def main():
293337
argparser.error(f"No such file '{ocpath}'")
294338

295339
cfg = OtConfiguration()
296-
cfg.load_top_config(cfgpath)
297340
cfg.load_lifecycle(lcpath)
298341
cfg.load_otp_constants(ocpath)
299-
cfg.save(var, args.socid, args.count, args.out)
342+
cfg.save(topvar, args.socid, args.count, args.out)
300343

301344
except (IOError, ValueError, ImportError) as exc:
302345
print(f'\nError: {exc}', file=sys.stderr)

0 commit comments

Comments
 (0)