/*
 * Copyright (c) 2017, Intel Corporation.
 *
 * 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.
 *
 * 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.
 *
 *  Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
 *          Keyon Jie <yang.jie@linux.intel.com>
 */


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

#include "uapi/manifest.h"
#include "rimage.h"
#include "file_format.h"
#include "css.h"
#include "cse.h"
#include "plat_auth.h"
#include "manifest.h"

static int man_open_rom_file(struct image *image)
{
	sprintf(image->out_rom_file, "%s.rom", image->out_file);
	unlink(image->out_rom_file);

	/* allocate ROM image  */
	image->rom_image = calloc(image->adsp->rom_size, 1);
	if (image->rom_image == NULL)
		return -ENOMEM;

	/* open ROM outfile for writing */
	image->out_rom_fd = fopen(image->out_rom_file, "w");
	if (image->out_rom_fd == NULL) {
		fprintf(stderr, "error: unable to open %s for writing %d\n",
				image->out_rom_file, errno);
	}

	return 0;
}

static int man_open_unsigned_file(struct image *image)
{
	sprintf(image->out_unsigned_file, "%s.uns", image->out_file);
	unlink(image->out_unsigned_file);

	/* open unsigned FW outfile for writing */
	image->out_unsigned_fd = fopen(image->out_unsigned_file, "w");
	if (image->out_unsigned_fd == NULL) {
		fprintf(stderr, "error: unable to open %s for writing %d\n",
				image->out_unsigned_file, errno);
	}

	return 0;
}

static int man_open_manifest_file(struct image *image)
{
	/* open manifest outfile for writing */
	sprintf(image->out_man_file, "%s.met", image->out_file);
	unlink(image->out_man_file);

	image->out_man_fd = fopen(image->out_man_file, "w");
	if (image->out_man_fd == NULL) {
		fprintf(stderr, "error: unable to open %s for writing %d\n",
				image->out_man_file, errno);
	}

	return 0;
}

static int man_init_image(struct image *image)
{
	/* allocate image and copy template manifest */
	image->fw_image = calloc(image->adsp->image_size, 1);
	if (image->fw_image == NULL)
		return -ENOMEM;

	memcpy(image->fw_image, image->adsp->man,
		sizeof(struct fw_image_manifest));

	return 0;
}

/* we should call this after all segments size set up via iterate */
static uint32_t elf_to_file_offset(struct image *image,
	struct module *module, struct sof_man_module *man_module,
	Elf32_Shdr *section)
{
	uint32_t elf_addr = section->sh_addr, file_offset = 0;

	if (section->sh_type == SHT_PROGBITS) {
		if (section->sh_flags & SHF_EXECINSTR) {
			/* text segment */
			file_offset = elf_addr - module->text_start +
				module->foffset;
		} else {
			/* rodata segment, append to text segment */
			file_offset = elf_addr - module->data_start +
				module->foffset + module->text_fixup_size;

		}
	} else if (section->sh_type == SHT_NOBITS) {
		/* bss segment */
		file_offset = 0;
	}

	return file_offset;
}

/* write SRAM sections */
static int man_copy_sram(struct image *image, Elf32_Shdr *section,
	struct module *module, struct sof_man_module *man_module,
	int section_idx)
{
	uint32_t offset = elf_to_file_offset(image, module,
		man_module, section);
	uint32_t end = offset + section->sh_size;
	int seg_type = -1;
	void *buffer = image->fw_image + offset;
	size_t count;

	switch (section->sh_type) {
	case SHT_PROGBITS:
		/* text or data */
		if (section->sh_flags & SHF_EXECINSTR)
			seg_type = SOF_MAN_SEGMENT_TEXT;
		else
			seg_type = SOF_MAN_SEGMENT_RODATA;
		break;
	case SHT_NOBITS:
		seg_type = SOF_MAN_SEGMENT_BSS;
	default:
		return 0;
	}

	/* file_offset for segment should not be 0s, we set it to
	  * the smallest offset of its modules ATM.
	  */
	if (man_module->segment[seg_type].file_offset > offset ||
		man_module->segment[seg_type].file_offset == 0)
		man_module->segment[seg_type].file_offset = offset;

	count = fread(buffer, 1, section->sh_size, module->fd);
	if (count != section->sh_size) {
		fprintf(stderr, "error: cant read section %d\n", -errno);
		return -errno;
	}

	/* get module end offset  ? */
	if (end > image->image_end)
		image->image_end = end;

	fprintf(stdout, "\t%d\t0x%x\t0x%x\t\t0x%x\t%s\n", section_idx,
		section->sh_addr, section->sh_size, offset,
		seg_type == SOF_MAN_SEGMENT_TEXT ? "TEXT" : "DATA");

	return 0;
}

static int man_copy_elf_section(struct image *image, Elf32_Shdr *section,
	struct module *module, struct sof_man_module *man_module, int idx)
{
	int ret;

	/* seek to ELF section */
	ret = fseek(module->fd, section->sh_offset, SEEK_SET);
	if (ret < 0) {
		fprintf(stderr, "error: can't seek to section %d\n", ret);
		return ret;
	}

	/* write data to DRAM or ROM image */
	if (!elf_is_rom(image, section))
		return man_copy_sram(image, section, module, man_module, idx);

	return 0;
}

static int man_get_module_manifest(struct image *image, struct module *module,
		struct sof_man_module *man_module)
{
	Elf32_Shdr *section;
	struct sof_man_segment_desc *segment;
	struct sof_man_module_manifest sof_mod;
	size_t count;
	int ret, man_section_idx;

	fprintf(stdout, "Module Write: %s\n", module->elf_file);

	/* find manifest module data */
	man_section_idx = elf_find_section(image, module, ".module");
	if (man_section_idx < 0) {
		return -EINVAL;
	}

	fprintf(stdout, " Manifest module metadata section at index %d\n",
		man_section_idx);
	section = &module->section[man_section_idx];

	/* load in manifest data */
	/* module built using xcc has preceding bytes */
	if (section->sh_size > sizeof(sof_mod))
		ret = fseek(module->fd,
			section->sh_offset + XCC_MOD_OFFSET, SEEK_SET);
	else
		ret = fseek(module->fd, section->sh_offset, SEEK_SET);

	if (ret < 0) {
		fprintf(stderr, "error: can't seek to section %d\n", ret);
		return ret;
	}

	count = fread(&sof_mod, 1, sizeof(sof_mod), module->fd);
	if (count != sizeof(sof_mod)) {
		fprintf(stderr, "error: can't read section %d\n", -errno);
		return -errno;
	}

	/* configure man_module with sofmod data */
	memcpy(man_module->struct_id, "$AME", 4);
	man_module->entry_point = sof_mod.module.entry_point;
	memcpy(man_module->name, sof_mod.module.name, SOF_MAN_MOD_NAME_LEN);
	memcpy(man_module->uuid, sof_mod.module.uuid, 16);
	man_module->affinity_mask = sof_mod.module.affinity_mask;
	man_module->type.auto_start = sof_mod.module.type.auto_start;
	man_module->type.domain_dp = sof_mod.module.type.domain_dp;
	man_module->type.domain_ll = sof_mod.module.type.domain_ll;
	man_module->type.load_type = sof_mod.module.type.load_type;

	/* read out text_fixup_size from memory mapping */
	module->text_fixup_size = sof_mod.text_size;

	/* text segment */
	segment = &man_module->segment[SOF_MAN_SEGMENT_TEXT];
	segment->flags.r.contents = 1;
	segment->flags.r.alloc = 1;
	segment->flags.r.load = 1;
	segment->flags.r.readonly = 1;
	segment->flags.r.code = 1;

	/* data segment */
	segment = &man_module->segment[SOF_MAN_SEGMENT_RODATA];
	segment->flags.r.contents = 1;
	segment->flags.r.alloc = 1;
	segment->flags.r.load = 1;
	segment->flags.r.readonly = 1;
	segment->flags.r.data = 1;
	segment->flags.r.type = 1;

	/* bss segment */
	segment = &man_module->segment[SOF_MAN_SEGMENT_BSS];
	segment->flags.r.alloc = 1;
	segment->flags.r.type = 2;

	fprintf(stdout, " Entry point 0x%8.8x\n", man_module->entry_point);

	return 0;
}

static inline const char *segment_name(int i)
{
	switch (i) {
	case SOF_MAN_SEGMENT_TEXT:
		return "TEXT";
	case SOF_MAN_SEGMENT_RODATA:
		return "DATA";
	case SOF_MAN_SEGMENT_BSS:
		return "BSS";
	default:
		return "NONE";
	}
}

/* make sure no segments collide */
static int man_module_validate(struct sof_man_module *man_module)
{
	uint32_t istart, iend;
	uint32_t jstart, jend;
	int i, j;

	for (i = 0; i < 3; i++) {

		istart = man_module->segment[i].v_base_addr;
		iend = istart + man_module->segment[i].flags.r.length *
			MAN_PAGE_SIZE;

		for (j = 0; j < 3; j++) {

			/* don't validate segment against itself */
			if (i == j)
				continue;

			jstart = man_module->segment[j].v_base_addr;
			jend = jstart + man_module->segment[j].flags.r.length *
				MAN_PAGE_SIZE;

			if (jstart > istart && jstart < iend)
				goto err;

			if (jend > istart && jend < iend)
				goto err;
		}
	}

	/* success, no overlapping segments */
	return 0;

err:
	fprintf(stderr, "error: segment %s [0x%8.8x:0x%8.8x] overlaps",
		segment_name(i), istart, iend);
	fprintf(stderr, " with %s [0x%8.8x:0x%8.8x]\n",
		segment_name(j), jstart, jend);
	return -EINVAL;
}

static int man_module_create(struct image *image, struct module *module,
	struct sof_man_module *man_module)
{
	/* create module and segments */
	uint32_t valid = (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR);
	Elf32_Shdr *section;
	int i, err;
	unsigned int pages;

	image->image_end = 0;

	err = man_get_module_manifest(image, module, man_module);
	if (err < 0)
		return err;

	/* stack size ??? convert sizes to PAGES */
	man_module->instance_bss_size = 1;

	/* max number of instances of this module ?? */
	man_module->instance_max_count = 1;

	fprintf(stdout, "\n\tTotals\tStart\t\tEnd\t\tSize");

	fprintf(stdout, "\n\tTEXT\t0x%8.8x\t0x%8.8x\t0x%x\n",
		module->text_start, module->text_end,
		module->text_end - module->text_start);
	fprintf(stdout, "\tDATA\t0x%8.8x\t0x%8.8x\t0x%x\n",
		module->data_start, module->data_end,
		module->data_end - module->data_start);
	fprintf(stdout, "\tBSS\t0x%8.8x\t0x%8.8x\t0x%x\n\n ",
		module->bss_start, module->bss_end,
		module->bss_end - module->bss_start);

	/* main module */
	/* text section is first */
	man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset =
		module->foffset;
	man_module->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr =
		module->text_start;

	/* calculates those padding 0s by the start of next segment */
	pages = module->text_file_size / MAN_PAGE_SIZE;
	if (module->text_file_size % MAN_PAGE_SIZE)
		pages += 1;

	if (module->text_fixup_size == 0)
		module->text_fixup_size = module->text_file_size;

	/* check if text_file_size is bigger then text_fixup_size */
	if (module->text_file_size > module->text_fixup_size) {
		fprintf(stderr, "error: too small text size assigned!\n");
		return -EINVAL;
	}

	man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length = pages;

	/* data section */
	man_module->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr =
		module->data_start;
	man_module->segment[SOF_MAN_SEGMENT_RODATA].file_offset =
			module->foffset + module->text_fixup_size;
	pages = module->data_file_size / MAN_PAGE_SIZE;
	if (module->data_file_size % MAN_PAGE_SIZE)
		pages += 1;

	man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length = pages;

	/* bss is last */
	man_module->segment[SOF_MAN_SEGMENT_BSS].file_offset = 0;
	man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = module->bss_start;
	pages = (module->bss_end - module->bss_start) / MAN_PAGE_SIZE;
	if ((module->bss_end - module->bss_start) % MAN_PAGE_SIZE)
		pages += 1;
	man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length = pages;
	if (pages == 0) {
		man_module->segment[SOF_MAN_SEGMENT_BSS].flags.ul = 0;
		man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.type =
				SOF_MAN_SEGMENT_EMPTY;
	}

	fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\tType\n");

	if (man_module_validate(man_module) < 0)
		return -EINVAL;

	/* find all sections and copy to corresponding segments */
	for (i = 0; i < module->hdr.e_shnum; i++) {

		section = &module->section[i];

		/* only check valid sections */
		if (!(section->sh_flags & valid))
			continue;

		if (section->sh_size == 0)
			continue;

		/* text or data section */
		if (!elf_is_rom(image, section))
			err = man_copy_elf_section(image, section, module,
				man_module, i);

		if (err < 0) {
			fprintf(stderr, "error: failed to write section #%d\n", i);
			return err;
		}
	}
	fprintf(stdout, "\n");

	/* round module end upto nearest page */
	if (image->image_end % MAN_PAGE_SIZE) {
		image->image_end = (image->image_end / MAN_PAGE_SIZE) + 1;
		image->image_end *= MAN_PAGE_SIZE;
	}

	fprintf(stdout, " Total pages text %d data %d bss %d module file limit: 0x%x\n\n",
		man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length,
		man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length,
		man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length,
		image->image_end);
	return 0;
}

static int man_module_create_reloc(struct image *image, struct module *module,
	struct sof_man_module *man_module)
{
	/* create module and segments */
	int err;
	unsigned int pages;
	void *buffer = image->fw_image + module->foffset;
	size_t count;

	image->image_end = 0;

	err = man_get_module_manifest(image, module, man_module);
	if (err < 0)
		return err;

	/* stack size ??? convert sizes to PAGES */
	man_module->instance_bss_size = 1;

	/* max number of instances of this module ?? */
	man_module->instance_max_count = 1;

	fprintf(stdout, "\n\tTotals\tStart\t\tEnd\t\tSize");

	fprintf(stdout, "\n\tTEXT\t0x%8.8x\t0x%8.8x\t0x%x\n",
		module->text_start, module->text_end,
		module->text_end - module->text_start);
	fprintf(stdout, "\tDATA\t0x%8.8x\t0x%8.8x\t0x%x\n",
		module->data_start, module->data_end,
		module->data_end - module->data_start);
	fprintf(stdout, "\tBSS\t0x%8.8x\t0x%8.8x\t0x%x\n\n ",
		module->bss_start, module->bss_end,
		module->bss_end - module->bss_start);

	/* main module */
	/* text section is first */
	man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset =
		module->foffset;
	man_module->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr = 0;
	man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length = 0;

	/* data section */
	man_module->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr = 0;
	man_module->segment[SOF_MAN_SEGMENT_RODATA].file_offset =
			module->foffset;
	pages = module->data_file_size / MAN_PAGE_SIZE;
	if (module->data_file_size % MAN_PAGE_SIZE)
		pages += 1;

	man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length = pages;

	/* bss is last */
	man_module->segment[SOF_MAN_SEGMENT_BSS].file_offset = 0;
	man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = 0;
	man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length = 0;

	fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\tType\n");

	/* seek to beginning of file */
	err = fseek(module->fd, 0, SEEK_SET);
	if (err < 0) {
		fprintf(stderr, "error: can't seek to section %d\n", err);
		return err;
	}

	count = fread(buffer, 1, module->file_size, module->fd);
	if (count != module->file_size) {
		fprintf(stderr, "error: can't read section %d\n", -errno);
		return -errno;
	}

	fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8x\t0x%x\t%s\n", 0,
		0, module->file_size, 0, "DATA");

	fprintf(stdout, "\n");
	image->image_end = module->foffset + module->file_size;

	/* round module end up to nearest page */
	if (image->image_end % MAN_PAGE_SIZE) {
		image->image_end = (image->image_end / MAN_PAGE_SIZE) + 1;
		image->image_end *= MAN_PAGE_SIZE;
	}

	fprintf(stdout, " Total pages text %d data %d bss %d module file limit: 0x%x\n\n",
		man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length,
		man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length,
		man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length,
		image->image_end);
	return 0;
}

static int man_write_unsigned_mod(struct image *image, int meta_start_offset,
	int meta_end_offset)
{
	int count;

	/* write metadata file for unsigned FW */
	count = fwrite(image->fw_image + meta_start_offset,
			sizeof(struct sof_man_adsp_meta_file_ext), 1,
			image->out_man_fd);

	/* did the metadata/manifest write succeed ? */
	if (count != 1) {
		fprintf(stderr, "error: failed to write meta %s %d\n",
			image->out_man_file, -errno);
		return -errno;
	}
	fclose(image->out_man_fd);

	/* now prepare the unsigned rimage */
	count = fwrite(image->fw_image + meta_end_offset,
			image->image_end - meta_end_offset,
			1, image->out_unsigned_fd);

	/* did the unsigned FW write succeed ? */
	if (count != 1) {
		fprintf(stderr, "error: failed to write firmware %s %d\n",
			image->out_unsigned_file, -errno);
		return -errno;
	}
	fclose(image->out_unsigned_fd);

	return 0;
}

static int man_write_fw_mod(struct image *image)
{
	int count;

	/* write ROM - for VM use only */
	count = fwrite(image->rom_image, image->adsp->rom_size, 1,
		image->out_rom_fd);
	if (count != 1) {
		fprintf(stderr, "error: failed to write rom %s %d\n",
			image->out_rom_file, -errno);
		return -errno;
	}
	fclose(image->out_rom_fd);

	/* write manifest and signed image */
	count = fwrite(image->fw_image,
			image->image_end,
			1, image->out_fd);

	/* did the image write succeed ? */
	if (count != 1) {
		fprintf(stderr, "error: failed to write signed firmware %s %d\n",
			image->out_file, -errno);
		return -errno;
	}

	return 0;
}

static int man_create_modules(struct image *image, struct sof_man_fw_desc *desc)
{
	struct module *module;
	struct sof_man_module *man_module;
	int err;
	int i;

	for (i = 0; i < image->num_modules; i++) {
		man_module = sof_man_get_module(desc, i);
		module = &image->module[i];

		/* set module file offset */
		if (i == 0)
			module->foffset = FILE_TEXT_OFFSET;
		else
			module->foffset = image->image_end;

		if (image->reloc)
			err = man_module_create_reloc(image, module,
						      man_module);
		else
			err = man_module_create(image, module, man_module);

		if (err < 0)
			return err;
	}

	return 0;
}

static int man_hash_modules(struct image *image, struct sof_man_fw_desc *desc)
{
	struct sof_man_module *man_module;
	int i;

	for (i = 0; i < image->num_modules; i++) {
		man_module = sof_man_get_module(desc, i);

		ri_hash(image,
			man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset,
			(man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length +
			man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length) *
			MAN_PAGE_SIZE, man_module->hash);
	}

	return 0;
}

/* used by others */
static int man_write_fw(struct image *image)
{
	struct sof_man_fw_desc *desc;
	struct fw_image_manifest *m;
	uint8_t hash[SOF_MAN_MOD_SHA256_LEN];
	int ret, i;

	/* init image */
	ret = man_init_image(image);
	if (ret < 0)
		goto err;

	/* open ROM image */
	ret = man_open_rom_file(image);
	if (ret < 0)
		goto err;

	/* open unsigned firmware */
	ret = man_open_unsigned_file(image);
	if (ret < 0)
		goto err;

	/* create the manifest */
	ret = man_open_manifest_file(image);
	if (ret < 0)
		goto err;

	/* create the module */
	m = image->fw_image;
	desc = image->fw_image + MAN_DESC_OFFSET;

	/* create each module */
	m->desc.header.num_module_entries = image->num_modules;
	man_create_modules(image, desc);

	fprintf(stdout, "Firmware completing manifest\n");

	/* create structures from end of file to start of file */
	ri_adsp_meta_data_create(image, MAN_META_EXT_OFFSET,
				 MAN_FW_DESC_OFFSET);
	ri_plat_ext_data_create(image);
	ri_css_hdr_create(image);
	ri_cse_create(image);

	fprintf(stdout, "Firmware file size 0x%x page count %d\n",
		FILE_TEXT_OFFSET - MAN_DESC_OFFSET + image->image_end,
		desc->header.preload_page_count);

	/* calculate hash for each module */
	man_hash_modules(image, desc);

	/* calculate hash for ADSP meta data extension - 0x480 to end */
	ri_hash(image, MAN_FW_DESC_OFFSET, image->image_end
		- MAN_FW_DESC_OFFSET, m->adsp_file_ext.comp_desc[0].hash);

	/* calculate hash for platform auth data - repeated in hash 2 and 4 */
	ri_hash(image, MAN_META_EXT_OFFSET,
		sizeof(struct sof_man_adsp_meta_file_ext), hash);

	/* hash values in reverse order */
	for (i = 0; i < SOF_MAN_MOD_SHA256_LEN; i++) {
		m->signed_pkg.module[0].hash[i] =
		m->partition_info.module[0].hash[i] =
			hash[SOF_MAN_MOD_SHA256_LEN - 1 - i];
	}

	/* sign manifest */
	ret = ri_manifest_sign(image);
	if (ret < 0)
		goto err;

	/* write the firmware */
	ret = man_write_fw_mod(image);
	if (ret < 0)
		goto err;

	/* write the unsigned files*/
	ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET,
				     MAN_FW_DESC_OFFSET);
	if (ret < 0)
		goto err;

	fprintf(stdout, "Firmware manifest and signing completed !\n");
	return 0;

err:
	free(image->rom_image);
	free(image->fw_image);
	unlink(image->out_file);
	unlink(image->out_rom_file);
	return ret;
}

/* used to sign with MEU */
static int man_write_fw_meu(struct image *image)
{
	const int meta_start_offset = image->meu_offset -
		sizeof(struct sof_man_adsp_meta_file_ext) - MAN_EXT_PADDING;
	struct sof_man_adsp_meta_file_ext *meta;
	struct sof_man_fw_desc *desc;
	uint32_t preload_size;
	int ret;

	/* allocate image */
	image->fw_image = calloc(image->adsp->image_size, 1);
	if (image->fw_image == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	/* open unsigned firmware */
	ret = man_open_unsigned_file(image);
	if (ret < 0)
		goto err;

	/* create the manifest */
	ret = man_open_manifest_file(image);
	if (ret < 0)
		goto err;

	/* create the module */
	meta = image->fw_image + meta_start_offset;
	desc = image->fw_image + MAN_DESC_OFFSET;

	/* copy data */
	memcpy(meta, &image->adsp->man->adsp_file_ext,
	       sizeof(struct sof_man_adsp_meta_file_ext));
	memcpy(desc, &image->adsp->man->desc,
	       sizeof(struct sof_man_fw_desc));

	/* create each module */
	desc->header.num_module_entries = image->num_modules;
	man_create_modules(image, desc);

	fprintf(stdout, "Firmware completing manifest\n");

	/* create structures from end of file to start of file */
	ri_adsp_meta_data_create(image, meta_start_offset, image->meu_offset);

	/* write preload page count */
	preload_size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET;
	preload_size += MAN_PAGE_SIZE - (preload_size % MAN_PAGE_SIZE);
	desc->header.preload_page_count = preload_size / MAN_PAGE_SIZE;

	/* calculate hash for each module */
	man_hash_modules(image, desc);

	/* calculate hash for ADSP meta data extension */
	ri_hash(image, image->meu_offset, image->image_end -
		image->meu_offset, meta->comp_desc[0].hash);

	/* write the unsigned files */
	ret = man_write_unsigned_mod(image, meta_start_offset,
				     image->meu_offset);
	if (ret < 0)
		goto err;

	fprintf(stdout, "Firmware manifest completed!\n");
	return 0;

err:
	free(image->fw_image);
	unlink(image->out_file);
	return ret;
}

#define ADSP_APL_DSP_ROM_BASE	0xBEFE0000
#define ADSP_APL_DSP_ROM_SIZE	0x00002000
#define APL_DSP_BASE_ENTRY	0xa000a000

#define ADSP_CNL_DSP_ROM_BASE	0xBEFE0000
#define ADSP_CNL_DSP_ROM_SIZE	0x00002000
#define CNL_DSP_IMR_BASE_ENTRY	0xb0038000
#define CNL_DSP_HP_BASE_ENTRY	0xbe040000

/* list of supported adsp */
const struct adsp machine_apl = {
	.name = "apl",
	.rom_base = ADSP_APL_DSP_ROM_BASE,
	.rom_size = ADSP_APL_DSP_ROM_SIZE,
	.sram_base = APL_DSP_BASE_ENTRY,
	.sram_size = 0x100000,
	.image_size = 0x100000,
	.dram_offset = 0,
	.machine_id = MACHINE_APOLLOLAKE,
	.write_firmware = man_write_fw,
	.write_firmware_meu = man_write_fw_meu,
	.man = &apl_manifest,
};

const struct adsp machine_cnl = {
	.name = "cnl",
	.rom_base = ADSP_CNL_DSP_ROM_BASE,
	.rom_size = ADSP_CNL_DSP_ROM_SIZE,
	.imr_base = CNL_DSP_IMR_BASE_ENTRY,
	.imr_size = 0x100000,
	.sram_base = CNL_DSP_HP_BASE_ENTRY,
	.sram_size = 0x100000,
	.image_size = 0x100000,
	.dram_offset = 0,
	.machine_id = MACHINE_CANNONLAKE,
	.write_firmware = man_write_fw,
	.write_firmware_meu = man_write_fw_meu,
	.man = &cnl_manifest,
};
