1#!/usr/bin/env python3
2# SPDX-License-Identifier: BSD-3-Clause
3#
4# Copyright (c) 2019, Intel Corporation. All rights reserved.
5#
6# Author: Marcin Maka <marcin.maka@linux.intel.com>
7
8""" Parses manifests included in sof binary and prints extracted metadata
9    in readable form.
10"""
11
12# pylint: disable=too-few-public-methods
13# pylint: disable=too-many-arguments
14# pylint: disable=too-many-instance-attributes
15
16import sys
17import argparse
18import struct
19
20# To extend the DSP memory layout list scroll down to DSP_MEM_SPACE_EXT
21
22# Public keys signatures recognized by parse_css_manifest()
23# - add a new one as array of bytes and append entry to KNOWN_KEYS below.
24#   you can use --full_bytes to dump the bytes in below format
25
26APL_INTEL_PROD_KEY = bytes([0x1f, 0xf4, 0x58, 0x74, 0x64, 0xd4, 0xae, 0x90,
27                            0x03, 0xb6, 0x71, 0x0d, 0xb5, 0xaf, 0x6d, 0xd6,
28                            0x96, 0xce, 0x28, 0x95, 0xd1, 0x5b, 0x40, 0x59,
29                            0xcd, 0xdf, 0x0c, 0x55, 0xd2, 0xc1, 0xbd, 0x58,
30                            0xc3, 0x0d, 0x83, 0xe2, 0xac, 0xfa, 0xe0, 0xcc,
31                            0x54, 0xf6, 0x5f, 0x72, 0xc2, 0x11, 0x05, 0x93,
32                            0x1d, 0xb7, 0xe4, 0x4f, 0xa4, 0x95, 0xf5, 0x84,
33                            0x77, 0x07, 0x24, 0x6e, 0x72, 0xce, 0x57, 0x41,
34                            0xf2, 0x0b, 0x49, 0x49, 0x0c, 0xe2, 0x76, 0xf8,
35                            0x19, 0xc7, 0x9f, 0xe1, 0xca, 0x77, 0x20, 0x1b,
36                            0x5d, 0x1d, 0xed, 0xee, 0x5c, 0x54, 0x1d, 0xf6,
37                            0x76, 0x14, 0xce, 0x6a, 0x24, 0x80, 0xc9, 0xce,
38                            0x2e, 0x92, 0xe9, 0x35, 0xc7, 0x1a, 0xe9, 0x97,
39                            0x7f, 0x25, 0x2b, 0xa8, 0xf3, 0xc1, 0x4d, 0x6b,
40                            0xae, 0xd9, 0xcd, 0x0c, 0xbb, 0x08, 0x6d, 0x2b,
41                            0x01, 0x44, 0xe2, 0xb9, 0x44, 0x4e, 0x4d, 0x5c,
42                            0xdf, 0x8a, 0x89, 0xa5, 0x3c, 0x27, 0xa0, 0x54,
43                            0xde, 0xc5, 0x5b, 0xde, 0x58, 0x10, 0x8c, 0xaa,
44                            0xc4, 0x37, 0x5b, 0x73, 0x58, 0xfb, 0xe3, 0xcf,
45                            0x57, 0xf5, 0x65, 0xd3, 0x19, 0x06, 0xed, 0x36,
46                            0x47, 0xb0, 0x91, 0x67, 0xec, 0xc1, 0xe1, 0x7b,
47                            0x4f, 0x85, 0x66, 0x61, 0x31, 0x99, 0xfc, 0x98,
48                            0x7a, 0x56, 0x70, 0x95, 0x85, 0x52, 0xa0, 0x30,
49                            0x37, 0x92, 0x11, 0x9e, 0x7f, 0x33, 0x44, 0xd3,
50                            0x81, 0xfd, 0x14, 0x74, 0x51, 0x1c, 0x01, 0x14,
51                            0xc8, 0x4b, 0xf6, 0xd6, 0xeb, 0x67, 0xef, 0xfc,
52                            0x0a, 0x5f, 0xcc, 0x31, 0x73, 0xf8, 0xa9, 0xe3,
53                            0xcb, 0xb4, 0x8b, 0x91, 0xa1, 0xf0, 0xb9, 0x6e,
54                            0x1f, 0xea, 0xd3, 0xa3, 0xe4, 0x0f, 0x96, 0x74,
55                            0x3c, 0x17, 0x5b, 0x68, 0x7c, 0x87, 0xfc, 0x90,
56                            0x10, 0x89, 0x23, 0xca, 0x5d, 0x17, 0x5b, 0xc1,
57                            0xb5, 0xc2, 0x49, 0x4e, 0x2a, 0x5f, 0x47, 0xc2])
58
59CNL_INTEL_PROD_KEY = bytes([0x41, 0xa0, 0x3e, 0x14, 0x1e, 0x7e, 0x29, 0x72,
60                            0x89, 0x97, 0xc2, 0xa7, 0x7d, 0xbc, 0x1d, 0x25,
61                            0xf4, 0x9a, 0xa8, 0xb7, 0x89, 0x10, 0x73, 0x31,
62                            0x58, 0xbd, 0x46, 0x55, 0x78, 0xcf, 0xd9, 0xe1,
63                            0x7d, 0xfa, 0x24, 0x23, 0xfa, 0x5c, 0x7c, 0xc9,
64                            0x3d, 0xc8, 0xb5, 0x74, 0x87, 0xa, 0x8c, 0xe7,
65                            0x33, 0xc2, 0x71, 0x26, 0xb1, 0x4d, 0x32, 0x45,
66                            0x23, 0x17, 0xcb, 0xa6, 0xa2, 0xd0, 0xcc, 0x9e,
67                            0x2b, 0xa6, 0x9, 0x42, 0x52, 0xf1, 0xe6, 0xbd,
68                            0x73, 0x92, 0x2a, 0xfb, 0x7f, 0xc4, 0x8d, 0x5,
69                            0xec, 0x69, 0x7f, 0xd4, 0xa2, 0x6c, 0x46, 0xd4,
70                            0x5d, 0x92, 0x1d, 0x17, 0x75, 0x39, 0x16, 0x4c,
71                            0x61, 0xa8, 0xda, 0x93, 0xd6, 0x26, 0x23, 0xa,
72                            0xc8, 0x2d, 0xcc, 0x81, 0xf4, 0xcc, 0x85, 0x42,
73                            0xaa, 0xa3, 0x15, 0x8, 0x62, 0x8f, 0x72, 0x9b,
74                            0x5f, 0x90, 0x2f, 0xd5, 0x94, 0xdc, 0xad, 0xf,
75                            0xa9, 0x8, 0x8c, 0x2e, 0x20, 0xf4, 0xdf, 0x12,
76                            0xf, 0xe2, 0x1e, 0xeb, 0xfb, 0xf7, 0xe9, 0x22,
77                            0xef, 0xa7, 0x12, 0x3d, 0x43, 0x3b, 0x62, 0x8e,
78                            0x2e, 0xeb, 0x78, 0x8, 0x6e, 0xd0, 0xb0, 0xea,
79                            0x37, 0x43, 0x16, 0xd8, 0x11, 0x5a, 0xb5, 0x5,
80                            0x60, 0xf2, 0x91, 0xa7, 0xaa, 0x7d, 0x7, 0x17,
81                            0xb7, 0x5b, 0xec, 0x45, 0xf4, 0x4a, 0xaf, 0x5c,
82                            0xa3, 0x30, 0x62, 0x8e, 0x4d, 0x63, 0x2, 0x2,
83                            0xed, 0x4b, 0x1f, 0x1b, 0x9a, 0x2, 0x29, 0x9,
84                            0xc1, 0x7a, 0xc5, 0xeb, 0xc7, 0xdb, 0xa1, 0x6f,
85                            0x61, 0x31, 0xfa, 0x7b, 0x3b, 0xe0, 0x6a, 0x1c,
86                            0xee, 0x55, 0xed, 0xf0, 0xf9, 0x7a, 0xaf, 0xaa,
87                            0xc7, 0x76, 0xf5, 0xfb, 0x6a, 0xbc, 0x65, 0xde,
88                            0x42, 0x3e, 0x1c, 0xdf, 0xcc, 0x69, 0x75, 0x1,
89                            0x38, 0x8, 0x66, 0x20, 0xea, 0x6, 0x91, 0xb8,
90                            0xcd, 0x1d, 0xfa, 0xfd, 0xe8, 0xa0, 0xba, 0x91])
91
92ICL_INTEL_PROD_KEY = bytes([0x63, 0xdf, 0x54, 0xe3, 0xc1, 0xe5, 0xd9, 0xd2,
93                            0xb8, 0xb5, 0x13, 0xb3, 0xec, 0xc2, 0x64, 0xb5,
94                            0x16, 0xb4, 0xfc, 0x56, 0x92, 0x67, 0x17, 0xc7,
95                            0x91, 0x7b, 0x3d, 0xb0, 0x22, 0xbf, 0x7f, 0x92,
96                            0x39, 0x35, 0xcc, 0x64, 0x1c, 0xad, 0x8, 0x75,
97                            0xe7, 0x67, 0xb, 0x8, 0xf8, 0x57, 0xdb, 0x9c,
98                            0xde, 0xab, 0xe, 0xbd, 0x27, 0x5f, 0x5, 0x51,
99                            0xcf, 0x6e, 0x3e, 0xc9, 0xdd, 0xe6, 0x51, 0x14,
100                            0x57, 0xe1, 0x8a, 0x23, 0xae, 0x7a, 0xa5, 0x5f,
101                            0xdc, 0x16, 0x13, 0x1b, 0x28, 0x3b, 0xab, 0xf1,
102                            0xc3, 0xb5, 0x73, 0xc0, 0x72, 0xd8, 0x86, 0x7a,
103                            0x76, 0x3a, 0x2, 0xbe, 0x2f, 0x3e, 0xfe, 0x93,
104                            0x83, 0xa1, 0xd, 0xa0, 0xfc, 0x26, 0x7f, 0x6b,
105                            0x2e, 0x5a, 0xfd, 0xac, 0x6b, 0x53, 0xd3, 0xb8,
106                            0xff, 0x5e, 0xc7, 0x5, 0x25, 0xff, 0xe7, 0x78,
107                            0x9c, 0x45, 0xe4, 0x17, 0xbd, 0xf4, 0x52, 0x4e,
108                            0x3c, 0xa2, 0xa, 0x4d, 0x54, 0xb5, 0x40, 0x30,
109                            0xb3, 0x48, 0xba, 0x6c, 0xfa, 0x63, 0xc0, 0x65,
110                            0x2e, 0xde, 0x9, 0x2e, 0xa1, 0x95, 0x85, 0xc0,
111                            0x78, 0xd9, 0x98, 0x64, 0x3c, 0x29, 0x2e, 0x48,
112                            0x66, 0x1e, 0xaf, 0x1d, 0xa0, 0x7c, 0x15, 0x3,
113                            0x7f, 0x9e, 0x5f, 0x38, 0xf5, 0xc1, 0xe1, 0xe9,
114                            0xbe, 0x77, 0xa2, 0x9c, 0x83, 0xf2, 0x25, 0x54,
115                            0x22, 0xfe, 0x29, 0x66, 0x5, 0xc2, 0xc9, 0x6b,
116                            0x8b, 0xa6, 0xa3, 0xf9, 0xb1, 0x6b, 0xaf, 0xe7,
117                            0x14, 0x77, 0xff, 0x17, 0xc9, 0x7c, 0x7c, 0x4e,
118                            0x83, 0x28, 0x2a, 0xe5, 0xc3, 0xcc, 0x6e, 0x25,
119                            0xa, 0x62, 0xbb, 0x97, 0x44, 0x86, 0x7c, 0xa2,
120                            0xd4, 0xf1, 0xd4, 0xf8, 0x8, 0x17, 0xf4, 0x6c,
121                            0xcc, 0x95, 0x99, 0xd4, 0x86, 0x37, 0x4, 0x9f,
122                            0x5, 0x76, 0x1b, 0x44, 0x55, 0x75, 0xd9, 0x32,
123                            0x35, 0xf1, 0xec, 0x4d, 0x93, 0x73, 0xe6, 0xc4])
124
125TGL_INTEL_PROD_KEY = bytes([0xd3, 0x72, 0x92, 0x99, 0x4e, 0xb9, 0xcd, 0x67,
126                            0x41, 0x86, 0x16, 0x77, 0x35, 0xa1, 0x34, 0x85,
127                            0x43, 0x96, 0xd9, 0x53, 0x76, 0x4d, 0xd0, 0x63,
128                            0x17, 0x72, 0x96, 0xee, 0xf6, 0xdc, 0x50, 0x53,
129                            0x4b, 0x4, 0xaa, 0xfe, 0x3d, 0xd7, 0x21, 0x29,
130                            0x79, 0x6, 0x76, 0xee, 0xb3, 0x70, 0x23, 0x8,
131                            0x26, 0xa8, 0x83, 0x3d, 0x70, 0x13, 0x9d, 0x65,
132                            0xcb, 0xd5, 0xc6, 0xf, 0x92, 0x93, 0x38, 0x29,
133                            0x19, 0xa6, 0x7c, 0xbf, 0xf1, 0x76, 0x75, 0x2,
134                            0x9e, 0x32, 0x8f, 0x1f, 0x5, 0xa6, 0x2d, 0x89,
135                            0x6d, 0x38, 0xba, 0x38, 0xd, 0xf1, 0xe9, 0xe8,
136                            0xed, 0xf7, 0x6c, 0x20, 0x8d, 0x91, 0xc, 0xf8,
137                            0xdd, 0x9a, 0x56, 0xd3, 0xf7, 0xbf, 0x3c, 0xda,
138                            0xc8, 0x5d, 0xb, 0xef, 0x20, 0x5a, 0xc1, 0x5f,
139                            0x91, 0x94, 0xee, 0x90, 0xb8, 0xfc, 0x2c, 0x31,
140                            0x75, 0xc3, 0x7e, 0x86, 0xf6, 0x4f, 0x45, 0x4c,
141                            0x64, 0xe1, 0xe9, 0xe5, 0xcd, 0xf0, 0xec, 0xef,
142                            0xa7, 0xbd, 0x31, 0x62, 0x40, 0xa8, 0x48, 0x52,
143                            0xd5, 0x23, 0xce, 0x4, 0x45, 0x2f, 0xb, 0x3d,
144                            0xe0, 0x7a, 0xcf, 0xe5, 0x2a, 0x45, 0x5e, 0x91,
145                            0x1d, 0x41, 0xa7, 0x40, 0x85, 0x34, 0xe, 0x50,
146                            0x45, 0x59, 0xbf, 0xd, 0xa6, 0x6, 0xf9, 0xf6,
147                            0xce, 0xa2, 0x76, 0x72, 0x0, 0x62, 0x73, 0x37,
148                            0x1a, 0xbe, 0xd2, 0xe3, 0x1b, 0x7b, 0x26, 0x7b,
149                            0x32, 0xaa, 0x79, 0xed, 0x59, 0x23, 0xb6, 0xdb,
150                            0x9f, 0x3c, 0x3d, 0x65, 0xf3, 0xbb, 0x4b, 0xb4,
151                            0x97, 0xaa, 0x2a, 0xae, 0x48, 0xf4, 0xc5, 0x59,
152                            0x8d, 0x82, 0x4a, 0xb, 0x15, 0x4d, 0xd5, 0x4,
153                            0xa6, 0xc1, 0x2d, 0x83, 0x19, 0xc4, 0xc6, 0x49,
154                            0xba, 0x0, 0x1b, 0x2b, 0x70, 0xb, 0x26, 0x7c,
155                            0xb8, 0x94, 0x18, 0xe4, 0x9a, 0xf6, 0x5a, 0x68,
156                            0x9d, 0x44, 0xd2, 0xed, 0xd5, 0x67, 0x42, 0x47,
157                            0x5f, 0x73, 0xc5, 0xa7, 0xe5, 0x87, 0xa9, 0x4d,
158                            0xae, 0xc1, 0xb, 0x2c, 0x46, 0x16, 0xd7, 0x4e,
159                            0xf0, 0xdc, 0x61, 0x58, 0x51, 0xb1, 0x2, 0xbc,
160                            0xca, 0x17, 0xb1, 0x1a, 0xa, 0x96, 0x3b, 0x25,
161                            0x1c, 0x63, 0x56, 0x65, 0x20, 0x6e, 0x1b, 0x21,
162                            0xb1, 0x94, 0x7a, 0xf5, 0xbf, 0x83, 0x21, 0x86,
163                            0x38, 0xf1, 0x66, 0x1a, 0xa, 0x75, 0x73, 0xa,
164                            0xe, 0xc7, 0x64, 0x68, 0xc7, 0xf9, 0xc3, 0x4a,
165                            0x73, 0xfb, 0x86, 0xa5, 0x7, 0xb8, 0x8b, 0xf0,
166                            0xa3, 0x3b, 0xa9, 0x8f, 0x33, 0xa7, 0xce, 0xfe,
167                            0x36, 0x60, 0xbd, 0x5, 0xf0, 0x9a, 0x30, 0xe5,
168                            0xe1, 0x43, 0x25, 0x1c, 0x1, 0x4a, 0xd4, 0x23,
169                            0x1e, 0x8f, 0xb9, 0xdd, 0xd8, 0xb2, 0x24, 0xef,
170                            0x36, 0x4d, 0x5b, 0x8f, 0xba, 0x4f, 0xe9, 0x48,
171                            0xe7, 0x51, 0x42, 0x59, 0x56, 0xa, 0x1c, 0xf,
172                            0x5d, 0x62, 0x4a, 0x80, 0x96, 0x31, 0xf8, 0xb5])
173
174EHL_INTEL_PROD_KEY = bytes([0xb5, 0xb0, 0xe2, 0x25, 0x3d, 0xc7, 0x54, 0x10,
175                            0xde, 0x3c, 0xc9, 0x24, 0x97, 0x74, 0xbc, 0x02,
176                            0x7d, 0x0b, 0xd6, 0x61, 0x2e, 0x35, 0x65, 0xed,
177                            0x78, 0xf6, 0x85, 0x73, 0x1f, 0x8c, 0xda, 0x8f,
178                            0x50, 0x79, 0xc7, 0x0c, 0x9e, 0xb4, 0x09, 0x3b,
179                            0xfc, 0x2e, 0x4e, 0xf3, 0x46, 0xfe, 0x3f, 0x20,
180                            0x9d, 0x8d, 0xf6, 0x3e, 0xc3, 0x46, 0x92, 0xf9,
181                            0xce, 0xbb, 0x7d, 0x0b, 0xb3, 0x45, 0x35, 0x76,
182                            0xbe, 0x19, 0x87, 0x21, 0x6c, 0x79, 0xfa, 0xf4,
183                            0xc8, 0x8e, 0x07, 0x26, 0x03, 0x0d, 0xe9, 0xe3,
184                            0x1e, 0x61, 0x7c, 0xd1, 0x45, 0x10, 0x61, 0x1c,
185                            0x79, 0x3f, 0x10, 0xa9, 0x42, 0x60, 0x2c, 0x7a,
186                            0x7a, 0x89, 0x1b, 0x54, 0xda, 0x0e, 0x54, 0x08,
187                            0x30, 0x0f, 0x6e, 0x37, 0xea, 0xb7, 0x58, 0xa0,
188                            0xaf, 0x4a, 0x94, 0x2c, 0x43, 0x50, 0x74, 0xed,
189                            0x16, 0xdc, 0x11, 0xa1, 0xd3, 0x6e, 0x54, 0xa6,
190                            0x56, 0xf9, 0x40, 0x8c, 0x3f, 0xa3, 0x74, 0xae,
191                            0x4f, 0x48, 0xc8, 0x79, 0x30, 0x5a, 0x99, 0x79,
192                            0x26, 0xe1, 0x52, 0x9b, 0xfe, 0x9e, 0xaf, 0x96,
193                            0xcc, 0xe6, 0x9a, 0x53, 0x2e, 0xe4, 0x40, 0xcc,
194                            0xad, 0x19, 0x8e, 0x23, 0x53, 0x63, 0xc8, 0xfd,
195                            0x96, 0xeb, 0x27, 0x9b, 0x3e, 0x49, 0x0d, 0x90,
196                            0xb0, 0x67, 0xb4, 0x05, 0x4a, 0x55, 0x5b, 0xb0,
197                            0xa5, 0x68, 0xb8, 0x60, 0xa4, 0x81, 0x6a, 0x3e,
198                            0x8c, 0xbc, 0x29, 0xcd, 0x85, 0x45, 0x3c, 0xf4,
199                            0x86, 0xf8, 0x9b, 0x69, 0xb5, 0xc5, 0xb9, 0xaa,
200                            0xc8, 0xed, 0x7d, 0x70, 0x45, 0xb6, 0xf6, 0x5b,
201                            0x48, 0x62, 0xf6, 0x68, 0xe8, 0xdd, 0x79, 0xda,
202                            0xb0, 0xe9, 0x3c, 0x8f, 0x01, 0x92, 0x80, 0x73,
203                            0x89, 0x7d, 0x9a, 0xaf, 0x31, 0x85, 0x75, 0x7c,
204                            0x89, 0xf3, 0x6c, 0x77, 0x95, 0x5b, 0xa9, 0xc5,
205                            0xe1, 0x33, 0xe0, 0x44, 0x81, 0x7e, 0x72, 0xa5,
206                            0xbb, 0x3d, 0x40, 0xb7, 0xc9, 0x77, 0xd8, 0xc3,
207                            0xe3, 0xef, 0x42, 0xae, 0x57, 0x91, 0x63, 0x0c,
208                            0x26, 0xac, 0x5e, 0x10, 0x51, 0x28, 0xe6, 0x61,
209                            0xad, 0x4d, 0xc4, 0x93, 0xb2, 0xe0, 0xb4, 0x31,
210                            0x60, 0x5a, 0x97, 0x0e, 0x80, 0x86, 0x91, 0xc9,
211                            0xcd, 0xfc, 0x97, 0xc3, 0x78, 0xbd, 0xca, 0xce,
212                            0xd3, 0x96, 0xee, 0x75, 0x81, 0xe0, 0x8b, 0x45,
213                            0x8e, 0x20, 0x4b, 0x98, 0x31, 0x0f, 0xf9, 0x66,
214                            0xb3, 0x04, 0xb7, 0x0d, 0xde, 0x68, 0x1e, 0x2a,
215                            0xe4, 0xec, 0x45, 0x2a, 0x0a, 0x24, 0x81, 0x82,
216                            0xcb, 0x86, 0xa0, 0x61, 0x7f, 0xe7, 0x96, 0x84,
217                            0x4b, 0x30, 0xc4, 0x7d, 0x5c, 0x1b, 0x2c, 0x1e,
218                            0x66, 0x68, 0x71, 0x1d, 0x39, 0x6c, 0x23, 0x07,
219                            0x6d, 0xf3, 0x3e, 0x64, 0xc3, 0x03, 0x97, 0x84,
220                            0x14, 0xd1, 0xf6, 0x50, 0xf4, 0x32, 0x5d, 0xae,
221                            0xad, 0x23, 0x46, 0x0c, 0x9f, 0xfc, 0x3e, 0xb9])
222
223COMMUNITY_KEY = bytes([0x85, 0x00, 0xe1, 0x68, 0xaa, 0xeb, 0xd2, 0x07,
224                       0x1b, 0x7c, 0x5e, 0xed, 0xd6, 0xe7, 0xe5, 0xf9,
225                       0xc1, 0x0e, 0x47, 0xd4, 0x4c, 0xab, 0x8c, 0xf0,
226                       0xe8, 0xee, 0x8b, 0x40, 0x36, 0x35, 0x58, 0x8f,
227                       0xf4, 0x6f, 0xfc, 0xfd, 0x0f, 0xdd, 0x55, 0x8b,
228                       0x45, 0x8c, 0xf0, 0x47, 0xdc, 0xb4, 0xac, 0x21,
229                       0x3b, 0x4b, 0x20, 0xe6, 0x81, 0xb3, 0xcc, 0x90,
230                       0xd4, 0x5e, 0xf1, 0xa4, 0x9b, 0x68, 0x52, 0xc8,
231                       0xf1, 0x2d, 0xf9, 0xc4, 0x77, 0xc6, 0x4d, 0xa9,
232                       0x90, 0xc7, 0x10, 0xfd, 0x43, 0xc8, 0x4b, 0x6b,
233                       0x23, 0x5e, 0x92, 0xf5, 0x8f, 0xac, 0xd5, 0x7d,
234                       0x60, 0x27, 0x36, 0x7c, 0x21, 0x4e, 0x21, 0x99,
235                       0xde, 0xcb, 0xc0, 0x45, 0xf3, 0x04, 0x22, 0xb8,
236                       0x7d, 0x16, 0x68, 0x40, 0xf9, 0x5c, 0xf0, 0xb9,
237                       0x7e, 0x8c, 0x05, 0xb6, 0xfc, 0x28, 0xbb, 0x3d,
238                       0xd8, 0xff, 0xb6, 0xa4, 0xd4, 0x54, 0x27, 0x3b,
239                       0x1a, 0x42, 0x4e, 0xf5, 0xa6, 0xa8, 0x5e, 0x44,
240                       0xe2, 0x9e, 0xed, 0x68, 0x6a, 0x27, 0x60, 0x13,
241                       0x8d, 0x2f, 0x27, 0x70, 0xcd, 0x57, 0xc9, 0x18,
242                       0xa3, 0xb0, 0x30, 0xa1, 0xf4, 0xe6, 0x32, 0x12,
243                       0x89, 0x2a, 0xaf, 0x40, 0xa5, 0xfd, 0x52, 0xf1,
244                       0xaa, 0x8a, 0xa4, 0xef, 0x20, 0x3d, 0x10, 0xa3,
245                       0x70, 0xf2, 0x39, 0xc5, 0x05, 0x99, 0x22, 0x10,
246                       0x81, 0x83, 0x6e, 0x45, 0xa4, 0xf3, 0x5a, 0x9d,
247                       0x6a, 0xb8, 0x88, 0xfe, 0x69, 0x40, 0xd1, 0xb1,
248                       0xcb, 0x2a, 0xdb, 0x28, 0x05, 0xde, 0x54, 0xbf,
249                       0x3d, 0x86, 0x5f, 0x39, 0x8b, 0xc1, 0xf4, 0xaf,
250                       0x00, 0x61, 0x86, 0x01, 0xfa, 0x22, 0xac, 0xf6,
251                       0x2c, 0xa4, 0x17, 0x6a, 0xa7, 0xd8, 0x0a, 0x8c,
252                       0x9f, 0xbf, 0x1f, 0x62, 0xb2, 0x2e, 0x68, 0x52,
253                       0x3f, 0x82, 0x8f, 0xe5, 0x28, 0x4d, 0xdb, 0xb5,
254                       0x5a, 0x96, 0x28, 0x27, 0x19, 0xaf, 0x43, 0xb9])
255
256COMMUNITY_KEY2 = bytes([0x6b, 0x75, 0xed, 0x58, 0x20, 0x08, 0x85, 0x95,
257                        0xa0, 0x49, 0x8b, 0x9e, 0xbd, 0x5f, 0x34, 0x82,
258                        0x0a, 0x9d, 0x1e, 0x9a, 0xb6, 0x76, 0x43, 0x19,
259                        0xb7, 0x76, 0x45, 0x5b, 0x59, 0xab, 0xbb, 0xf3,
260                        0x9e, 0x72, 0xf2, 0x41, 0x24, 0x92, 0x97, 0xef,
261                        0x39, 0xc0, 0xed, 0xc4, 0x7a, 0x4e, 0xdb, 0xec,
262                        0xeb, 0xc7, 0x4c, 0xf6, 0x45, 0xbe, 0xb2, 0xe0,
263                        0x13, 0x6a, 0xdc, 0x06, 0x7a, 0x1c, 0xbd, 0x8d,
264                        0xd8, 0xd2, 0xd7, 0x82, 0x6d, 0xbe, 0x03, 0x76,
265                        0x3b, 0x6b, 0xb8, 0x2f, 0xcc, 0xbe, 0x30, 0x56,
266                        0x61, 0x87, 0x09, 0xdf, 0x44, 0x51, 0xf8, 0x82,
267                        0xc5, 0x78, 0x05, 0x45, 0x8c, 0xe3, 0x78, 0x0e,
268                        0xd3, 0x7a, 0xd4, 0xf4, 0xbe, 0x96, 0xde, 0xb8,
269                        0x3b, 0x78, 0x90, 0x8b, 0xd3, 0xdd, 0x0b, 0xdd,
270                        0xbe, 0x56, 0xf3, 0x9a, 0x34, 0xc9, 0x38, 0x47,
271                        0x8d, 0xc4, 0xbd, 0x5e, 0x68, 0xf8, 0x62, 0xc4,
272                        0x28, 0xdd, 0x00, 0x48, 0x93, 0xb5, 0xad, 0x74,
273                        0x52, 0xe5, 0xf3, 0xd2, 0x97, 0xde, 0xbc, 0x0a,
274                        0x85, 0x95, 0xe9, 0xfa, 0xd2, 0xac, 0xdc, 0xdc,
275                        0x59, 0x74, 0xfa, 0x57, 0xf2, 0xd3, 0x61, 0xc6,
276                        0x2b, 0x26, 0xde, 0x57, 0x50, 0xe2, 0x58, 0x6b,
277                        0x79, 0x65, 0x0b, 0x49, 0x2c, 0x59, 0x28, 0x25,
278                        0x64, 0x31, 0x93, 0x65, 0x9a, 0x0a, 0x88, 0x98,
279                        0x9a, 0x77, 0x00, 0x47, 0x8f, 0xa0, 0xc7, 0x6b,
280                        0x58, 0x90, 0xa9, 0xb5, 0x15, 0xff, 0x65, 0x7c,
281                        0x84, 0x02, 0xd4, 0xdd, 0x09, 0xf1, 0x25, 0xad,
282                        0xf9, 0x30, 0xaa, 0x34, 0x5b, 0x77, 0xef, 0xb2,
283                        0x75, 0x3d, 0x54, 0x9d, 0xcc, 0x0d, 0x11, 0xda,
284                        0x91, 0x01, 0x2e, 0x51, 0xdc, 0x0c, 0x8a, 0x92,
285                        0x71, 0x44, 0x9a, 0xd5, 0x69, 0x5d, 0x7a, 0xad,
286                        0xaf, 0xdf, 0x25, 0xea, 0x95, 0x21, 0xbb, 0x99,
287                        0x53, 0x89, 0xbc, 0x54, 0xca, 0xf3, 0x54, 0xf5,
288                        0xbb, 0x38, 0x27, 0x64, 0xce, 0xf2, 0x17, 0x25,
289                        0x75, 0x33, 0x1a, 0x2d, 0x19, 0x00, 0xff, 0x9b,
290                        0xd9, 0x4d, 0x0c, 0xb1, 0xa5, 0x55, 0x55, 0xa9,
291                        0x29, 0x8e, 0xfb, 0x82, 0x43, 0xeb, 0xfa, 0xc8,
292                        0x33, 0x76, 0xf3, 0x7d, 0xee, 0x95, 0xe1, 0x39,
293                        0xba, 0xa5, 0x4a, 0xd5, 0xb1, 0x8a, 0xa6, 0xff,
294                        0x8f, 0x4b, 0x45, 0x8c, 0xe9, 0x7b, 0x87, 0xae,
295                        0x8d, 0x32, 0x6e, 0x16, 0xe7, 0x9e, 0x85, 0x22,
296                        0x71, 0x3d, 0x17, 0xba, 0x54, 0xed, 0x73, 0x87,
297                        0xe5, 0x9d, 0xbf, 0xc0, 0xcd, 0x76, 0xfa, 0x83,
298                        0xd4, 0xc5, 0x30, 0xd1, 0xc7, 0x25, 0x49, 0x25,
299                        0x75, 0x4d, 0x0a, 0x4a, 0x2d, 0x13, 0x1c, 0x12,
300                        0x2e, 0x5d, 0x2a, 0xe2, 0xa9, 0xae, 0xbf, 0x8f,
301                        0xdf, 0x24, 0x76, 0xf5, 0x81, 0x1e, 0x09, 0x5d,
302                        0x63, 0x04, 0xaf, 0x24, 0x45, 0x87, 0xf4, 0x96,
303                        0x55, 0xd1, 0x7d, 0xc6, 0x0d, 0x79, 0x12, 0xa9])
304
305KNOWN_KEYS = {APL_INTEL_PROD_KEY : 'APL Intel prod key',
306              CNL_INTEL_PROD_KEY : 'CNL Intel prod key',
307              ICL_INTEL_PROD_KEY : 'ICL Intel prod key',
308              TGL_INTEL_PROD_KEY : 'TGL Intel prod key',
309              EHL_INTEL_PROD_KEY : 'EHL Intel prod key',
310              COMMUNITY_KEY : 'Community key',
311              COMMUNITY_KEY2 : 'Community 3k key'}
312
313def parse_params():
314    """ Parses parameters
315    """
316    parser = argparse.ArgumentParser(description='SOF Binary Info Utility')
317    parser.add_argument('-v', '--verbose', help='increase output verbosity',
318                        action='store_true')
319    parser.add_argument('--headers', help='display headers only',
320                        action='store_true')
321    parser.add_argument('--full_bytes', help='display full byte arrays',
322                        action='store_true')
323    parser.add_argument('--no_colors', help='disable colors in output',
324                        action='store_true')
325    parser.add_argument('--no_cse', help='disable cse manifest parsing',
326                        action='store_true')
327    parser.add_argument('--no_headers', help='skip information about headers',
328                        action='store_true')
329    parser.add_argument('--no_modules', help='skip information about modules',
330                        action='store_true')
331    parser.add_argument('--no_memory', help='skip information about memory',
332                        action='store_true')
333    parser.add_argument('sof_ri_path', help='path to fw binary file to parse')
334    parsed_args = parser.parse_args()
335
336    return parsed_args
337
338# Helper Functions
339
340def change_color(color):
341    """ Prints escape code to change text color
342    """
343    color_code = {'red':91, 'green':92, 'yellow':93, 'blue':94,
344                  'magenta':95, 'cyan':96, 'white':98, 'none':0}
345    return '\033[{}m'.format(color_code[color])
346
347def uint_to_string(uint, both=False):
348    """ Prints uint in readable form
349    """
350    if both:
351        return hex(uint) + ' (' + repr(uint) + ')'
352    return hex(uint)
353
354def date_to_string(date):
355    """ Prints BCD date in readable form
356    """
357    return date[2:6]+'/'+date[6:8]+'/'+date[8:10]
358
359def chararr_to_string(chararr, max_len):
360    """ Prints array of characters (null terminated or till max_len)
361        in readable form
362    """
363    out = ''
364    for i in range(0, max_len):
365        if chararr[i] == 0:
366            return out
367        out += '{:c}'.format(chararr[i])
368    return out
369
370def mod_type_to_string(mod_type):
371    """ Prints module type in readable form
372    """
373    out = '('
374    # type
375    if (mod_type & 0xf) == 0:
376        out += ' builtin'
377    elif (mod_type & 0xf) == 1:
378        out += ' loadable'
379    # Module that may be instantiated by fw on startup
380    if ((mod_type >> 4) & 0x1) == 1:
381        out += ' auto_start'
382    # Module designed to run with low latency scheduler
383    if ((mod_type >> 5) & 0x1) == 1:
384        out += ' LL'
385    # Module designed to run with edf scheduler
386    if ((mod_type >> 6) & 0x1) == 1:
387        out += ' DP'
388    out += ' )'
389    return out
390
391def seg_flags_to_string(flags):
392    """ Prints module segment flags in readable form
393    """
394    out = '('
395    if flags & 0x1 == 0x1:
396        out = out + ' contents'
397    if flags & 0x2 == 0x2:
398        out = out + ' alloc'
399    if flags & 0x4 == 0x4:
400        out = out + ' load'
401    if flags & 0x8 == 0x8:
402        out = out + ' readonly'
403    if flags & 0x10 == 0x10:
404        out = out + ' code'
405    if flags & 0x20 == 0x20:
406        out = out + ' data'
407    out = out + ' type=' + repr((flags>>8)&0xf)
408    out = out + ' pages=' + repr((flags>>16)&0xffff)
409    out = out + ' )'
410    return out
411
412# Parsers
413
414def parse_extended_manifest_ae1(reader):
415    ext_mft = ExtendedManifestAE1()
416    hdr = Component('ext_mft_hdr', 'Header', 0)
417    ext_mft.add_comp(hdr)
418
419    sig = reader.read_string(4)
420    reader.info('Extended Manifest (' + sig + ')', -4)
421    hdr.add_a(Astring('sig', sig))
422
423    # Next dword is the total length of the extended manifest
424    # (need to use it for further parsing)
425    reader.ext_mft_length = reader.read_dw()
426    hdr.add_a(Auint('length', reader.ext_mft_length))
427    hdr.add_a(Astring('ver', '{}.{}'.format(reader.read_w(), reader.read_w())))
428    hdr.add_a(Auint('entries', reader.read_dw()))
429
430    reader.ff_data(reader.ext_mft_length-16)
431    return ext_mft
432
433def parse_extended_manifest_xman(reader):
434    ext_mft = ExtendedManifestXMan()
435    hdr = Component('ext_mft_hdr', 'Header', 0)
436    ext_mft.add_comp(hdr)
437
438    sig = reader.read_string(4)
439    reader.info('Extended Manifest (' + sig + ')', -4)
440    hdr.add_a(Astring('sig', sig))
441
442    # Next dword is the total length of the extended manifest
443    # (need to use it for further parsing)
444    reader.ext_mft_length = reader.read_dw()
445    hdr_length = reader.read_dw()
446    hdr_ver = reader.read_dw()
447
448    major = hdr_ver >> 24
449    minor = (hdr_ver >> 12) & 0xFFF
450    patch = hdr_ver & 0xFFF
451
452    hdr.add_a(Auint('length', reader.ext_mft_length))
453    hdr.add_a(Astring('ver', '{}.{}.{}'.format(major, minor, patch)))
454    hdr.add_a(Auint('hdr_length', hdr_length))
455
456    reader.ff_data(reader.ext_mft_length-16)
457    return ext_mft
458
459def parse_extended_manifest(reader):
460    """ Parses extended manifest from sof binary
461    """
462
463    reader.info('Looking for Extended Manifest')
464    # Try to detect signature first
465    sig = reader.read_string(4)
466    reader.set_offset(0)
467    if sig == '$AE1':
468        ext_mft = parse_extended_manifest_ae1(reader)
469    elif sig == 'XMan':
470        ext_mft = parse_extended_manifest_xman(reader)
471    else:
472        ext_mft = ExtendedManifestAE1()
473        hdr = Component('ext_mft_hdr', 'Header', 0)
474        ext_mft.add_comp(hdr)
475        reader.info('info: Extended Manifest not found (sig = '+sig+')')
476        reader.ext_mft_length = 0
477        hdr.add_a(Auint('length', reader.ext_mft_length))
478
479    return ext_mft
480
481def parse_cse_manifest(reader):
482    """ Parses CSE manifest form sof binary
483    """
484    reader.info('Looking for CSE Manifest')
485    cse_mft = CseManifest(reader.get_offset())
486
487    # Try to detect signature first
488    sig = reader.read_string(4)
489    if sig != '$CPD':
490        reader.error('CSE Manifest NOT found ' + sig + ')', -4)
491        sys.exit(1)
492    reader.info('CSE Manifest (' + sig + ')', -4)
493
494    # Read the header
495    hdr = Component('cse_mft_hdr', 'Header', reader.get_offset())
496    cse_mft.add_comp(hdr)
497    hdr.add_a(Astring('sig', sig))
498    # read number of entries
499    nb_entries = reader.read_dw()
500    reader.info('# of entries {}'.format(nb_entries))
501    hdr.add_a(Adec('nb_entries', nb_entries))
502    # read version (1byte for header ver and 1 byte for entry ver)
503    ver = reader.read_w()
504    hdr.add_a(Ahex('header_version', ver))
505    header_length = reader.read_b()
506    hdr.add_a(Ahex('header_length', header_length))
507    hdr.add_a(Ahex('checksum', reader.read_b()))
508    hdr.add_a(Astring('partition_name', reader.read_string(4)))
509
510    reader.set_offset(cse_mft.file_offset + header_length)
511    # Read entries
512    nb_index = 0
513    while nb_index < nb_entries:
514        reader.info('Looking for CSE Manifest entry')
515        entry_name = reader.read_string(12)
516        entry_offset = reader.read_dw()
517        entry_length = reader.read_dw()
518        # reserved field
519        reader.read_dw()
520
521        hdr_entry = Component('cse_hdr_entry', 'Entry', reader.get_offset())
522        hdr_entry.add_a(Astring('entry_name', entry_name))
523        hdr_entry.add_a(Ahex('entry_offset', entry_offset))
524        hdr_entry.add_a(Ahex('entry_length', entry_length))
525        hdr.add_comp(hdr_entry)
526
527        reader.info('CSE Entry name {} length {}'.format(entry_name,
528                    entry_length))
529
530        if '.man' in entry_name:
531            entry = CssManifest(entry_name,
532                                reader.ext_mft_length + entry_offset)
533            cur_off = reader.set_offset(reader.ext_mft_length + entry_offset)
534            parse_css_manifest(entry, reader,
535                               reader.ext_mft_length + entry_offset + entry_length)
536            reader.set_offset(cur_off)
537        elif '.met' in entry_name:
538            cur_off = reader.set_offset(reader.ext_mft_length + entry_offset)
539            entry = parse_mft_extension(reader, 0)
540            entry.name = '{} ({})'.format(entry_name, entry.name)
541            reader.set_offset(cur_off)
542        else:
543            # indicate the place, the entry is enumerated. mft parsed later
544            entry = Component('adsp_mft_cse_entry', entry_name, entry_offset)
545        cse_mft.add_comp(entry)
546
547        nb_index += 1
548
549    return cse_mft
550
551def parse_css_manifest(css_mft, reader, limit):
552    """ Parses CSS manifest from sof binary
553    """
554    reader.info('Parsing CSS Manifest')
555    ver, = struct.unpack('I', reader.get_data(0, 4))
556    if ver == 4:
557        reader.info('CSS Manifest type 4')
558        return parse_css_manifest_4(css_mft, reader, limit)
559
560    reader.error('CSS Manifest NOT found or NOT recognized!')
561    sys.exit(1)
562
563def parse_css_manifest_4(css_mft, reader, size_limit):
564    """ Parses CSS manifest type 4 from sof binary
565    """
566
567    reader.info('Parsing CSS Manifest type 4')
568    # CSS Header
569    hdr = Component('css_mft_hdr', 'Header', reader.get_offset())
570    css_mft.add_comp(hdr)
571
572    hdr.add_a(Auint('type', reader.read_dw()))
573    header_len_dw = reader.read_dw()
574    hdr.add_a(Auint('header_len_dw', header_len_dw))
575    hdr.add_a(Auint('header_version', reader.read_dw()))
576    hdr.add_a(Auint('reserved0', reader.read_dw(), 'red'))
577    hdr.add_a(Ahex('mod_vendor', reader.read_dw()))
578    hdr.add_a(Adate('date', hex(reader.read_dw())))
579    size = reader.read_dw()
580    hdr.add_a(Auint('size', size))
581    hdr.add_a(Astring('header_id', reader.read_string(4)))
582    hdr.add_a(Auint('padding', reader.read_dw()))
583    hdr.add_a(Aversion('fw_version', reader.read_w(), reader.read_w(),
584                       reader.read_w(), reader.read_w()))
585    hdr.add_a(Auint('svn', reader.read_dw()))
586    reader.read_bytes(18*4)
587    modulus_size = reader.read_dw()
588    hdr.add_a(Adec('modulus_size', modulus_size))
589    exponent_size = reader.read_dw()
590    hdr.add_a(Adec('exponent_size', exponent_size))
591    modulus = reader.read_bytes(modulus_size * 4)
592    hdr.add_a(Amodulus('modulus', modulus, KNOWN_KEYS.get(modulus, 'Other')))
593    hdr.add_a(Abytes('exponent', reader.read_bytes(exponent_size * 4)))
594    hdr.add_a(Abytes('signature', reader.read_bytes(modulus_size * 4)))
595
596    # Move right after the header
597    reader.set_offset(css_mft.file_offset + header_len_dw*4)
598
599    # Anything packed here is
600    #   either an 'Extension' beginning with
601    #     dw0 - extension type
602    #     dw1 - extension length (in bytes)
603    #   that could be parsed if extension type is recognized
604    #
605    #   or series of 0xffffffff that should be skipped
606    reader.info('Parsing CSS Manifest extensions end 0x{:x}'.format(size_limit))
607    ext_idx = 0
608    while reader.get_offset() < size_limit:
609        ext_type = reader.read_dw()
610        reader.info('Reading extension type 0x{:x}'.format(ext_type))
611        if ext_type == 0xffffffff:
612            continue
613        reader.set_offset(reader.get_offset() - 4)
614        css_mft.add_comp(parse_mft_extension(reader, ext_idx))
615        ext_idx += 1
616
617    return css_mft
618
619def parse_mft_extension(reader, ext_id):
620    """ Parses mft extension from sof binary
621    """
622    ext_type = reader.read_dw()
623    ext_len = reader.read_dw()
624    if ext_type == 15:
625        begin_off = reader.get_offset()
626        ext = PlatFwAuthExtension(ext_id, reader.get_offset()-8)
627        ext.add_a(Astring('name', reader.read_string(4)))
628        ext.add_a(Auint('vcn', reader.read_dw()))
629        ext.add_a(Abytes('bitmap', reader.read_bytes(16), 'red'))
630        ext.add_a(Auint('svn', reader.read_dw()))
631        read_len = reader.get_offset() - begin_off
632        reader.ff_data(ext_len - read_len)
633    elif ext_type == 17:
634        ext = AdspMetadataFileExt(ext_id, reader.get_offset()-8)
635        ext.add_a(Auint('adsp_imr_type', reader.read_dw(), 'red'))
636        # skip reserved part
637        reader.read_bytes(16)
638        reader.read_dw()
639        reader.read_dw()
640        #
641        ext.add_a(Auint('version', reader.read_dw()))
642        ext.add_a(Abytes('sha_hash', reader.read_bytes(32)))
643        ext.add_a(Auint('base_offset', reader.read_dw()))
644        ext.add_a(Auint('limit_offset', reader.read_dw()))
645        ext.add_a(Abytes('attributes', reader.read_bytes(16)))
646    else:
647        ext = MftExtension(ext_id, 'Other Extension', reader.get_offset()-8)
648        reader.ff_data(ext_len-8)
649    ext.add_a(Auint('type', ext_type))
650    ext.add_a(Auint('length', ext_len))
651    return ext
652
653def parse_adsp_manifest_hdr(reader):
654    """ Parses ADSP manifest hader from sof binary
655    """
656    # Verify signature
657    try:
658        sig = reader.read_string(4)
659    except UnicodeDecodeError:
660        print('\n' + reader.offset_to_string() + \
661              '\terror: Failed to decode signature, wrong position?')
662        sys.exit(1)
663    if sig != '$AM1':
664        reader.error('ADSP Manifest NOT found!', -4)
665        sys.exit(1)
666    reader.info('ADSP Manifest (' + sig + ')', -4)
667
668    hdr = Component('adsp_mft_hdr', 'ADSP Manifest Header',
669                    reader.get_offset() -4)
670    hdr.add_a(Astring('sig', sig))
671
672    hdr.add_a(Auint('size', reader.read_dw()))
673    hdr.add_a(Astring('name', chararr_to_string(reader.read_bytes(8), 8)))
674    hdr.add_a(Auint('preload', reader.read_dw()))
675    hdr.add_a(Auint('fw_image_flags', reader.read_dw()))
676    hdr.add_a(Auint('feature_mask', reader.read_dw()))
677    hdr.add_a(Aversion('build_version', reader.read_w(), reader.read_w(),
678                       reader.read_w(), reader.read_w()))
679
680    hdr.add_a(Adec('num_module_entries', reader.read_dw()))
681    hdr.add_a(Ahex('hw_buf_base_addr', reader.read_dw()))
682    hdr.add_a(Auint('hw_buf_length', reader.read_dw()))
683    hdr.add_a(Ahex('load_offset', reader.read_dw()))
684
685    return hdr
686
687def parse_adsp_manifest_mod_entry(index, reader):
688    """ Parses ADSP manifest module entry from sof binary
689    """
690    # Verify Mod Entry signature
691    try:
692        sig = reader.read_string(4)
693    except UnicodeDecodeError:
694        print(reader.offset_to_string() + \
695              '\terror: Failed to decode ModuleEntry signature')
696        sys.exit(1)
697    if sig != '$AME':
698        reader.error('ModuleEntry signature NOT found!')
699        sys.exit(1)
700    reader.info('Module Entry signature found (' + sig + ')', -4)
701
702    mod = AdspModuleEntry('mod_entry_'+repr(index),
703                          reader.get_offset() -4)
704    mod.add_a(Astring('sig', sig))
705
706    mod.add_a(Astring('mod_name',
707                      chararr_to_string(reader.read_bytes(8), 8)))
708    mod.add_a(Astring('uuid', reader.read_uuid()))
709    me_type = reader.read_dw()
710    mod.add_a(Astring('type',
711                      hex(me_type) + ' ' + mod_type_to_string(me_type)))
712    mod.add_a(Abytes('hash', reader.read_bytes(32)))
713    mod.add_a(Ahex('entry_point', reader.read_dw()))
714    mod.add_a(Adec('cfg_offset', reader.read_w()))
715    mod.add_a(Adec('cfg_count', reader.read_w()))
716    mod.add_a(Auint('affinity_mask', reader.read_dw()))
717    mod.add_a(Adec('instance_max_count', reader.read_w()))
718    mod.add_a(Auint('instance_stack_size', reader.read_w()))
719    for i in range(0, 3):
720        seg_flags = reader.read_dw()
721        mod.add_a(Astring('seg_'+repr(i)+'_flags',
722                          hex(seg_flags) + ' ' + seg_flags_to_string(seg_flags)))
723        mod.add_a(Ahex('seg_'+repr(i)+'_v_base_addr', reader.read_dw()))
724        mod.add_a(Ahex('seg_'+repr(i)+'_size', ((seg_flags>>16)&0xffff)*0x1000))
725        mod.add_a(Ahex('seg_'+repr(i)+'_file_offset', reader.read_dw()))
726
727    return mod
728
729def parse_adsp_manifest(reader, name):
730    """ Parses ADSP manifest from sof binary
731    """
732    adsp_mft = AdspManifest(name, reader.get_offset())
733    adsp_mft.add_comp(parse_adsp_manifest_hdr(reader))
734    num_module_entries = adsp_mft.cdir['adsp_mft_hdr'].adir['num_module_entries'].val
735    for i in range(0, num_module_entries):
736        mod_entry = parse_adsp_manifest_mod_entry(i, reader)
737        adsp_mft.add_comp(mod_entry)
738
739    return adsp_mft
740
741def parse_fw_bin(path, no_cse, verbose):
742    """ Parses sof binary
743    """
744    reader = BinReader(path, verbose)
745
746    parsed_bin = FwBin()
747    parsed_bin.add_a(Astring('file_name', reader.file_name))
748    parsed_bin.add_a(Auint('file_size', reader.file_size))
749    parsed_bin.add_comp(parse_extended_manifest(reader))
750    if not no_cse:
751        parsed_bin.add_comp(parse_cse_manifest(reader))
752    reader.set_offset(reader.ext_mft_length + 0x2000)
753    parsed_bin.add_comp(parse_adsp_manifest(reader, 'cavs0015'))
754
755    reader.info('Parsing finished', show_offset = False)
756    return parsed_bin
757
758class BinReader():
759    """ sof binary reader
760    """
761    def __init__(self, path, verbose):
762        self.verbose = verbose
763        self.cur_offset = 0
764        self.ext_mft_length = 0
765        self.info('Reading SOF ri image ' + path, show_offset=False)
766        self.file_name = path
767        # read the content
768        self.data = open(path, 'rb').read()
769        self.file_size = len(self.data)
770        self.info('File size ' + uint_to_string(self.file_size, True),
771                  show_offset=False)
772
773    def get_offset(self):
774        """ Retrieve the offset, the reader is at
775        """
776        return self.cur_offset
777
778    def ff_data(self, delta_offset):
779        """ Forwards the read pointer by specified number of bytes
780        """
781        self.cur_offset += delta_offset
782
783    def set_offset(self, offset):
784        """ Set current reader offset
785        """
786        old_offset = self.cur_offset
787        self.cur_offset = offset
788        return old_offset
789
790    def get_data(self, beg, length):
791        """ Retrieves the data from beg to beg+length.
792            This one is good to peek the data w/o advancing the read pointer
793        """
794        return self.data[self.cur_offset +beg : self.cur_offset +beg +length]
795
796    def read_bytes(self, count):
797        """ Reads the specified number of bytes from the stream
798        """
799        bts = self.get_data(0, count)
800        self.ff_data(count)
801        return bts
802
803    def read_dw(self):
804        """ Reads a dword from the stream
805        """
806        dword, = struct.unpack('I', self.get_data(0, 4))
807        self.ff_data(4)
808        return dword
809
810    def read_w(self):
811        """ Reads a word from the stream
812        """
813        word, = struct.unpack('H', self.get_data(0, 2))
814        self.ff_data(2)
815        return word
816
817    def read_b(self):
818        """ Reads a byte from the stream
819        """
820        byte, = struct.unpack('B', self.get_data(0, 1))
821        self.ff_data(1)
822        return byte
823
824    def read_string(self, size_in_file):
825        """ Reads a string from the stream, potentially padded with zeroes
826        """
827        return self.read_bytes(size_in_file).decode().rstrip('\0')
828
829    def read_uuid(self):
830        """ Reads a UUID from the stream and returns as string
831        """
832        out = '{:08x}'.format(self.read_dw())
833        out += '-'+'{:04x}'.format(self.read_w())
834        out += '-'+'{:04x}'.format(self.read_w())
835        out += '-'+'{:02x}'.format(self.read_b()) + \
836               '{:02x}'.format(self.read_b()) + '-'
837        for _ in range(0, 6):
838            out += '{:02x}'.format(self.read_b())
839        return out
840
841    def offset_to_string(self, delta=0):
842        """ Retrieves readable representation of the current offset value
843        """
844        return uint_to_string(self.cur_offset+delta)
845
846    def info(self, loginfo, off_delta=0, verb_info=True, show_offset=True):
847        """ Prints 'info' log to the output, respects verbose mode
848        """
849        if verb_info and not self.verbose:
850            return
851        if show_offset:
852            print(self.offset_to_string(off_delta) + '\t' + loginfo)
853        else:
854            print(loginfo)
855
856    def error(self, logerror, off_delta=0):
857        """ Prints 'error' log to the output
858        """
859        print(self.offset_to_string(off_delta) + '\terror: ' + logerror)
860
861# Data Model
862
863class Attribute():
864    """ Attribute: base class with global formatting options
865    """
866    no_colors = False
867    full_bytes = True
868
869class Auint(Attribute):
870    """ Attribute : unsigned integer
871    """
872    def __init__(self, name, val, color='none'):
873        self.name = name
874        self.val = val
875        self.color = color
876
877    def __str__(self):
878        if Attribute.no_colors:
879            return uint_to_string(self.val)
880        return '{}{}{}'.format(change_color(self.color),
881                               uint_to_string(self.val),
882                               change_color('none'))
883
884class Ahex(Attribute):
885    """ Attribute : unsigned integer printed as hex
886    """
887    def __init__(self, name, val, color='none'):
888        self.name = name
889        self.val = val
890        self.color = color
891
892    def __str__(self):
893        if Attribute.no_colors:
894            return hex(self.val)
895        return '{}{}{}'.format(change_color(self.color), hex(self.val),
896                               change_color('none'))
897
898class Adec(Attribute):
899    """ Attribute: integer printed as dec
900    """
901    def __init__(self, name, val):
902        self.name = name
903        self.val = val
904
905    def __str__(self):
906        return repr(self.val)
907
908class Abytes(Attribute):
909    """ Attribute: array of bytes
910    """
911    def __init__(self, name, val, color='none'):
912        self.name = name
913        self.val = val
914        self.color = color
915
916    def __str__(self):
917        length = len(self.val)
918        if Attribute.no_colors:
919            out = ''
920        else:
921            out = '{}'.format(change_color(self.color))
922        if length <= 16:
923            out += ' '.join(['{:02x}'.format(b) for b in self.val])
924        elif Attribute.full_bytes:
925            """ n is num pre row
926                print 8 num pre line, useful for add more KEY
927            """
928            n = 8
929            out += '\n'
930            out += ',\n'.join([', '.join(['0x{:02x}'.format(b) for b in self.val[i:i + n]]) for i in range(0, length, n)])
931        else:
932            out += ' '.join('{:02x}'.format(b) for b in self.val[:8])
933            out += ' ... '
934            out += ' '.join('{:02x}'.format(b) for b in self.val[length-8:length])
935        if not Attribute.no_colors:
936            out += '{}'.format(change_color('none'))
937        return out
938
939class Adate(Attribute):
940    """ Attribute: Date in BCD format
941    """
942    def __init__(self, name, val):
943        self.name = name
944        self.val = val
945
946    def __str__(self):
947        return date_to_string(self.val)
948
949class Astring(Attribute):
950    """ Attribute: String
951    """
952    def __init__(self, name, val):
953        self.name = name
954        self.val = val
955
956    def __str__(self):
957        return self.val
958
959class Aversion(Attribute):
960    """ Attribute: version
961    """
962    def __init__(self, name, major, minor, hotfix, build):
963        self.name = name
964        self.val = '{:d}.{:d}.{:d}.{:d}'.format(major, minor, hotfix, build)
965
966    def __str__(self):
967        return self.val
968
969class Amodulus(Abytes):
970    """ Attribute: modulus from RSA public key
971    """
972    def __init__(self, name, val, val_type):
973        super().__init__(name, val)
974        self.val_type = val_type
975
976    def __str__(self):
977        out = super().__str__()
978        if not Attribute.full_bytes:
979            if Attribute.no_colors:
980                out += ' ({})'.format(self.val_type)
981            else:
982                out += ' {}({}){}'.format(change_color('red'), self.val_type,
983                                          change_color('none'))
984        return out
985
986class Component():
987    """ A component of sof binary
988    """
989    def __init__(self, uid, name, file_offset):
990        self.uid = uid
991        self.name = name
992        self.file_offset = file_offset
993        self.attribs = []
994        self.adir = {}
995        self.max_attr_name_len = 0
996        self.components = []
997        self.cdir = {}
998
999    def add_a(self, attrib):
1000        """ Adds an attribute
1001        """
1002        self.max_attr_name_len = max(self.max_attr_name_len,
1003                                     len(attrib.name))
1004        self.attribs.append(attrib)
1005        self.adir[attrib.name] = attrib
1006
1007    def add_comp(self, comp):
1008        """ Adds a nested component
1009        """
1010        self.components.append(comp)
1011        self.cdir[comp.uid] = comp
1012
1013    def get_comp(self, comp_uid):
1014        """ Retrieves a nested component by id
1015        """
1016        for comp in self.components:
1017            if comp.uid == comp_uid:
1018                return comp
1019        return None
1020
1021    def dump_info(self, pref, comp_filter):
1022        """ Prints out the content (name, all attributes, and nested comps)
1023        """
1024        print(pref + self.name)
1025        for attrib in self.attribs:
1026            print("{:}  {:<{:}} {:}".format(pref, attrib.name,
1027                                            self.max_attr_name_len, attrib))
1028        self.dump_comp_info(pref, comp_filter)
1029
1030    def dump_attrib_info(self, pref, attr_name):
1031        """ Prints out a single attribute
1032        """
1033        attrib = self.adir[attr_name]
1034        print("{:}  {:<{:}} {:}".format(pref, attrib.name,
1035                                        self.max_attr_name_len, attrib))
1036
1037    def dump_comp_info(self, pref, comp_filter=''):
1038        """ Prints out all nested components (filtered by name set to 'filter')
1039        """
1040        for comp in self.components:
1041            if comp.name in comp_filter:
1042                continue
1043            print()
1044            comp.dump_info(pref + '  ', comp_filter)
1045
1046    def add_comp_to_mem_map(self, mem_map):
1047        for comp in self.components:
1048            comp.add_comp_to_mem_map(mem_map)
1049
1050class ExtendedManifestAE1(Component):
1051    """ Extended manifest
1052    """
1053    def __init__(self):
1054        super(ExtendedManifestAE1, self).__init__('ext_mft',
1055                                               'Extended Manifest', 0)
1056
1057    def dump_info(self, pref, comp_filter):
1058        hdr = self.cdir['ext_mft_hdr']
1059        if hdr.adir['length'].val == 0:
1060            return
1061        out = '{}{}'.format(pref, self.name)
1062        out += ' ver {}'.format(hdr.adir['ver'])
1063        out += ' entries {}'.format(hdr.adir['entries'])
1064        print(out)
1065        self.dump_comp_info(pref, comp_filter + ['Header'])
1066
1067class ExtendedManifestXMan(Component):
1068    """ Extended manifest
1069    """
1070    def __init__(self):
1071        super(ExtendedManifestXMan, self).__init__('ext_mft',
1072                                               'Extended Manifest', 0)
1073
1074    def dump_info(self, pref, comp_filter):
1075        hdr = self.cdir['ext_mft_hdr']
1076        if hdr.adir['length'].val == 0:
1077            return
1078        out = '{}{}'.format(pref, self.name)
1079        out += ' ver {}'.format(hdr.adir['ver'])
1080        out += ' length {}'.format(hdr.adir['length'].val)
1081        print(out)
1082        self.dump_comp_info(pref, comp_filter + ['Header'])
1083
1084class CseManifest(Component):
1085    """ CSE Manifest
1086    """
1087    def __init__(self, offset):
1088        super(CseManifest, self).__init__('cse_mft', 'CSE Manifest', offset)
1089
1090    def dump_info(self, pref, comp_filter):
1091        hdr = self.cdir['cse_mft_hdr']
1092        print('{}{} ver {} checksum {} partition name {}'.
1093              format(pref,
1094                     self.name, hdr.adir['header_version'],
1095                     hdr.adir['checksum'], hdr.adir['partition_name']))
1096        self.dump_comp_info(pref, comp_filter + ['Header'])
1097
1098class CssManifest(Component):
1099    """ CSS Manifest
1100    """
1101    def __init__(self, name, offset):
1102        super(CssManifest, self).__init__('css_mft', name, offset)
1103
1104    def dump_info(self, pref, comp_filter):
1105        hdr = self.cdir['css_mft_hdr']
1106        out = '{}{} (CSS Manifest)'.format(pref, self.name)
1107        out += ' type {}'.format(hdr.adir['type'])
1108        out += ' ver {}'.format(hdr.adir['header_version'])
1109        out += ' date {}'.format(hdr.adir['date'])
1110        print(out)
1111        print('{}  Rsvd0 {}'.
1112              format(pref, hdr.adir['reserved0']))
1113        print('{}  Modulus size (dwords) {}'.
1114              format(pref, hdr.adir['modulus_size']))
1115        print('{}    {}'.format(pref, hdr.adir['modulus']))
1116        print('{}  Exponent size (dwords) {}'.
1117              format(pref,
1118                     hdr.adir['exponent_size']))
1119        print('{}    {}'.format(pref, hdr.adir['exponent']))
1120        print('{}  Signature'.format(pref))
1121        print('{}    {}'.format(pref, hdr.adir['signature']))
1122        # super().dump_info(pref)
1123        self.dump_comp_info(pref, comp_filter + ['Header'])
1124
1125class MftExtension(Component):
1126    """ Manifest Extension
1127    """
1128    def __init__(self, ext_id, name, offset):
1129        super(MftExtension, self).__init__('mft_ext'+repr(ext_id), name,
1130                                           offset)
1131
1132    def dump_info(self, pref, comp_filter):
1133        print('{}{} type {} length {}'.
1134              format(pref, self.name,
1135                     self.adir['type'], self.adir['length']))
1136
1137class PlatFwAuthExtension(MftExtension):
1138    """ Platform FW Auth Extension
1139    """
1140    def __init__(self, ext_id, offset):
1141        super(PlatFwAuthExtension,
1142              self).__init__(ext_id, 'Plat Fw Auth Extension', offset)
1143
1144    def dump_info(self, pref, comp_filter):
1145        out = '{}{}'.format(pref, self.name)
1146        out += ' name {}'.format(self.adir['name'])
1147        out += ' vcn {}'.format(self.adir['vcn'])
1148        out += ' bitmap {}'.format(self.adir['bitmap'])
1149        out += ' svn {}'.format(self.adir['svn'])
1150        print(out)
1151
1152class AdspMetadataFileExt(MftExtension):
1153    """ ADSP Metadata File Extension
1154    """
1155    def __init__(self, ext_id, offset):
1156        super(AdspMetadataFileExt,
1157              self).__init__(ext_id, 'ADSP Metadata File Extension',
1158                             offset)
1159
1160    def dump_info(self, pref, comp_filter):
1161        out = '{}{}'.format(pref, self.name)
1162        out += ' ver {}'.format(self.adir['version'])
1163        out += ' base offset {}'.format(self.adir['base_offset'])
1164        out += ' limit offset {}'.format(self.adir['limit_offset'])
1165        print(out)
1166        print('{}  IMR type {}'.format(pref, self.adir['adsp_imr_type']))
1167        print('{}  Attributes'.format(pref))
1168        print('{}    {}'.format(pref, self.adir['attributes']))
1169
1170class AdspManifest(Component):
1171    """ ADSP Manifest
1172    """
1173    def __init__(self, name, offset):
1174        super(AdspManifest, self).__init__('adsp_mft', name, offset)
1175
1176    def dump_info(self, pref, comp_filter):
1177        hdr = self.cdir['adsp_mft_hdr']
1178        out = '{}{} (ADSP Manifest)'.format(pref, self.name)
1179        out += ' name {}'.format(hdr.adir['name'])
1180        out += ' build ver {}'.format(hdr.adir['build_version'])
1181        out += ' feature mask {}'.format(hdr.adir['feature_mask'])
1182        out += ' image flags {}'.format(hdr.adir['fw_image_flags'])
1183        print(out)
1184        print('{}  HW buffers base address {} length {}'.
1185              format(pref,
1186                     hdr.adir['hw_buf_base_addr'],
1187                     hdr.adir['hw_buf_length']))
1188        print('{}  Load offset {}'.format(pref,
1189                                          hdr.adir['load_offset']))
1190        self.dump_comp_info(pref, comp_filter + ['ADSP Manifest Header'])
1191
1192class AdspModuleEntry(Component):
1193    """ ADSP Module Entry
1194    """
1195    def __init__(self, uid, offset):
1196        super(AdspModuleEntry, self).__init__(uid, 'Module Entry', offset)
1197
1198    def dump_info(self, pref, comp_filter):
1199        print('{}{:9} {}'.format(pref, str(self.adir['mod_name']),
1200            self.adir['uuid']))
1201        print('{}  entry point {} type {}'.format(pref, self.adir['entry_point'],
1202            self.adir['type']))
1203        out = '{}  cfg offset {} count {} affinity {}'.format(pref,
1204            self.adir['cfg_offset'], self.adir['cfg_count'],
1205            self.adir['affinity_mask'])
1206        out += ' instance max count {} stack size {}'.format(
1207            self.adir['instance_max_count'], self.adir['instance_stack_size'])
1208        print(out)
1209        print('{}  .text   {} file offset {} flags {}'.format(pref,
1210            self.adir['seg_0_v_base_addr'], self.adir['seg_0_file_offset'],
1211            self.adir['seg_0_flags']))
1212        print('{}  .rodata {} file offset {} flags {}'.format(pref,
1213            self.adir['seg_1_v_base_addr'], self.adir['seg_1_file_offset'],
1214            self.adir['seg_1_flags']))
1215        print('{}  .bss    {} file offset {} flags {}'.format(pref,
1216            self.adir['seg_2_v_base_addr'], self.adir['seg_2_file_offset'],
1217            self.adir['seg_2_flags']))
1218
1219    def add_comp_to_mem_map(self, mem_map):
1220        mem_map.insert_segment(DspMemorySegment(
1221            self.adir['mod_name'].val + '.text',
1222            self.adir['seg_0_v_base_addr'].val,
1223            self.adir['seg_0_size'].val));
1224        mem_map.insert_segment(DspMemorySegment(
1225            self.adir['mod_name'].val + '.rodata',
1226            self.adir['seg_1_v_base_addr'].val,
1227            self.adir['seg_1_size'].val));
1228        mem_map.insert_segment(DspMemorySegment(
1229            self.adir['mod_name'].val + '.bss',
1230            self.adir['seg_2_v_base_addr'].val,
1231            self.adir['seg_2_size'].val));
1232
1233class FwBin(Component):
1234    """ Parsed sof binary
1235    """
1236    def __init__(self):
1237        super(FwBin, self).__init__('bin', 'SOF Binary', 0)
1238
1239    def dump_info(self, pref, comp_filter):
1240        """ Print out the content
1241        """
1242        print('SOF Binary {} size {}'.format(
1243            self.adir['file_name'], self.adir['file_size']))
1244        self.dump_comp_info(pref, comp_filter)
1245
1246    def populate_mem_map(self, mem_map):
1247        """ Adds modules' segments to the memory map
1248        """
1249        self.add_comp_to_mem_map(mem_map)
1250
1251# DSP Memory Layout
1252def get_mem_map(ri_path):
1253    """ Retrieves memory map for platform determined by the file name
1254    """
1255    for plat_name in DSP_MEM_SPACE_EXT:
1256        # use full firmware name for match
1257        if "sof-{}.ri".format(plat_name) in ri_path:
1258            return DSP_MEM_SPACE_EXT[plat_name]
1259    return DspMemory('Memory layout undefined', [])
1260
1261def add_lmap_mem_info(ri_path, mem_map):
1262    """ Optional lmap processing
1263    """
1264    lmap_path = ri_path[0:ri_path.rfind('.')] + '.lmap'
1265    try:
1266        with open(lmap_path) as lmap:
1267            it_lines = iter(lmap.readlines())
1268            for line in it_lines:
1269                if 'Sections:' in line:
1270                    next(it_lines)
1271                    break;
1272            for line in it_lines:
1273                tok = line.split()
1274                mem_map.insert_segment(DspMemorySegment(tok[1],
1275                    int(tok[3], 16), int(tok[2], 16)))
1276                next(it_lines)
1277
1278    except FileNotFoundError:
1279        return
1280
1281class DspMemorySegment(object):
1282    """ Single continuous memory space
1283    """
1284    def __init__(self, name, base_address, size):
1285        self.name = name
1286        self.base_address = base_address
1287        self.size = size
1288        self.used_size = 0
1289        self.inner_segments = []
1290
1291    def is_inner(self, segment):
1292        return self.base_address <= segment.base_address and \
1293            segment.base_address + segment.size <= self.base_address + self.size
1294
1295    def insert_segment(self, segment):
1296        for seg in self.inner_segments:
1297            if seg.is_inner(segment):
1298                seg.insert_segment(segment)
1299                return
1300        self.inner_segments.append(segment)
1301        self.used_size += segment.size
1302
1303    def dump_info(self, pref):
1304        free_size = self.size - self.used_size
1305        out = '{}{:<35} 0x{:x}'.format(pref, self.name, self.base_address)
1306        if self.used_size > 0:
1307            out += ' ({} + {}  {:.2f}% used)'.format(self.used_size, free_size,
1308                self.used_size*100/self.size)
1309        else:
1310            out += ' ({})'.format(free_size)
1311        print(out)
1312        for seg in self.inner_segments:
1313            seg.dump_info(pref + '  ')
1314
1315class DspMemory(object):
1316    """ Dsp Memory, all top-level segments
1317    """
1318    def __init__(self, platform_name, segments):
1319        self.platform_name = platform_name
1320        self.segments = segments
1321
1322    def insert_segment(self, segment):
1323        """ Inserts segment
1324        """
1325        for seg in self.segments:
1326            if seg.is_inner(segment):
1327                seg.insert_segment(segment)
1328                return
1329
1330    def dump_info(self):
1331        print(self.platform_name)
1332        for seg in self.segments:
1333            seg.dump_info('  ')
1334
1335# Layouts of DSP memory for known platforms
1336
1337APL_MEMORY_SPACE = DspMemory('Intel Apollolake',
1338    [
1339        DspMemorySegment('imr', 0xa0000000, 4*1024*1024),
1340        DspMemorySegment('l2 hpsram', 0xbe000000, 8*64*1024),
1341        DspMemorySegment('l2 lpsram', 0xbe800000, 2*64*1024)
1342    ])
1343
1344CNL_MEMORY_SPACE = DspMemory('Intel Cannonlake',
1345    [
1346        DspMemorySegment('imr', 0xb0000000, 8*0x1024*0x1024),
1347        DspMemorySegment('l2 hpsram', 0xbe000000, 48*64*1024),
1348        DspMemorySegment('l2 lpsram', 0xbe800000, 1*64*1024)
1349    ])
1350
1351ICL_MEMORY_SPACE = DspMemory('Intel Icelake',
1352    [
1353        DspMemorySegment('imr', 0xb0000000, 8*1024*1024),
1354        DspMemorySegment('l2 hpsram', 0xbe000000, 47*64*1024),
1355        DspMemorySegment('l2 lpsram', 0xbe800000, 1*64*1024)
1356    ])
1357
1358TGL_LP_MEMORY_SPACE = DspMemory('Intel Tigerlake-LP',
1359    [
1360        DspMemorySegment('imr', 0xb0000000,16*1024*1024),
1361        DspMemorySegment('l2 hpsram', 0xbe000000, 46*64*1024),
1362        DspMemorySegment('l2 lpsram', 0xbe800000, 1*64*1024)
1363    ])
1364
1365JSL_MEMORY_SPACE = DspMemory('Intel Jasperlake',
1366    [
1367        DspMemorySegment('imr', 0xb0000000, 8*1024*1024),
1368        DspMemorySegment('l2 hpsram', 0xbe000000, 16*64*1024),
1369        DspMemorySegment('l2 lpsram', 0xbe800000, 1*64*1024)
1370    ])
1371
1372TGL_H_MEMORY_SPACE = DspMemory('Intel Tigerlake-H',
1373    [
1374        DspMemorySegment('imr', 0xb0000000, 16*1024*1024),
1375        DspMemorySegment('l2 hpsram', 0xbe000000, 30*64*1024),
1376        DspMemorySegment('l2 lpsram', 0xbe800000, 1*64*1024)
1377    ])
1378
1379DSP_MEM_SPACE_EXT = {
1380    'apl' : APL_MEMORY_SPACE,
1381    'cnl' : CNL_MEMORY_SPACE,
1382    'icl' : ICL_MEMORY_SPACE,
1383    'tgl' : TGL_LP_MEMORY_SPACE,
1384    'jsl' : JSL_MEMORY_SPACE,
1385    'tgl-h' : TGL_H_MEMORY_SPACE,
1386    'ehl' : TGL_LP_MEMORY_SPACE,
1387}
1388
1389def main(args):
1390    """ main function
1391    """
1392    if sys.stdout.isatty():
1393        Attribute.no_colors = args.no_colors
1394    else:
1395        Attribute.no_colors = True
1396
1397    Attribute.full_bytes = args.full_bytes
1398
1399    fw_bin = parse_fw_bin(args.sof_ri_path, args.no_cse, args.verbose)
1400
1401    comp_filter = []
1402    if args.headers or args.no_modules:
1403        comp_filter.append('Module Entry')
1404    if args.no_headers:
1405        comp_filter.append('CSE Manifest')
1406    fw_bin.dump_info('', comp_filter)
1407    if not args.no_memory:
1408        mem = get_mem_map(args.sof_ri_path)
1409        fw_bin.populate_mem_map(mem)
1410        add_lmap_mem_info(args.sof_ri_path, mem)
1411        print()
1412        mem.dump_info()
1413
1414if __name__ == "__main__":
1415    ARGS = parse_params()
1416    main(ARGS)
1417