1 
2 /* int-sethandler.c - register an interrupt handler in XTOS */
3 
4 /*
5  * Copyright (c) 1999-2017 Cadence Design Systems, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 
27 #include "xtos-internal.h"
28 #include "xtos-structs.h"
29 #include <sof/lib/cpu.h>
30 
31 
32 #if XCHAL_HAVE_INTERRUPTS
33 #if CONFIG_MULTICORE
34 extern struct xtos_core_data *core_data_ptr[CONFIG_CORE_COUNT];
35 #else
36 /*
37  *  Table of interrupt handlers.
38  *  NOTE:  if the NSA/NSAU instructions are configured, then to save
39  *  a few cycles in the interrupt dispatcher code, the
40  *  xtos_interrupt_table[] array is filled in reverse.
41  *  IMPORTANT:  Use the MAPINT() macro defined in xtos-internal.h to index entries in this array.
42  */
43 extern XtosIntHandlerEntry      xtos_interrupt_table[XCHAL_NUM_INTERRUPTS];
44 #endif
45 #endif
46 
_xtos_set_interrupt_handler_arg(int n,_xtos_handler f,void * arg)47 _xtos_handler _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg )
48 {
49 #if XCHAL_HAVE_INTERRUPTS
50     XtosIntHandlerEntry *entry;
51     _xtos_handler old;
52     _xtos_handler ret;
53 
54     if( (n < 0) || (n >= XCHAL_NUM_INTERRUPTS) ) {
55         ret = 0;     /* invalid interrupt number */
56     }
57     else if( (int) Xthal_intlevel[n] > XTOS_LOCKLEVEL ) {
58         ret = 0;     /* priority level too high to safely handle in C */
59     }
60     else {
61 #if CONFIG_MULTICORE
62         entry = &(core_data_ptr[cpu_get_id()]->xtos_int_data.xtos_interrupt_table.array[MAPINT(n)]);
63 #else
64         entry = xtos_interrupt_table + MAPINT(n);
65 #endif
66         old = entry->handler;
67         if (f) {
68             entry->handler = f;
69             entry->u.varg  = arg;
70         } else {
71             entry->handler = &xtos_unhandled_interrupt;
72             entry->u.narg  = n;
73         }
74         ret = (old == &xtos_unhandled_interrupt) ? 0 : old;
75     }
76 
77     return ret;
78 #else
79     return 0;
80 #endif
81 }
82 
83 
_xtos_set_interrupt_handler(int n,_xtos_handler f)84 _xtos_handler _xtos_set_interrupt_handler( int n, _xtos_handler f )
85 {
86     return _xtos_set_interrupt_handler_arg( n, f, (void *) n );
87 }
88 
89