1 /* 2 * FreeRTOS Kernel V11.0.1 3 * Copyright (C) 2015-2019 Cadence Design Systems, Inc. 4 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 * 6 * SPDX-License-Identifier: MIT 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy of 9 * this software and associated documentation files (the "Software"), to deal in 10 * the Software without restriction, including without limitation the rights to 11 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 12 * the Software, and to permit persons to whom the Software is furnished to do so, 13 * subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in all 16 * copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * https://www.FreeRTOS.org 26 * https://github.com/FreeRTOS 27 * 28 */ 29 30 /* 31 * Xtensa-specific interrupt and exception functions for RTOS ports. 32 * Also see xtensa_intr_asm.S. 33 */ 34 35 #include <stdlib.h> 36 37 #include <xtensa/config/core.h> 38 39 #include "xtensa_api.h" 40 41 42 #if XCHAL_HAVE_EXCEPTIONS 43 44 /* Handler table is in xtensa_intr_asm.S */ 45 46 extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM ]; 47 48 49 /* 50 * Default handler for unhandled exceptions. 51 */ xt_unhandled_exception(XtExcFrame * frame)52 void xt_unhandled_exception( XtExcFrame * frame ) 53 { 54 exit( -1 ); 55 } 56 57 58 /* 59 * This function registers a handler for the specified exception. 60 * The function returns the address of the previous handler. 61 * On error, it returns 0. 62 */ xt_set_exception_handler(int n,xt_exc_handler f)63 xt_exc_handler xt_set_exception_handler( int n, 64 xt_exc_handler f ) 65 { 66 xt_exc_handler old; 67 68 if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) ) 69 { 70 return 0; /* invalid exception number */ 71 } 72 73 old = _xt_exception_table[ n ]; 74 75 if( f ) 76 { 77 _xt_exception_table[ n ] = f; 78 } 79 else 80 { 81 _xt_exception_table[ n ] = &xt_unhandled_exception; 82 } 83 84 return( ( old == &xt_unhandled_exception ) ? 0 : old ); 85 } 86 87 #endif /* if XCHAL_HAVE_EXCEPTIONS */ 88 89 #if XCHAL_HAVE_INTERRUPTS 90 91 /* Handler table is in xtensa_intr_asm.S */ 92 93 typedef struct xt_handler_table_entry 94 { 95 void * handler; 96 void * arg; 97 } xt_handler_table_entry; 98 99 extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS ]; 100 101 102 /* 103 * Default handler for unhandled interrupts. 104 */ xt_unhandled_interrupt(void * arg)105 void xt_unhandled_interrupt( void * arg ) 106 { 107 exit( -1 ); 108 } 109 110 111 /* 112 * This function registers a handler for the specified interrupt. The "arg" 113 * parameter specifies the argument to be passed to the handler when it is 114 * invoked. The function returns the address of the previous handler. 115 * On error, it returns 0. 116 */ xt_set_interrupt_handler(int n,xt_handler f,void * arg)117 xt_handler xt_set_interrupt_handler( int n, 118 xt_handler f, 119 void * arg ) 120 { 121 xt_handler_table_entry * entry; 122 xt_handler old; 123 124 if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) ) 125 { 126 return 0; /* invalid interrupt number */ 127 } 128 129 if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL ) 130 { 131 return 0; /* priority level too high to safely handle in C */ 132 } 133 134 entry = _xt_interrupt_table + n; 135 old = entry->handler; 136 137 if( f ) 138 { 139 entry->handler = f; 140 entry->arg = arg; 141 } 142 else 143 { 144 entry->handler = &xt_unhandled_interrupt; 145 entry->arg = ( void * ) n; 146 } 147 148 return( ( old == &xt_unhandled_interrupt ) ? 0 : old ); 149 } 150 151 152 #endif /* XCHAL_HAVE_INTERRUPTS */ 153