blob: 16785dbb4d1a5564fe0d93726d253b89f4db0ee1 [file] [log] [blame]
Manish Pandeyd27b37d2021-03-02 14:41:58 +00001/*
Madhukar Pappireddy7caaa4a2022-01-28 17:01:35 -06002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Manish Pandeyd27b37d2021-03-02 14:41:58 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <debug.h>
8
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -05009#include "cactus_message_loop.h"
10#include "cactus_test_cmds.h"
11#include <drivers/arm/sp805.h>
Manish Pandeyd27b37d2021-03-02 14:41:58 +000012#include <ffa_helpers.h>
13#include <sp_helpers.h>
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050014#include "spm_common.h"
Manish Pandey58971b62020-09-21 21:10:38 +010015#include <spm_helpers.h>
Manish Pandeyd27b37d2021-03-02 14:41:58 +000016
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050017#include <platform_def.h>
Manish Pandeyf7aafef2021-03-03 11:31:47 +000018
J-Alvesa076d4c2021-10-19 16:06:15 +010019#define NOTIFICATION_PENDING_INTERRUPT_INTID 5
20
21extern void notification_pending_interrupt_handler(void);
22
Daniel Boulbye79d2072021-03-03 11:34:53 +000023extern ffa_id_t g_ffa_id;
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050024extern ffa_id_t g_dir_req_source_id;
Madhukar Pappireddyca1e2012022-06-22 17:05:09 -050025static uint32_t managed_exit_interrupt_id;
Manish Pandeyf7aafef2021-03-03 11:31:47 +000026
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -060027/* Secure virtual interrupt that was last handled by Cactus SP. */
28uint32_t last_serviced_interrupt[PLATFORM_CORE_COUNT];
29
Madhukar Pappireddy7caaa4a2022-01-28 17:01:35 -060030extern spinlock_t sp_handler_lock[NUM_VINT_ID];
31
Madhukar Pappireddyca1e2012022-06-22 17:05:09 -050032/*
33 * Managed exit ID discoverable by querying the SPMC through
34 * FFA_FEATURES API.
35 */
36void discover_managed_exit_interrupt_id(void)
37{
38 struct ffa_value ffa_ret;
39
40 /* Interrupt ID value is returned through register W2. */
41 ffa_ret = ffa_features(FFA_FEATURE_MEI);
42 managed_exit_interrupt_id = ffa_feature_intid(ffa_ret);
43
44 VERBOSE("Discovered managed exit interrupt ID: %d\n",
45 managed_exit_interrupt_id);
46}
47
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050048static void post_interrupt_handler(uint32_t intid)
Manish Pandeyf7aafef2021-03-03 11:31:47 +000049{
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -060050 unsigned int core_pos = get_current_core_id();
Manish Pandeyf7aafef2021-03-03 11:31:47 +000051
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -060052 last_serviced_interrupt[core_pos] = intid;
53
Madhukar Pappireddy7caaa4a2022-01-28 17:01:35 -060054 /* Invoke the tail end handler registered by the SP. */
55 spin_lock(&sp_handler_lock[intid]);
56 if (sp_interrupt_tail_end_handler[intid]) {
57 sp_interrupt_tail_end_handler[intid]();
58 }
59 spin_unlock(&sp_handler_lock[intid]);
Manish Pandeyd27b37d2021-03-02 14:41:58 +000060}
Madhukar Pappireddye9c90932022-06-22 17:15:45 -050061
Madhukar Pappireddy92d2e812022-09-19 13:48:13 -050062/*
63 * Cactus SP does not implement application threads. Hence, once the Cactus SP
64 * sends the managed exit response to the direct request originator, execution
65 * is still frozen in interrupt handler context.
66 * Though it moves to WAITING state, it is not able to accept new direct request
67 * message from any endpoint. It can only receive a direct request message with
68 * the command CACTUS_RESUME_AFTER_MANAGED_EXIT from the originator of the
69 * suspended direct request message in order to return from the interrupt
70 * handler context and resume the processing of suspended request.
71 */
72void send_managed_exit_response(void)
73{
74 struct ffa_value ffa_ret;
75 bool waiting_resume_after_managed_exit;
76
77 /* Send managed exit response. */
78 ffa_ret = cactus_response(g_ffa_id, g_dir_req_source_id,
79 MANAGED_EXIT_INTERRUPT_ID);
80 waiting_resume_after_managed_exit = true;
81
82 while (waiting_resume_after_managed_exit) {
83
84 waiting_resume_after_managed_exit =
85 (ffa_func_id(ffa_ret) != FFA_MSG_SEND_DIRECT_REQ_SMC32 &&
86 ffa_func_id(ffa_ret) != FFA_MSG_SEND_DIRECT_REQ_SMC64) ||
87 ffa_dir_msg_source(ffa_ret) != g_dir_req_source_id ||
88 cactus_get_cmd(ffa_ret) != CACTUS_RESUME_AFTER_MANAGED_EXIT;
89
90 if (waiting_resume_after_managed_exit) {
91 ERROR("Expected a direct message request from endpoint"
92 " %x with command CACTUS_RESUME_AFTER_MANAGED_EXIT\n",
93 g_dir_req_source_id);
94 ffa_ret = cactus_error_resp(g_ffa_id,
95 ffa_dir_msg_source(ffa_ret),
96 CACTUS_ERROR_TEST);
97 }
98 }
99 VERBOSE("Resuming the suspended command\n");
100}
101
Madhukar Pappireddye9c90932022-06-22 17:15:45 -0500102void cactus_interrupt_handler_irq(void)
103{
104 uint32_t intid = spm_interrupt_get();
105
106 if (intid == managed_exit_interrupt_id) {
107 /*
108 * A secure partition performs its housekeeping and
109 * sends a direct response to signal interrupt
110 * completion. This is a pure virtual interrupt, no
111 * need for deactivation.
112 */
113 VERBOSE("vIRQ: Sending ME response to %x\n",
114 g_dir_req_source_id);
Madhukar Pappireddy92d2e812022-09-19 13:48:13 -0500115 send_managed_exit_response();
Madhukar Pappireddye9c90932022-06-22 17:15:45 -0500116 } else {
117 switch (intid) {
118 case IRQ_TWDOG_INTID:
119 /*
120 * Interrupt triggered due to Trusted watchdog timer expiry.
121 * Clear the interrupt and stop the timer.
122 */
123 VERBOSE("Trusted WatchDog timer stopped\n");
124 sp805_twdog_stop();
125
126 /* Perform secure interrupt de-activation. */
127 spm_interrupt_deactivate(intid);
128
129 break;
130 case NOTIFICATION_PENDING_INTERRUPT_INTID:
131 notification_pending_interrupt_handler();
132 break;
133 default:
134 ERROR("%s: Interrupt ID %x not handled!\n", __func__,
135 intid);
136 panic();
137 break;
138 }
139 }
140 post_interrupt_handler(intid);
141}
142
143void cactus_interrupt_handler_fiq(void)
144{
145 uint32_t intid = spm_interrupt_get();
146
147 switch (intid) {
148 case MANAGED_EXIT_INTERRUPT_ID:
149 /*
150 * A secure partition performs its housekeeping and sends a
151 * direct response to signal interrupt completion.
152 * This is a pure virtual interrupt, no need for deactivation.
153 */
154 VERBOSE("vFIQ: Sending ME response to %x\n",
155 g_dir_req_source_id);
Madhukar Pappireddy92d2e812022-09-19 13:48:13 -0500156 send_managed_exit_response();
Madhukar Pappireddye9c90932022-06-22 17:15:45 -0500157 break;
158 default:
159 /*
160 * Currently only managed exit interrupt is supported by vFIQ.
161 */
162 panic();
163 break;
164 }
165 post_interrupt_handler(intid);
166}