1010
1111from argparse import ArgumentParser , FileType
1212from binascii import unhexlify
13- from os .path import basename , dirname , join as joinpath , normpath
13+ from io import IOBase
14+ from os .path import (basename , dirname , isfile , join as joinpath , normpath ,
15+ split as splitpath )
1416from re import match as re_match
1517from traceback import format_exception
16- from typing import Optional
18+ from typing import Optional , Union
1719import sys
1820
1921QEMU_PYPATH = joinpath (dirname (dirname (dirname (normpath (__file__ )))),
2830 _EXC = exc
2931from ot .otp import (OtpImage , OtpLifecycleExtension , OtpMap , OtpPartition ,
3032 OtpPartitionDesc , OtpRegisterDef )
33+ from ot .top import OpenTitanTop
3134from ot .util .log import configure_loggers
3235from ot .util .misc import HexInt , to_bool
3336
@@ -50,6 +53,31 @@ def parse_lc_token(tkdesc: str) -> tuple[str, 'LifeCycleTokenPair']:
5053 return token_name , tkeng .build_from_text (tktext )
5154
5255
56+ def get_top_name (* filepaths : list [Union [str , IOBase ]]) -> Optional [str ]:
57+ """Try to retrieve the top name from a list of configuration files.
58+
59+ :param filepaths: list of file path or file objects
60+ :return: the name of the identified top, if found
61+ """
62+ for filepath in filepaths :
63+ if not isinstance (filepath , str ):
64+ filepath = getattr (filepath , 'name' , None )
65+ if not filepath :
66+ continue
67+ if not isfile (filepath ):
68+ continue
69+ fdir = dirname (filepath )
70+ top_names = set (OpenTitanTop .names )
71+ while fdir :
72+ fdir , tail = splitpath (fdir )
73+ top_prefix = 'top_'
74+ if tail .startswith (top_prefix ):
75+ candidate = tail .removeprefix (top_prefix )
76+ if candidate in top_names :
77+ return candidate
78+ return None
79+
80+
5381def main ():
5482 """Main routine"""
5583 debug = True
@@ -143,6 +171,9 @@ def main():
143171 default = outkinds [0 ],
144172 help = f'select output format for code generation'
145173 f' (default: { outkinds [0 ]} )' )
174+ commands .add_argument ('--top-name' ,
175+ help = 'optional top name for code generation '
176+ '(default: auto)' )
146177 extra = argparser .add_argument_group (title = 'Extras' )
147178 extra .add_argument ('-v' , '--verbose' , action = 'count' ,
148179 help = 'increase verbosity' )
@@ -226,8 +257,11 @@ def main():
226257 partdesc .save (args .out_kind , basename (args .otp_map .name ),
227258 basename (sys .argv [0 ]), output )
228259 elif args .generate == 'REGS' :
260+ topname = args .top_name
261+ if not topname :
262+ topname = get_top_name (args .otp_map )
229263 regdef = OtpRegisterDef (otpmap )
230- regdef .save (args .out_kind , basename (args .otp_map .name ),
264+ regdef .save (args .out_kind , topname , basename (args .otp_map .name ),
231265 basename (sys .argv [0 ]), output )
232266 elif args .generate == 'LCVAL' :
233267 lcext .save (args .out_kind , output , True )
0 commit comments