rimage: update to new SOF driver file format.

Support the SOF driver file format.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
This commit is contained in:
Liam Girdwood 2017-06-09 14:25:36 +01:00
parent 072fb5c43f
commit 03acfd640d
5 changed files with 152 additions and 135 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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@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;
/*
* 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 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));
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];
/*
* 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 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;
} __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

View File

@ -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);

View File

@ -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;