1 /**************************************************************************/
2 /* Copyright (c) Cadence Design Systems, Inc. */
3 /* */
4 /* Permission is hereby granted, free of charge, to any person obtaining */
5 /* a copy of this software and associated documentation files (the */
6 /* "Software"), to deal in the Software without restriction, including */
7 /* without limitation the rights to use, copy, modify, merge, publish, */
8 /* distribute, sublicense, and/or sell copies of the Software, and to */
9 /* permit persons to whom the Software is furnished to do so, subject to */
10 /* the following conditions: */
11 /* */
12 /* The above copyright notice and this permission notice shall be */
13 /* included in all copies or substantial portions of the Software. */
14 /* */
15 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
16 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
17 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
18 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
19 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
20 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
21 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
22 /**************************************************************************/
23
24 /**************************************************************************/
25 /* */
26 /* DESCRIPTION */
27 /* */
28 /* Xtensa-specific interrupt handler wrapper. */
29 /* */
30 /* RELEASE HISTORY */
31 /* */
32 /* DATE NAME DESCRIPTION */
33 /* */
34 /* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
35 /* */
36 /**************************************************************************/
37
38
39 #include <xtensa/config/core.h>
40 #include <xtensa/core-macros.h>
41
42 #include "xtensa_rtos.h"
43 #include "xtensa_api.h"
44
45 #include "tx_api.h"
46 #include "tx_thread.h"
47
48 #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
49 #include "tx_execution_profile.h"
50 #endif
51
52
53 #if (XCHAL_HAVE_XEA3 && XCHAL_HAVE_INTERRUPTS)
54
55 /* Table of interrupt hooks. Used for testing ONLY. */
56 #ifdef XT_INTEXC_HOOKS
57 volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
58 #endif
59
60
61 /* Handler table is in xtensa_intr_asm.S */
62
63 typedef struct xt_handler_table_entry {
64 void * handler;
65 void * arg;
66 } xt_handler_table_entry;
67
68 extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS + 1];
69 extern int32_t xt_sw_intnum;
70
71 static int32_t xt_wflag;
72
73
74 /**************************************************************************/
75 /* Wrapper for interrupt handlers. Argument is (intnum << 2). */
76 /* Execution comes here from the dispatch code if the wrapper is */
77 /* enabled. */
78 /**************************************************************************/
79 void
xt_interrupt_wrapper(void * arg)80 xt_interrupt_wrapper(void * arg)
81 {
82 uint32_t intnum = (uint32_t)(arg) >> 2;
83 xt_handler_table_entry * entry;
84 xt_handler handler;
85
86 /* Increment interrupt nest counter. */
87 _tx_thread_system_state++;
88
89 #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
90 /* Call the ISR enter function to indicate an ISR is executing. */
91 _tx_execution_isr_enter();
92 #endif
93
94 /* Load handler address and argument from table. Note that the
95 first entry in the table points to this wrapper, so we have
96 to skip ahead one.
97 */
98 entry = _xt_interrupt_table + intnum + 1;
99 handler = (xt_handler) entry->handler;
100
101 (*handler)(entry->arg);
102
103 #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
104 /* Call the ISR exit function to indicate an ISR is complete. */
105 _tx_execution_isr_exit();
106 #endif
107
108 /* If a context switch is pending, trigger the SW interrupt
109 to process the switch. Set an internal flag so we don't
110 trigger the sw interrupt again when handling it.
111 */
112 if (xt_wflag != 0) {
113 xt_wflag = 0;
114 }
115 else if (_tx_thread_current_ptr != _tx_thread_execute_ptr) {
116 xt_wflag = 1;
117 xt_interrupt_trigger(xt_sw_intnum);
118 }
119
120 /* Decrement interrupt nest counter. */
121 _tx_thread_system_state--;
122 }
123
124 #endif /* XCHAL_HAVE_XEA3 && XCHAL_HAVE_INTERRUPTS */
125
126