On Tue, 30 Jun 2015, Damien Lespiau <damien.lespiau@xxxxxxxxx> wrote: > So we can inspect fw headers. Sample output: Nitpick on the tool name, I'd like to make a distinction between tools that dump some blob from the driver/hardware/bios/whatever, and tools that decode those blobs. (See also the confusing naming with intel_bios_dumper vs. intel_bios_reader.) I'd call this "intel_firmware_decode". Another nitpick is that I'd plan on using getopt from the beginning, and having a -f or --file option for the input. BR, Jani. > Firmware: skl_dmc_ver1_18.bin (7892 bytes) > CSS header (128 bytes) > module_type: DMC (9) > header_len: 32 > header_ver: 0x10000 > module_id: 0x0 > module_vendor: 0x0 > date: 0x7df060c > size: 1973 > key_size: 0 > modulus_size: 0 > exponent_size: 0 > version: 1.18 (0x10012) > kernel_header_info: 0x0 > Package header (256 bytes) > header_len: 64 > header_ver: 1 > num_entries: 3 > Firmware #1 > stepping: A.* > offset: 4294967295 > Firmware #2 > stepping: B.* > offset: 4294967295 > Firmware #3 > stepping: *.* > offset: 0 > 0x7f0867143000 > 0x7f0867143180 > signature: 0x40403e3e > header_len: 128 > header_ver: 1 > dmcc_ver: 520 > project: 0x900 > fw_size: 1845 > fw_version: 0x10008 > mmio_count: 3 > write(0x0008f074, 0x00002fc0) > write(0x0008f004, 0x02500204) > write(0x0008f034, 0xc003b400) > > Signed-off-by: Damien Lespiau <damien.lespiau@xxxxxxxxx> > --- > tools/.gitignore | 1 + > tools/Makefile.sources | 1 + > tools/intel_fw_dump.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 289 insertions(+) > create mode 100644 tools/intel_fw_dump.c > > diff --git a/tools/.gitignore b/tools/.gitignore > index 5a2f5ff..5a5c62c 100644 > --- a/tools/.gitignore > +++ b/tools/.gitignore > @@ -10,6 +10,7 @@ intel_dump_decode > intel_error_decode > intel_forcewaked > intel_framebuffer_dump > +intel_fw_dump > intel_gpu_frequency > intel_gpu_time > intel_gpu_top > diff --git a/tools/Makefile.sources b/tools/Makefile.sources > index 5acf45a..6f51162 100644 > --- a/tools/Makefile.sources > +++ b/tools/Makefile.sources > @@ -17,6 +17,7 @@ bin_PROGRAMS = \ > intel_forcewaked \ > intel_gpu_frequency \ > intel_framebuffer_dump \ > + intel_fw_dump \ > intel_gpu_time \ > intel_gpu_top \ > intel_gtt \ > diff --git a/tools/intel_fw_dump.c b/tools/intel_fw_dump.c > new file mode 100644 > index 0000000..ae6e02c > --- /dev/null > +++ b/tools/intel_fw_dump.c > @@ -0,0 +1,287 @@ > +/* > + * Copyright © 2015 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > + * IN THE SOFTWARE. > + * > + * Authors: > + * Damien Lespiau <damien.lespiau@xxxxxxxxx> > + */ > + > +#include <fcntl.h> > +#include <stdio.h> > +#include <stdint.h> > +#include <stdlib.h> > +#include <string.h> > +#include <unistd.h> > +#include <sys/types.h> > +#include <sys/mman.h> > +#include <sys/stat.h> > + > +#include "igt_core.h" > + > +#define __packed __attribute__((packed)) > + > +struct intel_css_header { > + /* 0x09 for DMC */ > + uint32_t module_type; > + > + /* Includes the DMC specific header in dwords */ > + uint32_t header_len; > + > + /* always value would be 0x10000 */ > + uint32_t header_ver; > + > + /* Not used */ > + uint32_t module_id; > + > + /* Not used */ > + uint32_t module_vendor; > + > + /* in YYYYMMDD format */ > + uint32_t date; > + > + /* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */ > + uint32_t size; > + > + /* Not used */ > + uint32_t key_size; > + > + /* Not used */ > + uint32_t modulus_size; > + > + /* Not used */ > + uint32_t exponent_size; > + > + /* Not used */ > + uint32_t reserved1[12]; > + > + /* Major Minor */ > + uint32_t version; > + > + /* Not used */ > + uint32_t reserved2[8]; > + > + /* Not used */ > + uint32_t kernel_header_info; > +} __packed; > + > +struct intel_fw_info { > + uint16_t reserved1; > + > + /* Stepping (A, B, C, ..., *). * is a wildcard */ > + char stepping; > + > + /* Sub-stepping (0, 1, ..., *). * is a wildcard */ > + char substepping; > + > + uint32_t offset; > + uint32_t reserved2; > +} __packed; > + > +struct intel_package_header { > + /* DMC container header length in dwords */ > + unsigned char header_len; > + > + /* always value would be 0x01 */ > + unsigned char header_ver; > + > + unsigned char reserved[10]; > + > + /* Number of valid entries in the FWInfo array below */ > + uint32_t num_entries; > + > + struct intel_fw_info fw_info[20]; > +} __packed; > + > +struct intel_dmc_header { > + /* always value would be 0x40403E3E */ > + uint32_t signature; > + > + /* DMC binary header length */ > + unsigned char header_len; > + > + /* 0x01 */ > + unsigned char header_ver; > + > + /* Reserved */ > + uint16_t dmcc_ver; > + > + /* Major, Minor */ > + uint32_t project; > + > + /* Firmware program size (excluding header) in dwords */ > + uint32_t fw_size; > + > + /* Major Minor version */ > + uint32_t fw_version; > + > + /* Number of valid MMIO cycles present. */ > + uint32_t mmio_count; > + > + /* MMIO address */ > + uint32_t mmioaddr[8]; > + > + /* MMIO data */ > + uint32_t mmiodata[8]; > + > + /* FW filename */ > + unsigned char dfile[32]; > + > + uint32_t reserved1[2]; > +} __packed; > + > +typedef struct { > + int fd; > + uint8_t *base; > + struct intel_css_header *css_header; > + struct intel_package_header *package_header; > +} csr_t; > + > +static void csr_open(csr_t *ctx, const char *filename) > +{ > + struct stat st; > + > + ctx->fd = open(filename, O_RDWR); > + igt_fail_on_f(ctx->fd == -1, "Couldn't open %s\n", filename); > + > + fstat(ctx->fd, &st); > + ctx->base = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, > + ctx->fd, 0); > + igt_fail_on_f(ctx->base == MAP_FAILED, "Couldn't mmap %s\n", filename); > + > + printf("Firmware: %s (%zd bytes)\n", filename, st.st_size); > + > + ctx->css_header = (struct intel_css_header *)ctx->base; > + ctx->package_header = (struct intel_package_header *) > + (ctx->base + sizeof(*ctx->css_header)); > +} > + > +#define print_d32(p, field) \ > + printf(" "#field": %u\n", (p)->field) > +#define print_x32(p, field) \ > + printf(" "#field": 0x%x\n", (p)->field) > +#define print_s(p, field) \ > + printf(" "#field": %s\n", (p)->field) > + > +static const char *module_type_name(uint32_t module_type) > +{ > + switch (module_type) { > + case 0x9: > + return "DMC"; > + default: > + return "Unknown"; > + } > +} > + > +static void dump_css(csr_t *ctx) > +{ > + struct intel_css_header *css = ctx->css_header; > + > + printf("CSS header (%zd bytes)\n", sizeof(*css)); > + printf(" module_type: %s (%d)\n", module_type_name(css->module_type), > + css->module_type); > + print_d32(css, header_len); > + print_x32(css, header_ver); > + print_x32(css, module_id); > + print_x32(css, module_vendor); > + print_x32(css, date); > + print_d32(css, size); > + print_d32(css, key_size); > + print_d32(css, modulus_size); > + print_d32(css, exponent_size); > + /* uint32_t reserved1[12]; */ > + printf(" version: %d.%d (0x%x)\n", css->version >> 16, > + css->version & 0xffff, css->version); > + /* uint32_t reserved2[8]; */ > + print_x32(css, kernel_header_info); > + > +} > + > +static void dump_dmc(csr_t *ctx, struct intel_fw_info *info) > +{ > + struct intel_dmc_header *dmc; > + unsigned int i; > + > + if (info->offset == 0xffffffff) > + return; > + > + dmc = (struct intel_dmc_header *)(ctx->base + sizeof(*ctx->css_header) > + + sizeof(*ctx->package_header) + > + info->offset); > + > + print_x32(dmc, signature); > + print_d32(dmc, header_len); > + print_d32(dmc, header_ver); > + print_d32(dmc, dmcc_ver); > + print_x32(dmc, project); > + print_d32(dmc, fw_size); > + print_x32(dmc, fw_version); > + print_d32(dmc, mmio_count); > + > + for (i = 0; i < dmc->mmio_count; i++) { > + printf(" write(0x%08x, 0x%08x)\n", dmc->mmioaddr[i], > + dmc->mmiodata[i]); > + } > +} > + > +static void dump_package(csr_t *ctx) > +{ > + struct intel_package_header *package = ctx->package_header; > + unsigned int i; > + > + printf("Package header (%zd bytes)\n", sizeof(*package)); > + > + print_d32(package, header_len); > + print_d32(package, header_ver); > + /* unsigned char reserved[10]; */ > + print_d32(package, num_entries); > + > + for (i = 0; i < package->num_entries; i++) { > + struct intel_fw_info *info = &package->fw_info[i]; > + > + printf("Firmware #%d\n", i + 1); > + printf(" stepping: %c.%c\n", info->stepping, > + info->substepping); > + print_d32(info, offset); > + > + dump_dmc(ctx, info); > + } > +} > + > +static void csr_dump(csr_t *ctx) > +{ > + dump_css(ctx); > + dump_package(ctx); > +} > + > +static csr_t ctx; > + > +int main(int argc, char **argv) > +{ > + if (argc != 2) { > + fprintf(stderr, "Usage: %s firmware.bin\n", argv[0]); > + return 1; > + } > + > + csr_open(&ctx, argv[1]); > + csr_dump(&ctx); > + > + return 0; > +} > -- > 2.1.0 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx