blob: 7654d2e86d9c6924f67c9bab3514ca8d57d66745 [file] [log] [blame]
Achin Gupta76717892014-05-09 11:42:56 +01001/*
Dan Handleyeb839ce2015-03-23 18:13:33 +00002 * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
Achin Gupta76717892014-05-09 11:42:56 +01003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch_helpers.h>
32#include <assert.h>
33#include <debug.h>
Achin Gupta76717892014-05-09 11:42:56 +010034#include <platform.h>
Dan Handleyed6ff952014-05-14 17:44:19 +010035#include <platform_def.h>
Dan Handleye2c27f52014-08-01 17:58:27 +010036#include <tsp.h>
37#include "tsp_private.h"
Achin Gupta76717892014-05-09 11:42:56 +010038
39/*******************************************************************************
Soby Mathewbec98512015-09-03 18:29:38 +010040 * This function updates the TSP statistics for S-EL1 interrupts handled
41 * synchronously i.e the ones that have been handed over by the TSPD. It also
42 * keeps count of the number of times control was passed back to the TSPD
43 * after handling the interrupt. In the future it will be possible that the
44 * TSPD hands over an S-EL1 interrupt to the TSP but does not expect it to
45 * return execution. This statistic will be useful to distinguish between these
46 * two models of synchronous S-EL1 interrupt handling. The 'elr_el3' parameter
47 * contains the address of the instruction in normal world where this S-EL1
48 * interrupt was generated.
Achin Gupta76717892014-05-09 11:42:56 +010049 ******************************************************************************/
Soby Mathewbec98512015-09-03 18:29:38 +010050void tsp_update_sync_sel1_intr_stats(uint32_t type, uint64_t elr_el3)
Achin Gupta76717892014-05-09 11:42:56 +010051{
Soby Mathewda43b662015-07-08 21:45:46 +010052 uint32_t linear_id = plat_my_core_pos();
Achin Gupta76717892014-05-09 11:42:56 +010053
Soby Mathewbec98512015-09-03 18:29:38 +010054 tsp_stats[linear_id].sync_sel1_intr_count++;
55 if (type == TSP_HANDLE_SEL1_INTR_AND_RETURN)
56 tsp_stats[linear_id].sync_sel1_intr_ret_count++;
Achin Gupta76717892014-05-09 11:42:56 +010057
Dan Handley91b624e2014-07-29 17:14:00 +010058#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
Achin Gupta76717892014-05-09 11:42:56 +010059 spin_lock(&console_lock);
Soby Mathewbec98512015-09-03 18:29:38 +010060 VERBOSE("TSP: cpu 0x%lx sync s-el1 interrupt request from 0x%lx\n",
Soby Mathewda43b662015-07-08 21:45:46 +010061 read_mpidr(), elr_el3);
Soby Mathewbec98512015-09-03 18:29:38 +010062 VERBOSE("TSP: cpu 0x%lx: %d sync s-el1 interrupt requests,"
63 " %d sync s-el1 interrupt returns\n",
Soby Mathewda43b662015-07-08 21:45:46 +010064 read_mpidr(),
Soby Mathewbec98512015-09-03 18:29:38 +010065 tsp_stats[linear_id].sync_sel1_intr_count,
66 tsp_stats[linear_id].sync_sel1_intr_ret_count);
Achin Gupta76717892014-05-09 11:42:56 +010067 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +010068#endif
Achin Gupta76717892014-05-09 11:42:56 +010069}
70
Soby Mathewbc912822015-09-22 12:01:18 +010071/******************************************************************************
72 * This function is invoked when a non S-EL1 interrupt is received and causes
73 * the preemption of TSP. This function returns TSP_PREEMPTED and results
74 * in the control being handed over to EL3 for handling the interrupt.
75 *****************************************************************************/
76int32_t tsp_handle_preemption(void)
77{
78 uint32_t linear_id = plat_my_core_pos();
79
80 tsp_stats[linear_id].preempt_intr_count++;
81#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
82 spin_lock(&console_lock);
83 VERBOSE("TSP: cpu 0x%lx: %d preempt interrupt requests\n",
84 read_mpidr(), tsp_stats[linear_id].preempt_intr_count);
85 spin_unlock(&console_lock);
86#endif
87 return TSP_PREEMPTED;
88}
89
Achin Gupta76717892014-05-09 11:42:56 +010090/*******************************************************************************
Soby Mathewbec98512015-09-03 18:29:38 +010091 * TSP interrupt handler is called as a part of both synchronous and
92 * asynchronous handling of TSP interrupts. Currently the physical timer
93 * interrupt is the only S-EL1 interrupt that this handler expects. It returns
94 * 0 upon successfully handling the expected interrupt and all other
95 * interrupts are treated as normal world or EL3 interrupts.
Achin Gupta76717892014-05-09 11:42:56 +010096 ******************************************************************************/
Soby Mathewbec98512015-09-03 18:29:38 +010097int32_t tsp_common_int_handler(void)
Achin Gupta76717892014-05-09 11:42:56 +010098{
Soby Mathewda43b662015-07-08 21:45:46 +010099 uint32_t linear_id = plat_my_core_pos(), id;
Achin Gupta76717892014-05-09 11:42:56 +0100100
101 /*
102 * Get the highest priority pending interrupt id and see if it is the
103 * secure physical generic timer interrupt in which case, handle it.
104 * Otherwise throw this interrupt at the EL3 firmware.
Soby Mathewbc912822015-09-22 12:01:18 +0100105 *
106 * There is a small time window between reading the highest priority
107 * pending interrupt and acknowledging it during which another
108 * interrupt of higher priority could become the highest pending
109 * interrupt. This is not expected to happen currently for TSP.
Achin Gupta76717892014-05-09 11:42:56 +0100110 */
Dan Handley701fea72014-05-27 16:17:21 +0100111 id = plat_ic_get_pending_interrupt_id();
Achin Gupta76717892014-05-09 11:42:56 +0100112
113 /* TSP can only handle the secure physical timer interrupt */
Dan Handley4fd2f5c2014-08-04 11:41:20 +0100114 if (id != TSP_IRQ_SEC_PHY_TIMER)
Soby Mathewbc912822015-09-22 12:01:18 +0100115 return tsp_handle_preemption();
Achin Gupta76717892014-05-09 11:42:56 +0100116
117 /*
Soby Mathewbc912822015-09-22 12:01:18 +0100118 * Acknowledge and handle the secure timer interrupt. Also sanity check
119 * if it has been preempted by another interrupt through an assertion.
Achin Gupta76717892014-05-09 11:42:56 +0100120 */
Dan Handley701fea72014-05-27 16:17:21 +0100121 id = plat_ic_acknowledge_interrupt();
Dan Handley4fd2f5c2014-08-04 11:41:20 +0100122 assert(id == TSP_IRQ_SEC_PHY_TIMER);
Achin Gupta76717892014-05-09 11:42:56 +0100123 tsp_generic_timer_handler();
Dan Handley701fea72014-05-27 16:17:21 +0100124 plat_ic_end_of_interrupt(id);
Achin Gupta76717892014-05-09 11:42:56 +0100125
126 /* Update the statistics and print some messages */
Soby Mathewbec98512015-09-03 18:29:38 +0100127 tsp_stats[linear_id].sel1_intr_count++;
Dan Handley91b624e2014-07-29 17:14:00 +0100128#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
Achin Gupta76717892014-05-09 11:42:56 +0100129 spin_lock(&console_lock);
Soby Mathewbec98512015-09-03 18:29:38 +0100130 VERBOSE("TSP: cpu 0x%lx handled S-EL1 interrupt %d\n",
Soby Mathewda43b662015-07-08 21:45:46 +0100131 read_mpidr(), id);
Soby Mathewbec98512015-09-03 18:29:38 +0100132 VERBOSE("TSP: cpu 0x%lx: %d S-EL1 requests\n",
133 read_mpidr(), tsp_stats[linear_id].sel1_intr_count);
Achin Gupta76717892014-05-09 11:42:56 +0100134 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +0100135#endif
Achin Gupta76717892014-05-09 11:42:56 +0100136 return 0;
137}