blob: 181e31bc49adee5abb95983e716c2fa417fb48eb [file] [log] [blame]
Abdellatif El Khlifif16a48f2023-08-04 14:33:43 +01001// 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 */
Abdellatif El Khlifif16a48f2023-08-04 14:33:43 +01008#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
Tom Rini36162182023-10-07 15:13:08 -0400190U_BOOT_LONGHELP(armffa,
Abdellatif El Khlifif16a48f2023-08-04 14:33:43 +0100191 "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"
Tom Rini36162182023-10-07 15:13:08 -0400196 " - displays information about the FF-A device/driver\n");
Abdellatif El Khlifif16a48f2023-08-04 14:33:43 +0100197
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));