blob: dc64512f3e0aee0dc2eb97c3866962a9f4b43d64 [file] [log] [blame]
Manish Pandey9ee6a8d2021-03-03 09:53:33 +00001/*
Madhukar Pappireddy407befc2021-12-17 11:06:17 -06002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Manish Pandey9ee6a8d2021-03-03 09:53:33 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/debug.h>
Madhukar Pappireddy3c287262021-08-05 14:39:24 -05008#include <drivers/arm/sp805.h>
Manish Pandey9ee6a8d2021-03-03 09:53:33 +00009#include <sp_helpers.h>
10#include <spm_helpers.h>
11
12#include "cactus_message_loop.h"
13#include "cactus_test_cmds.h"
14
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050015#include <platform.h>
16
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -060017/* Secure virtual interrupt that was last handled by Cactus SP. */
18extern uint32_t last_serviced_interrupt[PLATFORM_CORE_COUNT];
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -060019static int flag_set;
20
21static void sec_wdog_interrupt_handled(void)
22{
23 expect(flag_set, 0);
24 flag_set = 1;
25}
26
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000027CACTUS_CMD_HANDLER(sleep_cmd, CACTUS_SLEEP_CMD)
28{
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050029 uint64_t time_lapsed;
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000030 uint32_t sleep_time = cactus_get_sleep_time(*args);
31
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050032 VERBOSE("Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
33 sleep_time);
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000034
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050035 time_lapsed = sp_sleep_elapsed_time(sleep_time);
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000036
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050037 /* Lapsed time should be at least equal to sleep time. */
38 VERBOSE("Sleep complete: %llu\n", time_lapsed);
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000039
40 return cactus_response(ffa_dir_msg_dest(*args),
41 ffa_dir_msg_source(*args),
42 time_lapsed);
43}
44
Madhukar Pappireddyb6402592021-08-20 13:13:49 -050045CACTUS_CMD_HANDLER(sleep_fwd_cmd, CACTUS_FWD_SLEEP_CMD)
46{
47 smc_ret_values ffa_ret;
48 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
49 ffa_id_t fwd_dest = cactus_get_fwd_sleep_dest(*args);
50 uint32_t sleep_ms = cactus_get_sleep_time(*args);
51
Madhukar Pappireddyb6402592021-08-20 13:13:49 -050052 VERBOSE("VM%x requested %x to sleep for value %u\n",
53 ffa_dir_msg_source(*args), fwd_dest, sleep_ms);
54
55 ffa_ret = cactus_sleep_cmd(vm_id, fwd_dest, sleep_ms);
56
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050057 while (ffa_ret.ret0 == FFA_INTERRUPT) {
58 /* Received FFA_INTERRUPT in blocked state. */
59 VERBOSE("Processing FFA_INTERRUPT while blocked on direct response\n");
60 unsigned int my_core_pos = platform_get_core_pos(read_mpidr_el1());
61
62 ffa_ret = ffa_run(fwd_dest, my_core_pos);
63 }
64
Madhukar Pappireddyb6402592021-08-20 13:13:49 -050065 if (!is_ffa_direct_response(ffa_ret)) {
66 ERROR("Encountered error in CACTUS_FWD_SLEEP_CMD response\n");
67 return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),
68 CACTUS_ERROR_FFA_CALL);
69 }
70
71 if (cactus_get_response(ffa_ret) != sleep_ms) {
72 ERROR("Request returned: %u ms!\n",
73 cactus_get_response(ffa_ret));
74 return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),
75 CACTUS_ERROR_TEST);
76
77 }
78
79 return cactus_success_resp(vm_id, ffa_dir_msg_source(*args), 0);
80}
81
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000082CACTUS_CMD_HANDLER(interrupt_cmd, CACTUS_INTERRUPT_CMD)
83{
84 uint32_t int_id = cactus_get_interrupt_id(*args);
85 bool enable = cactus_get_interrupt_enable(*args);
86 enum interrupt_pin pin = cactus_get_interrupt_pin(*args);
87 int64_t ret;
88
89 ret = spm_interrupt_enable(int_id, enable, pin);
90 if (ret != 0) {
91 return cactus_error_resp(ffa_dir_msg_dest(*args),
92 ffa_dir_msg_source(*args),
93 CACTUS_ERROR_TEST);
94 }
95
96 return cactus_response(ffa_dir_msg_dest(*args),
97 ffa_dir_msg_source(*args),
98 CACTUS_SUCCESS);
99}
Madhukar Pappireddy3c287262021-08-05 14:39:24 -0500100
101CACTUS_CMD_HANDLER(twdog_cmd, CACTUS_TWDOG_START_CMD)
102{
103 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
104 ffa_id_t source = ffa_dir_msg_source(*args);
105
106 uint64_t time_ms = cactus_get_wdog_duration(*args);
107
108 VERBOSE("Starting TWDOG: %llums\n", time_ms);
109 sp805_twdog_refresh();
110 sp805_twdog_start((time_ms * ARM_SP805_TWDG_CLK_HZ) / 1000);
111
112 return cactus_success_resp(vm_id, source, time_ms);
113}
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600114
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600115bool handle_twdog_interrupt_sp_sleep(uint32_t sleep_time, uint64_t *time_lapsed)
116{
117 sp_register_interrupt_tail_end_handler(sec_wdog_interrupt_handled,
118 IRQ_TWDOG_INTID);
119 *time_lapsed += sp_sleep_elapsed_time(sleep_time);
120
121 if (flag_set == 0) {
122 return false;
123 }
124
125 /* Reset the flag and unregister the handler. */
126 flag_set = 0;
127 sp_unregister_interrupt_tail_end_handler(IRQ_TWDOG_INTID);
128
129 return true;
130}
131
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600132CACTUS_CMD_HANDLER(sleep_twdog_cmd, CACTUS_SLEEP_TRIGGER_TWDOG_CMD)
133{
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600134 uint64_t time_lapsed = 0;
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600135 uint32_t sleep_time = cactus_get_sleep_time(*args) / 2;
136 uint64_t time_ms = cactus_get_wdog_trigger_duration(*args);
137
138 VERBOSE("Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
139 sleep_time);
140
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600141 if (!handle_twdog_interrupt_sp_sleep(sleep_time, &time_lapsed)) {
142 goto fail;
143 }
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600144
145 /* Lapsed time should be at least equal to sleep time. */
146 VERBOSE("Sleep complete: %llu\n", time_lapsed);
147
148 VERBOSE("Starting TWDOG: %llums\n", time_ms);
149 sp805_twdog_refresh();
150 sp805_twdog_start((time_ms * ARM_SP805_TWDG_CLK_HZ) / 1000);
151
152 VERBOSE("2nd Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
153 sleep_time);
154
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600155 if (!handle_twdog_interrupt_sp_sleep(sleep_time, &time_lapsed)) {
156 goto fail;
157 }
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600158
159 /* Lapsed time should be at least equal to sleep time. */
160 VERBOSE("2nd Sleep complete: %llu\n", time_lapsed);
161
162 return cactus_response(ffa_dir_msg_dest(*args),
163 ffa_dir_msg_source(*args),
164 time_lapsed);
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600165fail:
166 /* Test failed. */
167 ERROR("Watchdog interrupt not handled\n");
168 return cactus_error_resp(ffa_dir_msg_dest(*args),
169 ffa_dir_msg_source(*args),
170 CACTUS_ERROR_TEST);
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600171}
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -0600172
173CACTUS_CMD_HANDLER(interrupt_serviced_cmd, CACTUS_LAST_INTERRUPT_SERVICED_CMD)
174{
175 unsigned int core_pos = get_current_core_id();
176
177 return cactus_response(ffa_dir_msg_dest(*args),
178 ffa_dir_msg_source(*args),
179 last_serviced_interrupt[core_pos]);
180}