// SPDX-License-Identifier: GPL-2.0+
/**
 * (C) Copyright 2014, Cavium Inc.
**/

#include <common.h>
#include <command.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/ptrace.h>

#include <asm/system.h>
#include <cavium/thunderx_svc.h>
#include <cavium/atf.h>
#include <cavium/atf_part.h>

#include <asm/psci.h>

#include <malloc.h>

ssize_t atf_read_mmc(uintptr_t offset, void *buffer, size_t size)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_MMC_READ;
	regs.regs[1] = offset;
	regs.regs[2] = size;
	regs.regs[3] = (uintptr_t)buffer;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_read_nor(uintptr_t offset, void *buffer, size_t size)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_NOR_READ;
	regs.regs[1] = offset;
	regs.regs[2] = size;
	regs.regs[3] = (uintptr_t)buffer;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_get_pcount(void)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_PART_COUNT;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_get_part(struct storage_partition *part, unsigned int index)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_GET_PART;
	regs.regs[1] = (uintptr_t)part;
	regs.regs[2] = index;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_erase_nor(uintptr_t offset, size_t size)
{
	struct pt_regs regs;

	regs.regs[0] = THUNDERX_NOR_ERASE;
	regs.regs[1] = offset;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_write_nor(uintptr_t offset, const void *buffer, size_t size)
{
	struct pt_regs regs;

	regs.regs[0] = THUNDERX_NOR_WRITE;
	regs.regs[1] = offset;
	regs.regs[2] = size;
	regs.regs[3] = (uintptr_t)buffer;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_write_mmc(uintptr_t offset, const void *buffer, size_t size)
{
	struct pt_regs regs;

	regs.regs[0] = THUNDERX_MMC_WRITE;
	regs.regs[1] = offset;
	regs.regs[2] = size;
	regs.regs[3] = (uintptr_t)buffer;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_dram_size(unsigned int node)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_DRAM_SIZE;
	regs.regs[1] = node;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_node_count(void)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_NODE_COUNT;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_env_count(void)
{
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_ENV_COUNT;

	smc_call(&regs);

	return regs.regs[0];
}

ssize_t atf_env_string(size_t index, char *str)
{
	uint64_t *buf = (void *)str;
	struct pt_regs regs;
	regs.regs[0] = THUNDERX_ENV_STRING;
	regs.regs[1] = index;

	smc_call(&regs);

	if (regs.regs > 0) {
		buf[0] = regs.regs[0];
		buf[1] = regs.regs[1];
		buf[2] = regs.regs[2];
		buf[3] = regs.regs[3];

		return 1;
	} else {
		return regs.regs[0];
	}
}

#ifdef CONFIG_CMD_ATF

static void atf_print_ver(void)
{
	struct pt_regs regs;
	regs.regs[0] = ARM_STD_SVC_VERSION;

	smc_call(&regs);

	printf("ARM Std FW version: %ld.%ld\n", regs.regs[0], regs.regs[1]);

	regs.regs[0] = THUNDERX_SVC_VERSION;

	smc_call(&regs);

	printf("ThunderX OEM ver: %ld.%ld\n", regs.regs[0], regs.regs[1]);
}

static void atf_print_uid(void)
{
}

static void atf_print_part_table(void)
{
	size_t pcount;
	unsigned long i;
	int ret;
	char *ptype;

	struct storage_partition *part = (void *)CFG_SYS_LOWMEM_BASE;

	pcount = atf_get_pcount();

	printf("Partition count: %lu\n\n", pcount);
	printf("%10s %10s %10s\n", "Type", "Size", "Offset");

	for (i = 0; i < pcount; i++) {
		ret = atf_get_part(part, i);

		if (ret < 0) {
			printf("Uknown error while reading partition: %d\n",
			       ret);
			return;
		}

		switch (part->type) {
		case PARTITION_NBL1FW_REST:
			ptype = "NBL1FW";
			break;
		case PARTITION_BL2_BL31:
			ptype = "BL2_BL31";
			break;
		case PARTITION_UBOOT:
			ptype = "BOOTLDR";
			break;
		case PARTITION_KERNEL:
			ptype = "KERNEL";
			break;
		case PARTITION_DEVICE_TREE:
			ptype = "DEVTREE";
			break;
		default:
			ptype = "UNKNOWN";
		}
		printf("%10s %10d %10lx\n", ptype, part->size, part->offset);
	}
}

int do_atf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	ssize_t ret;
	size_t size, offset;
	void *buffer = 0;
	unsigned int index, node;
	char str[4 * sizeof(uint64_t)];

	if ((argc == 5) && !strcmp(argv[1], "readmmc")) {
		buffer = (void *)hextoul(argv[2], NULL);
		offset = dectoul(argv[3], NULL);
		size = dectoul(argv[4], NULL);

		ret = atf_read_mmc(offset, buffer, size);
	} else if ((argc == 5) && !strcmp(argv[1], "readnor")) {
		buffer = (void *)hextoul(argv[2], NULL);
		offset = dectoul(argv[3], NULL);
		size = dectoul(argv[4], NULL);

		ret = atf_read_nor(offset, buffer, size);
	} else if ((argc == 5) && !strcmp(argv[1], "writemmc")) {
		buffer = (void *)hextoul(argv[2], NULL);
		offset = dectoul(argv[3], NULL);
		size = dectoul(argv[4], NULL);

		ret = atf_write_mmc(offset, buffer, size);
	} else if ((argc == 5) && !strcmp(argv[1], "writenor")) {
		buffer = (void *)hextoul(argv[2], NULL);
		offset = dectoul(argv[3], NULL);
		size = dectoul(argv[4], NULL);

		ret = atf_write_nor(offset, buffer, size);
	} else if ((argc == 2) && !strcmp(argv[1], "part")) {
		atf_print_part_table();
	} else if ((argc == 4) && !strcmp(argv[1], "erasenor")) {
		offset = dectoul(argv[2], NULL);
		size = dectoul(argv[3], NULL);

		ret = atf_erase_nor(offset, size);
	} else if ((argc == 2) && !strcmp(argv[1], "envcount")) {
		ret = atf_env_count();
		printf("Number of environment strings: %zd\n", ret);
	} else if ((argc == 3) && !strcmp(argv[1], "envstring")) {
		index = dectoul(argv[2], NULL);
		ret = atf_env_string(index, str);
		if (ret > 0)
			printf("Environment string %d: %s\n", index, str);
		else
			printf("Return code: %zd\n", ret);
	} else if ((argc == 3) && !strcmp(argv[1], "dramsize")) {
		node = dectoul(argv[2], NULL);
		ret = atf_dram_size(node);
		printf("DRAM size: %zd Mbytes\n", ret >> 20);
	} else if ((argc == 2) && !strcmp(argv[1], "nodes")) {
		ret = atf_node_count();
		printf("Nodes count: %zd\n", ret);
	} else if ((argc == 2) && !strcmp(argv[1], "ver")) {
		atf_print_ver();
	} else if ((argc == 2) && !strcmp(argv[1], "uid")) {
		atf_print_uid();
	} else {
		return CMD_RET_USAGE;
	}

	return 0;
}

U_BOOT_CMD(
	atf,   10,   1,     do_atf,
	"issue calls to ATF",
	"\t readmmc addr offset size - read MMC card\n"
	"\t readnor addr offset size - read NOR flash\n"
	"\t writemmc addr offset size - write MMC card\n"
	"\t writenor addr offset size - write NOR flash\n"
	"\t erasenor offset size - erase NOR flash\n"
	"\t nodes - number of nodes\n"
	"\t dramsize node - size of DRAM attached to node\n"
	"\t envcount - number of environment strings\n"
	"\t envstring index - print the environment string\n"
	"\t part - print MMC partition table\n"
	"\t ver - print ATF call set versions\n"
);

#endif
