blob: e08c4ddb6b60380c6d941b3d2e78c093b04a9e22 [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 Pappireddyca1e2012022-06-22 17:05:09 -050024static uint32_t managed_exit_interrupt_id;
Manish Pandeyf7aafef2021-03-03 11:31:47 +000025
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -060026/* Secure virtual interrupt that was last handled by Cactus SP. */
27uint32_t last_serviced_interrupt[PLATFORM_CORE_COUNT];
28
Madhukar Pappireddy7caaa4a2022-01-28 17:01:35 -060029extern spinlock_t sp_handler_lock[NUM_VINT_ID];
30
Madhukar Pappireddyca1e2012022-06-22 17:05:09 -050031/*
32 * Managed exit ID discoverable by querying the SPMC through
33 * FFA_FEATURES API.
34 */
35void discover_managed_exit_interrupt_id(void)
36{
37 struct ffa_value ffa_ret;
38
39 /* Interrupt ID value is returned through register W2. */
40 ffa_ret = ffa_features(FFA_FEATURE_MEI);
41 managed_exit_interrupt_id = ffa_feature_intid(ffa_ret);
42
43 VERBOSE("Discovered managed exit interrupt ID: %d\n",
44 managed_exit_interrupt_id);
45}
46
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050047void cactus_interrupt_handler(void)
Manish Pandeyf7aafef2021-03-03 11:31:47 +000048{
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050049 uint32_t intid = spm_interrupt_get();
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 Pappireddycd183ef2021-08-05 15:34:07 -050052 switch (intid) {
53 case MANAGED_EXIT_INTERRUPT_ID:
54 /*
55 * A secure partition performs its housekeeping and sends a
56 * direct response to signal interrupt completion.
57 * This is a pure virtual interrupt, no need for deactivation.
58 */
59 cactus_response(g_ffa_id, HYP_ID, MANAGED_EXIT_INTERRUPT_ID);
60 break;
61 case IRQ_TWDOG_INTID:
62 /*
63 * Interrupt triggered due to Trusted watchdog timer expiry.
64 * Clear the interrupt and stop the timer.
65 */
Olivier Deprezb92d91b2022-03-16 17:14:26 +010066 VERBOSE("Trusted WatchDog timer stopped\n");
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050067 sp805_twdog_stop();
Manish Pandeyd27b37d2021-03-02 14:41:58 +000068
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050069 /* Perform secure interrupt de-activation. */
70 spm_interrupt_deactivate(intid);
Manish Pandeyd27b37d2021-03-02 14:41:58 +000071
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050072 break;
J-Alvesa076d4c2021-10-19 16:06:15 +010073 case NOTIFICATION_PENDING_INTERRUPT_INTID:
74 notification_pending_interrupt_handler();
75 break;
Madhukar Pappireddycd183ef2021-08-05 15:34:07 -050076 default:
77 /*
78 * Currently the only source of secure interrupt is Trusted
79 * Watchdog timer.
80 */
81 ERROR("%s: Interrupt ID %x not handled!\n", __func__,
82 intid);
83 panic();
Manish Pandeyf7aafef2021-03-03 11:31:47 +000084 }
Madhukar Pappireddy7caaa4a2022-01-28 17:01:35 -060085
Madhukar Pappireddyf4c8e8d2022-02-15 15:52:53 -060086 last_serviced_interrupt[core_pos] = intid;
87
Madhukar Pappireddy7caaa4a2022-01-28 17:01:35 -060088 /* Invoke the tail end handler registered by the SP. */
89 spin_lock(&sp_handler_lock[intid]);
90 if (sp_interrupt_tail_end_handler[intid]) {
91 sp_interrupt_tail_end_handler[intid]();
92 }
93 spin_unlock(&sp_handler_lock[intid]);
Manish Pandeyd27b37d2021-03-02 14:41:58 +000094}