blob: 35fdf30f6339f7305fd2188a18ba92a10c5b558b [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
62void cactus_interrupt_handler_irq(void)
63{
64 uint32_t intid = spm_interrupt_get();
65
66 if (intid == managed_exit_interrupt_id) {
67 /*
68 * A secure partition performs its housekeeping and
69 * sends a direct response to signal interrupt
70 * completion. This is a pure virtual interrupt, no
71 * need for deactivation.
72 */
73 VERBOSE("vIRQ: Sending ME response to %x\n",
74 g_dir_req_source_id);
75 cactus_response(g_ffa_id, g_dir_req_source_id,
76 managed_exit_interrupt_id);
77 } else {
78 switch (intid) {
79 case IRQ_TWDOG_INTID:
80 /*
81 * Interrupt triggered due to Trusted watchdog timer expiry.
82 * Clear the interrupt and stop the timer.
83 */
84 VERBOSE("Trusted WatchDog timer stopped\n");
85 sp805_twdog_stop();
86
87 /* Perform secure interrupt de-activation. */
88 spm_interrupt_deactivate(intid);
89
90 break;
91 case NOTIFICATION_PENDING_INTERRUPT_INTID:
92 notification_pending_interrupt_handler();
93 break;
94 default:
95 ERROR("%s: Interrupt ID %x not handled!\n", __func__,
96 intid);
97 panic();
98 break;
99 }
100 }
101 post_interrupt_handler(intid);
102}
103
104void cactus_interrupt_handler_fiq(void)
105{
106 uint32_t intid = spm_interrupt_get();
107
108 switch (intid) {
109 case MANAGED_EXIT_INTERRUPT_ID:
110 /*
111 * A secure partition performs its housekeeping and sends a
112 * direct response to signal interrupt completion.
113 * This is a pure virtual interrupt, no need for deactivation.
114 */
115 VERBOSE("vFIQ: Sending ME response to %x\n",
116 g_dir_req_source_id);
117 cactus_response(g_ffa_id, g_dir_req_source_id,
118 MANAGED_EXIT_INTERRUPT_ID);
119 break;
120 default:
121 /*
122 * Currently only managed exit interrupt is supported by vFIQ.
123 */
124 panic();
125 break;
126 }
127 post_interrupt_handler(intid);
128}