1/*******************************************************************************
2Copyright (c) 2006-2015 Cadence Design Systems Inc.
3
4Permission is hereby granted, free of charge, to any person obtaining
5a copy of this software and associated documentation files (the
6"Software"), to deal in the Software without restriction, including
7without limitation the rights to use, copy, modify, merge, publish,
8distribute, sublicense, and/or sell copies of the Software, and to
9permit persons to whom the Software is furnished to do so, subject to
10the following conditions:
11
12The above copyright notice and this permission notice shall be included
13in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22******************************************************************************/
23
24/******************************************************************************
25  Xtensa interrupt handling data and assembly routines.
26  Also see xtensa_intr.c and xtensa_vectors.S.
27******************************************************************************/
28
29#include <xtensa/hal.h>
30#include <xtensa/config/core.h>
31
32#include "xtensa/xtensa_context.h"
33#include "freertos/FreeRTOSConfig.h"
34
35#if XCHAL_HAVE_INTERRUPTS
36
37/*
38-------------------------------------------------------------------------------
39  INTENABLE virtualization information.
40-------------------------------------------------------------------------------
41*/
42
43
44#if XT_USE_SWPRI
45/* Warning - this is not multicore-compatible. */
46    .data
47    .global _xt_intdata
48    .align  8
49_xt_intdata:
50    .global _xt_intenable
51    .type   _xt_intenable,@object
52    .size   _xt_intenable,4
53    .global _xt_vpri_mask
54    .type   _xt_vpri_mask,@object
55    .size   _xt_vpri_mask,4
56
57_xt_intenable:     .word   0             /* Virtual INTENABLE     */
58_xt_vpri_mask:     .word   0xFFFFFFFF    /* Virtual priority mask */
59#endif
60
61/*
62-------------------------------------------------------------------------------
63  Table of C-callable interrupt handlers for each interrupt. Note that not all
64  slots can be filled, because interrupts at level > EXCM_LEVEL will not be
65  dispatched to a C handler by default.
66
67  Stored as:
68  int 0 cpu 0
69  int 0 cpu 1
70  ...
71  int 0 cpu n
72  int 1 cpu 0
73  int 1 cpu 1
74  etc
75-------------------------------------------------------------------------------
76*/
77
78    .data
79    .global _xt_interrupt_table
80    .align  8
81
82_xt_interrupt_table:
83
84    .set    i, 0
85    .rept   XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS
86    .word   xt_unhandled_interrupt      /* handler address               */
87    .word   i                           /* handler arg (default: intnum) */
88    .set    i, i+1
89    .endr
90
91#endif /* XCHAL_HAVE_INTERRUPTS */
92
93
94#if XCHAL_HAVE_EXCEPTIONS
95
96/*
97-------------------------------------------------------------------------------
98  Table of C-callable exception handlers for each exception. Note that not all
99  slots will be active, because some exceptions (e.g. coprocessor exceptions)
100  are always handled by the OS and cannot be hooked by user handlers.
101
102  Stored as:
103  exc 0 cpu 0
104  exc 0 cpu 1
105  ...
106  exc 0 cpu n
107  exc 1 cpu 0
108  exc 1 cpu 1
109  etc
110-------------------------------------------------------------------------------
111*/
112
113    .data
114    .global _xt_exception_table
115    .align  4
116
117_xt_exception_table:
118    .rept   XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS
119    .word   xt_unhandled_exception    /* handler address */
120    .endr
121
122#endif
123
124
125/*
126-------------------------------------------------------------------------------
127  unsigned int xt_ints_on ( unsigned int mask )
128
129  Enables a set of interrupts. Does not simply set INTENABLE directly, but
130  computes it as a function of the current virtual priority if XT_USE_SWPRI is
131  enabled.
132  Can be called from interrupt handlers.
133-------------------------------------------------------------------------------
134*/
135
136    .text
137    .align  4
138    .global xt_ints_on
139    .type   xt_ints_on,@function
140
141xt_ints_on:
142
143    ENTRY0
144
145#if XCHAL_HAVE_INTERRUPTS
146#if XT_USE_SWPRI
147    movi    a3, 0
148    movi    a4, _xt_intdata
149    xsr     a3, INTENABLE        /* Disables all interrupts   */
150    rsync
151    l32i    a3, a4, 0            /* a3 = _xt_intenable        */
152    l32i    a6, a4, 4            /* a6 = _xt_vpri_mask        */
153    or      a5, a3, a2           /* a5 = _xt_intenable | mask */
154    s32i    a5, a4, 0            /* _xt_intenable |= mask     */
155    and     a5, a5, a6           /* a5 = _xt_intenable & _xt_vpri_mask */
156    wsr     a5, INTENABLE        /* Reenable interrupts       */
157    mov     a2, a3               /* Previous mask             */
158#else
159    movi    a3, 0
160    xsr     a3, INTENABLE        /* Disables all interrupts   */
161    rsync
162    or      a2, a3, a2           /* set bits in mask */
163    wsr     a2, INTENABLE        /* Re-enable ints */
164    rsync
165    mov     a2, a3               /* return prev mask */
166#endif
167#else
168    movi    a2, 0                /* Return zero */
169#endif
170    RET0
171
172    .size   xt_ints_on, . - xt_ints_on
173
174
175/*
176-------------------------------------------------------------------------------
177  unsigned int xt_ints_off ( unsigned int mask )
178
179  Disables a set of interrupts. Does not simply set INTENABLE directly,
180  but computes it as a function of the current virtual priority if XT_USE_SWPRI is
181  enabled.
182  Can be called from interrupt handlers.
183-------------------------------------------------------------------------------
184*/
185
186    .text
187    .align  4
188    .global xt_ints_off
189    .type   xt_ints_off,@function
190
191xt_ints_off:
192
193    ENTRY0
194#if XCHAL_HAVE_INTERRUPTS
195#if XT_USE_SWPRI
196    movi    a3, 0
197    movi    a4, _xt_intdata
198    xsr     a3, INTENABLE        /* Disables all interrupts    */
199    rsync
200    l32i    a3, a4, 0            /* a3 = _xt_intenable         */
201    l32i    a6, a4, 4            /* a6 = _xt_vpri_mask         */
202    or      a5, a3, a2           /* a5 = _xt_intenable | mask  */
203    xor     a5, a5, a2           /* a5 = _xt_intenable & ~mask */
204    s32i    a5, a4, 0            /* _xt_intenable &= ~mask     */
205    and     a5, a5, a6           /* a5 = _xt_intenable & _xt_vpri_mask */
206    wsr     a5, INTENABLE        /* Reenable interrupts        */
207    mov     a2, a3               /* Previous mask              */
208#else
209    movi    a4, 0
210    xsr     a4, INTENABLE        /* Disables all interrupts   */
211    rsync
212    or      a3, a4, a2           /* set bits in mask */
213    xor     a3, a3, a2           /* invert bits in mask set in mask, essentially clearing them */
214    wsr     a3, INTENABLE        /* Re-enable ints */
215    rsync
216    mov     a2, a4               /* return prev mask */
217#endif
218#else
219    movi    a2, 0                /* return zero */
220#endif
221    RET0
222
223    .size   xt_ints_off, . - xt_ints_off
224