// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2024, Linaro Limited
 */

#include <fwu.h>
#include <fwu_mdata.h>
#include <log.h>

#include <linux/types.h>

#define FWU_MDATA_VERSION	0x2U

static inline struct fwu_fw_store_desc *fwu_get_fw_desc(struct fwu_mdata *mdata)
{
	return (struct fwu_fw_store_desc *)((u8 *)mdata + sizeof(*mdata));
}

static uint32_t fwu_check_trial_state(struct fwu_mdata *mdata, uint32_t bank)
{
	return mdata->bank_state[bank] == FWU_BANK_VALID ? 1 : 0;
}

static void fwu_data_init(void)
{
	int i;
	size_t image_info_size;
	void *dst_img_info, *src_img_info;
	struct fwu_data *data = fwu_get_data();
	struct fwu_mdata *mdata = data->fwu_mdata;

	data->crc32 = mdata->crc32;
	data->version = mdata->version;
	data->active_index = mdata->active_index;
	data->previous_active_index = mdata->previous_active_index;
	data->metadata_size = mdata->metadata_size;
	fwu_plat_get_bootidx(&data->boot_index);
	data->trial_state = fwu_check_trial_state(mdata, data->boot_index);

	data->num_banks = fwu_get_fw_desc(mdata)->num_banks;
	data->num_images = fwu_get_fw_desc(mdata)->num_images;

	for (i = 0; i < 4; i++) {
		data->bank_state[i] = mdata->bank_state[i];
	}

	image_info_size = sizeof(data->fwu_images);
	src_img_info = &fwu_get_fw_desc(mdata)->img_entry[0];
	dst_img_info = &data->fwu_images[0];

	memcpy(dst_img_info, src_img_info, image_info_size);
}

static int fwu_mdata_sanity_checks(void)
{
	uint8_t num_banks;
	uint16_t num_images;
	struct fwu_data *data = fwu_get_data();
	struct fwu_mdata *mdata = data->fwu_mdata;

	if (mdata->version != FWU_MDATA_VERSION) {
		log_err("FWU metadata version %u. Expected value of %u\n",
			mdata->version, FWU_MDATA_VERSION);
		return -EINVAL;
	}

	if (!mdata->desc_offset) {
		log_err("No image information provided with the Metadata. ");
		log_err("Image information expected in the metadata\n");
		return -EINVAL;
	}

	if (mdata->desc_offset != 0x20) {
		log_err("Descriptor Offset(0x%x) in the FWU Metadata not equal to 0x20\n",
			mdata->desc_offset);
		return -EINVAL;
	}

	num_banks = fwu_get_fw_desc(mdata)->num_banks;
	num_images = fwu_get_fw_desc(mdata)->num_images;

	if (num_banks != CONFIG_FWU_NUM_BANKS) {
		log_err("Number of Banks(%u) in FWU Metadata different from the configured value(%d)",
			num_banks, CONFIG_FWU_NUM_BANKS);
		return -EINVAL;
	}

	if (num_images != CONFIG_FWU_NUM_IMAGES_PER_BANK) {
		log_err("Number of Images(%u) in FWU Metadata different from the configured value(%d)",
			num_images, CONFIG_FWU_NUM_IMAGES_PER_BANK);
		return -EINVAL;
	}

	return 0;
}

static int fwu_bank_state_update(bool trial_state, uint32_t bank)
{
	int ret;
	struct fwu_data *data = fwu_get_data();
	struct fwu_mdata *mdata = data->fwu_mdata;

	mdata->bank_state[bank] = data->bank_state[bank] = trial_state ?
		FWU_BANK_VALID : FWU_BANK_ACCEPTED;

	ret = fwu_sync_mdata(mdata, BOTH_PARTS);
	if (ret)
		log_err("Unable to set bank_state for bank %u\n", bank);
	else
		data->trial_state = trial_state;

	return ret;
}

static int fwu_trial_state_start(uint update_index)
{
	int ret;

	ret = fwu_trial_state_ctr_start();
	if (ret)
		return ret;

	ret = fwu_bank_state_update(1, update_index);
	if (ret)
		return ret;

	return 0;
}

/**
 * fwu_populate_mdata_image_info() - Populate the image information
 * of the metadata
 * @data: Version agnostic FWU metadata information
 *
 * Populate the image information in the FWU metadata by copying it
 * from the version agnostic structure. This is done before the
 * metadata gets written to the storage media.
 *
 * Return: None
 */
void fwu_populate_mdata_image_info(struct fwu_data *data)
{
	size_t image_info_size;
	struct fwu_mdata *mdata = data->fwu_mdata;
	void *dst_img_info, *src_img_info;

	image_info_size = sizeof(data->fwu_images);
	dst_img_info = &fwu_get_fw_desc(mdata)->img_entry[0];
	src_img_info = &data->fwu_images[0];

	memcpy(dst_img_info, src_img_info, image_info_size);
}

/**
 * fwu_state_machine_updates() - Update FWU state of the platform
 * @trial_state: Is platform transitioning into Trial State
 * @update_index: Bank number to which images have been updated
 *
 * On successful completion of updates, transition the platform to
 * either Trial State or Regular State.
 *
 * To transition the platform to Trial State, start the
 * TrialStateCtr counter, followed by setting the value of bank_state
 * field of the metadata to Valid state(applicable only in version 2
 * of metadata).
 *
 * In case, the platform is to transition directly to Regular State,
 * update the bank_state field of the metadata to Accepted
 * state(applicable only in version 2 of metadata).
 *
 * Return: 0 if OK, -ve on error
 */
int fwu_state_machine_updates(bool trial_state, uint32_t update_index)
{
	return trial_state ? fwu_trial_state_start(update_index) :
		fwu_bank_state_update(0, update_index);
}

/**
 * fwu_get_mdata_size() - Get the FWU metadata size
 * @mdata_size: Size of the metadata structure
 *
 * Get the size of the FWU metadata from the structure. This is later used
 * to allocate memory for the structure.
 *
 * Return: 0 if OK, -ve on error
 */
int fwu_get_mdata_size(uint32_t *mdata_size)
{
	int ret = 0;
	struct fwu_mdata mdata = { 0 };
	struct fwu_data *data = fwu_get_data();
	struct udevice *fwu_dev = fwu_get_dev();

	if (data->metadata_size) {
		*mdata_size = data->metadata_size;
		return 0;
	}

	ret = fwu_read_mdata(fwu_dev, &mdata, 1,
			     sizeof(struct fwu_mdata));
	if (ret) {
		log_err("FWU metadata read failed\n");
		return ret;
	}

	*mdata_size = mdata.metadata_size;
	if (!*mdata_size)
		return -EINVAL;

	return 0;
}

/**
 * fwu_init() - FWU specific initialisations
 *
 * Carry out some FWU specific initialisations including allocation
 * of memory for the metadata copies, and reading the FWU metadata
 * copies into the allocated memory. The metadata fields are then
 * copied into a version agnostic structure.
 *
 * Return: 0 if OK, -ve on error
 */
int fwu_init(void)
{
	int ret;
	struct fwu_mdata mdata = { 0 };
	struct udevice *fwu_dev = fwu_get_dev();

	/*
	 * First we read only the top level structure
	 * and get the size of the complete structure.
	 */
	ret = fwu_read_mdata(fwu_dev, &mdata, 1,
			     sizeof(struct fwu_mdata));
	if (ret) {
		log_err("FWU metadata read failed\n");
		return ret;
	}

	ret = fwu_mdata_copies_allocate(mdata.metadata_size);
	if (ret)
		return ret;

	/*
	 * Now read the entire structure, both copies, and
	 * validate that the copies.
	 */
	ret = fwu_get_mdata(NULL);
	if (ret)
		return ret;

	ret = fwu_mdata_sanity_checks();
	if (ret)
		return ret;

	fwu_data_init();

	return 0;
}
