// SPDX-License-Identifier: BSD-2-Clause
/**
 * Copyright 2017-2019 NXP
 *
 * Brief   CAAM Random Number Generator manager.
 *         Implementation of RNG functions.
 */
#include <atomic.h>
#include <caam_common.h>
#include <caam_hal_rng.h>
#include <caam_jr.h>
#include <caam_rng.h>
#include <caam_utils_mem.h>
#include <crypto/crypto.h>
#include <kernel/panic.h>
#include <mm/core_memprot.h>
#include <rng_support.h>
#include <tee/cache.h>
#include <string.h>

/*
 * Define the RNG Data buffer size and number
 */
#define RNG_DATABUF_SIZE	1024
#define RNG_DATABUF_NB		2

/*
 * Define the number of descriptor entry to generate random data
 */
#define RNG_GEN_DESC_ENTRIES	5

/*
 * Status of the data generation
 */
enum rngsta {
	DATA_EMPTY = 0, /* Data bufer empty */
	DATA_ONGOING,   /* Data generation on going */
	DATA_FAILURE,   /* Error during data generation */
	DATA_OK,        /* Data generation complete with success */
};

/*
 * RNG Data generation
 */
struct rngdata {
	struct caam_jobctx jobctx; /* Job Ring Context */
	uint32_t job_id;           /* Job Id enqueued */

	uint8_t *data;           /* Random Data buffer */
	size_t size;             /* Size in bytes of the Random data buffer */
	size_t rdindex;          /* Current data index in the buffer */

	enum rngsta status;      /* Status of the data generation */
};

/*
 * RNG module private data
 */
struct rng_privdata {
	vaddr_t baseaddr;                       /* RNG base address */
	bool instantiated;                      /* RNG instantiated */
	struct rngdata databuf[RNG_DATABUF_NB]; /* RNG Data generation */
	uint8_t dataidx;                        /* Current RNG Data buffer */
};

static struct rng_privdata *rng_privdata;

/* Allocate and initialize module private data */
static enum caam_status do_allocate(void)
{
	struct rngdata *rngdata = NULL;
	unsigned int idx = 0;

	/* Allocate the Module resources */
	rng_privdata = caam_calloc(sizeof(*rng_privdata));
	if (!rng_privdata) {
		RNG_TRACE("Private Data allocation error");
		return CAAM_OUT_MEMORY;
	}

	rng_privdata->instantiated = false;

	/* Allocates the RNG Data Buffers */
	for (idx = 0; idx < RNG_DATABUF_NB; idx++) {
		rngdata = &rng_privdata->databuf[idx];
		rngdata->data = caam_calloc_align(RNG_DATABUF_SIZE);
		if (!rngdata->data)
			return CAAM_OUT_MEMORY;

		rngdata->size = RNG_DATABUF_SIZE;
		rngdata->jobctx.desc = caam_calloc_desc(RNG_GEN_DESC_ENTRIES);
		if (!rngdata->jobctx.desc)
			return CAAM_OUT_MEMORY;
	}

	return CAAM_NO_ERROR;
}

/* Free module private data */
static void do_free(void)
{
	struct rngdata *rng = NULL;
	unsigned int idx = 0;

	if (rng_privdata) {
		for (idx = 0; idx < RNG_DATABUF_NB; idx++) {
			rng = &rng_privdata->databuf[idx];

			/* Check if there is a Job ongoing to cancel it */
			if (atomic_load_u32(&rng->status) == DATA_ONGOING)
				caam_jr_cancel(rng->job_id);

			caam_free_desc(&rng->jobctx.desc);
			caam_free(rng->data);
			rng->data = NULL;
		}

		caam_free(rng_privdata);
		rng_privdata = NULL;
	}
}

#ifdef CFG_NXP_CAAM_RNG_DRV
/*
 * RNG data generation job ring callback completion
 *
 * @jobctx      RNG data JR Job Context
 */
static void rng_data_done(struct caam_jobctx *jobctx)
{
	struct rngdata *rng = jobctx->context;

	RNG_TRACE("RNG Data id 0x%08" PRIx32 " done with status 0x%" PRIx32,
		  rng->job_id, jobctx->status);

	if (JRSTA_SRC_GET(jobctx->status) == JRSTA_SRC(NONE)) {
		atomic_store_u32(&rng->status, DATA_OK);

		/* Invalidate the data buffer to ensure software gets it */
		cache_operation(TEE_CACHEINVALIDATE, rng->data, rng->size);
	} else {
		RNG_TRACE("RNG Data completion in error 0x%" PRIx32,
			  jobctx->status);
		atomic_store_u32(&rng->status, DATA_FAILURE);
	}

	rng->job_id = 0;
	rng->rdindex = 0;
}

/*
 * Prepares the data generation descriptors
 *
 * @rng       Reference to the RNG Data object
 */
static enum caam_status prepare_gen_desc(struct rngdata *rng)
{
	paddr_t paddr = 0;
	uint32_t *desc = NULL;

	/* Convert the buffer virtual address to physical address */
	paddr = virt_to_phys(rng->data);
	if (!paddr)
		return CAAM_FAILURE;

	desc = rng->jobctx.desc;

	caam_desc_init(desc);
	caam_desc_add_word(desc, DESC_HEADER(0));
	caam_desc_add_word(desc, RNG_GEN_DATA);
	caam_desc_add_word(desc, FIFO_ST(RNG_TO_MEM, rng->size));
	caam_desc_add_ptr(desc, paddr);

	RNG_DUMPDESC(desc);

	/* Prepare the job context */
	rng->jobctx.context = rng;
	rng->jobctx.callback = rng_data_done;
	return CAAM_NO_ERROR;
}

/*
 * Launches a RNG Data generation
 *
 * @rng      RNG Data context
 */
static enum caam_status do_rng_start(struct rngdata *rng)
{
	enum caam_status ret = CAAM_FAILURE;

	/* Ensure that data buffer is visible from the HW */
	cache_operation(TEE_CACHEFLUSH, rng->data, rng->size);

	rng->job_id = 0;
	atomic_store_u32(&rng->status, DATA_EMPTY);

	ret = caam_jr_enqueue(&rng->jobctx, &rng->job_id);

	if (ret == CAAM_PENDING) {
		atomic_store_u32(&rng->status, DATA_ONGOING);
		ret = CAAM_NO_ERROR;
	} else {
		RNG_TRACE("RNG Job Ring Error 0x%08x", ret);
		atomic_store_u32(&rng->status, DATA_FAILURE);
		ret = CAAM_FAILURE;
	}

	return ret;
}

/* Checks if there are random data available */
static enum caam_status do_check_data(void)
{
	enum caam_status ret = CAAM_FAILURE;
	struct rngdata *rng = NULL;
	uint32_t wait_jobs = 0;
	unsigned int idx = 0;
	unsigned int loop = 4;

	/* Check if there is a RNG Job to be run */
	for (idx = 0; idx < RNG_DATABUF_NB; idx++) {
		rng = &rng_privdata->databuf[idx];
		if (atomic_load_u32(&rng->status) == DATA_EMPTY) {
			RNG_TRACE("Start RNG #%" PRIu32 " data generation",
				  idx);
			ret = do_rng_start(rng);
			if (ret != CAAM_NO_ERROR)
				return CAAM_FAILURE;
		}
	}

	/* Check if the current data buffer contains data */
	rng = &rng_privdata->databuf[rng_privdata->dataidx];

	switch (atomic_load_u32(&rng->status)) {
	case DATA_OK:
		return CAAM_NO_ERROR;

	default:
		/* Wait until one of the data buffer completes */
		do {
			wait_jobs = 0;
			for (idx = 0; idx < RNG_DATABUF_NB; idx++) {
				rng = &rng_privdata->databuf[idx];
				wait_jobs |= rng->job_id;

				if (atomic_load_u32(&rng->status) == DATA_OK) {
					RNG_TRACE("RNG Data buffer #%" PRIu32
						  " ready",
						  idx);
					rng_privdata->dataidx = idx;
					return CAAM_NO_ERROR;
				}
			}

			if (!wait_jobs) {
				RNG_TRACE("There are no Data Buffers ongoing");
				return CAAM_FAILURE;
			}

			/* Need to wait until one of the jobs completes */
			(void)caam_jr_dequeue(wait_jobs, 100);
		} while (loop--);

		break;
	}

	return CAAM_FAILURE;
}

/*
 * Return the requested random data
 *
 * @buf  [out] data buffer
 * @len  number of bytes to returns
 */
static TEE_Result do_rng_read(uint8_t *buf, size_t len)
{
	struct rngdata *rng = NULL;
	size_t remlen = len;
	uint8_t *rngbuf = buf;

	if (!rng_privdata) {
		RNG_TRACE("RNG Driver not initialized");
		return TEE_ERROR_BAD_STATE;
	}

	if (!rng_privdata->instantiated) {
		RNG_TRACE("RNG Driver not initialized");
		return TEE_ERROR_BAD_STATE;
	}

	do {
		if (do_check_data() != CAAM_NO_ERROR) {
			RNG_TRACE("No Data available or Error");
			return TEE_ERROR_BAD_STATE;
		}

		rng = &rng_privdata->databuf[rng_privdata->dataidx];
		RNG_TRACE("Context #%" PRIu8
			  " contains %zu data asked %zu (%zu)",
			  rng_privdata->dataidx, rng->size - rng->rdindex,
			  remlen, len);

		/* Check that current context data are available */
		if ((rng->size - rng->rdindex) <= remlen) {
			/*
			 * There is no or just enough data available,
			 * copy all data
			 */
			RNG_TRACE("Copy all available data");
			memcpy(rngbuf, &rng->data[rng->rdindex],
			       rng->size - rng->rdindex);

			remlen -= rng->size - rng->rdindex;
			rngbuf += rng->size - rng->rdindex;
			/* Set the RNG data status as empty */
			atomic_store_u32(&rng->status, DATA_EMPTY);
		} else {
			/* There is enough data in the current context */
			RNG_TRACE("Copy %zu data", remlen);
			memcpy(rngbuf, &rng->data[rng->rdindex], remlen);
			rng->rdindex += remlen;
			remlen = 0;
		}
	} while (remlen);

	return TEE_SUCCESS;
}

/* Initialize the RNG module to generate data */
static enum caam_status caam_rng_init_data(void)
{
	enum caam_status retstatus = CAAM_FAILURE;
	struct rngdata *rng = NULL;
	unsigned int idx = 0;

	for (idx = 0; idx < RNG_DATABUF_NB; idx++) {
		rng = &rng_privdata->databuf[idx];
		retstatus = prepare_gen_desc(rng);

		if (retstatus != CAAM_NO_ERROR)
			break;
	}

	return retstatus;
}
#endif /* CFG_NXP_CAAM_RNG_DRV */

/*
 * Prepares the instantiation descriptor
 *
 * @nb_sh      Number of the State Handle
 * @sh_status  State Handles status
 * @desc       Reference to the descriptor
 * @desc       [out] Descriptor filled
 */
static void prepare_inst_desc(uint32_t nb_sh, uint32_t sh_status,
			      uint32_t *desc)
{
	bool key_loaded = false;
	unsigned int sh_idx = 0;
	unsigned int nb_max_sh = nb_sh;

	/* Read the SH and secure key status */
	key_loaded = caam_hal_rng_key_loaded(rng_privdata->baseaddr);
	RNG_TRACE("RNG SH Status 0x%08" PRIx32 " - Key Status %" PRId8,
		  sh_status, key_loaded);

	while (sh_status & BIT(sh_idx))
		sh_idx++;

	RNG_TRACE("Instantiation start at SH%" PRIu32 " (%" PRIu32 ")", sh_idx,
		  nb_max_sh);

	/* Don't set the descriptor header now */
	caam_desc_init(desc);
	caam_desc_add_word(desc, DESC_HEADER(0));
	/* First State Handle to instantiate */
	caam_desc_add_word(desc, RNG_SH_INST(sh_idx));

	/* Next State Handles */
	for (sh_idx++; sh_idx < nb_max_sh; sh_idx++) {
		if (!(sh_status & BIT(sh_idx))) {
			/*
			 * If there is more SH to instantiate, add a wait loop
			 * followed by a reset of the done status to execute
			 * next command
			 */
			caam_desc_add_word(desc,
					   JUMP_C1_LOCAL(ALL_COND_TRUE,
							 JMP_COND(NONE), 1));
			caam_desc_add_word(desc,
					   LD_NOCLASS_IMM(REG_CLEAR_WRITTEN,
							  sizeof(uint32_t)));
			caam_desc_add_word(desc, 0x1);
			caam_desc_add_word(desc, RNG_SH_INST(sh_idx));
		}
	}

	/* Load the Key if needed */
	if (!key_loaded) {
		/*
		 * Add a wait loop while previous operation not completed,
		 * followed by a register clear before executing next command
		 */
		caam_desc_add_word(desc, JUMP_C1_LOCAL(ALL_COND_TRUE,
						       JMP_COND(NONE), 1));
		caam_desc_add_word(desc, LD_NOCLASS_IMM(REG_CLEAR_WRITTEN,
							sizeof(uint32_t)));
		caam_desc_add_word(desc, 0x1);
		caam_desc_add_word(desc, RNG_GEN_SECKEYS);
	}

	RNG_DUMPDESC(desc);
}

enum caam_status caam_rng_instantiation(void)
{
	enum caam_status retstatus = CAAM_FAILURE;
	struct caam_jobctx jobctx = {};
	uint32_t *desc = NULL;
	uint32_t sh_status = 0;
	uint32_t nb_sh = 0;
	uint32_t sh_mask = 0;
	uint32_t inc_delay = 0;

	RNG_TRACE("RNG Instantation");

	/* Check if RNG is already instantiated */
	if (caam_hal_rng_instantiated(rng_privdata->baseaddr)) {
		RNG_TRACE("RNG already instantiated");
		retstatus = CAAM_NO_ERROR;
		goto end_inst;
	}

	/*
	 * RNG needs to be instantiated. Allocate and prepare the
	 * Job Descriptor
	 */

	/* Calculate the State Handles bit mask */
	nb_sh = caam_hal_rng_get_nb_sh(rng_privdata->baseaddr);
	sh_mask = GENMASK_32(nb_sh - 1, 0);

	/*
	 * The maximum size of the descriptor is:
	 *    |----------------------|
	 *    | Header               | = 1
	 *    |----------------------|
	 *    | First instantation   | = 1
	 *    |----------------------|-------------------------
	 *    | wait complete        | = 1
	 *    |----------------------|
	 *    | Clear done status    |       Repeat (nb_sh - 1)
	 *    |                      | = 2
	 *    |----------------------|
	 *    | next SH instantation | = 1
	 *    |----------------------|-------------------------
	 *    | wait complete        | = 1
	 *    |----------------------|
	 *    | Clear done status    | = 2
	 *    |                      |
	 *    |----------------------|
	 *    | Generate Secure Keys | = 1
	 *    |----------------------|
	 *    | Pad with a 0         | = 1
	 */
	desc = caam_calloc_desc(2 + (nb_sh - 1) * 4 + 4 + 1);
	if (!desc) {
		RNG_TRACE("Descriptor Allocation error");
		retstatus = CAAM_OUT_MEMORY;
		goto end_inst;
	}

	jobctx.desc = desc;

	do {
		/* Check if all State Handles are instantiated */
		sh_status = caam_hal_rng_get_sh_status(rng_privdata->baseaddr);
		if ((sh_status & sh_mask) == sh_mask) {
			RNG_TRACE("RNG All SH are instantiated (0x%08" PRIx32
				  ")",
				  sh_status);
			retstatus = CAAM_NO_ERROR;
			goto end_inst;
		}

		if (sh_status == 0) {
			retstatus = caam_hal_rng_kick(rng_privdata->baseaddr,
						      inc_delay);
			RNG_TRACE("RNG Kick (inc=%" PRIu32 ") ret 0x%08x",
				  inc_delay, retstatus);
			if (retstatus != CAAM_NO_ERROR) {
				retstatus = CAAM_FAILURE;
				goto end_inst;
			}
			inc_delay += 200;
		}

		prepare_inst_desc(nb_sh, sh_status, desc);

		retstatus = caam_jr_enqueue(&jobctx, NULL);
		RNG_TRACE("RNG Job returned 0x%08x", retstatus);

		if (retstatus != CAAM_NO_ERROR &&
		    retstatus != CAAM_JOB_STATUS)
			goto end_inst;

		if (retstatus == CAAM_JOB_STATUS) {
			RNG_TRACE("RNG Job status 0x%08" PRIx32, jobctx.status);
			if ((JRSTA_SRC_GET(jobctx.status) != JRSTA_SRC(CCB)) ||
			    (JRSTA_CCB_GET_ERR(jobctx.status) !=
			     (JRSTA_CCB_CHAID_RNG | JRSTA_CCB_ERRID_HW)))
				retstatus = CAAM_FAILURE;
			else
				retstatus = CAAM_NO_ERROR;
		}
	} while (retstatus == CAAM_NO_ERROR);

end_inst:
	if (retstatus == CAAM_NO_ERROR)
		rng_privdata->instantiated = true;

	caam_free_desc(&desc);

	RNG_TRACE("RNG Instantiation return 0x%08x", retstatus);

	return retstatus;
}

enum caam_status caam_rng_init(vaddr_t ctrl_addr)
{
	enum caam_status retstatus = CAAM_FAILURE;

	RNG_TRACE("Initialization");
	retstatus = do_allocate();
	if (retstatus == CAAM_NO_ERROR) {
		rng_privdata->baseaddr = ctrl_addr;
		retstatus = caam_rng_instantiation();
	}

#ifdef CFG_NXP_CAAM_RNG_DRV
	if (retstatus == CAAM_NO_ERROR)
		retstatus = caam_rng_init_data();
#endif

	if (retstatus != CAAM_NO_ERROR)
		do_free();

	return retstatus;
}

#ifdef CFG_NXP_CAAM_RNG_DRV
TEE_Result crypto_rng_read(void *buf, size_t blen)
{
	if (!buf)
		return TEE_ERROR_BAD_PARAMETERS;

	return do_rng_read(buf, blen);
}

uint8_t hw_get_random_byte(void)
{
	uint8_t data = 0;

	if (do_rng_read(&data, 1) != TEE_SUCCESS)
		panic();

	return data;
}
#endif
