/* ------------------------------------------ | |
* Copyright (c) 2016, Synopsys, Inc. All rights reserved. | |
* Redistribution and use in source and binary forms, with or without modification, | |
* are permitted provided that the following conditions are met: | |
* 1) Redistributions of source code must retain the above copyright notice, this | |
* list of conditions and the following disclaimer. | |
* 2) Redistributions in binary form must reproduce the above copyright notice, | |
* this list of conditions and the following disclaimer in the documentation and/or | |
* other materials provided with the distribution. | |
* 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may | |
* be used to endorse or promote products derived from this software without | |
* specific prior written permission. | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* | |
* \version 2016.05 | |
* \date 2014-07-15 | |
* \author Wayne Ren(Wei.Ren@synopsys.com) | |
--------------------------------------------- */ | |
/** | |
* \file | |
* \ingroup ARC_HAL_EXCEPTION_CPU | |
* \brief assembly part of exception and interrupt processing | |
*/ | |
/** | |
* \addtogroup ARC_HAL_EXCEPTION_CPU | |
* @{ | |
*/ | |
/* function documentation */ | |
/** | |
* \fn void exc_entry_cpu(void) | |
* \brief default entry of CPU exceptions, such as TLB miss and swap. | |
* | |
* \fn void exc_entry_int(void) | |
* \brief normal interrupt exception entry. | |
* In default, all interrupt exceptions are installed with normal entry. | |
* If FIRQ is required, exc_entry_firq should be the entry. | |
* | |
* \fn void exc_entry_firq(void) | |
* \brief firq exception entry | |
*/ | |
/** }@ */ | |
/** @cond EXCEPTION_ASM */ | |
#define __ASSEMBLY__ | |
#include "embARC_BSP_config.h" | |
#include "../inc/arc/arc.h" | |
#include "../inc/arc/arc_asm_common.h" | |
.file "arc_exc_asm.S" | |
/* entry for cpu exception handling */ | |
.text | |
.global exc_entry_cpu | |
.weak exc_entry_cpu | |
.align 4 | |
exc_entry_cpu: | |
EXCEPTION_PROLOGUE | |
mov r3, sp /* as exception handler's para(exc_frame) */ | |
/* exc_nest_count +1 */ | |
ld r0, [exc_nest_count] | |
add r0, r0, 1 | |
st r0, [exc_nest_count] | |
/* find the exception cause */ | |
lr r0, [AUX_ECR] | |
lsr r0, r0, 16 | |
bmsk r0, r0, 7 | |
mov r1, exc_int_handler_table | |
ld.as r2, [r1, r0] | |
mov r0, r3 | |
jl [r2] /* jump to exception handler where interrupts are not allowed! */ | |
/* interrupts are not allowed */ | |
exc_return: | |
/* exc_nest_count -1 */ | |
ld r0, [exc_nest_count] | |
sub r0, r0, 1 | |
st r0, [exc_nest_count] | |
EXCEPTION_EPILOGUE | |
rtie | |
/****** entry for normal interrupt exception handling ******/ | |
.global exc_entry_int | |
.weak exc_entry_int | |
.align 4 | |
exc_entry_int: | |
clri /* disable interrupt */ | |
#if ARC_FEATURE_FIRQ == 1 | |
#if ARC_FEATURE_RGF_NUM_BANKS > 1 | |
lr r0, [AUX_IRQ_ACT] /* check whether it is P0 interrupt */ | |
btst r0, 0 | |
bnz exc_entry_firq | |
#else | |
PUSH r10 | |
lr r10, [AUX_IRQ_ACT] | |
btst r10, 0 | |
POP r10 | |
bnz exc_entry_firq | |
#endif | |
#endif | |
INTERRUPT_PROLOGUE /* save scratch regs, this will be affected */ | |
/* exc_nest_count +1 */ | |
ld r0, [exc_nest_count] | |
add r0, r0, 1 | |
st r0, [exc_nest_count] | |
lr r0, [AUX_IRQ_CAUSE] | |
mov r1, exc_int_handler_table | |
ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */ | |
/* for the case of software triggered interrupt */ | |
lr r3, [AUX_IRQ_HINT] | |
cmp r3, r0 | |
bne.d irq_hint_handled | |
xor r3, r3, r3 | |
sr r3, [AUX_IRQ_HINT] | |
irq_hint_handled: | |
seti /* enable higher priority interrupt */ | |
mov r0, sp | |
jl [r2] /* jump to interrupt handler */ | |
/* no interrupts are allowed from here */ | |
int_return: | |
clri /* disable interrupt */ | |
/* exc_nest_count -1 */ | |
ld r0, [exc_nest_count] | |
sub r0, r0, 1 | |
st r0, [exc_nest_count] | |
INTERRUPT_EPILOGUE | |
rtie | |
/****** entry for fast irq exception handling ******/ | |
.global exc_entry_firq | |
.weak exc_entry_firq | |
.align 4 | |
exc_entry_firq: | |
clri /* disable interrupt */ | |
SAVE_FIQ_EXC_REGS | |
/* exc_nest_count +1 */ | |
ld r0, [exc_nest_count] | |
add r0, r0, 1 | |
st r0, [exc_nest_count] | |
lr r0, [AUX_IRQ_CAUSE] | |
mov r1, exc_int_handler_table | |
ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */ | |
/* for the case of software triggered interrupt */ | |
lr r3, [AUX_IRQ_HINT] | |
cmp r3, r0 | |
bne.d firq_hint_handled | |
xor r3, r3, r3 | |
sr r3, [AUX_IRQ_HINT] | |
firq_hint_handled: | |
jl [r2] /* jump to interrupt handler */ | |
/* no interrupts are allowed from here */ | |
firq_return: | |
/* exc_nest_count -1 */ | |
ld r0, [exc_nest_count] | |
sub r0, r0, 1 | |
st r0, [exc_nest_count] | |
RESTORE_FIQ_EXC_REGS | |
rtie | |
/** @endcond */ |