// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 *
 * Authors:
 *   Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
 */
#include <arm_ffa.h>
#include <command.h>
#include <dm.h>
#include <mapmem.h>
#include <stdlib.h>
#include <asm/io.h>

/* Select the right physical address formatting according to the platform */
#ifdef CONFIG_PHYS_64BIT
#define PhysAddrLength "ll"
#else
#define PhysAddrLength ""
#endif
#define PHYS_ADDR_LN "%" PhysAddrLength "x"

/**
 * ffa_get_dev() - Return the FF-A device
 * @devp:	pointer to the FF-A device
 *
 * Search for the FF-A device.
 *
 * Return:
 * 0 on success. Otherwise, failure
 */
static int ffa_get_dev(struct udevice **devp)
{
	int ret;

	ret = uclass_first_device_err(UCLASS_FFA, devp);
	if (ret) {
		log_err("Cannot find FF-A bus device\n");
		return ret;
	}

	return 0;
}

/**
 * do_ffa_getpart() - implementation of the getpart subcommand
 * @cmdtp:		Command Table
 * @flag:		flags
 * @argc:		number of arguments
 * @argv:		arguments
 *
 * Query a secure partition information. The secure partition UUID is provided
 * as an argument. The function uses the arm_ffa driver
 * partition_info_get operation which implements FFA_PARTITION_INFO_GET
 * ABI to retrieve the data. The input UUID string is expected to be in big
 * endian format.
 *
 * Return:
 *
 * CMD_RET_SUCCESS: on success, otherwise failure
 */
static int do_ffa_getpart(struct cmd_tbl *cmdtp, int flag, int argc,
			  char *const argv[])
{
	u32 count = 0;
	int ret;
	struct ffa_partition_desc *descs;
	u32 i;
	struct udevice *dev;

	if (argc != 2) {
		log_err("Missing argument\n");
		return CMD_RET_USAGE;
	}

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

	/* Ask the driver to fill the buffer with the SPs info */

	ret = ffa_partition_info_get(dev, argv[1], &count, &descs);
	if (ret) {
		log_err("Failure in querying partition(s) info (error code: %d)\n", ret);
		return CMD_RET_FAILURE;
	}

	/* SPs found , show the partition information */
	for (i = 0; i < count ; i++) {
		log_info("Partition: id = %x , exec_ctxt %x , properties %x\n",
			 descs[i].info.id,
			 descs[i].info.exec_ctxt,
			 descs[i].info.properties);
	}

	return CMD_RET_SUCCESS;
}

/**
 * do_ffa_ping() - implementation of the ping subcommand
 * @cmdtp:		Command Table
 * @flag:		flags
 * @argc:		number of arguments
 * @argv:		arguments
 *
 * Send data to a secure partition. The secure partition UUID is provided
 * as an argument. Use the arm_ffa driver sync_send_receive operation
 * which implements FFA_MSG_SEND_DIRECT_{REQ,RESP} ABIs to send/receive data.
 *
 * Return:
 *
 * CMD_RET_SUCCESS: on success, otherwise failure
 */
static int do_ffa_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct ffa_send_direct_data msg = {
			.data0 = 0xaaaaaaaa,
			.data1 = 0xbbbbbbbb,
			.data2 = 0xcccccccc,
			.data3 = 0xdddddddd,
			.data4 = 0xeeeeeeee,
	};
	u16 part_id;
	int ret;
	struct udevice *dev;

	if (argc != 2) {
		log_err("Missing argument\n");
		return CMD_RET_USAGE;
	}

	part_id = strtoul(argv[1], NULL, 16);
	if (!part_id) {
		log_err("Partition ID can not be 0\n");
		return CMD_RET_USAGE;
	}

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

	ret = ffa_sync_send_receive(dev, part_id, &msg, 1);
	if (!ret) {
		u8 cnt;

		log_info("SP response:\n[LSB]\n");
		for (cnt = 0;
		     cnt < sizeof(struct ffa_send_direct_data) / sizeof(u64);
		     cnt++)
			log_info("%llx\n", ((u64 *)&msg)[cnt]);
		return CMD_RET_SUCCESS;
	}

	log_err("Sending direct request error (%d)\n", ret);
	return CMD_RET_FAILURE;
}

/**
 *do_ffa_devlist() - implementation of the devlist subcommand
 * @cmdtp: [in]		Command Table
 * @flag:		flags
 * @argc:		number of arguments
 * @argv:		arguments
 *
 * Query the device belonging to the UCLASS_FFA
 * class.
 *
 * Return:
 *
 * CMD_RET_SUCCESS: on success, otherwise failure
 */
static int do_ffa_devlist(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct udevice *dev;
	int ret;

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

	log_info("device %s, addr " PHYS_ADDR_LN ", driver %s, ops " PHYS_ADDR_LN "\n",
		 dev->name,
		 map_to_sysmem(dev),
		 dev->driver->name,
		 map_to_sysmem(dev->driver->ops));

	return CMD_RET_SUCCESS;
}

U_BOOT_LONGHELP(armffa,
	"getpart <partition UUID>\n"
	"       - lists the partition(s) info\n"
	"ping <partition ID>\n"
	"       - sends a data pattern to the specified partition\n"
	"devlist\n"
	"       - displays information about the FF-A device/driver\n");

U_BOOT_CMD_WITH_SUBCMDS(armffa, "Arm FF-A test command", armffa_help_text,
			U_BOOT_SUBCMD_MKENT(getpart, 2, 1, do_ffa_getpart),
			U_BOOT_SUBCMD_MKENT(ping, 2, 1, do_ffa_ping),
			U_BOOT_SUBCMD_MKENT(devlist, 1, 1, do_ffa_devlist));
