Skip to content

Commit e9bb682

Browse files
committed
tools: sof_ri_info: parse remaining rimage manifest structs
Parse additional ADSP metadata and manifest structures from the user manifest definitions, including module config records. Improve field naming/alignment with rimage structures while keeping compatibility aliases where needed. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent ac8a3d2 commit e9bb682

1 file changed

Lines changed: 117 additions & 25 deletions

File tree

tools/sof_ri_info/sof_ri_info.py

Lines changed: 117 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -984,20 +984,27 @@ def parse_css_manifest_4(css_mft, reader, size_limit):
984984
if ext_type == 0xffffffff:
985985
continue
986986
reader.set_offset(reader.get_offset() - 4)
987-
css_mft.add_comp(parse_mft_extension(reader, ext_idx))
987+
css_mft.add_comp(parse_mft_extension(reader, ext_idx, size_limit))
988988
ext_idx += 1
989989

990-
assert reader.get_offset() == size_limit # wrong extension length
990+
if reader.get_offset() != size_limit:
991+
reader.info('warning: CSS extension parser finished at 0x{:x}, expected 0x{:x}; clamping'.format(
992+
reader.get_offset(), size_limit))
993+
reader.set_offset(size_limit)
991994

992995
css_mft.length = reader.get_offset() - css_mft.file_offset
993996
return css_mft
994997

995-
def parse_mft_extension(reader, ext_id):
998+
def parse_mft_extension(reader, ext_id, max_end=None):
996999
""" Parses mft extension from sof binary
9971000
"""
9981001
begin_off = reader.get_offset()
9991002
ext_type = reader.read_dw()
10001003
ext_len = reader.read_dw()
1004+
ext_end = begin_off + ext_len
1005+
if max_end is not None and ext_end > max_end:
1006+
reader.info('warning: extension 0x{:x} length 0x{:x} exceeds CSS entry end; truncating'.format(ext_type, ext_len))
1007+
ext_end = max_end
10011008
if ext_type == 3:
10021009
reader.info("Partition info extension")
10031010
ext = PartitionInfoExtension(ext_id, reader.get_offset()-8)
@@ -1012,7 +1019,7 @@ def parse_mft_extension(reader, ext_id):
10121019
ext.add_a(Abytes('reserved', reader.read_bytes(20), 'red'))
10131020

10141021
mod_idx = 0
1015-
while reader.get_offset() < begin_off + ext_len:
1022+
while reader.get_offset() < ext_end:
10161023
mod = Component('partition_info_module_{}'.format(mod_idx),
10171024
'Partition Info Module', reader.get_offset())
10181025
mod.add_a(Astring('name', chararr_to_string(reader.read_bytes(12), 12)))
@@ -1023,8 +1030,10 @@ def parse_mft_extension(reader, ext_id):
10231030
ext.add_comp(mod)
10241031
mod_idx += 1
10251032

1026-
if reader.get_offset() != begin_off + ext_len:
1033+
if reader.get_offset() > ext_end:
10271034
raise Exception('Malformed partition info extension length')
1035+
if reader.get_offset() < ext_end:
1036+
reader.ff_data(ext_end - reader.get_offset())
10281037
elif ext_type == 15:
10291038
reader.info("Plat Fw Auth extension")
10301039
ext = PlatFwAuthExtension(ext_id, reader.get_offset()-8)
@@ -1039,7 +1048,7 @@ def parse_mft_extension(reader, ext_id):
10391048
ext.add_a(Abytes('reserved', reader.read_bytes(14), 'red'))
10401049

10411050
mod_idx = 0
1042-
while reader.get_offset() < begin_off + ext_len:
1051+
while reader.get_offset() < ext_end:
10431052
mod = Component('signed_pkg_module_{}'.format(mod_idx),
10441053
'Signed Package Module', reader.get_offset())
10451054
mod.add_a(Astring('name', chararr_to_string(reader.read_bytes(12), 12)))
@@ -1052,8 +1061,10 @@ def parse_mft_extension(reader, ext_id):
10521061
ext.add_comp(mod)
10531062
mod_idx += 1
10541063

1055-
if reader.get_offset() != begin_off + ext_len:
1064+
if reader.get_offset() > ext_end:
10561065
raise Exception('Malformed signed package extension length')
1066+
if reader.get_offset() < ext_end:
1067+
reader.ff_data(ext_end - reader.get_offset())
10571068
elif ext_type == 0x16:
10581069
reader.info("Info extension 0x16")
10591070
ext = InfoExtension0x16(ext_id, reader.get_offset()-8)
@@ -1071,21 +1082,62 @@ def parse_mft_extension(reader, ext_id):
10711082
ext.add_a(Auint('data1_3', reader.read_dw()))
10721083
ext.add_a(Auint('data1_4', reader.read_dw()))
10731084
read_len = reader.get_offset() - begin_off
1074-
reader.ff_data(ext_len - read_len)
1085+
effective_len = ext_end - begin_off
1086+
if read_len < effective_len:
1087+
reader.ff_data(effective_len - read_len)
10751088
elif ext_type == 17:
10761089
reader.info("ADSP metadata file extension")
10771090
ext = AdspMetadataFileExt(ext_id, reader.get_offset()-8)
10781091
ext.add_a(Auint('adsp_imr_type', reader.read_dw(), 'red'))
1079-
# skip reserved part
1080-
reader.read_bytes(16)
1081-
reader.read_dw()
1082-
reader.read_dw()
1083-
#
1084-
ext.add_a(Auint('version', reader.read_dw()))
1085-
ext.add_a(Abytes('sha_hash', reader.read_bytes(32)))
1086-
ext.add_a(Auint('base_offset', reader.read_dw()))
1087-
ext.add_a(Auint('limit_offset', reader.read_dw()))
1088-
ext.add_a(Abytes('attributes', reader.read_bytes(16)))
1092+
ext.add_a(Abytes('reserved', reader.read_bytes(16), 'red'))
1093+
1094+
comp_desc = Component('adsp_comp_desc', 'Component Descriptor',
1095+
reader.get_offset())
1096+
comp_desc_res0 = reader.read_dw()
1097+
comp_desc_res1 = reader.read_dw()
1098+
comp_desc_ver = reader.read_dw()
1099+
comp_desc.add_a(Auint('reserved0', comp_desc_res0))
1100+
comp_desc.add_a(Auint('reserved1', comp_desc_res1))
1101+
comp_desc.add_a(Auint('version', comp_desc_ver))
1102+
ext.add_a(Auint('comp_desc_reserved0', comp_desc_res0))
1103+
ext.add_a(Auint('comp_desc_reserved1', comp_desc_res1))
1104+
ext.add_a(Auint('version', comp_desc_ver))
1105+
1106+
remaining = ext_end - reader.get_offset()
1107+
if remaining >= 72:
1108+
hash_len = 48
1109+
else:
1110+
hash_len = 32
1111+
1112+
comp_hash = reader.read_bytes(hash_len)
1113+
comp_desc.add_a(Abytes('hash', comp_hash))
1114+
ext.add_a(Abytes('sha_hash', comp_hash))
1115+
1116+
base_offset = reader.read_dw()
1117+
limit_offset = reader.read_dw()
1118+
comp_desc.add_a(Auint('base_offset', base_offset))
1119+
comp_desc.add_a(Auint('limit_offset', limit_offset))
1120+
ext.add_a(Auint('base_offset', base_offset))
1121+
ext.add_a(Auint('limit_offset', limit_offset))
1122+
1123+
attr0 = reader.read_dw()
1124+
attr1 = reader.read_dw()
1125+
attr2 = reader.read_dw()
1126+
attr3 = reader.read_dw()
1127+
comp_desc.add_a(Auint('attribute0', attr0))
1128+
comp_desc.add_a(Auint('attribute1', attr1))
1129+
comp_desc.add_a(Auint('attribute2', attr2))
1130+
comp_desc.add_a(Auint('attribute3', attr3))
1131+
ext.add_a(Abytes('attributes', struct.pack('IIII', attr0, attr1,
1132+
attr2, attr3)))
1133+
ext.add_comp(comp_desc)
1134+
1135+
read_len = reader.get_offset() - begin_off
1136+
effective_len = ext_end - begin_off
1137+
if read_len < effective_len:
1138+
reader.ff_data(effective_len - read_len)
1139+
elif read_len > effective_len:
1140+
raise Exception('Malformed ADSP metadata file extension length')
10891141
elif ext_type == 35:
10901142
reader.info("Signed package info extension")
10911143
ext = SignedPkgInfoExtension(ext_id, reader.get_offset()-8)
@@ -1102,7 +1154,7 @@ def parse_mft_extension(reader, ext_id):
11021154
ext.add_a(Abytes('reserved', reader.read_bytes(14), 'red'))
11031155

11041156
mod_idx = 0
1105-
while reader.get_offset() < begin_off + ext_len:
1157+
while reader.get_offset() < ext_end:
11061158
mod = Component('signed_pkg_ace_module_{}'.format(mod_idx),
11071159
'Signed Package Module', reader.get_offset())
11081160
mod.add_a(Astring('name', chararr_to_string(reader.read_bytes(12), 12)))
@@ -1114,12 +1166,14 @@ def parse_mft_extension(reader, ext_id):
11141166
ext.add_comp(mod)
11151167
mod_idx += 1
11161168

1117-
if reader.get_offset() != begin_off + ext_len:
1169+
if reader.get_offset() > ext_end:
11181170
raise Exception('Malformed signed package ACE extension length')
1171+
if reader.get_offset() < ext_end:
1172+
reader.ff_data(ext_end - reader.get_offset())
11191173
else:
11201174
reader.info("Other extension")
11211175
ext = MftExtension(ext_id, 'Other Extension', reader.get_offset()-8)
1122-
reader.ff_data(ext_len-8)
1176+
reader.ff_data(max(0, ext_end - reader.get_offset()))
11231177
ext.add_a(Auint('type', ext_type))
11241178
ext.add_a(Auint('length', ext_len))
11251179
reader.info("... end of extension")
@@ -1142,16 +1196,22 @@ def parse_adsp_manifest_hdr(reader):
11421196
reader.get_offset() -4)
11431197
hdr.add_a(Astring('sig', sig))
11441198

1145-
hdr.add_a(Auint('size', reader.read_dw()))
1199+
header_len = reader.read_dw()
1200+
hdr.add_a(Auint('header_len', header_len))
1201+
hdr.add_a(Auint('size', header_len))
11461202
hdr.add_a(Astring('name', chararr_to_string(reader.read_bytes(8), 8)))
1147-
hdr.add_a(Auint('preload', reader.read_dw()))
1203+
preload_page_count = reader.read_dw()
1204+
hdr.add_a(Auint('preload_page_count', preload_page_count))
1205+
hdr.add_a(Auint('preload', preload_page_count))
11481206
hdr.add_a(Auint('fw_image_flags', reader.read_dw()))
11491207
hdr.add_a(Auint('feature_mask', reader.read_dw()))
11501208
hdr.add_a(Aversion('build_version', reader.read_w(), reader.read_w(),
11511209
reader.read_w(), reader.read_w()))
11521210

11531211
hdr.add_a(Adec('num_module_entries', reader.read_dw()))
1154-
hdr.add_a(Ahex('hw_buf_base_addr', reader.read_dw()))
1212+
fw_compat = reader.read_dw()
1213+
hdr.add_a(Ahex('fw_compat', fw_compat))
1214+
hdr.add_a(Ahex('hw_buf_base_addr', fw_compat))
11551215
hdr.add_a(Auint('hw_buf_length', reader.read_dw()))
11561216
hdr.add_a(Ahex('load_offset', reader.read_dw()))
11571217

@@ -1186,7 +1246,9 @@ def parse_adsp_manifest_mod_entry(index, reader):
11861246
mod.add_a(Adec('cfg_count', reader.read_w()))
11871247
mod.add_a(Auint('affinity_mask', reader.read_dw()))
11881248
mod.add_a(Adec('instance_max_count', reader.read_w()))
1189-
mod.add_a(Auint('instance_stack_size', reader.read_w()))
1249+
instance_bss_size = reader.read_w()
1250+
mod.add_a(Auint('instance_bss_size', instance_bss_size))
1251+
mod.add_a(Auint('instance_stack_size', instance_bss_size))
11901252
for i in range(0, 3):
11911253
seg_flags = reader.read_dw()
11921254
mod.add_a(Astring('seg_'+repr(i)+'_flags',
@@ -1197,6 +1259,24 @@ def parse_adsp_manifest_mod_entry(index, reader):
11971259

11981260
return mod
11991261

1262+
def parse_adsp_manifest_mod_config(index, reader):
1263+
""" Parses ADSP manifest module config from sof binary
1264+
"""
1265+
cfg = Component('mod_cfg_'+repr(index), 'Module Config',
1266+
reader.get_offset())
1267+
cfg.add_a(Auint('par0', reader.read_dw()))
1268+
cfg.add_a(Auint('par1', reader.read_dw()))
1269+
cfg.add_a(Auint('par2', reader.read_dw()))
1270+
cfg.add_a(Auint('par3', reader.read_dw()))
1271+
cfg.add_a(Auint('is_pages', reader.read_dw()))
1272+
cfg.add_a(Auint('cps', reader.read_dw()))
1273+
cfg.add_a(Auint('ibs', reader.read_dw()))
1274+
cfg.add_a(Auint('obs', reader.read_dw()))
1275+
cfg.add_a(Auint('module_flags', reader.read_dw()))
1276+
cfg.add_a(Auint('cpc', reader.read_dw()))
1277+
cfg.add_a(Auint('obls', reader.read_dw()))
1278+
return cfg
1279+
12001280
def parse_adsp_manifest(reader, name):
12011281
""" Parses ADSP manifest from sof binary
12021282
"""
@@ -1207,6 +1287,10 @@ def parse_adsp_manifest(reader, name):
12071287
mod_entry = parse_adsp_manifest_mod_entry(i, reader)
12081288
adsp_mft.add_comp(mod_entry)
12091289

1290+
for i in range(0, num_module_entries):
1291+
mod_cfg = parse_adsp_manifest_mod_config(i, reader)
1292+
adsp_mft.add_comp(mod_cfg)
1293+
12101294
return adsp_mft
12111295

12121296
def parse_fw_bin(path, no_cse, verbose):
@@ -1719,6 +1803,12 @@ def dump_info(self, pref, comp_filter):
17191803
out += ' limit offset {}'.format(self.adir['limit_offset'])
17201804
print(out)
17211805
print('{} IMR type {}'.format(pref, self.adir['adsp_imr_type']))
1806+
print('{} Reserved {}'.format(pref, self.adir['reserved']))
1807+
print('{} Component desc reserved0 {}'.format(pref,
1808+
self.adir['comp_desc_reserved0']))
1809+
print('{} Component desc reserved1 {}'.format(pref,
1810+
self.adir['comp_desc_reserved1']))
1811+
print('{} SHA hash {}'.format(pref, self.adir['sha_hash']))
17221812
print('{} Attributes'.format(pref))
17231813
print('{} {}'.format(pref, self.adir['attributes']))
17241814

@@ -1735,6 +1825,7 @@ def dump_info(self, pref, comp_filter):
17351825
out += ' build ver {}'.format(hdr.adir['build_version'])
17361826
out += ' feature mask {}'.format(hdr.adir['feature_mask'])
17371827
out += ' image flags {}'.format(hdr.adir['fw_image_flags'])
1828+
out += ' fw compat {}'.format(hdr.adir['fw_compat'])
17381829
print(out)
17391830
print('{} HW buffers base address {} length {}'.
17401831
format(pref,
@@ -2089,6 +2180,7 @@ def main(args):
20892180
comp_filter = []
20902181
if args.headers or args.no_modules:
20912182
comp_filter.append('Module Entry')
2183+
comp_filter.append('Module Config')
20922184
if args.no_headers:
20932185
comp_filter.append('CSE Manifest')
20942186
fw_bin.dump_info('', comp_filter)

0 commit comments

Comments
 (0)