// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
 */

#include <command.h>
#include <console.h>
#include <log.h>
#include <misc.h>
#include <asm/arch/bsec.h>
#include <dm/device.h>
#include <dm/uclass.h>
#include <linux/printk.h>

/*
 * Closed device: OTP0
 * STM32MP15x: bit 6 of OPT0
 * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device
 */
#define STM32_OTP_CLOSE_ID		0
#define STM32_OTP_STM32MP13X_CLOSE_MASK	0x3F
#define STM32_OTP_STM32MP15X_CLOSE_MASK	BIT(6)

/* PKH is the first element of the key list */
#define STM32KEY_PKH 0

struct stm32key {
	char *name;
	char *desc;
	u8 start;
	u8 size;
};

const struct stm32key stm32mp13_list[] = {
	[STM32KEY_PKH] = {
		.name = "PKHTH",
		.desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm)",
		.start = 24,
		.size = 8,
	},
	{
		.name = "EDMK",
		.desc = "Encryption/Decryption Master Key",
		.start = 92,
		.size = 4,
	}
};

const struct stm32key stm32mp15_list[] = {
	[STM32KEY_PKH] = {
		.name = "PKH",
		.desc = "Hash of the ECC Public Key (ECDSA is the authentication algorithm)",
		.start = 24,
		.size = 8,
	}
};

/* index of current selected key in stm32key list, 0 = PKH by default */
static u8 stm32key_index;

static u8 get_key_nb(void)
{
	if (IS_ENABLED(CONFIG_STM32MP13X))
		return ARRAY_SIZE(stm32mp13_list);

	if (IS_ENABLED(CONFIG_STM32MP15X))
		return ARRAY_SIZE(stm32mp15_list);
}

static const struct stm32key *get_key(u8 index)
{
	if (IS_ENABLED(CONFIG_STM32MP13X))
		return &stm32mp13_list[index];

	if (IS_ENABLED(CONFIG_STM32MP15X))
		return &stm32mp15_list[index];
}

static u32 get_otp_close_mask(void)
{
	if (IS_ENABLED(CONFIG_STM32MP13X))
		return STM32_OTP_STM32MP13X_CLOSE_MASK;

	if (IS_ENABLED(CONFIG_STM32MP15X))
		return STM32_OTP_STM32MP15X_CLOSE_MASK;
}

static int get_misc_dev(struct udevice **dev)
{
	int ret;

	ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(stm32mp_bsec), dev);
	if (ret)
		log_err("Can't find stm32mp_bsec driver\n");

	return ret;
}

static void read_key_value(const struct stm32key *key, u32 addr)
{
	int i;

	for (i = 0; i < key->size; i++) {
		printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i,
		       addr, __be32_to_cpu(*(u32 *)addr));
		addr += 4;
	}
}

static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked)
{
	int i, word, ret;
	int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0;
	u32 val, lock;
	bool status;

	for (i = 0, word = key->start; i < key->size; i++, word++) {
		ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
		if (ret != 4)
			val = ~0x0;
		ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
		if (ret != 4)
			lock = BSEC_LOCK_ERROR;
		if (print)
			printf("%s OTP %i: %08x lock : %08x\n", key->name, word, val, lock);
		if (val == ~0x0)
			nb_invalid++;
		else if (val == 0x0)
			nb_zero++;
		if (lock & BSEC_LOCK_PERM)
			nb_lock++;
		if (lock & BSEC_LOCK_ERROR)
			nb_lock_err++;
	}

	status = nb_lock_err || (nb_lock == key->size);
	if (locked)
		*locked = status;
	if (nb_lock_err && print)
		printf("%s lock is invalid!\n", key->name);
	else if (!status && print)
		printf("%s is not locked!\n", key->name);

	if (nb_invalid == key->size) {
		if (print)
			printf("%s is invalid!\n", key->name);
		return -EINVAL;
	}
	if (nb_zero == key->size) {
		if (print)
			printf("%s is free!\n", key->name);
		return -ENOENT;
	}

	return 0;
}

static int read_close_status(struct udevice *dev, bool print, bool *closed)
{
	int word, ret, result;
	u32 val, lock, mask;
	bool status;

	result = 0;
	word = STM32_OTP_CLOSE_ID;
	ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
	if (ret < 0)
		result = ret;
	if (ret != 4)
		val = 0x0;

	ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
	if (ret < 0)
		result = ret;
	if (ret != 4)
		lock = BSEC_LOCK_ERROR;

	mask = get_otp_close_mask();
	status = (val & mask) == mask;
	if (closed)
		*closed = status;
	if (print)
		printf("OTP %d: closed status: %d lock : %08x\n", word, status, lock);

	return result;
}

static int fuse_key_value(struct udevice *dev, const struct stm32key *key, u32 addr, bool print)
{
	u32 word, val;
	int i, ret;

	for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) {
		val = __be32_to_cpu(*(u32 *)addr);
		if (print)
			printf("Fuse %s OTP %i : %08x\n", key->name, word, val);

		ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
		if (ret != 4) {
			log_err("Fuse %s OTP %i failed\n", key->name, word);
			return ret;
		}
		/* on success, lock the OTP for the key */
		val = BSEC_LOCK_PERM;
		ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4);
		if (ret != 4) {
			log_err("Lock %s OTP %i failed\n", key->name, word);
			return ret;
		}
	}

	return 0;
}

static int confirm_prog(void)
{
	puts("Warning: Programming fuses is an irreversible operation!\n"
			"         This may brick your system.\n"
			"         Use this command only if you are sure of what you are doing!\n"
			"\nReally perform this fuse programming? <y/N>\n");

	if (confirm_yesno())
		return 1;

	puts("Fuse programming aborted\n");
	return 0;
}

static void display_key_info(const struct stm32key *key)
{
	printf("%s : %s\n", key->name, key->desc);
	printf("\tOTP%d..%d\n", key->start, key->start + key->size);
}

static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	int i;

	for (i = 0; i < get_key_nb(); i++)
		display_key_info(get_key(i));

	return CMD_RET_SUCCESS;
}

static int do_stm32key_select(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	const struct stm32key *key;
	int i;

	if (argc == 1) {
		printf("Selected key:\n");
		key = get_key(stm32key_index);
		display_key_info(key);
		return CMD_RET_SUCCESS;
	}

	for (i = 0; i < get_key_nb(); i++) {
		key = get_key(i);
		if (!strcmp(key->name, argv[1])) {
			printf("%s selected\n", key->name);
			stm32key_index = i;
			return CMD_RET_SUCCESS;
		}
	}

	printf("Unknown key %s\n", argv[1]);

	return CMD_RET_FAILURE;
}

static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	const struct stm32key *key;
	struct udevice *dev;
	u32 addr;
	int ret, i;
	int result;

	ret = get_misc_dev(&dev);

	if (argc == 1) {
		if (ret)
			return CMD_RET_FAILURE;
		key = get_key(stm32key_index);
		ret = read_key_otp(dev, key, true, NULL);
		if (ret != -ENOENT)
			return CMD_RET_FAILURE;
		return CMD_RET_SUCCESS;
	}

	if (!strcmp("-a", argv[1])) {
		if (ret)
			return CMD_RET_FAILURE;
		result = CMD_RET_SUCCESS;
		for (i = 0; i < get_key_nb(); i++) {
			key = get_key(i);
			ret = read_key_otp(dev, key, true, NULL);
			if (ret != -ENOENT)
				result = CMD_RET_FAILURE;
		}
		ret = read_close_status(dev, true, NULL);
		if (ret)
			result = CMD_RET_FAILURE;

		return result;
	}

	addr = hextoul(argv[1], NULL);
	if (!addr)
		return CMD_RET_USAGE;

	key = get_key(stm32key_index);
	printf("Read %s at 0x%08x\n", key->name, addr);
	read_key_value(key, addr);

	return CMD_RET_SUCCESS;
}

static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	const struct stm32key *key = get_key(stm32key_index);
	struct udevice *dev;
	u32 addr;
	int ret;
	bool yes = false, lock;

	if (argc < 2)
		return CMD_RET_USAGE;

	if (argc == 3) {
		if (strcmp(argv[1], "-y"))
			return CMD_RET_USAGE;
		yes = true;
	}

	addr = hextoul(argv[argc - 1], NULL);
	if (!addr)
		return CMD_RET_USAGE;

	ret = get_misc_dev(&dev);
	if (ret)
		return CMD_RET_FAILURE;

	if (read_key_otp(dev, key, !yes, &lock) != -ENOENT) {
		printf("Error: can't fuse again the OTP\n");
		return CMD_RET_FAILURE;
	}
	if (lock) {
		printf("Error: %s is locked\n", key->name);
		return CMD_RET_FAILURE;
	}

	if (!yes) {
		printf("Writing %s with\n", key->name);
		read_key_value(key, addr);
	}

	if (!yes && !confirm_prog())
		return CMD_RET_FAILURE;

	if (fuse_key_value(dev, key, addr, !yes))
		return CMD_RET_FAILURE;

	printf("%s updated !\n", key->name);

	return CMD_RET_SUCCESS;
}

static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	const struct stm32key *key;
	bool yes, lock, closed;
	struct udevice *dev;
	u32 val;
	int ret;

	yes = false;
	if (argc == 2) {
		if (strcmp(argv[1], "-y"))
			return CMD_RET_USAGE;
		yes = true;
	}

	ret = get_misc_dev(&dev);
	if (ret)
		return CMD_RET_FAILURE;

	if (read_close_status(dev, !yes, &closed))
		return CMD_RET_FAILURE;

	if (closed) {
		printf("Error: already closed!\n");
		return CMD_RET_FAILURE;
	}

	/* check PKH status before to close */
	key = get_key(STM32KEY_PKH);
	ret = read_key_otp(dev, key, !yes, &lock);
	if (ret) {
		if (ret == -ENOENT)
			printf("Error: %s not programmed!\n", key->name);
		return CMD_RET_FAILURE;
	}
	if (!lock)
		printf("Warning: %s not locked!\n", key->name);

	if (!yes && !confirm_prog())
		return CMD_RET_FAILURE;

	val = get_otp_close_mask();
	ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4);
	if (ret != 4) {
		printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID);
		return CMD_RET_FAILURE;
	}

	printf("Device is closed !\n");

	return CMD_RET_SUCCESS;
}

static char stm32key_help_text[] =
	"list : list the supported key with description\n"
	"stm32key select [<key>] : Select the key identified by <key> or display the key used for read/fuse command\n"
	"stm32key read [<addr> | -a ] : Read the curent key at <addr> or current / all (-a) key in OTP\n"
	"stm32key fuse [-y] <addr> : Fuse the current key at addr in OTP\n"
	"stm32key close [-y] : Close the device\n";

U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Manage key on STM32", stm32key_help_text,
	U_BOOT_SUBCMD_MKENT(list, 1, 0, do_stm32key_list),
	U_BOOT_SUBCMD_MKENT(select, 2, 0, do_stm32key_select),
	U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read),
	U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse),
	U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close));
