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