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