blob: 9a8e9a1d91b35a7000f8b13be1dfdfb4ea3bbbf2 [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>
Olivier Deprez19626b42023-12-21 18:29:05 +010014#include <spm_helpers.h>
Madhukar Pappireddy611d0952025-01-31 16:07:08 -060015#include <psci.h>
J-Alvesf7535f42021-07-30 11:58:41 +010016
17/**
18 * Counter of the number of handled requests, for each CPU. The number of
19 * requests can be accessed from another Cactus SP, or from the normal world
20 * using a special test command.
21 */
22static uint32_t requests_counter[PLATFORM_CORE_COUNT];
J-Alves0e1e7ca2021-01-25 14:11:06 +000023
24/**
25 * Begin and end of command handler table, respectively. Both symbols defined by
26 * the linker.
27 */
28extern struct cactus_cmd_handler cactus_cmd_handler_begin[];
29extern struct cactus_cmd_handler cactus_cmd_handler_end[];
30
J-Alveseeb25472021-03-11 09:54:21 +000031#define PRINT_CMD(smc_ret) \
32 VERBOSE("cmd %lx; args: %lx, %lx, %lx, %lx\n", \
J-Alvesb3f13d72022-07-04 12:03:17 +010033 smc_ret.arg3, smc_ret.arg4, smc_ret.arg5, \
34 smc_ret.arg6, smc_ret.arg7)
J-Alveseeb25472021-03-11 09:54:21 +000035
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050036/* Global FFA_MSG_DIRECT_REQ source ID */
37ffa_id_t g_dir_req_source_id;
38
J-Alves0e1e7ca2021-01-25 14:11:06 +000039/**
40 * Traverses command table from section ".cactus_handler", searches for a
41 * registered command and invokes the respective handler.
42 */
Daniel Boulbyce386b12022-03-29 18:36:36 +010043bool cactus_handle_cmd(struct ffa_value *cmd_args, struct ffa_value *ret,
J-Alves0e1e7ca2021-01-25 14:11:06 +000044 struct mailbox_buffers *mb)
45{
J-Alves4cb9dee2021-03-03 13:59:52 +000046 uint64_t in_cmd;
47
Olivier Deprez19626b42023-12-21 18:29:05 +010048 /* Get vCPU index for currently running vCPU. */
49 unsigned int core_pos = spm_get_my_core_pos();
J-Alvesf7535f42021-07-30 11:58:41 +010050
J-Alves0e1e7ca2021-01-25 14:11:06 +000051 if (cmd_args == NULL || ret == NULL) {
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050052 ERROR("Invalid arguments passed to %s!\n", __func__);
J-Alves0e1e7ca2021-01-25 14:11:06 +000053 return false;
54 }
55
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050056 /* Get the source of the Direct Request message. */
57 if (ffa_func_id(*cmd_args) == FFA_MSG_SEND_DIRECT_REQ_SMC32 ||
58 ffa_func_id(*cmd_args) == FFA_MSG_SEND_DIRECT_REQ_SMC64) {
59 g_dir_req_source_id = ffa_dir_msg_source(*cmd_args);
60 }
61
J-Alveseeb25472021-03-11 09:54:21 +000062 PRINT_CMD((*cmd_args));
63
J-Alves4cb9dee2021-03-03 13:59:52 +000064 in_cmd = cactus_get_cmd(*cmd_args);
J-Alves0e1e7ca2021-01-25 14:11:06 +000065
66 for (struct cactus_cmd_handler *it_cmd = cactus_cmd_handler_begin;
67 it_cmd < cactus_cmd_handler_end;
68 it_cmd++) {
69 if (it_cmd->id == in_cmd) {
70 *ret = it_cmd->fn(cmd_args, mb);
J-Alvesf7535f42021-07-30 11:58:41 +010071
72 /*
73 * Increment the number of requests handled in current
74 * core.
75 */
76 requests_counter[core_pos]++;
77
J-Alves0e1e7ca2021-01-25 14:11:06 +000078 return true;
79 }
80 }
81
J-Alvesf7535f42021-07-30 11:58:41 +010082 /* Handle special command. */
83 if (in_cmd == CACTUS_GET_REQ_COUNT_CMD) {
84 uint32_t requests_counter_resp;
85
86 /* Read value from array. */
87 requests_counter_resp = requests_counter[core_pos];
88 VERBOSE("Requests Counter %u, core: %u\n", requests_counter_resp,
89 core_pos);
90
91 *ret = cactus_success_resp(
92 ffa_dir_msg_dest(*cmd_args),
93 ffa_dir_msg_source(*cmd_args),
94 requests_counter_resp);
95 return true;
96 }
97
J-Alves4cb9dee2021-03-03 13:59:52 +000098 *ret = cactus_error_resp(ffa_dir_msg_dest(*cmd_args),
99 ffa_dir_msg_source(*cmd_args),
100 CACTUS_ERROR_UNHANDLED);
101 return true;
J-Alves0e1e7ca2021-01-25 14:11:06 +0000102}
Madhukar Pappireddy611d0952025-01-31 16:07:08 -0600103
104struct ffa_value cactus_handle_framework_msg(struct ffa_value args)
105{
106 ffa_id_t source_id = ffa_dir_msg_source(args);
107 ffa_id_t destination_id = ffa_dir_msg_dest(args);
108 uint32_t status_code;
109 uint32_t framework_msg = ffa_get_framework_msg(args);
110 uint32_t psci_function = args.arg3;
111
112 /*
113 * As of now, Cactus supports receiving only PSCI power management
114 * request as framework message.
115 */
116 if (framework_msg != FFA_FRAMEWORK_MSG_PSCI_REQ) {
117 ERROR("Unsupported framework message received by SP:%x\n",
118 destination_id);
119 status_code = PSCI_E_DENIED;
120 goto out;
121 }
122
123 /* Cactus only supports receiving CPU_OFF PSCI function as message. */
124 if (psci_function != SMC_PSCI_CPU_OFF) {
125 ERROR("Unsupported PSCI function(%x) received by SP:%x through "
126 "framework message\n", psci_function, destination_id);
127 status_code = PSCI_E_DENIED;
128 goto out;
129 }
130
131 /* Only SPMC can send the PSCI framework message. */
132 if (source_id != SPMC_ID) {
133 ERROR("Framework message source illegal %x\n", source_id);
134 status_code = PSCI_E_DENIED;
135 goto out;
136 }
137
138 status_code = PSCI_E_SUCCESS;
139 /*
140 * Return successful status for PSCI power management request through
141 * direct response Framework message.
142 */
143 VERBOSE("PSCI power management request handled successfully by SP:%x\n",
144 destination_id);
145out:
146 return ffa_framework_msg_send_direct_resp(destination_id, source_id,
147 FFA_FRAMEWORK_MSG_PSCI_RESP, status_code);
148}