// 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_ARCH_FEATURES, ARM_SMCCC_TRNG_VERSION, 0, 0, 0, 0, 0, 0, &res);
	if (res.a0 == ARM_SMCCC_RET_NOT_SUPPORTED)
		return false;

	(*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_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),
};
