blob: 3fa5f238adb2efaf3c7c7b41720c84a87a449af3 [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 Pappireddyca8264c2022-01-28 17:14:21 -060017static int flag_set;
18
19static void sec_wdog_interrupt_handled(void)
20{
21 expect(flag_set, 0);
22 flag_set = 1;
23}
24
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000025CACTUS_CMD_HANDLER(sleep_cmd, CACTUS_SLEEP_CMD)
26{
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050027 uint64_t time_lapsed;
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000028 uint32_t sleep_time = cactus_get_sleep_time(*args);
29
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050030 VERBOSE("Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
31 sleep_time);
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000032
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050033 time_lapsed = sp_sleep_elapsed_time(sleep_time);
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000034
Madhukar Pappireddya09d5f72021-10-26 14:50:52 -050035 /* Lapsed time should be at least equal to sleep time. */
36 VERBOSE("Sleep complete: %llu\n", time_lapsed);
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000037
38 return cactus_response(ffa_dir_msg_dest(*args),
39 ffa_dir_msg_source(*args),
40 time_lapsed);
41}
42
Madhukar Pappireddyb6402592021-08-20 13:13:49 -050043CACTUS_CMD_HANDLER(sleep_fwd_cmd, CACTUS_FWD_SLEEP_CMD)
44{
45 smc_ret_values ffa_ret;
46 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
47 ffa_id_t fwd_dest = cactus_get_fwd_sleep_dest(*args);
48 uint32_t sleep_ms = cactus_get_sleep_time(*args);
49
Madhukar Pappireddyb6402592021-08-20 13:13:49 -050050 VERBOSE("VM%x requested %x to sleep for value %u\n",
51 ffa_dir_msg_source(*args), fwd_dest, sleep_ms);
52
53 ffa_ret = cactus_sleep_cmd(vm_id, fwd_dest, sleep_ms);
54
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050055 while (ffa_ret.ret0 == FFA_INTERRUPT) {
56 /* Received FFA_INTERRUPT in blocked state. */
57 VERBOSE("Processing FFA_INTERRUPT while blocked on direct response\n");
58 unsigned int my_core_pos = platform_get_core_pos(read_mpidr_el1());
59
60 ffa_ret = ffa_run(fwd_dest, my_core_pos);
61 }
62
Madhukar Pappireddyb6402592021-08-20 13:13:49 -050063 if (!is_ffa_direct_response(ffa_ret)) {
64 ERROR("Encountered error in CACTUS_FWD_SLEEP_CMD response\n");
65 return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),
66 CACTUS_ERROR_FFA_CALL);
67 }
68
69 if (cactus_get_response(ffa_ret) != sleep_ms) {
70 ERROR("Request returned: %u ms!\n",
71 cactus_get_response(ffa_ret));
72 return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),
73 CACTUS_ERROR_TEST);
74
75 }
76
77 return cactus_success_resp(vm_id, ffa_dir_msg_source(*args), 0);
78}
79
Manish Pandey9ee6a8d2021-03-03 09:53:33 +000080CACTUS_CMD_HANDLER(interrupt_cmd, CACTUS_INTERRUPT_CMD)
81{
82 uint32_t int_id = cactus_get_interrupt_id(*args);
83 bool enable = cactus_get_interrupt_enable(*args);
84 enum interrupt_pin pin = cactus_get_interrupt_pin(*args);
85 int64_t ret;
86
87 ret = spm_interrupt_enable(int_id, enable, pin);
88 if (ret != 0) {
89 return cactus_error_resp(ffa_dir_msg_dest(*args),
90 ffa_dir_msg_source(*args),
91 CACTUS_ERROR_TEST);
92 }
93
94 return cactus_response(ffa_dir_msg_dest(*args),
95 ffa_dir_msg_source(*args),
96 CACTUS_SUCCESS);
97}
Madhukar Pappireddy3c287262021-08-05 14:39:24 -050098
99CACTUS_CMD_HANDLER(twdog_cmd, CACTUS_TWDOG_START_CMD)
100{
101 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
102 ffa_id_t source = ffa_dir_msg_source(*args);
103
104 uint64_t time_ms = cactus_get_wdog_duration(*args);
105
106 VERBOSE("Starting TWDOG: %llums\n", time_ms);
107 sp805_twdog_refresh();
108 sp805_twdog_start((time_ms * ARM_SP805_TWDG_CLK_HZ) / 1000);
109
110 return cactus_success_resp(vm_id, source, time_ms);
111}
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600112
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600113bool handle_twdog_interrupt_sp_sleep(uint32_t sleep_time, uint64_t *time_lapsed)
114{
115 sp_register_interrupt_tail_end_handler(sec_wdog_interrupt_handled,
116 IRQ_TWDOG_INTID);
117 *time_lapsed += sp_sleep_elapsed_time(sleep_time);
118
119 if (flag_set == 0) {
120 return false;
121 }
122
123 /* Reset the flag and unregister the handler. */
124 flag_set = 0;
125 sp_unregister_interrupt_tail_end_handler(IRQ_TWDOG_INTID);
126
127 return true;
128}
129
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600130CACTUS_CMD_HANDLER(sleep_twdog_cmd, CACTUS_SLEEP_TRIGGER_TWDOG_CMD)
131{
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600132 uint64_t time_lapsed = 0;
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600133 uint32_t sleep_time = cactus_get_sleep_time(*args) / 2;
134 uint64_t time_ms = cactus_get_wdog_trigger_duration(*args);
135
136 VERBOSE("Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
137 sleep_time);
138
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600139 if (!handle_twdog_interrupt_sp_sleep(sleep_time, &time_lapsed)) {
140 goto fail;
141 }
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600142
143 /* Lapsed time should be at least equal to sleep time. */
144 VERBOSE("Sleep complete: %llu\n", time_lapsed);
145
146 VERBOSE("Starting TWDOG: %llums\n", time_ms);
147 sp805_twdog_refresh();
148 sp805_twdog_start((time_ms * ARM_SP805_TWDG_CLK_HZ) / 1000);
149
150 VERBOSE("2nd Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
151 sleep_time);
152
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600153 if (!handle_twdog_interrupt_sp_sleep(sleep_time, &time_lapsed)) {
154 goto fail;
155 }
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600156
157 /* Lapsed time should be at least equal to sleep time. */
158 VERBOSE("2nd Sleep complete: %llu\n", time_lapsed);
159
160 return cactus_response(ffa_dir_msg_dest(*args),
161 ffa_dir_msg_source(*args),
162 time_lapsed);
Madhukar Pappireddyca8264c2022-01-28 17:14:21 -0600163fail:
164 /* Test failed. */
165 ERROR("Watchdog interrupt not handled\n");
166 return cactus_error_resp(ffa_dir_msg_dest(*args),
167 ffa_dir_msg_source(*args),
168 CACTUS_ERROR_TEST);
Madhukar Pappireddy407befc2021-12-17 11:06:17 -0600169}