/*
 * Copyright (c) 2012-2014, NVIDIA CORPORATION.  All rights reserved.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 */

/*
 * data_layout.c - Code to manage the layout of data in the boot device.
 *
 */

#include "data_layout.h"
#include "cbootimage.h"
#include "crypto.h"
#include "set.h"
#include "context.h"
#include "parse.h"
#include <sys/param.h>

typedef struct blk_data_rec
{
	u_int32_t blk_number;
	u_int32_t pages_used; /* pages always used starting from 0. */
	u_int8_t *data;

	/* Pointer to ECC errors? */

	struct blk_data_rec *next;
} block_data;

/* Function prototypes */
static block_data
*new_block(u_int32_t blk_number, u_int32_t block_size);
static block_data
*find_block(u_int32_t blk_number, block_data  *block_list);
static block_data
*add_block(u_int32_t blk_number, block_data **block_list,
			u_int32_t block_size);
static int
erase_block(build_image_context *context, u_int32_t blk_number);

static int
write_page(build_image_context *context,
			u_int32_t blk_number,
			u_int32_t page_number,
			u_int8_t *data);

static void
insert_padding(u_int8_t *data, u_int32_t length);

static void
write_padding(u_int8_t *data, u_int32_t length);

static int write_bct(build_image_context *context,
		u_int32_t block,
		u_int32_t bct_slot);

static void
set_bl_data(build_image_context *context,
			u_int32_t instance,
			u_int32_t start_blk,
			u_int32_t start_page,
			u_int32_t length);

static int write_image(build_image_context *context, file_type image_type);

static void find_new_bct_blk(build_image_context *context);
static int finish_update(build_image_context *context);

u_int32_t
iceil_log2(u_int32_t a, u_int32_t b)
{
	return (a + (1 << b) - 1) >> b;
}

/* Returns the smallest power of 2 >= a */
u_int32_t
ceil_log2(u_int32_t a)
{
	u_int32_t result;

	result = log2(a);
	if ((1UL << result) < a)
		result++;

	return result;
}

static block_data *new_block(u_int32_t blk_number, u_int32_t block_size)
{
	block_data *new_block = malloc(sizeof(block_data));
	if (new_block == NULL)
		return NULL;

	new_block->blk_number = blk_number;
	new_block->pages_used = 0;
	new_block->data = malloc(block_size);
	if (new_block->data == NULL) {
		free(new_block);
		return NULL;
	}
	new_block->next = NULL;

	memset(new_block->data, 0, block_size);

	return new_block;
}

block_data *new_block_list(void)
{
	return NULL;
}

void destroy_block_list(block_data *block_list)
{
	block_data *next;

	while (block_list) {
		next = block_list->next;
		free(block_list->data);
		free(block_list);
		block_list = next;
	}
}

static block_data *find_block(u_int32_t blk_number, block_data  *block_list)
{
	while (block_list) {
		if (block_list->blk_number == blk_number)
			return block_list;

		block_list = block_list->next;
	}

	return NULL;
}

/* Returns pointer to block after adding it to block_list, if needed. */
static block_data *add_block(u_int32_t blk_number,
		block_data **block_list,
		u_int32_t block_size)
{
	block_data *block = find_block(blk_number,*block_list);
	block_data *parent;

	if (block == NULL) {
		block = new_block(blk_number, block_size);
		if (block == NULL)
			return block;

		/* Insert block into the list */
		if ((*block_list == NULL) ||
			(blk_number < (*block_list)->blk_number)) {
			block->next = *block_list;
			*block_list = block;
		} else {
			/* Search for the correct place to insert the block. */
			parent = *block_list;
			while (parent->next != NULL &&
				parent->next->blk_number < blk_number) {
				parent = parent->next;
			}

			block->next = parent->next;
			parent->next = block;
		}
	}

	return block;
}

static int
erase_block(build_image_context *context, u_int32_t blk_number)
{
	block_data   *block;

	assert(context != NULL);

	block = add_block(blk_number, &(context->memory), context->block_size);

	if (block == NULL)
		return -ENOMEM;
	if (block->data == NULL)
		return -ENOMEM;

	memset(block->data, 0, context->block_size);
	block->pages_used = 0;
	return 0;
}

static int
write_page(build_image_context *context,
	u_int32_t blk_number,
	u_int32_t page_number,
	u_int8_t *data)
{
	block_data *block;
	u_int8_t *page_ptr;

	assert(context);

	block = add_block(blk_number, &(context->memory), context->block_size);

	if (block == NULL)
		return -ENOMEM;
	if (block->data == NULL)
		return -ENOMEM;
	assert(((page_number + 1) * context->page_size)
			<= context->block_size);

	if (block->pages_used != page_number) {
		printf("Warning: Writing page in block out of order.\n");
		printf("     block=%d  page=%d\n", blk_number, page_number);
	}

	page_ptr = block->data + (page_number * context->page_size);
	memcpy(page_ptr, data, context->page_size);
	if (block->pages_used < (page_number+1))
		block->pages_used = page_number+1;
	return 0;
}

static void
insert_padding(u_int8_t *data, u_int32_t length)
{
	u_int32_t aes_blks;
	u_int32_t remaining;

	aes_blks = iceil_log2(length, NVBOOT_AES_BLOCK_SIZE_LOG2);
	remaining = (aes_blks << NVBOOT_AES_BLOCK_SIZE_LOG2) - length;

	write_padding(data + length, remaining);
}

static void
write_padding(u_int8_t *p, u_int32_t remaining)
{
	u_int8_t value = 0x80;

	while (remaining) {
		*p++ = value;
		remaining--;
		value = 0x00;
	}
}

static int
write_bct(build_image_context *context,
	u_int32_t block,
	u_int32_t bct_slot)
{
	u_int32_t pagesremaining;
	u_int32_t page;
	u_int32_t pages_per_bct;
	u_int8_t *buffer;
	u_int8_t *data;
	int err = 0;

	assert(context);

	pages_per_bct = iceil_log2(context->bct_size, context->page_size_log2);
	pagesremaining = pages_per_bct;
	page = bct_slot * pages_per_bct;

	/* Create a local copy of the BCT data */
	buffer = malloc(pages_per_bct * context->page_size);
	if (buffer == NULL)
		return -ENOMEM;
	memset(buffer, 0, pages_per_bct * context->page_size);

	memcpy(buffer, context->bct, context->bct_size);

	insert_padding(buffer, context->bct_size);

	/* Encrypt and compute hash */
	err = sign_bct(context, buffer);
	if (err != 0)
		goto fail;

	/* Write the BCT data to the storage device, picking up ECC errors */
	data = buffer;
	while (pagesremaining > 0) {
		err = write_page(context, block, page, data);
		if (err != 0)
			goto fail;
		page++;
		pagesremaining--;
		data += context->page_size;
	}
fail:
	/* Cleanup */
	free(buffer);
	return err;
}

#define SET_BL_FIELD(instance, field, value)   \
do {                                           \
    g_soc_config->setbl_param(instance,        \
        token_bl_##field,                      \
        &(value),                              \
        context->bct);                         \
} while (0);

#define GET_BL_FIELD(instance, field, ptr)     \
g_soc_config->getbl_param(instance,            \
        token_bl_##field,                      \
        ptr,                                   \
        context->bct);

#define COPY_BL_FIELD(from, to, field)         \
do {                                           \
    u_int32_t v;                               \
    GET_BL_FIELD(from, field, &v);             \
    SET_BL_FIELD(to,   field,  v);             \
} while (0);

#define SET_MTS_FIELD(instance, field, value)   \
do {                                            \
    g_soc_config->set_mts_info(context,         \
    instance,                                   \
    token_mts_info_##field,                     \
    value);                                     \
} while (0);

#define GET_MTS_FIELD(instance, field, ptr)     \
g_soc_config->get_mts_info(context,             \
        instance,                               \
        token_mts_info_##field,                 \
        ptr);

#define COPY_MTS_FIELD(from, to, field)         \
do {                                            \
    u_int32_t v;                                \
    GET_MTS_FIELD(from, field, &v);             \
    SET_MTS_FIELD(to,   field,  v);             \
} while (0);

#define SET_FIELD(is_bl, instance, field, value)\
do {                                            \
    if (is_bl) {                                \
        SET_BL_FIELD(instance, field,value);    \
    }                                           \
    else {                                      \
        SET_MTS_FIELD(instance, field, value);  \
    }                                           \
} while (0);

#define GET_FIELD(is_bl, instance, field, ptr)  \
do {                                            \
    if (is_bl) {                                \
        GET_BL_FIELD(instance, field, ptr);     \
    }                                           \
    else {                                      \
        GET_MTS_FIELD(instance, field, ptr);    \
    }                                           \
} while (0);

#define COPY_FIELD(is_bl, from, to, field)      \
do {                                            \
    if (is_bl) {                                \
        COPY_BL_FIELD(from, to, field);         \
    }                                           \
    else {                                      \
        COPY_MTS_FIELD(from, to, field);        \
    }                                           \
} while (0);

static void
set_bl_data(build_image_context *context,
		u_int32_t instance,
		u_int32_t start_blk,
		u_int32_t start_page,
		u_int32_t length)
{
	assert(context);

	SET_BL_FIELD(instance, version, context->version);
	SET_BL_FIELD(instance, start_blk, start_blk);
	SET_BL_FIELD(instance, start_page, start_page);
	SET_BL_FIELD(instance, length, length);
	SET_BL_FIELD(instance, load_addr, context->newbl_load_addr);
	SET_BL_FIELD(instance, entry_point, context->newbl_entry_point);
	SET_BL_FIELD(instance, attribute, context->newbl_attr);
}

static void
set_mts_data(build_image_context *context,
		u_int32_t instance,
		u_int32_t start_blk,
		u_int32_t start_page,
		u_int32_t length)
{
	assert(context);

	SET_MTS_FIELD(instance, version, context->version);
	SET_MTS_FIELD(instance, start_blk, start_blk);
	SET_MTS_FIELD(instance, start_page, start_page);
	SET_MTS_FIELD(instance, length, length);
	SET_MTS_FIELD(instance, load_addr, context->mts_load_addr);
	SET_MTS_FIELD(instance, entry_point, context->mts_entry_point);
	SET_MTS_FIELD(instance, attribute, context->mts_attr);
}

#define SET_DATA(is_bl, context, instance, start_blk, start_page, length) \
do {                                                                      \
    if (is_bl)                                                            \
        set_bl_data(context, instance, start_blk, start_page, length);    \
    else                                                                  \
        set_mts_data(context, instance, start_blk, start_page, length);   \
} while (0);

/*
 * Load the image then update it with the information from config file.
 * In the interest of expediency, all image's allocated from bottom to top
 * start at page 0 of a block, and all image's allocated from top to bottom
 * end at the end of a block.
 *
 * @param context      The main context pointer
 * @param image_type   The image type. Can be file_type_bl or file_type_mts
 *                     only right now
 * @return 0 for success
 */
static int
write_image(build_image_context *context, file_type image_type)
{
	u_int32_t i, j;
	u_int32_t image_instance;
	u_int32_t image_move_count = 0;
	u_int32_t image_move_remaining;
	u_int32_t current_blk;
	u_int32_t current_page;
	u_int32_t pages_in_image;
	u_int32_t image_used;
	u_int8_t  *image_storage; /* Holds the image after reading */
	u_int8_t  *buffer;	/* Holds the image for writing */
	u_int8_t  *src;	/* Scans through the image during writing */
	u_int32_t  image_actual_size; /* In bytes */
	u_int32_t  pagesremaining;
	u_int32_t  virtual_blk;
	u_int32_t  pages_per_blk;
	u_int32_t  image_version;
	u_int8_t  *hash_buffer;
	u_int32_t  hash_size;
	u_int32_t  image_max;
	parse_token token;
	int err = 0, is_bl;

	assert(context);

	/* Only support bootloader and mts image right now */
	if (image_type == file_type_bl) {
		is_bl = 1;
	}
	else if (image_type == file_type_mts) {
		is_bl = 0;
	}
	else {
		printf("Not supported image type!\n");
		return -EINVAL;
	}

	pages_per_blk = 1 << (context->block_size_log2
			- context->page_size_log2);

	g_soc_config->get_value(token_hash_size,
			&hash_size, context->bct);
	token = is_bl ? token_bootloaders_max : token_mts_max;
	g_soc_config->get_value(token, &image_max, context->bct);

	hash_buffer = calloc(1, hash_size);
	if (hash_buffer == NULL)
		return -ENOMEM;

	if (enable_debug) {
		printf("writing %s\n", is_bl ? "bootloader" : "mts image");
		printf("  redundancy = %d\n", context->redundancy);
	}

	/* Make room for the image in the BCT. */

	/* Determine how many to move.
	 * Note that this code will count Mts[0] only if there is already
	 * a mts in the device.
	 */
	GET_FIELD(is_bl, 0, version, &image_version);
	token = is_bl ? token_bootloader_used : token_mts_used;
	g_soc_config->get_value(token, &image_used, context->bct);
	for (image_instance = 0; image_instance < image_used; image_instance++) {
		u_int32_t tmp;
		GET_FIELD(is_bl, image_instance, version, &tmp);
		if (tmp == image_version)
			image_move_count++;
	}

	/* Adjust the move count, if needed, to avoid overflowing the mts table.
	 * This can happen due to too much redundancy.
	 */
	image_move_count = MIN(image_move_count, image_max - context->redundancy);

	/* Move the mts entries down. */
	image_move_remaining = image_move_count;
	while (image_move_remaining > 0) {
		u_int32_t  inst_from = image_move_remaining - 1;
		u_int32_t  inst_to   =
			image_move_remaining + context->redundancy - 1;

		COPY_FIELD(is_bl, inst_from, inst_to, version);
		COPY_FIELD(is_bl, inst_from, inst_to, start_blk);
		COPY_FIELD(is_bl, inst_from, inst_to, start_page);
		COPY_FIELD(is_bl, inst_from, inst_to, length);
		COPY_FIELD(is_bl, inst_from, inst_to, load_addr);
		COPY_FIELD(is_bl, inst_from, inst_to, entry_point);
		COPY_FIELD(is_bl, inst_from, inst_to, attribute);

		if (is_bl) {
			g_soc_config->getbl_param(inst_from,
				token_bl_crypto_hash,
				(u_int32_t*)hash_buffer,
				context->bct);
			g_soc_config->setbl_param(inst_to,
				token_bl_crypto_hash,
				(u_int32_t*)hash_buffer,
				context->bct);
		}

		image_move_remaining--;
	}

	/* Read the image into memory. */
	if (read_from_image(
		is_bl ? context->newbl_filename : context->mts_filename,
		0,
		is_bl ? MAX_BOOTLOADER_SIZE : MAX_MTS_SIZE,
		&image_storage,
		&image_actual_size,
		image_type) == 1) {
		printf("Error reading image %s.\n",
			is_bl ? context->newbl_filename : context->mts_filename);
		exit(1);
	}

	pages_in_image = iceil_log2(image_actual_size, context->page_size_log2);

	current_blk = context->next_bct_blk;
	current_page  = 0;
	for (image_instance = 0; image_instance < context->redundancy;
					image_instance++) {

		pagesremaining = pages_in_image;
		/* Advance to the next block if needed. */
		if (current_page > 0) {
			current_blk++;
			current_page = 0;
		}

		virtual_blk = 0;

		while (pagesremaining > 0) {
			/* Update the bad block table with relative
			  * bad blocks.
			  */
			if (virtual_blk == 0) {
				SET_DATA(is_bl,
					context,
					image_instance,
					current_blk,
					current_page,
					image_actual_size);
			}

			if (pagesremaining > pages_per_blk) {
				current_blk++;
				virtual_blk++;
				pagesremaining -= pages_per_blk;
			} else {
				current_page = pagesremaining;
				pagesremaining = 0;
			}
		}
	}

	/* Scan forwards to write each copy. */
	for (image_instance = 0; image_instance < context->redundancy;
					image_instance++) {

		/* Create a local copy of the BCT data */
		buffer = malloc(pages_in_image * context->page_size);
		if (buffer == NULL)
			return -ENOMEM;

		memset(buffer, 0, pages_in_image * context->page_size);
		memcpy(buffer, image_storage, image_actual_size);

		insert_padding(buffer, image_actual_size);

		pagesremaining = pages_in_image;

		if (is_bl) {
			GET_BL_FIELD(image_instance, start_blk, &current_blk);
			GET_BL_FIELD(image_instance, start_page,  &current_page);

			/* Encrypt and compute hash */
			sign_data_block(buffer,
					image_actual_size,
					hash_buffer);
			g_soc_config->setbl_param(image_instance,
					token_bl_crypto_hash,
					(u_int32_t*)hash_buffer,
					context->bct);
		}

		GET_FIELD(is_bl, image_instance, start_blk, &current_blk);
		GET_FIELD(is_bl, image_instance, start_page,  &current_page);

		/* Write the BCT data to the storage device,
		 * picking up ECC errors
		 */
		src = buffer;

		/* Write pages as we go. */
		virtual_blk = 0;
		while (pagesremaining) {
			if (current_page == 0) {
				/* Erase the block before writing into it. */
				erase_block(context, current_blk);
			}

			err = write_page(context,
				current_blk, current_page, src);
			if (err != 0)
				goto fail;
			pagesremaining--;
			src += context->page_size;
			current_page++;
			if (current_page >= pages_per_blk) {
				current_page = 0;
				current_blk++;
				virtual_blk++;
			}
			context->last_blk = current_blk;
		}
		context->next_bct_blk = context->last_blk + 1;
		free(buffer);
	}

	image_used = context->redundancy + image_move_count;
	token = is_bl ? token_bootloader_used : token_mts_used;
	g_soc_config->set_value(token, &image_used, context->bct);

	if (enable_debug) {
		for (i = 0; i < image_max; i++) {
			u_int32_t version;
			u_int32_t start_blk;
			u_int32_t start_page;
			u_int32_t length;
			u_int32_t load_addr;
			u_int32_t entry_point;

			GET_FIELD(is_bl, i, version,     &version);
			GET_FIELD(is_bl, i, start_blk,  &start_blk);
			GET_FIELD(is_bl, i, start_page,   &start_page);
			GET_FIELD(is_bl, i, length,      &length);
			GET_FIELD(is_bl, i, load_addr, &load_addr);
			GET_FIELD(is_bl, i, entry_point,  &entry_point);

			printf("%s%s[%d]: %d %04d %04d %04d 0x%08x 0x%08x\n",
				i < image_used ? "  " : "**",
				is_bl ? "BL" : "MTS",
				i,
				version,
				start_blk,
				start_page,
				length,
				load_addr,
				entry_point);
			if (is_bl) {
				g_soc_config->getbl_param(i,
					token_bl_crypto_hash,
					(u_int32_t*)hash_buffer,
					context->bct);
				for (j = 0; j < hash_size / 4; j++) {
					printf("%08x",
						*((u_int32_t*)(hash_buffer + 4*j)));
				}
				printf("\n");
			}
		}
	}
	free(image_storage);
	free(hash_buffer);
	return 0;

fail:
	/* Cleanup. */
	free(buffer);
	free(image_storage);
	free(hash_buffer);
	printf("Write image failed, error: %d.\n", err);
	return err;
}

void
update_context(struct build_image_context_rec *context)
{
	g_soc_config->get_value(token_partition_size,
			&context->partition_size,
			context->bct);
	g_soc_config->get_value(token_page_size_log2,
			&context->page_size_log2,
			context->bct);
	g_soc_config->get_value(token_block_size_log2,
			&context->block_size_log2,
			context->bct);
	g_soc_config->get_value(token_odm_data,
			&context->odm_data,
			context->bct);

	context->page_size = 1 << context->page_size_log2;
	context->block_size = 1 << context->block_size_log2;
	context->pages_per_blk = 1 << (context->block_size_log2 -
                                           context->page_size_log2);
}

/*
 * Allocate and initialize the memory for bct data.
 *
 * @param context		The main context pointer
 * @return 0 for success
 */
int
init_bct(struct build_image_context_rec *context)
{
	/* Allocate space for the bct.	 */
	context->bct = malloc(context->bct_size);

	if (context->bct == NULL)
		return -ENOMEM;

	memset(context->bct, 0, context->bct_size);
	context->bct_init = 1;

	return 0;
}

/*
 * Read the bct data from given file to allocated memory.
 * Assign the global parse interface to corresponding hardware interface
 *   according to the boot data version in bct file.
 *
 * @param context		The main context pointer
 * @return 0 for success
 */
int
read_bct_file(struct build_image_context_rec *context)
{
	u_int8_t  *bct_storage; /* Holds the Bl after reading */
	u_int32_t  bct_actual_size; /* In bytes */
	file_type bct_filetype = file_type_bct;
	int err = 0;

	if (read_from_image(context->bct_filename,
			0,
			NVBOOT_CONFIG_TABLE_SIZE_MAX,
			&bct_storage,
			&bct_actual_size,
			bct_filetype) == 1) {
		printf("Error reading bct file %s.\n", context->bct_filename);
		exit(1);
	}

	context->bct_size = bct_actual_size;
	if (context->bct_init != 1)
		err = init_bct(context);
	if (err != 0) {
		printf("Context initialization failed.  Aborting.\n");
		return err;
	}
	memcpy(context->bct, bct_storage, context->bct_size);
	free(bct_storage);

	if (!data_is_valid_bct(context))
		return ENODATA;

	return err;
}

/*
 * Update the next_bct_blk and make it point to the next
 * new blank block according to bct_copy given.
 *
 * @param context		The main context pointer
 */
static void
find_new_bct_blk(build_image_context *context)
{
	u_int32_t max_bct_search_blks;

	assert(context);

	g_soc_config->get_value(token_max_bct_search_blks,
			&max_bct_search_blks, context->bct);

	if (context->next_bct_blk > max_bct_search_blks) {
		printf("Error: Unable to locate a journal block.\n");
		exit(1);
	}
	context->next_bct_blk++;
}

/*
 * Initialization before bct and bootloader update.
 * Find the new blank block and erase it.
 *
 * @param context		The main context pointer
 * @return 0 for success
 */
int
begin_update(build_image_context *context)
{
	u_int32_t hash_size;
	u_int32_t reserved_size;
	u_int32_t reserved_offset;
	int err = 0;
	int i;

	assert(context);

	/* Ensure that the BCT block & page data is current. */
	if (enable_debug) {
		u_int32_t block_size_log2;
		u_int32_t page_size_log2;

		g_soc_config->get_value(token_block_size_log2,
			&block_size_log2, context->bct);
		g_soc_config->get_value(token_page_size_log2,
			&page_size_log2, context->bct);

		printf("begin_update(): bct data: b=%d p=%d\n",
			block_size_log2, page_size_log2);
	}

	g_soc_config->set_value(token_boot_data_version,
			&(context->boot_data_version), context->bct);
	g_soc_config->get_value(token_hash_size,
			&hash_size, context->bct);
	g_soc_config->get_value(token_reserved_size,
			&reserved_size, context->bct);
	g_soc_config->get_value(token_reserved_offset,
			&reserved_offset, context->bct);
	/* Set the odm data */
	g_soc_config->set_value(token_odm_data,
			&(context->odm_data), context->bct);

	/* Initialize the bad block table field. */
	g_soc_config->init_bad_block_table(context);
	/* Fill the reserved data w/the padding pattern. */
	write_padding(context->bct + reserved_offset, reserved_size);

	/* Create the pad before the BCT starting at block 1 */
	for (i = 0; i < context->pre_bct_pad_blocks; i++) {
		find_new_bct_blk(context);
		err = erase_block(context, i);
		if (err != 0)
			goto fail;
	}
	/* Find the next bct block starting at block pre_bct_pad_blocks. */
	for (i = 0; i < context->bct_copy; i++) {
		find_new_bct_blk(context);
		err = erase_block(context, i + context->pre_bct_pad_blocks);
		if (err != 0)
			goto fail;
	}
	return 0;
fail:
	printf("Erase block failed, error: %d.\n", err);
	return err;
}

/*
 * Write the BCT(s) starting at slot 0 of block context->pre_bct_pad_blocks.
 *
 * @param context		The main context pointer
 * @return 0 for success
 */
static int
finish_update(build_image_context *context)
{
	int err = 0;
	int i;

	for (i = 0; i < context->bct_copy; i++) {
		err = write_bct(context, i + context->pre_bct_pad_blocks, 0);
		if (err != 0)
			goto fail;
	}

	return 0;
fail:
	printf("Write BCT failed, error: %d.\n", err);
	return err;
}

/*
 * For now, ignore end state.
 */
int
update_bl(build_image_context *context)
{
	if (enable_debug)
		printf("**update_bl()\n");

	if (begin_update(context) != 0)
		return 1;
	if (write_image(context, file_type_bl) != 0)
		return 1;
	if (finish_update(context) != 0)
		return 1;
	return 0;
}

int
update_mts_image(build_image_context *context)
{
	if (enable_debug)
		printf("**update_mts()\n");

	if (begin_update(context) != 0)
		return 1;
	if (write_image(context, file_type_mts) != 0)
		return 1;
	if (finish_update(context) != 0)
		return 1;
	return 0;
}

/*
 * To write the current image:
 *   Loop over all blocks in the block data list:
 *     Write out the data of real blocks.
 *     Write out 0's for unused blocks.
 *     Stop on the last used page of the last used block.
 *
 * @param context		The main context pointer
 * @return 0 for success
 */
int
write_block_raw(build_image_context *context)
{
	block_data *block_list;
	block_data *block;
	u_int32_t blk_number;
	u_int32_t last_blk;
	u_int32_t pages_to_write;
	u_int8_t *data;
	u_int8_t *empty_blk = NULL;

	assert(context != NULL);
	assert(context->memory);

	block_list = context->memory;

	/* Compute the end of the image. */
	block_list = context->memory;
	while (block_list->next)
		block_list = block_list->next;

	last_blk = block_list->blk_number;

	/* Loop over all the storage from block 0, page 0 to
	 *last_blk, Lastpage
	 */
	for (blk_number = 0; blk_number <= last_blk; blk_number++) {
		block = find_block(blk_number, context->memory);
		if (block)	{
			pages_to_write = (blk_number == last_blk) ?
			block->pages_used :
			context->pages_per_blk;
			data = block->data;
		} else {
			/* Allocate empty_blk if needed. */
			if (empty_blk == NULL) {
				empty_blk = malloc(context->block_size);
				if (!empty_blk)
					return -ENOMEM;
				memset(empty_blk, 0, context->block_size);
			}
			pages_to_write = context->pages_per_blk;
			data = empty_blk;
		}
		/* Write the data */
		{
			size_t bytes = pages_to_write * context->page_size;

			if (fwrite(data, 1, bytes, context->raw_file) != bytes) {
				if (empty_blk) free(empty_blk);
				return -1;
			}
		}
	}

	if (empty_blk) free(empty_blk);
	return 0;
}

int write_data_block(FILE *fp, u_int32_t offset, u_int32_t size, u_int8_t *buffer)
{
	if (fseek(fp, offset, 0))
		return -1;

	return fwrite(buffer, 1, size, fp);
}

int data_is_valid_bct(build_image_context *context)
{
	/* get proper soc_config pointer by polling each supported chip */
	if (if_bct_is_t20_get_soc_config(context, &g_soc_config))
		return 1;
	if (if_bct_is_t30_get_soc_config(context, &g_soc_config))
		return 1;
	if (if_bct_is_t114_get_soc_config(context, &g_soc_config))
		return 1;
	if (if_bct_is_t124_get_soc_config(context, &g_soc_config))
		return 1;
	if (if_bct_is_t132_get_soc_config(context, &g_soc_config))
		return 1;

	return 0;
}

int get_bct_size_from_image(build_image_context *context)
{
	u_int8_t buffer[NVBOOT_CONFIG_TABLE_SIZE_MAX];
	u_int32_t bct_size = 0;
	FILE *fp;

	fp = fopen(context->input_image_filename, "r");
	if (!fp)
		return ENODATA;

	if (!fread(buffer, 1, NVBOOT_CONFIG_TABLE_SIZE_MAX, fp)) {
		fclose(fp);
		return ENODATA;
	}

	context->bct = buffer;
	if (data_is_valid_bct(context) && g_soc_config->get_bct_size)
		bct_size = g_soc_config->get_bct_size();

	fclose(fp);
	context->bct = 0;
	return bct_size;
}
