ARCv2: support manual regfile save on interrupts
[ Upstream commit e494239a007e601448110ac304fe055951f9de3b ] There's a hardware bug which affects the HSDK platform, triggered by micro-ops for auto-saving regfile on taken interrupt. The workaround is to inhibit autosave. Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
74b4dcea67
commit
3220aa9b00
@ -420,6 +420,14 @@ config ARC_HAS_ACCL_REGS
|
|||||||
(also referred to as r58:r59). These can also be used by gcc as GPR so
|
(also referred to as r58:r59). These can also be used by gcc as GPR so
|
||||||
kernel needs to save/restore per process
|
kernel needs to save/restore per process
|
||||||
|
|
||||||
|
config ARC_IRQ_NO_AUTOSAVE
|
||||||
|
bool "Disable hardware autosave regfile on interrupts"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
On HS cores, taken interrupt auto saves the regfile on stack.
|
||||||
|
This is programmable and can be optionally disabled in which case
|
||||||
|
software INTERRUPT_PROLOGUE/EPILGUE do the needed work
|
||||||
|
|
||||||
endif # ISA_ARCV2
|
endif # ISA_ARCV2
|
||||||
|
|
||||||
endmenu # "ARC CPU Configuration"
|
endmenu # "ARC CPU Configuration"
|
||||||
|
@ -17,6 +17,33 @@
|
|||||||
;
|
;
|
||||||
; Now manually save: r12, sp, fp, gp, r25
|
; Now manually save: r12, sp, fp, gp, r25
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
|
||||||
|
.ifnc \called_from, exception
|
||||||
|
st.as r9, [sp, -10] ; save r9 in it's final stack slot
|
||||||
|
sub sp, sp, 12 ; skip JLI, LDI, EI
|
||||||
|
|
||||||
|
PUSH lp_count
|
||||||
|
PUSHAX lp_start
|
||||||
|
PUSHAX lp_end
|
||||||
|
PUSH blink
|
||||||
|
|
||||||
|
PUSH r11
|
||||||
|
PUSH r10
|
||||||
|
|
||||||
|
sub sp, sp, 4 ; skip r9
|
||||||
|
|
||||||
|
PUSH r8
|
||||||
|
PUSH r7
|
||||||
|
PUSH r6
|
||||||
|
PUSH r5
|
||||||
|
PUSH r4
|
||||||
|
PUSH r3
|
||||||
|
PUSH r2
|
||||||
|
PUSH r1
|
||||||
|
PUSH r0
|
||||||
|
.endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_HAS_ACCL_REGS
|
#ifdef CONFIG_ARC_HAS_ACCL_REGS
|
||||||
PUSH r59
|
PUSH r59
|
||||||
PUSH r58
|
PUSH r58
|
||||||
@ -86,6 +113,33 @@
|
|||||||
POP r59
|
POP r59
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
|
||||||
|
.ifnc \called_from, exception
|
||||||
|
POP r0
|
||||||
|
POP r1
|
||||||
|
POP r2
|
||||||
|
POP r3
|
||||||
|
POP r4
|
||||||
|
POP r5
|
||||||
|
POP r6
|
||||||
|
POP r7
|
||||||
|
POP r8
|
||||||
|
POP r9
|
||||||
|
POP r10
|
||||||
|
POP r11
|
||||||
|
|
||||||
|
POP blink
|
||||||
|
POPAX lp_end
|
||||||
|
POPAX lp_start
|
||||||
|
|
||||||
|
POP r9
|
||||||
|
mov lp_count, r9
|
||||||
|
|
||||||
|
add sp, sp, 12 ; skip JLI, LDI, EI
|
||||||
|
ld.as r9, [sp, -10] ; reload r9 which got clobbered
|
||||||
|
.endif
|
||||||
|
#endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
@ -209,7 +209,9 @@ restore_regs:
|
|||||||
;####### Return from Intr #######
|
;####### Return from Intr #######
|
||||||
|
|
||||||
debug_marker_l1:
|
debug_marker_l1:
|
||||||
bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
|
; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
|
||||||
|
btst r0, STATUS_DE_BIT ; Z flag set if bit clear
|
||||||
|
bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set
|
||||||
|
|
||||||
.Lisr_ret_fast_path:
|
.Lisr_ret_fast_path:
|
||||||
; Handle special case #1: (Entry via Exception, Return via IRQ)
|
; Handle special case #1: (Entry via Exception, Return via IRQ)
|
||||||
|
@ -49,11 +49,13 @@ void arc_init_IRQ(void)
|
|||||||
|
|
||||||
*(unsigned int *)&ictrl = 0;
|
*(unsigned int *)&ictrl = 0;
|
||||||
|
|
||||||
|
#ifndef CONFIG_ARC_IRQ_NO_AUTOSAVE
|
||||||
ictrl.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */
|
ictrl.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */
|
||||||
ictrl.save_blink = 1;
|
ictrl.save_blink = 1;
|
||||||
ictrl.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */
|
ictrl.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */
|
||||||
ictrl.save_u_to_u = 0; /* user ctxt saved on kernel stack */
|
ictrl.save_u_to_u = 0; /* user ctxt saved on kernel stack */
|
||||||
ictrl.save_idx_regs = 1; /* JLI, LDI, EI */
|
ictrl.save_idx_regs = 1; /* JLI, LDI, EI */
|
||||||
|
#endif
|
||||||
|
|
||||||
WRITE_AUX(AUX_IRQ_CTRL, ictrl);
|
WRITE_AUX(AUX_IRQ_CTRL, ictrl);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ menuconfig ARC_SOC_HSDK
|
|||||||
bool "ARC HS Development Kit SOC"
|
bool "ARC HS Development Kit SOC"
|
||||||
depends on ISA_ARCV2
|
depends on ISA_ARCV2
|
||||||
select ARC_HAS_ACCL_REGS
|
select ARC_HAS_ACCL_REGS
|
||||||
|
select ARC_IRQ_NO_AUTOSAVE
|
||||||
select CLK_HSDK
|
select CLK_HSDK
|
||||||
select RESET_HSDK
|
select RESET_HSDK
|
||||||
select MIGHT_HAVE_PCI
|
select MIGHT_HAVE_PCI
|
||||||
|
Loading…
x
Reference in New Issue
Block a user