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