"Das U-Boot" Source Tree
at master 201 lines 4.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> 4 * 5 * Authors: 6 * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> 7 */ 8#include <arm_ffa.h> 9#include <command.h> 10#include <dm.h> 11#include <mapmem.h> 12#include <stdlib.h> 13#include <asm/io.h> 14 15/* Select the right physical address formatting according to the platform */ 16#ifdef CONFIG_PHYS_64BIT 17#define PhysAddrLength "ll" 18#else 19#define PhysAddrLength "" 20#endif 21#define PHYS_ADDR_LN "%" PhysAddrLength "x" 22 23/** 24 * ffa_get_dev() - Return the FF-A device 25 * @devp: pointer to the FF-A device 26 * 27 * Search for the FF-A device. 28 * 29 * Return: 30 * 0 on success. Otherwise, failure 31 */ 32static int ffa_get_dev(struct udevice **devp) 33{ 34 int ret; 35 36 ret = uclass_first_device_err(UCLASS_FFA, devp); 37 if (ret) { 38 log_err("Cannot find FF-A bus device\n"); 39 return ret; 40 } 41 42 return 0; 43} 44 45/** 46 * do_ffa_getpart() - implementation of the getpart subcommand 47 * @cmdtp: Command Table 48 * @flag: flags 49 * @argc: number of arguments 50 * @argv: arguments 51 * 52 * Query a secure partition information. The secure partition UUID is provided 53 * as an argument. The function uses the arm_ffa driver 54 * partition_info_get operation which implements FFA_PARTITION_INFO_GET 55 * ABI to retrieve the data. The input UUID string is expected to be in big 56 * endian format. 57 * 58 * Return: 59 * 60 * CMD_RET_SUCCESS: on success, otherwise failure 61 */ 62static int do_ffa_getpart(struct cmd_tbl *cmdtp, int flag, int argc, 63 char *const argv[]) 64{ 65 u32 count = 0; 66 int ret; 67 struct ffa_partition_desc *descs; 68 u32 i; 69 struct udevice *dev; 70 71 if (argc != 2) { 72 log_err("Missing argument\n"); 73 return CMD_RET_USAGE; 74 } 75 76 ret = ffa_get_dev(&dev); 77 if (ret) 78 return CMD_RET_FAILURE; 79 80 /* Ask the driver to fill the buffer with the SPs info */ 81 82 ret = ffa_partition_info_get(dev, argv[1], &count, &descs); 83 if (ret) { 84 log_err("Failure in querying partition(s) info (error code: %d)\n", ret); 85 return CMD_RET_FAILURE; 86 } 87 88 /* SPs found , show the partition information */ 89 for (i = 0; i < count ; i++) { 90 log_info("Partition: id = %x , exec_ctxt %x , properties %x\n", 91 descs[i].info.id, 92 descs[i].info.exec_ctxt, 93 descs[i].info.properties); 94 } 95 96 return CMD_RET_SUCCESS; 97} 98 99/** 100 * do_ffa_ping() - implementation of the ping subcommand 101 * @cmdtp: Command Table 102 * @flag: flags 103 * @argc: number of arguments 104 * @argv: arguments 105 * 106 * Send data to a secure partition. The secure partition UUID is provided 107 * as an argument. Use the arm_ffa driver sync_send_receive operation 108 * which implements FFA_MSG_SEND_DIRECT_{REQ,RESP} ABIs to send/receive data. 109 * 110 * Return: 111 * 112 * CMD_RET_SUCCESS: on success, otherwise failure 113 */ 114static int do_ffa_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 115{ 116 struct ffa_send_direct_data msg = { 117 .data0 = 0xaaaaaaaa, 118 .data1 = 0xbbbbbbbb, 119 .data2 = 0xcccccccc, 120 .data3 = 0xdddddddd, 121 .data4 = 0xeeeeeeee, 122 }; 123 u16 part_id; 124 int ret; 125 struct udevice *dev; 126 127 if (argc != 2) { 128 log_err("Missing argument\n"); 129 return CMD_RET_USAGE; 130 } 131 132 part_id = strtoul(argv[1], NULL, 16); 133 if (!part_id) { 134 log_err("Partition ID can not be 0\n"); 135 return CMD_RET_USAGE; 136 } 137 138 ret = ffa_get_dev(&dev); 139 if (ret) 140 return CMD_RET_FAILURE; 141 142 ret = ffa_sync_send_receive(dev, part_id, &msg, 1); 143 if (!ret) { 144 u8 cnt; 145 146 log_info("SP response:\n[LSB]\n"); 147 for (cnt = 0; 148 cnt < sizeof(struct ffa_send_direct_data) / sizeof(u64); 149 cnt++) 150 log_info("%llx\n", ((u64 *)&msg)[cnt]); 151 return CMD_RET_SUCCESS; 152 } 153 154 log_err("Sending direct request error (%d)\n", ret); 155 return CMD_RET_FAILURE; 156} 157 158/** 159 *do_ffa_devlist() - implementation of the devlist subcommand 160 * @cmdtp: [in] Command Table 161 * @flag: flags 162 * @argc: number of arguments 163 * @argv: arguments 164 * 165 * Query the device belonging to the UCLASS_FFA 166 * class. 167 * 168 * Return: 169 * 170 * CMD_RET_SUCCESS: on success, otherwise failure 171 */ 172static int do_ffa_devlist(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 173{ 174 struct udevice *dev; 175 int ret; 176 177 ret = ffa_get_dev(&dev); 178 if (ret) 179 return CMD_RET_FAILURE; 180 181 log_info("device %s, addr " PHYS_ADDR_LN ", driver %s, ops " PHYS_ADDR_LN "\n", 182 dev->name, 183 map_to_sysmem(dev), 184 dev->driver->name, 185 map_to_sysmem(dev->driver->ops)); 186 187 return CMD_RET_SUCCESS; 188} 189 190U_BOOT_LONGHELP(armffa, 191 "getpart <partition UUID>\n" 192 " - lists the partition(s) info\n" 193 "ping <partition ID>\n" 194 " - sends a data pattern to the specified partition\n" 195 "devlist\n" 196 " - displays information about the FF-A device/driver\n"); 197 198U_BOOT_CMD_WITH_SUBCMDS(armffa, "Arm FF-A test command", armffa_help_text, 199 U_BOOT_SUBCMD_MKENT(getpart, 2, 1, do_ffa_getpart), 200 U_BOOT_SUBCMD_MKENT(ping, 2, 1, do_ffa_ping), 201 U_BOOT_SUBCMD_MKENT(devlist, 1, 1, do_ffa_devlist));