[Sound-open-firmware] [PATCH 1/4] rimage: update to new SOF driver file format.

Liam Girdwood liam.r.girdwood at linux.intel.com
Fri Jun 9 15:57:56 CEST 2017


Support the SOF driver file format.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 rimage/baytrail.c    |  73 +++++++++-------------
 rimage/cherrytrail.c |   9 ++-
 rimage/file_format.h | 166 ++++++++++++++++++++++++++++++---------------------
 rimage/rimage.c      |  26 +++-----
 rimage/rimage.h      |  11 ++++
 5 files changed, 151 insertions(+), 134 deletions(-)

diff --git a/rimage/baytrail.c b/rimage/baytrail.c
index 0053f97..12ccd23 100644
--- a/rimage/baytrail.c
+++ b/rimage/baytrail.c
@@ -40,17 +40,6 @@ static const struct section byt_sections[] = {
 	{"NMIExceptionVector", 			0xff2c061c},
 };
 
-static const enum reef_module_id modules[] = {
-	REEF_MODULE_BASE_FW,
-	REEF_MODULE_AAC_5_1,
-	REEF_MODULE_PCM,
-	REEF_MODULE_PCM_SYSTEM,
-	REEF_MODULE_PCM_CAPTURE,
-	REEF_MODULE_PCM_REFERENCE,
-	REEF_MODULE_BLUETOOTH_RENDER_MODULE,
-	REEF_MODULE_BLUETOOTH_CAPTURE_MODULE,
-};
-
 static int is_iram(struct image *image, Elf32_Shdr *section)
 {
 	const struct adsp *adsp = image->adsp;
@@ -86,7 +75,7 @@ static int block_idx = 0;
 static int write_block(struct image *image, Elf32_Shdr *section)
 {
 	const struct adsp *adsp = image->adsp;
-	struct dma_block_info block;
+	struct snd_sof_blk_hdr block;
 	size_t count;
 	void *buffer;
 	int ret;
@@ -94,11 +83,13 @@ static int write_block(struct image *image, Elf32_Shdr *section)
 	block.size = section->sh_size;
 
 	if (is_iram(image, section)) {
-		block.type = REEF_IRAM;
-		block.ram_offset = section->sh_addr - adsp->iram_base;
+		block.type = SOF_BLK_TEXT;
+		block.offset = section->sh_addr - adsp->iram_base
+			+ adsp->host_iram_offset;
 	} else if (is_dram(image, section)) {
-		block.type = REEF_DRAM;
-		block.ram_offset = section->sh_addr - adsp->dram_base;
+		block.type = SOF_BLK_DATA;
+		block.offset = section->sh_addr - adsp->dram_base
+			+ adsp->host_dram_offset;
 	} else {
 		fprintf(stderr, "error: invalid block address/size 0x%x/0x%x\n",
 			section->sh_addr, section->sh_size);
@@ -153,18 +144,18 @@ out:
 int byt_write_modules(struct image *image)
 {
 	const struct adsp *adsp = image->adsp;
-	struct byt_module_header hdr;
+	struct snd_sof_mod_hdr hdr;
 	Elf32_Shdr *section;
 	size_t count;
 	int i, err;
 	uint32_t valid = (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR);
 
-	memcpy(hdr.signature, REEF_FW_SIGN, REEF_FW_SIGNATURE_SIZE);
-	hdr.blocks = image->num_sections - image->num_bss;
-	hdr.mod_size = image->text_size + image->data_size + \
-				   sizeof(struct dma_block_info) * hdr.blocks;
-	hdr.type = REEF_MODULE_BASE_FW;
-	hdr.entry_point = 0;//section->sh_addr;
+	fprintf(stdout, "Using BYT file format\n");
+
+	hdr.num_blocks = image->num_sections - image->num_bss;
+	hdr.size = image->text_size + image->data_size +
+		sizeof(struct snd_sof_blk_hdr) * hdr.num_blocks;
+	hdr.type = SOF_FW_BASE;
 
 	count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd);
 	if (count != 1) {
@@ -191,41 +182,28 @@ int byt_write_modules(struct image *image)
 		}
 	}
 
-	/* write the remaining 7 fake modules headers, to make the linux driver happy */
-	hdr.mod_size = 0;
-	hdr.blocks = 0;
-
-	for (i = 1; i < sizeof(modules) / sizeof(modules[0]); i++) {
-		hdr.type = modules[i];
-		count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd);
-		if (count != 1) {
-			fprintf(stderr, "error: failed to write section header %d\n", i);
-			return -errno ;
-		}
-	}
-
 	return 0;
 }
 
 /* used by others */
 int byt_write_header(struct image *image)
 {
-	struct fw_header hdr;
+	struct snd_sof_fw_header hdr;
 	size_t count;
 
-	memcpy(hdr.signature, REEF_FW_SIGN, REEF_FW_SIGNATURE_SIZE);
+	memcpy(hdr.sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE);
 
-	hdr.modules = sizeof(modules) / sizeof(modules[0]);
-	hdr.file_format = 0;
+	hdr.num_modules = 1;
+	hdr.abi = SND_SOF_FW_ABI;
 
-	image->fw_size += sizeof(struct dma_block_info) *
+	image->fw_size += sizeof(struct snd_sof_blk_hdr) *
 		(image->num_sections - image->num_bss);
-	image->fw_size += sizeof(struct byt_module_header) * hdr.modules;
+	image->fw_size += sizeof(struct snd_sof_mod_hdr) * hdr.num_modules;
 	hdr.file_size = image->fw_size;
 
 	fprintf(stdout, "fw: image size %ld (0x%lx) bytes %d modules\n\n",
 		hdr.file_size + sizeof(hdr), hdr.file_size + sizeof(hdr),
-		hdr.modules);
+		hdr.num_modules);
 	count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd);
 	if (count != 1)
 		return -errno;
@@ -233,14 +211,19 @@ int byt_write_header(struct image *image)
 	return 0;
 }
 
+#define IRAM_OFFSET		0x0C0000
+#define IRAM_SIZE		(80 * 1024)
+#define DRAM_OFFSET		0x100000
+#define DRAM_SIZE		(160 * 1024)
+
 const struct adsp byt_machine = {
 		.name = "byt",
 		.iram_base = 0xff2c0000,
 		.iram_size = 0x14000,
+		.host_iram_offset = IRAM_OFFSET,
 		.dram_base = 0xff300000,
 		.dram_size = 0x28000,
-		.image_size = 0xff300000 - 0xff2c0000 + 0x28000,
-		.dram_offset = 0xff300000 - 0xff2c0000,
+		.host_dram_offset = DRAM_OFFSET,
 		.machine_id = MACHINE_BAYTRAIL,
 		.ops = {
 			.write_header = byt_write_header,
diff --git a/rimage/cherrytrail.c b/rimage/cherrytrail.c
index a37a13d..e27bea6 100644
--- a/rimage/cherrytrail.c
+++ b/rimage/cherrytrail.c
@@ -40,14 +40,19 @@ static const struct section cht_sections[] = {
 	{"NMIExceptionVector", 			0xff2c061c},
 };
 
+#define IRAM_OFFSET		0x0C0000
+#define IRAM_SIZE		(80 * 1024)
+#define DRAM_OFFSET		0x100000
+#define DRAM_SIZE		(160 * 1024)
+
 const struct adsp cht_machine = {
 		.name = "cht",
 		.iram_base = 0xff2c0000,
 		.iram_size = 0x14000,
+		.host_iram_offset = IRAM_OFFSET,
 		.dram_base = 0xff300000,
 		.dram_size = 0x28000,
-		.image_size = 0xff300000 - 0xff2c0000 + 0x28000,
-		.dram_offset = 0xff300000 - 0xff2c0000,
+		.host_dram_offset = DRAM_OFFSET,
 		.machine_id = MACHINE_CHERRYTRAIL,
 		.ops = {
 				.write_header = byt_write_header,
diff --git a/rimage/file_format.h b/rimage/file_format.h
index 941df33..c813f49 100644
--- a/rimage/file_format.h
+++ b/rimage/file_format.h
@@ -1,88 +1,116 @@
 /*
- * ELF to firmware image creator.
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
  *
- * Copyright (c) 2015, Intel Corporation.
+ * GPL LICENSE SUMMARY
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
  *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
  */
 
-#ifndef __FILE_FORMAT_H__
-#define __FILE_FORMAT_H__
+/*
+ * Firmware file format .
+ */
 
-#define REEF_FW_SIGNATURE_SIZE	4
-#define REEF_FW_SIGN			"$SST"
-#define REEF_FW_LIB_SIGN		"$LIB"
+#ifndef __INCLUDE_UAPI_SOF_FW_H__
+#define __INCLUDE_UAPI_SOF_FW_H__
 
-#define REEF_IRAM	1
-#define REEF_DRAM	2
-#define REEF_REGS	3
-#define REEF_CACHE	3
+#define SND_SOF_FW_SIG_SIZE	4
+#define SND_SOF_FW_ABI		1
+#define SND_SOF_FW_SIG		"Reef"
 
-enum reef_module_id {
-	REEF_MODULE_BASE_FW = 0x0,
-	REEF_MODULE_MP3     = 0x1,
-	REEF_MODULE_AAC_5_1 = 0x2,
-	REEF_MODULE_AAC_2_0 = 0x3,
-	REEF_MODULE_SRC     = 0x4,
-	REEF_MODULE_WAVES   = 0x5,
-	REEF_MODULE_DOLBY   = 0x6,
-	REEF_MODULE_BOOST   = 0x7,
-	REEF_MODULE_LPAL    = 0x8,
-	REEF_MODULE_DTS     = 0x9,
-	REEF_MODULE_PCM_CAPTURE = 0xA,
-	REEF_MODULE_PCM_SYSTEM = 0xB,
-	REEF_MODULE_PCM_REFERENCE = 0xC,
-	REEF_MODULE_PCM = 0xD,
-	REEF_MODULE_BLUETOOTH_RENDER_MODULE = 0xE,
-	REEF_MODULE_BLUETOOTH_CAPTURE_MODULE = 0xF,
-	REEF_MAX_MODULE_ID,
+/*
+ * Firmware module is made up of 1 . N blocks of different types. The
+ * Block header is used to determine where and how block is to be copied in the
+ * DSP/host memory space.
+ */
+enum snd_sof_fw_blk_type {
+	SOF_BLK_IMAGE	= 0,	/* whole image - parsed by ROMs */
+	SOF_BLK_TEXT	= 1,
+	SOF_BLK_DATA	= 2,
+	SOF_BLK_CACHE	= 3,
+	SOF_BLK_REGS	= 4,
+	SOF_BLK_SIG	= 5,
+	SOF_BLK_ROM	= 6,
+	/* add new block types here */
 };
 
-struct dma_block_info {
-	uint32_t type;		/* IRAM/DRAM */
-	uint32_t size;		/* Bytes */
-	uint32_t ram_offset;	/* Offset in I/DRAM */
-	uint32_t rsvd;		/* Reserved field */
+struct snd_sof_blk_hdr {
+	enum snd_sof_fw_blk_type type;
+	uint32_t size;		/* bytes minus this header */
+	uint32_t offset;	/* offset from base */
 } __attribute__((packed));
 
-struct fw_module_info {
-	uint32_t persistent_size;
-	uint32_t scratch_size;
-} __attribute__((packed));
+/*
+ * Firmware file is made up of 1 .. N different modules types. The module
+ * type is used to determine how to load and parse the module.
+ */
+enum snd_sof_fw_mod_type {
+	SOF_FW_BASE	= 0,	/* base firmware image */
+	SOF_FW_MODULE	= 1,	/* firmware module */
+};
 
-struct fw_header {
-	unsigned char signature[REEF_FW_SIGNATURE_SIZE]; /* FW signature */
-	uint32_t file_size;		/* size of fw minus this header */
-	uint32_t modules;		/*  # of modules */
-	uint32_t file_format;	/* version of header format */
-	uint32_t reserved[4];
+struct snd_sof_mod_hdr {
+	enum snd_sof_fw_mod_type type;
+	uint32_t size;		/* bytes minus this header */
+	uint32_t num_blocks;	/* number of blocks */
 } __attribute__((packed));
 
-/* ABI 0 - used by reef driver and CoE BDW/HSW firmware*/
-struct hsw_module_header {
-	unsigned char signature[REEF_FW_SIGNATURE_SIZE]; /* module signature */
-	uint32_t mod_size;	/* size of module */
-	uint32_t blocks;	/* # of blocks */
-	uint16_t padding;
-	uint16_t type;	/* codec type, pp lib */
-	uint32_t entry_point;
-	struct fw_module_info info;
+/*
+ * Firmware file header.
+ */
+struct snd_sof_fw_header {
+	unsigned char sig[SND_SOF_FW_SIG_SIZE]; /* "Reef" */
+	uint32_t file_size; 	/* size of file minus this header */
+	uint32_t num_modules; 	/* number of modules */
+	uint32_t abi; 		/* version of header format */
 } __attribute__((packed));
 
-/* ABI 1 - used by CoE/MCG BYT/CHT/BSW driver */
-struct byt_module_header {
-	unsigned char signature[REEF_FW_SIGNATURE_SIZE];
-	uint32_t mod_size; /* size of module */
-	uint32_t blocks; /* # of blocks */
-	uint32_t type; /* codec type, pp lib */
-	uint32_t entry_point;
-}__attribute__((packed));
-
 #endif
diff --git a/rimage/rimage.c b/rimage/rimage.c
index bed6b48..0695ce3 100644
--- a/rimage/rimage.c
+++ b/rimage/rimage.c
@@ -223,9 +223,12 @@ int main(int argc, char *argv[])
 {
 	struct image image;
 	const char *mach = NULL;
-	int opt, ret, i, binary = 0;
+	int opt, ret, i;
 
 	memset(&image, 0, sizeof(image));
+	image.text_start = 0xffffffff;
+	image.data_start = 0xffffffff;
+	image.bss_start = 0xffffffff;
 
 	while ((opt = getopt(argc, argv, "ho:i:m:vba:sk:")) != -1) {
 		switch (opt) {
@@ -241,9 +244,6 @@ int main(int argc, char *argv[])
 		case 'v':
 			image.verbose = 1;
 			break;
-		case 'b':
-			binary = 1;
-			break;
 		case 's':
 			image.dump_sections = 1;
 			break;
@@ -282,26 +282,16 @@ found:
 			image.in_file, errno);
 	}
 
-	/* open outfile for reading */
+	/* open outfile for writing */
+	unlink(image.out_file);
 	image.out_fd = fopen(image.out_file, "w");
 	if (image.out_fd == NULL) {
 		fprintf(stderr, "error: unable to open %s for writing %d\n",
 			image.out_file, errno);
 	}
 
-	if (binary) {
-
-		switch(image.adsp->machine_id) {
-		case MACHINE_BAYTRAIL:
-			ret = write_byt_binary_image(&image);
-			break;
-		default:
-			fprintf(stderr, "error: not supported machine for binary input!\n");
-			return ret;
-		}
-
-	} else
-		ret = write_elf_data(&image);
+	/* write data */
+	ret = write_elf_data(&image);
 
 	/* close files */
 	fclose(image.out_fd);
diff --git a/rimage/rimage.h b/rimage/rimage.h
index 2c02932..9b8200a 100644
--- a/rimage/rimage.h
+++ b/rimage/rimage.h
@@ -50,6 +50,13 @@ struct image {
 	int data_size;
 	int file_size;
 	int num_modules;
+	uint32_t text_start;
+	uint32_t text_end;
+	uint32_t data_start;
+	uint32_t data_end;
+	uint32_t bss_start;
+	uint32_t bss_end;
+
 
 	/* disa */
 	void *in_buffer;
@@ -82,8 +89,12 @@ struct adsp {
 	uint32_t iram_size;
 	uint32_t dram_base;
 	uint32_t dram_size;
+	uint32_t host_iram_offset;
+	uint32_t host_dram_offset;
+
 	uint32_t image_size;
 	uint32_t dram_offset;
+
 	enum machine_id machine_id;
 	struct adsp_ops ops;
 	const struct section *sections;
-- 
2.11.0



More information about the Sound-open-firmware mailing list