// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2022-2023 Arm Limited and/or its affiliates * * Authors: * Abdellatif El Khlifi */ #include #include #include #include #include #include /* 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 \n" " - lists the partition(s) info\n" "ping \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));