/*
 * Copyright 2021 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <platform_def.h>
#include <common/debug.h>
#ifndef NXP_COINED_BB
#include <flash_info.h>
#include <fspi.h>
#include <fspi_api.h>
#endif
#include <lib/mmio.h>
#ifdef NXP_COINED_BB
#include <snvs.h>
#else
#include <xspi_error_codes.h>
#endif

#include <plat_nv_storage.h>

/*This structure will be a static structure and
 * will be populated as first step of BL2 booting-up.
 * fspi_strorage.c . To be located in the fspi driver folder.
 */

static nv_app_data_t nv_app_data;

int read_nv_app_data(void)
{
	int ret = 0;

#ifdef NXP_COINED_BB
	uint8_t *nv_app_data_array = (uint8_t *) &nv_app_data;
	uint8_t offset = 0U;

	ret = snvs_read_app_data();
	do {
		nv_app_data_array[offset] = snvs_read_app_data_bit(offset);
		offset++;

	} while (offset < APP_DATA_MAX_OFFSET);
	snvs_clear_app_data();
#else
	uintptr_t nv_base_addr = NV_STORAGE_BASE_ADDR;

	ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR);

	if (ret != XSPI_SUCCESS) {
		ERROR("Failed to initialized driver flexspi-nor.\n");
		ERROR("exiting warm-reset request.\n");
		return -ENODEV;
	}

	xspi_read(nv_base_addr,
		  (uint32_t *)&nv_app_data, sizeof(nv_app_data_t));
	xspi_sector_erase((uint32_t) nv_base_addr,
				F_SECTOR_ERASE_SZ);
#endif
	return ret;
}

int wr_nv_app_data(int data_offset,
			uint8_t *data,
			int data_size)
{
	int ret = 0;
#ifdef NXP_COINED_BB
#if !TRUSTED_BOARD_BOOT
	snvs_disable_zeroize_lp_gpr();
#endif
	/* In case LP SecMon General purpose register,
	 * only 1 bit flags can be saved.
	 */
	if ((data_size > 1) || (*data != DEFAULT_SET_VALUE)) {
		ERROR("Only binary value is allowed to be written.\n");
		ERROR("Use flash instead of SNVS GPR as NV location.\n");
		return -ENODEV;
	}
	snvs_write_app_data_bit(data_offset);
#else
	uint8_t read_val[sizeof(nv_app_data_t)];
	uint8_t ready_to_write_val[sizeof(nv_app_data_t)];
	uintptr_t nv_base_addr = NV_STORAGE_BASE_ADDR;

	assert((nv_base_addr + data_offset + data_size) > (nv_base_addr + F_SECTOR_ERASE_SZ));

	ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR);

	if (ret != XSPI_SUCCESS) {
		ERROR("Failed to initialized driver flexspi-nor.\n");
		ERROR("exiting warm-reset request.\n");
		return -ENODEV;
	}

	ret = xspi_read(nv_base_addr + data_offset, (uint32_t *)read_val, data_size);

	memset(ready_to_write_val, READY_TO_WRITE_VALUE, ARRAY_SIZE(ready_to_write_val));

	if (memcmp(read_val, ready_to_write_val, data_size) == 0) {
		xspi_write(nv_base_addr + data_offset, data, data_size);
	}
#endif

	return ret;
}

const nv_app_data_t *get_nv_data(void)
{
	return (const nv_app_data_t *) &nv_app_data;
}
