xref: /aosp_15_r20/external/igt-gpu-tools/tools/intel_firmware_decode.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Damien Lespiau <[email protected]>
25  */
26 
27 #include <fcntl.h>
28 #include <inttypes.h>
29 #include <stdio.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <sys/types.h>
35 #include <sys/mman.h>
36 #include <sys/stat.h>
37 
38 #include "igt_core.h"
39 
40 #define __packed                        __attribute__((packed))
41 
42 struct intel_css_header {
43 	/* 0x09 for DMC */
44 	uint32_t module_type;
45 
46 	/* Includes the DMC specific header in dwords */
47 	uint32_t header_len;
48 
49 	/* always value would be 0x10000 */
50 	uint32_t header_ver;
51 
52 	/* Not used */
53 	uint32_t module_id;
54 
55 	/* Not used */
56 	uint32_t module_vendor;
57 
58 	/* in YYYYMMDD format */
59 	uint32_t date;
60 
61 	/* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
62 	uint32_t size;
63 
64 	/* Not used */
65 	uint32_t key_size;
66 
67 	/* Not used */
68 	uint32_t modulus_size;
69 
70 	/* Not used */
71 	uint32_t exponent_size;
72 
73 	/* Not used */
74 	uint32_t reserved1[12];
75 
76 	/* Major Minor */
77 	uint32_t version;
78 
79 	/* Not used */
80 	uint32_t reserved2[8];
81 
82 	/* Not used */
83 	uint32_t kernel_header_info;
84 } __packed;
85 
86 struct intel_fw_info {
87 	uint16_t reserved1;
88 
89 	/* Stepping (A, B, C, ..., *). * is a wildcard */
90 	char stepping;
91 
92 	/* Sub-stepping (0, 1, ..., *). * is a wildcard */
93 	char substepping;
94 
95 	uint32_t offset;
96 	uint32_t reserved2;
97 } __packed;
98 
99 struct intel_package_header {
100 	/* DMC container header length in dwords */
101 	unsigned char header_len;
102 
103 	/* always value would be 0x01 */
104 	unsigned char header_ver;
105 
106 	unsigned char reserved[10];
107 
108 	/* Number of valid entries in the FWInfo array below */
109 	uint32_t num_entries;
110 
111 	struct intel_fw_info fw_info[20];
112 } __packed;
113 
114 struct intel_dmc_header {
115 	/* always value would be 0x40403E3E */
116 	uint32_t signature;
117 
118 	/* DMC binary header length */
119 	unsigned char header_len;
120 
121 	/* 0x01 */
122 	unsigned char header_ver;
123 
124 	/* Reserved */
125 	uint16_t dmcc_ver;
126 
127 	/* Major, Minor */
128 	uint32_t	project;
129 
130 	/* Firmware program size (excluding header) in dwords */
131 	uint32_t	fw_size;
132 
133 	/* Major Minor version */
134 	uint32_t fw_version;
135 
136 	/* Number of valid MMIO cycles present. */
137 	uint32_t mmio_count;
138 
139 	/* MMIO address */
140 	uint32_t mmioaddr[8];
141 
142 	/* MMIO data */
143 	uint32_t mmiodata[8];
144 
145 	/* FW filename  */
146 	unsigned char dfile[32];
147 
148 	uint32_t reserved1[2];
149 } __packed;
150 
151 typedef struct {
152 	int fd;
153 	uint8_t *base;
154 	struct intel_css_header *css_header;
155 	struct intel_package_header *package_header;
156 } csr_t;
157 
csr_open(csr_t * ctx,const char * filename)158 static void csr_open(csr_t *ctx, const char *filename)
159 {
160 	struct stat st;
161 
162 	ctx->fd = open(filename, O_RDWR);
163 	igt_fail_on_f(ctx->fd == -1, "Couldn't open %s\n", filename);
164 
165 	fstat(ctx->fd, &st);
166 	ctx->base = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
167 			 ctx->fd, 0);
168 	igt_fail_on_f(ctx->base == MAP_FAILED, "Couldn't mmap %s\n", filename);
169 
170 	printf("Firmware: %s (%"PRId64" bytes)\n", filename, (int64_t)st.st_size);
171 
172 	ctx->css_header = (struct intel_css_header *)ctx->base;
173 	ctx->package_header = (struct intel_package_header *)
174 				(ctx->base + sizeof(*ctx->css_header));
175 }
176 
177 #define print_d32(p, field) \
178 	printf("    "#field": %u\n", (p)->field)
179 #define print_x32(p, field) \
180 	printf("    "#field": 0x%x\n", (p)->field)
181 #define print_s(p, field) \
182 	printf("    "#field": %s\n", (p)->field)
183 
module_type_name(uint32_t module_type)184 static const char *module_type_name(uint32_t module_type)
185 {
186 	switch (module_type) {
187 	case 0x9:
188 		return "DMC";
189 	default:
190 		return "Unknown";
191 	}
192 }
193 
dump_css(csr_t * ctx)194 static void dump_css(csr_t *ctx)
195 {
196 	struct intel_css_header *css = ctx->css_header;
197 
198 	printf("CSS header (%zd bytes)\n", sizeof(*css));
199 	printf("    module_type: %s (%d)\n", module_type_name(css->module_type),
200 	       css->module_type);
201 	print_d32(css, header_len);
202 	print_x32(css, header_ver);
203 	print_x32(css, module_id);
204 	print_x32(css, module_vendor);
205 	print_x32(css, date);
206 	print_d32(css, size);
207 	print_d32(css, key_size);
208 	print_d32(css, modulus_size);
209 	print_d32(css, exponent_size);
210 	/* uint32_t reserved1[12]; */
211 	printf("    version: %d.%d (0x%x)\n", css->version >> 16,
212 	       css->version & 0xffff, css->version);
213 	/* uint32_t reserved2[8]; */
214 	print_x32(css, kernel_header_info);
215 
216 }
217 
dump_dmc(csr_t * ctx,struct intel_fw_info * info)218 static void dump_dmc(csr_t *ctx, struct intel_fw_info *info)
219 {
220 	struct intel_dmc_header *dmc;
221 	unsigned int i;
222 
223 	if (info->offset == 0xffffffff)
224 		return;
225 
226 	dmc = (struct intel_dmc_header *)(ctx->base + sizeof(*ctx->css_header)
227 					  + sizeof(*ctx->package_header) +
228 					  info->offset);
229 
230 	print_x32(dmc, signature);
231 	print_d32(dmc, header_len);
232 	print_d32(dmc, header_ver);
233 	print_d32(dmc, dmcc_ver);
234 	print_x32(dmc, project);
235 	print_d32(dmc, fw_size);
236 	print_x32(dmc, fw_version);
237 	print_d32(dmc, mmio_count);
238 
239 	for (i = 0; i < dmc->mmio_count; i++) {
240 		printf("        write(0x%08x, 0x%08x)\n", dmc->mmioaddr[i],
241 		       dmc->mmiodata[i]);
242 	}
243 }
244 
dump_package(csr_t * ctx)245 static void dump_package(csr_t *ctx)
246 {
247 	struct intel_package_header *package = ctx->package_header;
248 	unsigned int i;
249 
250 	printf("Package header (%zd bytes)\n", sizeof(*package));
251 
252 	print_d32(package, header_len);
253 	print_d32(package, header_ver);
254 	/* unsigned char reserved[10]; */
255 	print_d32(package, num_entries);
256 
257 	for (i = 0; i < package->num_entries; i++) {
258 		struct intel_fw_info *info = &package->fw_info[i];
259 
260 		printf("Firmware #%d\n", i + 1);
261 		printf("    stepping: %c.%c\n", info->stepping,
262 		       info->substepping);
263 		print_d32(info, offset);
264 
265 		dump_dmc(ctx, info);
266 	}
267 }
268 
csr_dump(csr_t * ctx)269 static void csr_dump(csr_t *ctx)
270 {
271 	dump_css(ctx);
272 	dump_package(ctx);
273 }
274 
275 static csr_t ctx;
276 
main(int argc,char ** argv)277 int main(int argc, char **argv)
278 {
279 	if (argc != 2) {
280 		fprintf(stderr, "Usage: %s firmware.bin\n", argv[0]);
281 		return 1;
282 	}
283 
284 	csr_open(&ctx, argv[1]);
285 	csr_dump(&ctx);
286 
287 	return 0;
288 }
289