// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/arm-smccc.h>
#include <linux/io.h>
#include <linux/mm.h>
#include "security_key.h"

#undef pr_fmt
#define pr_fmt(fmt) "unifykey: " fmt

static DEFINE_SPINLOCK(storage_lock);
static int storage_init_status;
static struct bl31_storage_share_mem *share_mem;

static unsigned long storage_smc_ops(u64 func)
{
	struct arm_smccc_res res;

	arm_smccc_smc((unsigned long)func, 0, 0, 0, 0, 0, 0, 0, &res);
	return res.a0;
}

void *secure_storage_getbuf(u32 *size)
{
	if (storage_init_status == 1) {
		*size = share_mem->size;
		return (void *)(share_mem->block);
	}

	*size = 0;
	return NULL;
}

unsigned long secure_storage_write(u8 *keyname, u8 *keybuf,
				   u32 keylen, u32 keyattr)
{
	u32	      *input;
	u32	      namelen;
	u8	      *keydata;
	u8	      *name;
	unsigned long ret;
	unsigned long lockflags;

	if (storage_init_status != 1)
		return RET_EUND;

	namelen = strlen(keyname);
	if (namelen + keylen + 12 > share_mem->size)
		return RET_EMEM;

	spin_lock_irqsave(&storage_lock, lockflags);
	input = (u32 *)(share_mem->in);
	*input++ = namelen;
	*input++ = keylen;
	*input++ = keyattr;
	name = (u8 *)input;
	memcpy(name, keyname, namelen);
	keydata = name + namelen;
	memcpy(keydata, keybuf, keylen);
	ret = storage_smc_ops(BL31_STORAGE_WRITE);
	spin_unlock_irqrestore(&storage_lock, lockflags);

	return ret;
}

unsigned long secure_storage_read(u8 *keyname, u8 *keybuf,
				  u32 keylen, u32 *readlen)
{
	u32	      *input;
	u32	      *output;
	u32	      namelen;
	u8	      *name;
	u8	      *buf;
	unsigned long ret;
	unsigned long lockflags;

	if (storage_init_status != 1)
		return RET_EUND;

	namelen = strlen(keyname);
	if (namelen + 8 > share_mem->size)
		return RET_EMEM;

	spin_lock_irqsave(&storage_lock, lockflags);
	input = (u32 *)(share_mem->in);
	output = (u32 *)(share_mem->out);
	*input++ = namelen;
	*input++ = keylen;
	name = (u8 *)input;
	memcpy(name, keyname, namelen);
	ret = storage_smc_ops(BL31_STORAGE_READ);
	if (ret == RET_OK) {
		*readlen = *output;
		if (*readlen > keylen)
			*readlen = keylen;
		buf = (u8 *)(output + 1);
		memcpy(keybuf, buf, *readlen);
	}
	spin_unlock_irqrestore(&storage_lock, lockflags);

	return ret;
}

unsigned long secure_storage_verify(u8 *keyname, u8 *hashbuf)
{
	u32	      *input;
	u32	      *output;
	u32	      namelen;
	u8	      *name;
	unsigned long ret;
	unsigned long lockflags;

	if (storage_init_status != 1)
		return RET_EUND;

	namelen = strlen(keyname);
	if (namelen + 4 > share_mem->size)
		return RET_EMEM;

	spin_lock_irqsave(&storage_lock, lockflags);
	input = (u32 *)(share_mem->in);
	output = (u32 *)(share_mem->out);
	*input++ = namelen;
	name = (u8 *)input;
	memcpy(name, keyname, namelen);
	ret = storage_smc_ops(BL31_STORAGE_VERIFY);
	if (ret == RET_OK)
		memcpy(hashbuf, (u8 *)output, 32);
	spin_unlock_irqrestore(&storage_lock, lockflags);

	return ret;
}

unsigned long secure_storage_query(u8 *key_name, u32 *retval)
{
	u32	      *input;
	u32	      *output;
	u32	      namelen;
	u8	      *name;
	unsigned long ret;
	unsigned long lockflags;

	if (storage_init_status != 1)
		return RET_EUND;

	namelen = strlen(key_name);
	if (namelen + 4 > share_mem->size)
		return RET_EMEM;

	spin_lock_irqsave(&storage_lock, lockflags);
	input = (u32 *)(share_mem->in);
	output = (u32 *)(share_mem->out);
	*input++ = namelen;
	name = (u8 *)input;
	memcpy(name, key_name, namelen);
	ret = storage_smc_ops(BL31_STORAGE_QUERY);
	if (ret == RET_OK)
		*retval = *output;
	spin_unlock_irqrestore(&storage_lock, lockflags);

	return ret;
}

unsigned long secure_storage_tell(u8 *keyname, u32 *retval)
{
	u32	      *input;
	u32	      *output;
	u32	      namelen;
	u8	      *name;
	unsigned long ret;
	unsigned long lockflags;

	if (storage_init_status != 1)
		return RET_EUND;

	namelen = strlen(keyname);
	if (namelen + 4 > share_mem->size)
		return RET_EMEM;

	spin_lock_irqsave(&storage_lock, lockflags);
	input = (u32 *)(share_mem->in);
	output = (u32 *)(share_mem->out);
	*input++ = namelen;
	name = (u8 *)input;
	memcpy(name, keyname, namelen);
	ret = storage_smc_ops(BL31_STORAGE_TELL);
	if (ret == RET_OK)
		*retval = *output;
	spin_unlock_irqrestore(&storage_lock, lockflags);

	return ret;
}

unsigned long secure_storage_status(u8 *keyname, u32 *retval)
{
	u32	      *input;
	u32	      *output;
	u32	      namelen;
	u8	      *name;
	u64	      ret;
	unsigned long lockflags;

	if (storage_init_status != 1)
		return RET_EUND;

	namelen = strlen(keyname);
	if (namelen + 4 > share_mem->size)
		return RET_EMEM;

	spin_lock_irqsave(&storage_lock, lockflags);
	input = (u32 *)(share_mem->in);
	output = (u32 *)(share_mem->out);
	*input++ = namelen;
	name = (u8 *)input;
	memcpy(name, keyname, namelen);
	ret = storage_smc_ops(BL31_STORAGE_STATUS);
	if (ret == RET_OK)
		*retval = *output;
	spin_unlock_irqrestore(&storage_lock, lockflags);

	return ret;
}

int __init security_key_init(struct platform_device *pdev)
{
	unsigned long phy_in;
	unsigned long phy_out;
	unsigned long phy_block;

	storage_init_status = -1;

	share_mem = devm_kzalloc(&pdev->dev, sizeof(*share_mem), GFP_KERNEL);
	if (IS_ERR_OR_NULL(share_mem)) {
		pr_err("fail to alloc mem for struct share_mem\n");
		return -ENOMEM;
	}

	phy_in = storage_smc_ops(BL31_STORAGE_IN);
	phy_out = storage_smc_ops(BL31_STORAGE_OUT);
	phy_block = storage_smc_ops(BL31_STORAGE_BLOCK);
	share_mem->size = storage_smc_ops(BL31_STORAGE_SIZE);

	if (!phy_in || phy_in == SMC_UNK ||
	    !phy_out || phy_out == SMC_UNK ||
	    !phy_block || phy_block == SMC_UNK ||
	    !(share_mem->size) || share_mem->size == SMC_UNK) {
		pr_err("fail to obtain phy addr of shared mem\n");
		return -EOPNOTSUPP;
	}

	/*
	 * The BL31 shared mem for key storage is
	 * part of secure monitor, and all of the
	 * mem locates at lowmem region, so its
	 * okay to call phys_to_virt directly
	 */
	if (valid_phys_addr_range(phy_in, share_mem->size)) {
		share_mem->in = (void __iomem *)phys_to_virt(phy_in);
		share_mem->out = (void __iomem *)phys_to_virt(phy_out);
		share_mem->block = (void __iomem *)phys_to_virt(phy_block);
	}	else {
		share_mem->in = ioremap_cache(phy_in, share_mem->size);
		share_mem->out = ioremap_cache(phy_out, share_mem->size);
		share_mem->block = ioremap_cache(phy_block, share_mem->size);
	}

	pr_info("storage in: 0x%lx, out: 0x%lx, block: 0x%lx\n",
		(long)(share_mem->in), (long)(share_mem->out),
		(long)(share_mem->block));

	if (!(share_mem->in) || !(share_mem->out) || !(share_mem->block)) {
		pr_err("fail to obtain virtual addr of shared mem\n");
		return -EINVAL;
	}

	storage_init_status = 1;
	pr_info("security_key init done!\n");
	return 0;
}
