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:
parent
072fb5c43f
commit
03acfd640d
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue