Skip to content
Permalink
Browse files

arch: arc: remove saved_r0/saved_sp used in firq handling

* do not use a specific variable (saved_r0/saved_sp) to free r0
  /exchange sp, but use stack to do that.

* it will make code scalable, e.g. for SMP, no need to define
  variables for each core

Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
  • Loading branch information...
vonhust authored and andrewboie committed Jul 3, 2019
1 parent abac940 commit 0318e3a7580dea09308ae38783a316429fd2c8db
Showing with 35 additions and 32 deletions.
  1. +26 −14 arch/arc/core/fast_irq.S
  2. +9 −18 arch/arc/core/isr_wrapper.S
@@ -23,11 +23,7 @@ GTEXT(_firq_enter)
GTEXT(_firq_exit)

GDATA(exc_nest_count)
#if CONFIG_RGF_NUM_BANKS == 1
GDATA(saved_r0)
#else
GDATA(saved_sp)
#endif


/**
*
@@ -98,19 +94,35 @@ SECTION_FUNC(TEXT, _firq_enter)
#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
/*
* because firq and rirq share the same interrupt stack,
* switch back to original register bank to get correct sp.
* to get better firq latency, an approach is to prepare
* separate interrupt stack for firq and do not do thread
* switch in firq.
*/
lr r1, [_ARC_V2_STATUS32]
and r1, r1, ~_ARC_V2_STATUS32_RB(7)
kflag r1

st sp, [saved_sp]
/* here use _ARC_V2_USER_SP and ilink to exchange sp
* save original value of _ARC_V2_USER_SP and ilink into
* the stack of interrupted context first, then restore them later
*/
st ilink, [sp]
lr ilink, [_ARC_V2_USER_SP]
st ilink, [sp, -4]
/* sp here is the sp of interrupted context */
sr sp, [_ARC_V2_USER_SP]

/* switch back to banked reg, only ilink can be used */
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
lr sp, [_ARC_V2_USER_SP]
ld ilink, [sp, -4]
sr ilink, [_ARC_V2_USER_SP]
ld ilink, [sp]
firq_nest_1:
#else
firq_nest:
@@ -176,8 +188,8 @@ _firq_no_reschedule:
*/
#if CONFIG_RGF_NUM_BANKS == 1
_pop_irq_stack_frame
ld r0,[saved_r0]
#endif
lr ilink, [_ARC_V2_ERET]
rtie

#ifdef CONFIG_PREEMPT_ENABLED
@@ -30,20 +30,6 @@ SECTION_VAR(BSS, exc_nest_count)
.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)
GTEXT(z_sys_power_save_idle_exit)
#endif
@@ -228,21 +214,26 @@ From RIRQ:
SECTION_FUNC(TEXT, _isr_wrapper)
#if defined(CONFIG_ARC_FIRQ)
#if CONFIG_RGF_NUM_BANKS == 1
st r0,[saved_r0]
/* free r0 here, use r0 to check whether irq is firq.
* for rirq, as sp will not change and r0 already saved, this action
* in fact is an action like nop.
* for firq, r0 will be restored later
*/
st r0, [sp]
#endif
lr r0, [_ARC_V2_AUX_IRQ_ACT]
ffs r0, r0
cmp r0, 0
#if CONFIG_RGF_NUM_BANKS == 1
bnz rirq_path
ld r0, [sp]
/* 1-register bank FIRQ handling must save registers on stack */
_create_irq_stack_frame
lr r0, [_ARC_V2_STATUS32_P0]
st_s r0, [sp, ___isf_t_status32_OFFSET]
mov r0,ilink
lr r0, [_ARC_V2_ERET]
st_s r0, [sp, ___isf_t_pc_OFFSET]
ld r0,[saved_r0]
st_s r0, [sp, ___isf_t_r0_OFFSET]

mov r3, _firq_exit
mov r2, _firq_enter
j_s [r2]

0 comments on commit 0318e3a

Please sign in to comment.
You can’t perform that action at this time.