aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2018-06-06 13:20:37 -0400
committerVineet Gupta <vgupta@synopsys.com>2019-02-21 14:03:18 -0500
commite494239a007e601448110ac304fe055951f9de3b (patch)
tree2814f3f12bddf8a5cda6c50ff5523a5066a03cb9
parentd5e3c55e01d8b1774b37b4647c30fb22f1d39077 (diff)
ARCv2: support manual regfile save on interrupts
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>
-rw-r--r--arch/arc/Kconfig8
-rw-r--r--arch/arc/include/asm/entry-arcv2.h54
-rw-r--r--arch/arc/kernel/entry-arcv2.S4
-rw-r--r--arch/arc/kernel/intc-arcv2.c2
-rw-r--r--arch/arc/plat-hsdk/Kconfig1
5 files changed, 68 insertions, 1 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 376366a7db81..7215f52b3413 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -407,6 +407,14 @@ config ARC_HAS_ACCL_REGS
407 (also referred to as r58:r59). These can also be used by gcc as GPR so 407 (also referred to as r58:r59). These can also be used by gcc as GPR so
408 kernel needs to save/restore per process 408 kernel needs to save/restore per process
409 409
410config ARC_IRQ_NO_AUTOSAVE
411 bool "Disable hardware autosave regfile on interrupts"
412 default n
413 help
414 On HS cores, taken interrupt auto saves the regfile on stack.
415 This is programmable and can be optionally disabled in which case
416 software INTERRUPT_PROLOGUE/EPILGUE do the needed work
417
410endif # ISA_ARCV2 418endif # ISA_ARCV2
411 419
412endmenu # "ARC CPU Configuration" 420endmenu # "ARC CPU Configuration"
diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h
index 309f4e6721b3..225e7df2d8ed 100644
--- a/arch/arc/include/asm/entry-arcv2.h
+++ b/arch/arc/include/asm/entry-arcv2.h
@@ -17,6 +17,33 @@
17 ; 17 ;
18 ; Now manually save: r12, sp, fp, gp, r25 18 ; Now manually save: r12, sp, fp, gp, r25
19 19
20#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
21.ifnc \called_from, exception
22 st.as r9, [sp, -10] ; save r9 in it's final stack slot
23 sub sp, sp, 12 ; skip JLI, LDI, EI
24
25 PUSH lp_count
26 PUSHAX lp_start
27 PUSHAX lp_end
28 PUSH blink
29
30 PUSH r11
31 PUSH r10
32
33 sub sp, sp, 4 ; skip r9
34
35 PUSH r8
36 PUSH r7
37 PUSH r6
38 PUSH r5
39 PUSH r4
40 PUSH r3
41 PUSH r2
42 PUSH r1
43 PUSH r0
44.endif
45#endif
46
20#ifdef CONFIG_ARC_HAS_ACCL_REGS 47#ifdef CONFIG_ARC_HAS_ACCL_REGS
21 PUSH r59 48 PUSH r59
22 PUSH r58 49 PUSH r58
@@ -86,6 +113,33 @@
86 POP r59 113 POP r59
87#endif 114#endif
88 115
116#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
117.ifnc \called_from, exception
118 POP r0
119 POP r1
120 POP r2
121 POP r3
122 POP r4
123 POP r5
124 POP r6
125 POP r7
126 POP r8
127 POP r9
128 POP r10
129 POP r11
130
131 POP blink
132 POPAX lp_end
133 POPAX lp_start
134
135 POP r9
136 mov lp_count, r9
137
138 add sp, sp, 12 ; skip JLI, LDI, EI
139 ld.as r9, [sp, -10] ; reload r9 which got clobbered
140.endif
141#endif
142
89.endm 143.endm
90 144
91/*------------------------------------------------------------------------*/ 145/*------------------------------------------------------------------------*/
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
index cc558a25b8fa..562089d62d9d 100644
--- a/arch/arc/kernel/entry-arcv2.S
+++ b/arch/arc/kernel/entry-arcv2.S
@@ -209,7 +209,9 @@ restore_regs:
209;####### Return from Intr ####### 209;####### Return from Intr #######
210 210
211debug_marker_l1: 211debug_marker_l1:
212 bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot 212 ; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
213 btst r0, STATUS_DE_BIT ; Z flag set if bit clear
214 bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set
213 215
214.Lisr_ret_fast_path: 216.Lisr_ret_fast_path:
215 ; Handle special case #1: (Entry via Exception, Return via IRQ) 217 ; Handle special case #1: (Entry via Exception, Return via IRQ)
diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
index 067ea362fb3e..cf18b3e5a934 100644
--- a/arch/arc/kernel/intc-arcv2.c
+++ b/arch/arc/kernel/intc-arcv2.c
@@ -49,11 +49,13 @@ void arc_init_IRQ(void)
49 49
50 *(unsigned int *)&ictrl = 0; 50 *(unsigned int *)&ictrl = 0;
51 51
52#ifndef CONFIG_ARC_IRQ_NO_AUTOSAVE
52 ictrl.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */ 53 ictrl.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */
53 ictrl.save_blink = 1; 54 ictrl.save_blink = 1;
54 ictrl.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */ 55 ictrl.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */
55 ictrl.save_u_to_u = 0; /* user ctxt saved on kernel stack */ 56 ictrl.save_u_to_u = 0; /* user ctxt saved on kernel stack */
56 ictrl.save_idx_regs = 1; /* JLI, LDI, EI */ 57 ictrl.save_idx_regs = 1; /* JLI, LDI, EI */
58#endif
57 59
58 WRITE_AUX(AUX_IRQ_CTRL, ictrl); 60 WRITE_AUX(AUX_IRQ_CTRL, ictrl);
59 61
diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig
index f25c085b9874..23e00216e5a5 100644
--- a/arch/arc/plat-hsdk/Kconfig
+++ b/arch/arc/plat-hsdk/Kconfig
@@ -9,6 +9,7 @@ menuconfig ARC_SOC_HSDK
9 bool "ARC HS Development Kit SOC" 9 bool "ARC HS Development Kit SOC"
10 depends on ISA_ARCV2 10 depends on ISA_ARCV2
11 select ARC_HAS_ACCL_REGS 11 select ARC_HAS_ACCL_REGS
12 select ARC_IRQ_NO_AUTOSAVE
12 select CLK_HSDK 13 select CLK_HSDK
13 select RESET_HSDK 14 select RESET_HSDK
14 select HAVE_PCI 15 select HAVE_PCI