mirror of
				https://github.com/tiagovignatti/intel-gpu-tools.git
				synced 2025-11-04 03:58:27 +00:00 
			
		
		
		
	tools: Add an intel_firmware_decode tool
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@intel.com>
			
			
This commit is contained in:
		
							parent
							
								
									ad411e2d5d
								
							
						
					
					
						commit
						669b5da2bc
					
				
							
								
								
									
										1
									
								
								tools/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								tools/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -10,6 +10,7 @@ intel_dump_decode
 | 
			
		||||
intel_error_decode
 | 
			
		||||
intel_forcewaked
 | 
			
		||||
intel_framebuffer_dump
 | 
			
		||||
intel_firmware_decode
 | 
			
		||||
intel_gpu_frequency
 | 
			
		||||
intel_gpu_time
 | 
			
		||||
intel_gpu_top
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ bin_PROGRAMS = 				\
 | 
			
		||||
	intel_forcewaked		\
 | 
			
		||||
	intel_gpu_frequency		\
 | 
			
		||||
	intel_framebuffer_dump 		\
 | 
			
		||||
	intel_firmware_decode		\
 | 
			
		||||
	intel_gpu_time 			\
 | 
			
		||||
	intel_gpu_top 			\
 | 
			
		||||
	intel_gtt 			\
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										287
									
								
								tools/intel_firmware_decode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								tools/intel_firmware_decode.c
									
									
									
									
									
										Normal file
									
								
							@ -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@intel.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user