1 From e3f16c67527e970e029fda10084bbffb744259ef Mon Sep 17 00:00:00 2001
2 From: Vineet Gupta <vgupta@synopsys.com>
3 Date: Wed, 6 Jun 2018 10:20:37 -0700
4 Subject: ARCv2: support manual regfile save on interrupts
6 [ Upstream commit e494239a007e601448110ac304fe055951f9de3b ]
8 There's a hardware bug which affects the HSDK platform, triggered by
9 micro-ops for auto-saving regfile on taken interrupt. The workaround is
12 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
13 Signed-off-by: Sasha Levin <sashal@kernel.org>
15 arch/arc/Kconfig | 8 +++++
16 arch/arc/include/asm/entry-arcv2.h | 54 ++++++++++++++++++++++++++++++
17 arch/arc/kernel/entry-arcv2.S | 4 ++-
18 arch/arc/kernel/intc-arcv2.c | 2 ++
19 arch/arc/plat-hsdk/Kconfig | 1 +
20 5 files changed, 68 insertions(+), 1 deletion(-)
22 diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
23 index ac69f307dcfe..74953e76a57d 100644
24 --- a/arch/arc/Kconfig
25 +++ b/arch/arc/Kconfig
26 @@ -420,6 +420,14 @@ config ARC_HAS_ACCL_REGS
27 (also referred to as r58:r59). These can also be used by gcc as GPR so
28 kernel needs to save/restore per process
30 +config ARC_IRQ_NO_AUTOSAVE
31 + bool "Disable hardware autosave regfile on interrupts"
34 + On HS cores, taken interrupt auto saves the regfile on stack.
35 + This is programmable and can be optionally disabled in which case
36 + software INTERRUPT_PROLOGUE/EPILGUE do the needed work
40 endmenu # "ARC CPU Configuration"
41 diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h
42 index 309f4e6721b3..225e7df2d8ed 100644
43 --- a/arch/arc/include/asm/entry-arcv2.h
44 +++ b/arch/arc/include/asm/entry-arcv2.h
47 ; Now manually save: r12, sp, fp, gp, r25
49 +#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
50 +.ifnc \called_from, exception
51 + st.as r9, [sp, -10] ; save r9 in it's final stack slot
52 + sub sp, sp, 12 ; skip JLI, LDI, EI
62 + sub sp, sp, 4 ; skip r9
76 #ifdef CONFIG_ARC_HAS_ACCL_REGS
83 +#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
84 +.ifnc \called_from, exception
105 + add sp, sp, 12 ; skip JLI, LDI, EI
106 + ld.as r9, [sp, -10] ; reload r9 which got clobbered
112 /*------------------------------------------------------------------------*/
113 diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
114 index cc558a25b8fa..562089d62d9d 100644
115 --- a/arch/arc/kernel/entry-arcv2.S
116 +++ b/arch/arc/kernel/entry-arcv2.S
117 @@ -209,7 +209,9 @@ restore_regs:
118 ;####### Return from Intr #######
121 - bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
122 + ; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
123 + btst r0, STATUS_DE_BIT ; Z flag set if bit clear
124 + bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set
127 ; Handle special case #1: (Entry via Exception, Return via IRQ)
128 diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
129 index 067ea362fb3e..cf18b3e5a934 100644
130 --- a/arch/arc/kernel/intc-arcv2.c
131 +++ b/arch/arc/kernel/intc-arcv2.c
132 @@ -49,11 +49,13 @@ void arc_init_IRQ(void)
134 *(unsigned int *)&ictrl = 0;
136 +#ifndef CONFIG_ARC_IRQ_NO_AUTOSAVE
137 ictrl.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */
138 ictrl.save_blink = 1;
139 ictrl.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */
140 ictrl.save_u_to_u = 0; /* user ctxt saved on kernel stack */
141 ictrl.save_idx_regs = 1; /* JLI, LDI, EI */
144 WRITE_AUX(AUX_IRQ_CTRL, ictrl);
146 diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig
147 index 9356753c2ed8..c285a83cbf08 100644
148 --- a/arch/arc/plat-hsdk/Kconfig
149 +++ b/arch/arc/plat-hsdk/Kconfig
150 @@ -9,6 +9,7 @@ menuconfig ARC_SOC_HSDK
151 bool "ARC HS Development Kit SOC"
153 select ARC_HAS_ACCL_REGS
154 + select ARC_IRQ_NO_AUTOSAVE
157 select MIGHT_HAVE_PCI