So we can inspect fw headers. Sample output: 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