blob: aba3124048e00a01dd1a84ff0a1be79f032b6061 [file] [log] [blame]
J-Alves0e1e7ca2021-01-25 14:11:06 +00001/*
Daniel Boulbyce386b12022-03-29 18:36:36 +01002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
J-Alves0e1e7ca2021-01-25 14:11:06 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
J-Alveseeb25472021-03-11 09:54:21 +00007#include <debug.h>
8
J-Alvesf7535f42021-07-30 11:58:41 +01009#include <cactus_message_loop.h>
10#include <cactus_test_cmds.h>
11#include <ffa_helpers.h>
12#include <events.h>
13#include <platform.h>
Madhukar Pappireddy11e57482025-03-28 11:46:16 -050014#include <sp_helpers.h>
Olivier Deprez19626b42023-12-21 18:29:05 +010015#include <spm_helpers.h>
Madhukar Pappireddy611d0952025-01-31 16:07:08 -060016#include <psci.h>
J-Alvesf7535f42021-07-30 11:58:41 +010017
18/**
19 * Counter of the number of handled requests, for each CPU. The number of
20 * requests can be accessed from another Cactus SP, or from the normal world
21 * using a special test command.
22 */
23static uint32_t requests_counter[PLATFORM_CORE_COUNT];
J-Alves0e1e7ca2021-01-25 14:11:06 +000024
25/**
26 * Begin and end of command handler table, respectively. Both symbols defined by
27 * the linker.
28 */
29extern struct cactus_cmd_handler cactus_cmd_handler_begin[];
30extern struct cactus_cmd_handler cactus_cmd_handler_end[];
31
J-Alveseeb25472021-03-11 09:54:21 +000032#define PRINT_CMD(smc_ret) \
33 VERBOSE("cmd %lx; args: %lx, %lx, %lx, %lx\n", \
J-Alvesb3f13d72022-07-04 12:03:17 +010034 smc_ret.arg3, smc_ret.arg4, smc_ret.arg5, \
35 smc_ret.arg6, smc_ret.arg7)
J-Alveseeb25472021-03-11 09:54:21 +000036
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050037/* Global FFA_MSG_DIRECT_REQ source ID */
38ffa_id_t g_dir_req_source_id;
39
J-Alves0e1e7ca2021-01-25 14:11:06 +000040/**
41 * Traverses command table from section ".cactus_handler", searches for a
42 * registered command and invokes the respective handler.
43 */
Daniel Boulbyce386b12022-03-29 18:36:36 +010044bool cactus_handle_cmd(struct ffa_value *cmd_args, struct ffa_value *ret,
J-Alves0e1e7ca2021-01-25 14:11:06 +000045 struct mailbox_buffers *mb)
46{
J-Alves4cb9dee2021-03-03 13:59:52 +000047 uint64_t in_cmd;
48
Olivier Deprez19626b42023-12-21 18:29:05 +010049 /* Get vCPU index for currently running vCPU. */
50 unsigned int core_pos = spm_get_my_core_pos();
J-Alvesf7535f42021-07-30 11:58:41 +010051
J-Alves0e1e7ca2021-01-25 14:11:06 +000052 if (cmd_args == NULL || ret == NULL) {
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050053 ERROR("Invalid arguments passed to %s!\n", __func__);
J-Alves0e1e7ca2021-01-25 14:11:06 +000054 return false;
55 }
56
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050057 /* Get the source of the Direct Request message. */
58 if (ffa_func_id(*cmd_args) == FFA_MSG_SEND_DIRECT_REQ_SMC32 ||
59 ffa_func_id(*cmd_args) == FFA_MSG_SEND_DIRECT_REQ_SMC64) {
60 g_dir_req_source_id = ffa_dir_msg_source(*cmd_args);
61 }
62
J-Alveseeb25472021-03-11 09:54:21 +000063 PRINT_CMD((*cmd_args));
64
J-Alves4cb9dee2021-03-03 13:59:52 +000065 in_cmd = cactus_get_cmd(*cmd_args);
J-Alves0e1e7ca2021-01-25 14:11:06 +000066
67 for (struct cactus_cmd_handler *it_cmd = cactus_cmd_handler_begin;
68 it_cmd < cactus_cmd_handler_end;
69 it_cmd++) {
70 if (it_cmd->id == in_cmd) {
71 *ret = it_cmd->fn(cmd_args, mb);
J-Alvesf7535f42021-07-30 11:58:41 +010072
73 /*
74 * Increment the number of requests handled in current
75 * core.
76 */
77 requests_counter[core_pos]++;
78
J-Alves0e1e7ca2021-01-25 14:11:06 +000079 return true;
80 }
81 }
82
J-Alvesf7535f42021-07-30 11:58:41 +010083 /* Handle special command. */
84 if (in_cmd == CACTUS_GET_REQ_COUNT_CMD) {
85 uint32_t requests_counter_resp;
86
87 /* Read value from array. */
88 requests_counter_resp = requests_counter[core_pos];
89 VERBOSE("Requests Counter %u, core: %u\n", requests_counter_resp,
90 core_pos);
91
92 *ret = cactus_success_resp(
93 ffa_dir_msg_dest(*cmd_args),
94 ffa_dir_msg_source(*cmd_args),
95 requests_counter_resp);
96 return true;
97 }
98
J-Alves4cb9dee2021-03-03 13:59:52 +000099 *ret = cactus_error_resp(ffa_dir_msg_dest(*cmd_args),
100 ffa_dir_msg_source(*cmd_args),
101 CACTUS_ERROR_UNHANDLED);
102 return true;
J-Alves0e1e7ca2021-01-25 14:11:06 +0000103}
Madhukar Pappireddy611d0952025-01-31 16:07:08 -0600104
105struct ffa_value cactus_handle_framework_msg(struct ffa_value args)
106{
107 ffa_id_t source_id = ffa_dir_msg_source(args);
108 ffa_id_t destination_id = ffa_dir_msg_dest(args);
109 uint32_t status_code;
Madhukar Pappireddya2b6b372025-02-11 15:39:32 -0600110
111#if CACTUS_PWR_MGMT_SUPPORT == 1
Madhukar Pappireddy611d0952025-01-31 16:07:08 -0600112 uint32_t framework_msg = ffa_get_framework_msg(args);
113 uint32_t psci_function = args.arg3;
Madhukar Pappireddy11e57482025-03-28 11:46:16 -0500114 struct ffa_value ret;
Madhukar Pappireddy611d0952025-01-31 16:07:08 -0600115
116 /*
117 * As of now, Cactus supports receiving only PSCI power management
118 * request as framework message.
119 */
120 if (framework_msg != FFA_FRAMEWORK_MSG_PSCI_REQ) {
121 ERROR("Unsupported framework message received by SP:%x\n",
122 destination_id);
123 status_code = PSCI_E_DENIED;
124 goto out;
125 }
126
127 /* Cactus only supports receiving CPU_OFF PSCI function as message. */
128 if (psci_function != SMC_PSCI_CPU_OFF) {
129 ERROR("Unsupported PSCI function(%x) received by SP:%x through "
130 "framework message\n", psci_function, destination_id);
131 status_code = PSCI_E_DENIED;
132 goto out;
133 }
134
135 /* Only SPMC can send the PSCI framework message. */
136 if (source_id != SPMC_ID) {
137 ERROR("Framework message source illegal %x\n", source_id);
138 status_code = PSCI_E_DENIED;
139 goto out;
140 }
141
142 status_code = PSCI_E_SUCCESS;
Madhukar Pappireddy11e57482025-03-28 11:46:16 -0500143
144 /*
145 * FF-A spec states that SPs are prohibited from invoking Direct
146 * request, FFA_RUN and FFA_YIELD interfaces while handling power
147 * management framework message. Make the Cactus SP intentionally
148 * invoke prohibited interfaces and attest that SPMC should deny such
149 * invocations.
150 */
151 ret = cactus_success_resp(destination_id, source_id, status_code);
152
153 /* Non-framework direct response must be denied. */
154 EXPECT(ffa_func_id(ret), FFA_ERROR);
155 EXPECT(ffa_error_code(ret), FFA_ERROR_DENIED);
156
157 ret = cactus_echo_send_cmd(destination_id, SP_ID(4), 0x9999);
158
159 /* Direct request message must be denied. */
160 EXPECT(ffa_func_id(ret), FFA_ERROR);
161 EXPECT(ffa_error_code(ret), FFA_ERROR_DENIED);
162
163 ret = ffa_run(SP_ID(4), 0);
164
165 /* FFA_RUN invocation must be denied. */
166 EXPECT(ffa_func_id(ret), FFA_ERROR);
167 EXPECT(ffa_error_code(ret), FFA_ERROR_DENIED);
168
169 ret = ffa_yield();
170
171 /* FFA_YIELD invocation must be denied. */
172 EXPECT(ffa_func_id(ret), FFA_ERROR);
173 EXPECT(ffa_error_code(ret), FFA_ERROR_DENIED);
174
Madhukar Pappireddy611d0952025-01-31 16:07:08 -0600175 /*
176 * Return successful status for PSCI power management request through
177 * direct response Framework message.
178 */
179 VERBOSE("PSCI power management request handled successfully by SP:%x\n",
180 destination_id);
181out:
Madhukar Pappireddya2b6b372025-02-11 15:39:32 -0600182#else
183 status_code = PSCI_E_DENIED;
184#endif
Madhukar Pappireddy611d0952025-01-31 16:07:08 -0600185 return ffa_framework_msg_send_direct_resp(destination_id, source_id,
186 FFA_FRAMEWORK_MSG_PSCI_RESP, status_code);
187}