10
10
11
11
from argparse import ArgumentParser , FileType
12
12
from 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 )
14
16
from re import match as re_match
15
17
from traceback import format_exception
16
- from typing import Optional
18
+ from typing import Optional , Union
17
19
import sys
18
20
19
21
QEMU_PYPATH = joinpath (dirname (dirname (dirname (normpath (__file__ )))),
28
30
_EXC = exc
29
31
from ot .otp import (OtpImage , OtpLifecycleExtension , OtpMap , OtpPartition ,
30
32
OtpPartitionDesc , OtpRegisterDef )
33
+ from ot .top import OpenTitanTop
31
34
from ot .util .log import configure_loggers
32
35
from ot .util .misc import HexInt , to_bool
33
36
@@ -50,6 +53,31 @@ def parse_lc_token(tkdesc: str) -> tuple[str, 'LifeCycleTokenPair']:
50
53
return token_name , tkeng .build_from_text (tktext )
51
54
52
55
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
+
53
81
def main ():
54
82
"""Main routine"""
55
83
debug = True
@@ -143,6 +171,9 @@ def main():
143
171
default = outkinds [0 ],
144
172
help = f'select output format for code generation'
145
173
f' (default: { outkinds [0 ]} )' )
174
+ commands .add_argument ('--top-name' ,
175
+ help = 'optional top name for code generation '
176
+ '(default: auto)' )
146
177
extra = argparser .add_argument_group (title = 'Extras' )
147
178
extra .add_argument ('-v' , '--verbose' , action = 'count' ,
148
179
help = 'increase verbosity' )
@@ -226,8 +257,11 @@ def main():
226
257
partdesc .save (args .out_kind , basename (args .otp_map .name ),
227
258
basename (sys .argv [0 ]), output )
228
259
elif args .generate == 'REGS' :
260
+ topname = args .top_name
261
+ if not topname :
262
+ topname = get_top_name (args .otp_map )
229
263
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 ),
231
265
basename (sys .argv [0 ]), output )
232
266
elif args .generate == 'LCVAL' :
233
267
lcext .save (args .out_kind , output , True )
0 commit comments