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