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