arch: arc: add nested interrupt support
* add nested interrupt support for interrupts + use a varibale exc_nest_count to trace nest interrupt and exception + regular interrupts can be nested by regular interrupts and fast interrupts + fast interrupt's priority is the highest, cannot be nested * remove the firq stack and exception stack + remove the coressponding kconfig option + all interrupts (normal and fast) and exceptions will be handled in the same stack (_interrupt stack) + the pros are, smaller memory footprint (no firq stack), simpler stack management, simpler codes, etc.. The cons are, possible 10-15 instructions overhead for the case where fast irq nests regular irq * add the case of ARC in test/kernel/gen_isr_table Signed-off-by: Wayne Ren <wei.ren@synopsys.com> Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
072ef10baf
commit
f8d061faf7
|
@ -103,15 +103,6 @@ config RGF_NUM_BANKS
|
|||
register bank, the fast interrupt handler must save
|
||||
and restore general purpose registers.
|
||||
|
||||
config FIRQ_STACK_SIZE
|
||||
int
|
||||
prompt "Size of stack for FIRQs (in bytes)"
|
||||
depends on CPU_ARCV2
|
||||
default 1024
|
||||
help
|
||||
FIRQs and regular IRQs have different stacks so that a FIRQ can start
|
||||
running without doing stack switching in software.
|
||||
|
||||
config ARC_STACK_CHECKING
|
||||
bool "Enable Stack Checking"
|
||||
depends on CPU_ARCV2
|
||||
|
|
|
@ -21,27 +21,13 @@
|
|||
|
||||
GTEXT(_firq_enter)
|
||||
GTEXT(_firq_exit)
|
||||
GTEXT(_firq_stack_setup)
|
||||
GTEXT(_firq_stack_suspend)
|
||||
GTEXT(_firq_stack_resume)
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
GDATA(_firq_stack)
|
||||
GDATA(_saved_firq_stack)
|
||||
|
||||
SECTION_VAR(NOINIT, _firq_stack)
|
||||
.space CONFIG_FIRQ_STACK_SIZE
|
||||
#else
|
||||
GDATA(saved_r0)
|
||||
#endif
|
||||
|
||||
.macro _firq_return
|
||||
GDATA(exc_nest_count)
|
||||
#if CONFIG_RGF_NUM_BANKS == 1
|
||||
b _firq_no_reschedule
|
||||
GDATA(saved_r0)
|
||||
#else
|
||||
rtie
|
||||
GDATA(saved_sp)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -66,7 +52,6 @@ GDATA(saved_r0)
|
|||
*/
|
||||
|
||||
SECTION_FUNC(TEXT, _firq_enter)
|
||||
|
||||
/*
|
||||
* ATTENTION:
|
||||
* If CONFIG_RGF_NUM_BANKS>1, firq uses a 2nd register bank so GPRs do
|
||||
|
@ -74,7 +59,6 @@ SECTION_FUNC(TEXT, _firq_enter)
|
|||
* If CONFIG_RGF_NUM_BANKS==1, firq must use the stack to save registers.
|
||||
* This has already been done by _isr_wrapper.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* disable stack checking */
|
||||
lr r2, [_ARC_V2_STATUS32]
|
||||
|
@ -95,8 +79,41 @@ SECTION_FUNC(TEXT, _firq_enter)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
ld r1, [exc_nest_count]
|
||||
add r0, r1, 1
|
||||
st r0, [exc_nest_count]
|
||||
cmp r1, 0
|
||||
|
||||
bgt.d firq_nest
|
||||
mov r0, sp
|
||||
|
||||
mov r1, _kernel
|
||||
ld sp, [r1, _kernel_offset_to_irq_stack]
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
b firq_nest_1
|
||||
firq_nest:
|
||||
mov r1, ilink
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
kflag r0
|
||||
|
||||
st sp, [saved_sp]
|
||||
|
||||
lr ilink, [_ARC_V2_STATUS32]
|
||||
or ilink, ilink, _ARC_V2_STATUS32_RB(1)
|
||||
kflag ilink
|
||||
mov r0, sp
|
||||
ld sp, [saved_sp]
|
||||
mov ilink, r1
|
||||
firq_nest_1:
|
||||
#else
|
||||
firq_nest:
|
||||
#endif
|
||||
push_s r0
|
||||
j @_isr_demux
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Work to be done exiting a FIRQ
|
||||
|
@ -106,6 +123,8 @@ SECTION_FUNC(TEXT, _firq_enter)
|
|||
|
||||
SECTION_FUNC(TEXT, _firq_exit)
|
||||
|
||||
pop sp
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
#ifndef CONFIG_FIRQ_NO_LPCC
|
||||
/* restore lp_count, lp_start, lp_end from r23-r25 */
|
||||
|
@ -114,29 +133,20 @@ SECTION_FUNC(TEXT, _firq_exit)
|
|||
sr r25, [_ARC_V2_LP_END]
|
||||
#endif
|
||||
#endif
|
||||
/* check if we're a nested interrupt: if so, let the interrupted
|
||||
* interrupt handle the reschedule */
|
||||
mov r1, exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
cmp r0, 0
|
||||
bne.d _firq_no_reschedule
|
||||
st r0, [r1]
|
||||
|
||||
#ifdef CONFIG_PREEMPT_ENABLED
|
||||
|
||||
mov_s r1, _kernel
|
||||
ld_s r2, [r1, _kernel_offset_to_current]
|
||||
|
||||
#if CONFIG_NUM_IRQ_PRIO_LEVELS > 1
|
||||
/* check if we're a nested interrupt: if so, let the interrupted
|
||||
* interrupt handle the reschedule */
|
||||
|
||||
lr r3, [_ARC_V2_AUX_IRQ_ACT]
|
||||
|
||||
/* the OS on ARCv2 always runs in kernel mode, so assume bit31 [U] in
|
||||
* AUX_IRQ_ACT is always 0: if the contents of AUX_IRQ_ACT is not 1, it
|
||||
* means that another bit is set so an interrupt was interrupted.
|
||||
*/
|
||||
|
||||
breq r3, 1, _firq_check_for_swap
|
||||
|
||||
_firq_return
|
||||
#endif
|
||||
|
||||
.balign 4
|
||||
_firq_check_for_swap:
|
||||
/*
|
||||
* Non-preemptible thread ? Do not schedule (see explanation of
|
||||
* preempt field in kernel_struct.h).
|
||||
|
@ -180,7 +190,6 @@ _firq_no_reschedule:
|
|||
sr r0, [_ARC_V2_LP_START]
|
||||
pop_s r0
|
||||
mov lp_count,r0
|
||||
ld r0,[saved_r0]
|
||||
#ifdef CONFIG_CODE_DENSITY
|
||||
pop_s r0
|
||||
sr r0, [_ARC_V2_EI_BASE]
|
||||
|
@ -189,6 +198,7 @@ _firq_no_reschedule:
|
|||
pop_s r0
|
||||
sr r0, [_ARC_V2_JLI_BASE]
|
||||
#endif
|
||||
ld r0,[saved_r0]
|
||||
add sp,sp,8 /* don't need ilink & status32_po from stack */
|
||||
#endif
|
||||
rtie
|
||||
|
@ -295,84 +305,3 @@ _firq_return_from_firq:
|
|||
rtie
|
||||
|
||||
#endif /* CONFIG_PREEMPT_ENABLED */
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Install the FIRQ stack in register bank 1 if CONFIG_RGF_NUM_BANK!=1
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
SECTION_FUNC(TEXT, _firq_stack_setup)
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
or r0, r0, _ARC_V2_STATUS32_RB(1)
|
||||
kflag r0
|
||||
|
||||
mov sp, _firq_stack
|
||||
add sp, sp, CONFIG_FIRQ_STACK_SIZE
|
||||
|
||||
/*
|
||||
* We have to reload r0 here, because it is bank1 r0 which contains
|
||||
* garbage, not bank0 r0 containing the previous value of status32.
|
||||
*/
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
kflag r0
|
||||
#endif
|
||||
|
||||
j_s [blink]
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Save the FIRQ context if CONFIG_RGF_NUM_BANK!=1
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
SECTION_FUNC(TEXT, _firq_stack_suspend)
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
/* Switch to bank 1 */
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
or r0, r0, _ARC_V2_STATUS32_RB(1)
|
||||
kflag r0
|
||||
|
||||
st sp, [_saved_firq_stack]
|
||||
|
||||
/* Switch back to bank 0 */
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
kflag r0
|
||||
#endif
|
||||
|
||||
j_s [blink]
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Restore the FIRQ context if CONFIG_RGF_NUM_BANK!=1
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
SECTION_FUNC(TEXT, _firq_stack_resume)
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
/* Switch to bank 1 */
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
or r0, r0, _ARC_V2_STATUS32_RB(1)
|
||||
kflag r0
|
||||
|
||||
ld sp, [_saved_firq_stack]
|
||||
|
||||
/* Switch back to bank 0 */
|
||||
lr r0, [_ARC_V2_STATUS32]
|
||||
and r0, r0, ~_ARC_V2_STATUS32_RB(7)
|
||||
kflag r0
|
||||
#endif
|
||||
|
||||
j_s [blink]
|
||||
|
|
|
@ -33,18 +33,7 @@ GTEXT(__ev_div_zero)
|
|||
GTEXT(__ev_dc_error)
|
||||
GTEXT(__ev_maligned)
|
||||
|
||||
SECTION_VAR(BSS, saved_stack_pointer)
|
||||
.balign 4
|
||||
.word 0
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS == 1
|
||||
GDATA(_exception_stack)
|
||||
SECTION_VAR(NOINIT, _exception_stack)
|
||||
.space 512
|
||||
/* note: QUARK_SE_C1000_SS can't afford 512B */
|
||||
#else
|
||||
GDATA(_firq_stack)
|
||||
#endif
|
||||
GDATA(exc_nest_count)
|
||||
|
||||
/*
|
||||
* @brief Fault handler installed in the fault and reserved vectors
|
||||
|
@ -82,15 +71,6 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_maligned)
|
|||
pop_s r2
|
||||
#endif
|
||||
|
||||
st sp, [saved_stack_pointer]
|
||||
#if CONFIG_RGF_NUM_BANKS == 1
|
||||
mov_s sp, _exception_stack
|
||||
add sp, sp, 512
|
||||
#else
|
||||
mov_s sp, _firq_stack
|
||||
add sp, sp, CONFIG_FIRQ_STACK_SIZE
|
||||
#endif
|
||||
|
||||
/* save caller saved registers */
|
||||
_create_irq_stack_frame
|
||||
|
||||
|
@ -99,13 +79,32 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_maligned)
|
|||
lr r0,[_ARC_V2_ERET]
|
||||
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
|
||||
|
||||
|
||||
ld r1, [exc_nest_count]
|
||||
add r0, r1, 1
|
||||
st r0, [exc_nest_count]
|
||||
cmp r1, 0
|
||||
|
||||
bgt.d exc_nest_handle
|
||||
mov r0, sp
|
||||
|
||||
mov r1, _kernel
|
||||
ld sp, [r1, _kernel_offset_to_irq_stack]
|
||||
exc_nest_handle:
|
||||
push_s r0
|
||||
|
||||
jl _Fault
|
||||
|
||||
pop sp
|
||||
|
||||
mov r1, exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
st r0, [r1]
|
||||
|
||||
/* if _Fault returns, restore the registers */
|
||||
_pop_irq_stack_frame
|
||||
|
||||
/* now restore the stack */
|
||||
ld sp,[saved_stack_pointer]
|
||||
rtie
|
||||
|
||||
#ifdef CONFIG_IRQ_OFFLOAD
|
||||
|
@ -136,26 +135,41 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
|||
lr r0,[_ARC_V2_ERET]
|
||||
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
|
||||
|
||||
ld r1, [exc_nest_count]
|
||||
add r0, r1, 1
|
||||
st r0, [exc_nest_count]
|
||||
cmp r1, 0
|
||||
|
||||
bgt.d trap_nest_handle
|
||||
mov r0, sp
|
||||
|
||||
mov r1, _kernel
|
||||
ld sp, [r1, _kernel_offset_to_irq_stack]
|
||||
trap_nest_handle:
|
||||
push_s r0
|
||||
|
||||
jl _irq_do_offload
|
||||
|
||||
mov_s r1, _kernel
|
||||
ld_s r2, [r1, _kernel_offset_to_current]
|
||||
pop sp
|
||||
|
||||
/* check if we're a nested interrupt: if so, let the
|
||||
* interrupted interrupt handle the reschedule
|
||||
*/
|
||||
lr r3, [_ARC_V2_AUX_IRQ_ACT]
|
||||
/* the OS on ARCv2 always runs in kernel mode, so assume bit31 [U] in
|
||||
* AUX_IRQ_ACT is always 0: if the contents of AUX_IRQ_ACT is 0, it
|
||||
* means trap was taken from outside an interrupt handler.
|
||||
* But if it was inside, let that handler do the swap.
|
||||
*/
|
||||
breq r3, 0, _trap_check_for_swap
|
||||
mov r1, exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
cmp r0, 0
|
||||
beq.d _trap_check_for_swap
|
||||
st r0, [r1]
|
||||
|
||||
_trap_return:
|
||||
_pop_irq_stack_frame
|
||||
rtie
|
||||
|
||||
.balign 4
|
||||
_trap_check_for_swap:
|
||||
mov_s r1, _kernel
|
||||
ld_s r2, [r1, _kernel_offset_to_current]
|
||||
/*
|
||||
* Non-preemptible thread ? Do not schedule (see explanation of
|
||||
* preempt field in kernel_struct.h).
|
||||
|
|
|
@ -23,13 +23,24 @@
|
|||
GTEXT(_isr_wrapper)
|
||||
GTEXT(_isr_demux)
|
||||
|
||||
GDATA(exc_nest_count)
|
||||
SECTION_VAR(BSS, exc_nest_count)
|
||||
.balign 4
|
||||
.word 0
|
||||
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS == 1
|
||||
GDATA(saved_r0)
|
||||
|
||||
SECTION_VAR(BSS, saved_r0)
|
||||
.balign 4
|
||||
.word 0
|
||||
#else
|
||||
GDATA(saved_sp)
|
||||
|
||||
SECTION_VAR(BSS, saved_sp)
|
||||
.balign 4
|
||||
.word 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_POWER_MANAGEMENT)
|
||||
|
@ -231,6 +242,14 @@ SECTION_FUNC(TEXT, _isr_wrapper)
|
|||
push_s r0
|
||||
mov r0,ilink
|
||||
push_s r0
|
||||
#ifdef CONFIG_CODE_DENSITY
|
||||
lr r0, [_ARC_V2_JLI_BASE]
|
||||
push_s r0
|
||||
lr r0, [_ARC_V2_LDI_BASE]
|
||||
push_s r0
|
||||
lr r0, [_ARC_V2_EI_BASE]
|
||||
push_s r0
|
||||
#endif
|
||||
mov r0,lp_count
|
||||
push_s r0
|
||||
lr r0, [_ARC_V2_LP_START]
|
||||
|
@ -326,6 +345,7 @@ _skip_sys_power_save_idle_exit:
|
|||
SECTION_FUNC(TEXT, _isr_demux)
|
||||
push_s r3
|
||||
|
||||
|
||||
/* cannot be done before this point because we must be able to run C */
|
||||
/* r0 is available to be stomped here, and exit_tickless_idle uses it */
|
||||
exit_tickless_idle
|
||||
|
@ -333,6 +353,12 @@ SECTION_FUNC(TEXT, _isr_demux)
|
|||
log_sleep_k_event
|
||||
|
||||
lr r0, [_ARC_V2_ICAUSE]
|
||||
/* handle software triggered interrupt */
|
||||
lr r3, [_ARC_V2_AUX_IRQ_HINT]
|
||||
brne r3, r0, irq_hint_handled
|
||||
sr 0, [_ARC_V2_AUX_IRQ_HINT]
|
||||
irq_hint_handled:
|
||||
|
||||
sub r0, r0, 16
|
||||
|
||||
mov r1, _sw_isr_table
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
GTEXT(_rirq_enter)
|
||||
GTEXT(_rirq_exit)
|
||||
GTEXT(_rirq_common_interrupt_swap)
|
||||
GDATA(exc_nest_count)
|
||||
|
||||
#if 0 /* TODO: when FIRQ is not present, all would be regular */
|
||||
#define NUM_REGULAR_IRQ_PRIO_LEVELS CONFIG_NUM_IRQ_PRIO_LEVELS
|
||||
|
@ -34,14 +35,6 @@ GTEXT(_rirq_common_interrupt_swap)
|
|||
* TODO: Revist this if FIRQ becomes configurable.
|
||||
*/
|
||||
|
||||
#if NUM_REGULAR_IRQ_PRIO_LEVELS > 1
|
||||
#error "nested regular interrupts are not supported."
|
||||
/*
|
||||
* Nesting of Regularing interrupts is not yet supported.
|
||||
* Set CONFIG_NUM_IRQ_PRIO_LEVELS to 2 even if SOC supports more.
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -58,20 +51,28 @@ GTEXT(_rirq_common_interrupt_swap)
|
|||
|
||||
SECTION_FUNC(TEXT, _rirq_enter)
|
||||
|
||||
mov r1, _kernel
|
||||
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* disable stack checking */
|
||||
lr r2, [_ARC_V2_STATUS32]
|
||||
bclr r2, r2, _ARC_V2_STATUS32_SC_BIT
|
||||
kflag r2
|
||||
#endif
|
||||
ld_s r2, [r1, _kernel_offset_to_current]
|
||||
#if NUM_REGULAR_IRQ_PRIO_LEVELS == 1
|
||||
st sp, [r2, _thread_offset_to_sp]
|
||||
clri
|
||||
ld r1, [exc_nest_count]
|
||||
add r0, r1, 1
|
||||
st r0, [exc_nest_count]
|
||||
cmp r1, 0
|
||||
|
||||
bgt.d rirq_nest
|
||||
mov r0, sp
|
||||
|
||||
mov r1, _kernel
|
||||
ld sp, [r1, _kernel_offset_to_irq_stack]
|
||||
#else
|
||||
#error regular irq nesting is not implemented
|
||||
#endif
|
||||
rirq_nest:
|
||||
push_s r0
|
||||
|
||||
seti
|
||||
j _isr_demux
|
||||
|
||||
|
||||
|
@ -83,6 +84,16 @@ SECTION_FUNC(TEXT, _rirq_enter)
|
|||
*/
|
||||
|
||||
SECTION_FUNC(TEXT, _rirq_exit)
|
||||
clri
|
||||
|
||||
pop sp
|
||||
|
||||
mov r1, exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
cmp r0, 0
|
||||
bne.d _rirq_return_from_rirq
|
||||
st r0, [r1]
|
||||
|
||||
#ifdef CONFIG_PREEMPT_ENABLED
|
||||
|
||||
|
@ -94,26 +105,6 @@ SECTION_FUNC(TEXT, _rirq_exit)
|
|||
* point on until return from interrupt.
|
||||
*/
|
||||
|
||||
clri
|
||||
|
||||
#if NUM_REGULAR_IRQ_PRIO_LEVELS > 1
|
||||
/* check if we're a nested interrupt: if so, let the interrupted interrupt
|
||||
* handle the reschedule */
|
||||
|
||||
lr r3, [_ARC_V2_AUX_IRQ_ACT]
|
||||
ffs r0, r3
|
||||
|
||||
asl r0, 1, r0
|
||||
|
||||
/* the OS on ARCv2 always runs in kernel mode, so assume bit31 [U] in
|
||||
* AUX_IRQ_ACT is always 0: if the contents of AUX_IRQ_ACT is greater
|
||||
* than FFS(AUX_IRQ_ACT), it means that another bit is set so an
|
||||
* interrupt was interrupted.
|
||||
*/
|
||||
|
||||
cmp r0, r3
|
||||
brgt _rirq_return_from_rirq
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Non-preemptible thread ? Do not schedule (see explanation of
|
||||
|
@ -134,8 +125,6 @@ SECTION_FUNC(TEXT, _rirq_exit)
|
|||
* b) needs to load it to restore the interrupted context.
|
||||
*/
|
||||
|
||||
ld sp, [r2, _thread_offset_to_sp]
|
||||
|
||||
/* check if the current thread needs to be rescheduled */
|
||||
ld_s r0, [r1, _kernel_offset_to_ready_q_cache]
|
||||
cmp_s r0, r2
|
||||
|
@ -218,10 +207,6 @@ _rirq_return_from_coop:
|
|||
|
||||
/* fall through to rtie instruction */
|
||||
|
||||
.balign 4
|
||||
_rirq_return_from_firq:
|
||||
_rirq_return_from_rirq:
|
||||
|
||||
/* rtie will pop the rest from the stack */
|
||||
|
||||
/* fall through to rtie instruction */
|
||||
|
@ -229,6 +214,8 @@ _rirq_return_from_rirq:
|
|||
#endif /* CONFIG_PREEMPT_ENABLED */
|
||||
|
||||
.balign 4
|
||||
_rirq_return_from_firq:
|
||||
_rirq_return_from_rirq:
|
||||
_rirq_no_reschedule:
|
||||
|
||||
rtie
|
||||
|
|
|
@ -17,26 +17,13 @@
|
|||
#include <arch/cpu.h>
|
||||
|
||||
GDATA(_interrupt_stack)
|
||||
GDATA(_firq_stack)
|
||||
GDATA(_main_stack)
|
||||
|
||||
/* use one of the available interrupt stacks during init */
|
||||
|
||||
/* FIRQ only ? */
|
||||
#if CONFIG_NUM_IRQ_PRIO_LEVELS == 1
|
||||
|
||||
/* FIRQ, but uses _interrupt_stack ? */
|
||||
#if CONFIG_RGF_NUM_BANKS == 1
|
||||
#define INIT_STACK _interrupt_stack
|
||||
#define INIT_STACK_SIZE CONFIG_ISR_STACK_SIZE
|
||||
#else
|
||||
#define INIT_STACK _firq_stack
|
||||
#define INIT_STACK_SIZE CONFIG_FIRQ_STACK_SIZE
|
||||
#endif
|
||||
#else
|
||||
#define INIT_STACK _interrupt_stack
|
||||
#define INIT_STACK_SIZE CONFIG_ISR_STACK_SIZE
|
||||
#endif
|
||||
#define INIT_STACK _interrupt_stack
|
||||
#define INIT_STACK_SIZE CONFIG_ISR_STACK_SIZE
|
||||
|
||||
GTEXT(__reset)
|
||||
GTEXT(__start)
|
||||
|
@ -106,13 +93,6 @@ done_cache_invalidate:
|
|||
mov_s r2, CONFIG_ISR_STACK_SIZE
|
||||
jl memset
|
||||
|
||||
#if CONFIG_RGF_NUM_BANKS != 1
|
||||
mov_s r0, _firq_stack
|
||||
mov_s r1, 0xaa
|
||||
mov_s r2, CONFIG_FIRQ_STACK_SIZE
|
||||
jl memset
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_INIT_STACKS */
|
||||
|
||||
mov sp, INIT_STACK
|
||||
|
|
|
@ -32,7 +32,6 @@ extern "C" {
|
|||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
extern void _firq_stack_setup(void);
|
||||
extern K_THREAD_STACK_DEFINE(_interrupt_stack, CONFIG_ISR_STACK_SIZE);
|
||||
|
||||
/*
|
||||
|
@ -56,7 +55,6 @@ static ALWAYS_INLINE void _irq_setup(void)
|
|||
|
||||
_kernel.irq_stack =
|
||||
K_THREAD_STACK_BUFFER(_interrupt_stack) + CONFIG_ISR_STACK_SIZE;
|
||||
_firq_stack_setup();
|
||||
}
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
|
|
@ -13,9 +13,7 @@ config SOC
|
|||
config NUM_IRQ_PRIO_LEVELS
|
||||
# This processor supports 4 priority levels:
|
||||
# 0 for Fast Interrupts (FIRQs) and 1-3 for Regular Interrupts (IRQs).
|
||||
# TODO: But regular irq nesting is not implemented --
|
||||
# so this must be 2 for now.
|
||||
default 2
|
||||
default 4
|
||||
|
||||
config NUM_IRQS
|
||||
# must be > the highest interrupt number used
|
||||
|
|
|
@ -13,9 +13,7 @@ config SOC
|
|||
config NUM_IRQ_PRIO_LEVELS
|
||||
# This processor supports 4 priority levels:
|
||||
# 0 for Fast Interrupts (FIRQs) and 1-3 for Regular Interrupts (IRQs).
|
||||
# TODO: But regular irq nesting is not implemented --
|
||||
# so this must be 2 for now.
|
||||
default 2
|
||||
default 4
|
||||
|
||||
config NUM_IRQS
|
||||
# must be > the highest interrupt number used
|
||||
|
|
|
@ -13,9 +13,7 @@ config SOC
|
|||
config NUM_IRQ_PRIO_LEVELS
|
||||
# This processor supports 4 priority levels:
|
||||
# 0 for Fast Interrupts (FIRQs) and 1-3 for Regular Interrupts (IRQs).
|
||||
# TODO: But regular irq nesting is not implemented --
|
||||
# so this must be 2 for now.
|
||||
default 2
|
||||
default 4
|
||||
|
||||
config NUM_IRQS
|
||||
# must be > the highest interrupt number used
|
||||
|
|
|
@ -29,7 +29,6 @@ extern void *_VectorTable;
|
|||
#include <v2/irq.h>
|
||||
|
||||
static u32_t _arc_v2_irq_unit_device_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||
u32_t _saved_firq_stack;
|
||||
struct arc_v2_irq_unit_ctx {
|
||||
u32_t irq_ctrl; /* Interrupt Context Saving Control Register. */
|
||||
u32_t irq_vect_base; /* Interrupt Vector Base. */
|
||||
|
@ -97,8 +96,6 @@ unsigned int _arc_v2_irq_unit_trigger_get(int irq)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||
extern void _firq_stack_suspend(void);
|
||||
extern void _firq_stack_resume(void);
|
||||
|
||||
static int _arc_v2_irq_unit_suspend(struct device *dev)
|
||||
{
|
||||
|
@ -123,8 +120,6 @@ static int _arc_v2_irq_unit_suspend(struct device *dev)
|
|||
ctx.irq_ctrl = _arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_CTRL);
|
||||
ctx.irq_vect_base = _arc_v2_aux_reg_read(_ARC_V2_IRQ_VECT_BASE);
|
||||
|
||||
_firq_stack_suspend();
|
||||
|
||||
_arc_v2_irq_unit_device_power_state = DEVICE_PM_SUSPEND_STATE;
|
||||
|
||||
return 0;
|
||||
|
@ -137,8 +132,6 @@ static int _arc_v2_irq_unit_resume(struct device *dev)
|
|||
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
_firq_stack_resume();
|
||||
|
||||
/* Interrupts from 0 to 15 are exceptions and they are ignored
|
||||
* by IRQ auxiliary registers. For that reason we skip those
|
||||
* values in this loop.
|
||||
|
|
|
@ -124,9 +124,6 @@ extern void idle(void *unused1, void *unused2, void *unused3);
|
|||
#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK)
|
||||
extern K_THREAD_STACK_DEFINE(sys_work_q_stack,
|
||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE);
|
||||
#if defined(CONFIG_ARC) && CONFIG_RGF_NUM_BANKS != 1
|
||||
extern K_THREAD_STACK_DEFINE(_firq_stack, CONFIG_FIRQ_STACK_SIZE);
|
||||
#endif /* CONFIG_ARC */
|
||||
|
||||
|
||||
void k_call_stacks_analyze(void)
|
||||
|
@ -134,9 +131,6 @@ void k_call_stacks_analyze(void)
|
|||
printk("Kernel stacks:\n");
|
||||
STACK_ANALYZE("main ", _main_stack);
|
||||
STACK_ANALYZE("idle ", _idle_stack);
|
||||
#if defined(CONFIG_ARC) && CONFIG_RGF_NUM_BANKS != 1
|
||||
STACK_ANALYZE("firq ", _firq_stack);
|
||||
#endif /* CONFIG_ARC */
|
||||
STACK_ANALYZE("interrupt", _interrupt_stack);
|
||||
STACK_ANALYZE("workqueue", sys_work_q_stack);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,11 @@ void trigger_irq(int irq)
|
|||
: "=r" (mip)
|
||||
: "r" (1 << irq));
|
||||
}
|
||||
#elif defined(CONFIG_CPU_ARCV2)
|
||||
void trigger_irq(int irq)
|
||||
{
|
||||
_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_HINT, irq);
|
||||
}
|
||||
#else
|
||||
/* So far, Nios II does not support this */
|
||||
#define NO_TRIGGER_FROM_SW
|
||||
|
|
Loading…
Reference in a new issue