Support the SOF driver file format.
Signed-off-by: Liam Girdwood <liam.r.girdwood(a)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(a)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