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

#define LOG_CATEGORY UCLASS_RNG

#include <dm.h>
#include <linker_lists.h>
#include <log.h>
#include <rng.h>
#include <dm/device_compat.h>
#include <linux/arm-smccc.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/psci.h>

#define DRIVER_NAME	"smccc-trng"

/**
 * Arm SMCCC TRNG firmware interface specification:
 * https://developer.arm.com/documentation/den0098/latest/
 */
#define ARM_SMCCC_TRNG_VERSION		0x84000050
#define ARM_SMCCC_TRNG_FEATURES		0x84000051
#define ARM_SMCCC_TRNG_GET_UUID		0x84000052
#define ARM_SMCCC_TRNG_RND_32		0x84000053
#define ARM_SMCCC_TRNG_RND_64		0xC4000053

#define ARM_SMCCC_RET_TRNG_SUCCESS		((ulong)0)
#define ARM_SMCCC_RET_TRNG_NOT_SUPPORTED	((ulong)-1)
#define ARM_SMCCC_RET_TRNG_INVALID_PARAMETER	((ulong)-2)
#define ARM_SMCCC_RET_TRNG_NO_ENTROPY		((ulong)-3)

#define TRNG_MAJOR_MASK		GENMASK(30, 16)
#define TRNG_MAJOR_SHIFT	16
#define TRNG_MINOR_MASK		GENMASK(15, 0)
#define TRNG_MINOR_SHIFT	0

#define TRNG_MAX_RND_64		(192 / 8)
#define TRNG_MAX_RND_32		(96 / 8)

/**
 * struct smccc_trng_priv - Private data for SMCCC TRNG support
 *
 * @smc64 - True if TRNG_RND_64 is supported, false if TRNG_RND_32 is supported
 */
struct smccc_trng_priv {
	bool smc64;
};

/*
 * Copy random bytes from ulong SMCCC output register to target buffer
 * Defines 2 function flavors for whether ARM_SMCCC_TRNG_RND_32 or
 * ARM_SMCCC_TRNG_RND_64 was used to invoke the service.
 */
static size_t smc32_copy_sample(u8 **ptr, size_t size, ulong *rnd)
{
	size_t len = min(size, sizeof(u32));
	u32 sample = *rnd;

	memcpy(*ptr, &sample, len);
	*ptr += len;

	return size - len;
}

static size_t smc64_copy_sample(u8 **ptr, size_t size, ulong *rnd)
{
	size_t len = min(size, sizeof(u64));
	u64 sample = *rnd;

	memcpy(*ptr, &sample, len);
	*ptr += len;

	return size - len;
}

static int smccc_trng_read(struct udevice *dev, void *data, size_t len)
{
	struct psci_plat_data *smccc = dev_get_parent_plat(dev);
	struct smccc_trng_priv *priv = dev_get_priv(dev);
	struct arm_smccc_res res;
	u32 func_id;
	u8 *ptr = data;
	size_t rem = len;
	size_t max_sz;
	size_t (*copy_sample)(u8 **ptr, size_t size, ulong *rnd);

	if (priv->smc64) {
		copy_sample = smc64_copy_sample;
		func_id = ARM_SMCCC_TRNG_RND_64;
		max_sz = TRNG_MAX_RND_64;
	} else {
		copy_sample = smc32_copy_sample;
		func_id = ARM_SMCCC_TRNG_RND_32;
		max_sz = TRNG_MAX_RND_32;
	}

	while (rem) {
		size_t sz = min(rem, max_sz);

		smccc->invoke_fn(func_id, sz * 8, 0, 0, 0, 0, 0, 0, &res);

		switch (res.a0) {
		case ARM_SMCCC_RET_TRNG_SUCCESS:
			break;
		case ARM_SMCCC_RET_TRNG_NO_ENTROPY:
			continue;
		default:
			return -EIO;
		}

		rem -= sz;

		sz = copy_sample(&ptr, sz, &res.a3);
		if (sz)
			sz = copy_sample(&ptr, sz, &res.a2);
		if (sz)
			sz = copy_sample(&ptr, sz, &res.a1);
	}

	return 0;
}

static const struct dm_rng_ops smccc_trng_ops = {
	.read = smccc_trng_read,
};

static bool smccc_trng_is_supported(void (*invoke_fn)(unsigned long a0, unsigned long a1,
						      unsigned long a2, unsigned long a3,
						      unsigned long a4, unsigned long a5,
						      unsigned long a6, unsigned long a7,
						      struct arm_smccc_res *res))
{
	struct arm_smccc_res res;

	(*invoke_fn)(ARM_SMCCC_TRNG_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
	if (res.a0 & BIT(31))
		return false;

	/* Test 64bit interface and fallback to 32bit interface */
	invoke_fn(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND_64,
		  0, 0, 0, 0, 0, 0, &res);

	if (res.a0 == ARM_SMCCC_RET_TRNG_NOT_SUPPORTED)
		invoke_fn(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND_32,
			  0, 0, 0, 0, 0, 0, &res);

	return res.a0 == ARM_SMCCC_RET_TRNG_SUCCESS;
}

ARM_SMCCC_FEATURE_DRIVER(smccc_trng) = {
	.driver_name = DRIVER_NAME,
	.is_supported = smccc_trng_is_supported,
};

static int smccc_trng_probe(struct udevice *dev)
{
	struct psci_plat_data *smccc = dev_get_parent_plat(dev);
	struct smccc_trng_priv *priv = dev_get_priv(dev);
	struct arm_smccc_res res;

	if (!smccc || !(smccc_trng_is_supported(smccc->invoke_fn)))
		return -ENODEV;

	/* At least one of 64bit and 32bit interfaces is available */
	smccc->invoke_fn(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND_64,
			 0, 0, 0, 0, 0, 0, &res);
	priv->smc64 = (res.a0 == ARM_SMCCC_RET_TRNG_SUCCESS);

#ifdef DEBUG
	smccc->invoke_fn(ARM_SMCCC_TRNG_GET_UUID, 0, 0, 0, 0, 0, 0, 0, &res);
	if (res.a0 != ARM_SMCCC_RET_TRNG_NOT_SUPPORTED) {
		unsigned long uuid_a0 = res.a0;
		unsigned long uuid_a1 = res.a1;
		unsigned long uuid_a2 = res.a2;
		unsigned long uuid_a3 = res.a3;
		unsigned long major, minor;

		smccc->invoke_fn(ARM_SMCCC_TRNG_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
		major = (res.a0 & TRNG_MAJOR_MASK) >> TRNG_MAJOR_SHIFT;
		minor = (res.a0 & TRNG_MINOR_MASK) >> TRNG_MINOR_SHIFT;

		dev_dbg(dev, "Version %lu.%lu, UUID %08lx-%04lx-%04lx-%04lx-%04lx%08lx\n",
			major, minor, uuid_a0, uuid_a1 >> 16, uuid_a1 & GENMASK(16, 0),
			uuid_a2 >> 16, uuid_a2 & GENMASK(16, 0), uuid_a3);
	} else {
		dev_warn(dev, "Can't get TRNG UUID\n");
	}
#endif

	return 0;
}

U_BOOT_DRIVER(smccc_trng) = {
	.name = DRIVER_NAME,
	.id = UCLASS_RNG,
	.ops = &smccc_trng_ops,
	.probe = smccc_trng_probe,
	.priv_auto = sizeof(struct smccc_trng_priv),
};
