diff --git a/MAINTAINERS b/MAINTAINERS index 5a2a546787..bf851cffd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -271,9 +271,12 @@ M: Abdellatif El Khlifi S: Maintained F: arch/sandbox/include/asm/sandbox_arm_ffa.h F: arch/sandbox/include/asm/sandbox_arm_ffa_priv.h +F: cmd/armffa.c F: doc/arch/arm64.ffa.rst +F: doc/usage/cmd/armffa.rst F: drivers/firmware/arm-ffa/ F: include/arm_ffa.h +F: test/cmd/armffa.c F: test/dm/ffa.c ARM FREESCALE IMX diff --git a/cmd/Kconfig b/cmd/Kconfig index 7f65e3187a..43ca10f69c 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -952,6 +952,16 @@ endmenu menu "Device access commands" +config CMD_ARMFFA + bool "Arm FF-A test command" + depends on ARM_FFA_TRANSPORT + help + Provides a test command for the FF-A support + supported options: + - Listing the partition(s) info + - Sending a data pattern to the specified partition + - Displaying the arm_ffa device info + config CMD_ARMFLASH #depends on FLASH_CFI_DRIVER bool "armflash" diff --git a/cmd/Makefile b/cmd/Makefile index 9f8c0b058b..9bebf321c3 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -12,6 +12,7 @@ obj-y += panic.o obj-y += version.o # command +obj-$(CONFIG_CMD_ARMFFA) += armffa.o obj-$(CONFIG_CMD_2048) += 2048.o obj-$(CONFIG_CMD_ACPI) += acpi.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o diff --git a/cmd/armffa.c b/cmd/armffa.c new file mode 100644 index 0000000000..7e6eafc03a --- /dev/null +++ b/cmd/armffa.c @@ -0,0 +1,202 @@ +// 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 +#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; +} + +static char armffa_help_text[] = + "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)); diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst index 71606373f9..325fb80346 100644 --- a/doc/arch/arm64.ffa.rst +++ b/doc/arch/arm64.ffa.rst @@ -120,6 +120,8 @@ At this stage the FF-A bus is registered with the DM and can be interacted with the DM APIs. Clients are able to probe then use the FF-A bus by calling uclass_first_device(). +Please refer to the armffa command implementation as an example of how to probe +and interact with the FF-A bus. When calling uclass_first_device(), the FF-A driver is probed and ends up calling ffa_do_probe() provided by the Uclass which does the following: @@ -219,6 +221,13 @@ Relationship between the sandbox emulator and the FF-A device ffa_emul 0 [ + ] sandbox_ffa_emul `-- arm-ffa-emul ffa 0 [ ] sandbox_arm_ffa `-- sandbox-arm-ffa +The armffa command +----------------------------------- + +armffa is a command showcasing how to use the FF-A bus and how to invoke the driver operations. + +Please refer the command documentation at :doc:`../usage/cmd/armffa` + Example of boot logs with FF-A enabled -------------------------------------- diff --git a/doc/usage/cmd/armffa.rst b/doc/usage/cmd/armffa.rst new file mode 100644 index 0000000000..13fa90c129 --- /dev/null +++ b/doc/usage/cmd/armffa.rst @@ -0,0 +1,94 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright 2022-2023 Arm Limited and/or its affiliates + +armffa command +============== + +Synopsis +-------- + +:: + + armffa [sub-command] [arguments] + + sub-commands: + + getpart [partition UUID] + + lists the partition(s) info + + ping [partition ID] + + sends a data pattern to the specified partition + + devlist + + displays information about the FF-A device/driver + +Description +----------- + +armffa is a command showcasing how to use the FF-A bus and how to invoke its operations. + +This provides a guidance to the client developers on how to call the FF-A bus interfaces. + +The command also allows to gather secure partitions information and ping these partitions. + +The command is also helpful in testing the communication with secure partitions. + +Example +------- + +The following examples are run on Corstone-1000 platform. + +* ping + +:: + + corstone1000# armffa ping 0x8003 + SP response: + [LSB] + fffffffe + 0 + 0 + 0 + 0 + +* ping (failure case) + +:: + + corstone1000# armffa ping 0 + Sending direct request error (-22) + +* getpart + +:: + + corstone1000# armffa getpart 33d532ed-e699-0942-c09c-a798d9cd722d + Partition: id = 8003 , exec_ctxt 1 , properties 3 + +* getpart (failure case) + +:: + + corstone1000# armffa getpart 33d532ed-e699-0942-c09c-a798d9cd7221 + INVALID_PARAMETERS: Unrecognized UUID + Failure in querying partitions count (error code: -22) + +* devlist + +:: + + corstone1000# armffa devlist + device name arm_ffa, dev 00000000fdf41c30, driver name arm_ffa, ops 00000000fffc0e98 + +Configuration +------------- + +The command is available if CONFIG_CMD_ARMFFA=y and CONFIG_ARM_FFA_TRANSPORT=y. + +Return value +------------ + +The return value $? is 0 (true) on success, 1 (false) on failure. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 072db53614..3326ec82ff 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -22,6 +22,7 @@ Shell commands cmd/acpi cmd/addrmap + cmd/armffa cmd/askenv cmd/base cmd/bdinfo diff --git a/drivers/firmware/arm-ffa/Kconfig b/drivers/firmware/arm-ffa/Kconfig index fc668c109d..d75f8b53fd 100644 --- a/drivers/firmware/arm-ffa/Kconfig +++ b/drivers/firmware/arm-ffa/Kconfig @@ -5,6 +5,7 @@ config ARM_FFA_TRANSPORT depends on DM && (ARM64 || SANDBOX) select ARM_SMCCC if !SANDBOX select ARM_SMCCC_FEATURES if !SANDBOX + imply CMD_ARMFFA select LIB_UUID select DEVRES help diff --git a/test/cmd/Makefile b/test/cmd/Makefile index a3cf983739..6e3d7e919e 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2013 Google, Inc +# Copyright 2022-2023 Arm Limited and/or its affiliates ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o @@ -24,6 +25,7 @@ obj-$(CONFIG_CMD_SEAMA) += seama.o ifdef CONFIG_SANDBOX obj-$(CONFIG_CMD_READ) += rw.o obj-$(CONFIG_CMD_SETEXPR) += setexpr.o +obj-$(CONFIG_ARM_FFA_TRANSPORT) += armffa.o endif obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o obj-$(CONFIG_CMD_WGET) += wget.o diff --git a/test/cmd/armffa.c b/test/cmd/armffa.c new file mode 100644 index 0000000000..9a44a397e8 --- /dev/null +++ b/test/cmd/armffa.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for armffa command + * + * Copyright 2022-2023 Arm Limited and/or its affiliates + * + * Authors: + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include +#include + +/* Basic test of 'armffa' command */ +static int dm_test_armffa_cmd(struct unit_test_state *uts) +{ + /* armffa getpart */ + ut_assertok(run_command("armffa getpart " SANDBOX_SERVICE1_UUID, 0)); + + /* armffa ping */ + ut_assertok(run_commandf("armffa ping 0x%x", SANDBOX_SP1_ID)); + + /* armffa devlist */ + ut_assertok(run_command("armffa devlist", 0)); + + return 0; +} + +DM_TEST(dm_test_armffa_cmd, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);