]>
Commit | Line | Data |
---|---|---|
ecf3b270 SL |
1 | From 867316d6f58e8730c52bd32477c0de8089ba65f4 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 | |
5 | ||
6 | [ Upstream commit e494239a007e601448110ac304fe055951f9de3b ] | |
7 | ||
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 | |
10 | to inhibit autosave. | |
11 | ||
12 | Signed-off-by: Vineet Gupta <vgupta@synopsys.com> | |
13 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
14 | --- | |
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(-) | |
21 | ||
22 | diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig | |
23 | index 9d06c9478a0d..82050893d0b3 100644 | |
24 | --- a/arch/arc/Kconfig | |
25 | +++ b/arch/arc/Kconfig | |
26 | @@ -417,6 +417,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 | |
29 | ||
30 | +config ARC_IRQ_NO_AUTOSAVE | |
31 | + bool "Disable hardware autosave regfile on interrupts" | |
32 | + default n | |
33 | + help | |
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 | |
37 | + | |
38 | endif # ISA_ARCV2 | |
39 | ||
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 257a68f3c2fe..9f581553dcc3 100644 | |
43 | --- a/arch/arc/include/asm/entry-arcv2.h | |
44 | +++ b/arch/arc/include/asm/entry-arcv2.h | |
45 | @@ -17,6 +17,33 @@ | |
46 | ; | |
47 | ; Now manually save: r12, sp, fp, gp, r25 | |
48 | ||
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 | |
53 | + | |
54 | + PUSH lp_count | |
55 | + PUSHAX lp_start | |
56 | + PUSHAX lp_end | |
57 | + PUSH blink | |
58 | + | |
59 | + PUSH r11 | |
60 | + PUSH r10 | |
61 | + | |
62 | + sub sp, sp, 4 ; skip r9 | |
63 | + | |
64 | + PUSH r8 | |
65 | + PUSH r7 | |
66 | + PUSH r6 | |
67 | + PUSH r5 | |
68 | + PUSH r4 | |
69 | + PUSH r3 | |
70 | + PUSH r2 | |
71 | + PUSH r1 | |
72 | + PUSH r0 | |
73 | +.endif | |
74 | +#endif | |
75 | + | |
76 | #ifdef CONFIG_ARC_HAS_ACCL_REGS | |
77 | PUSH r59 | |
78 | PUSH r58 | |
79 | @@ -86,6 +113,33 @@ | |
80 | POP r59 | |
81 | #endif | |
82 | ||
83 | +#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE | |
84 | +.ifnc \called_from, exception | |
85 | + POP r0 | |
86 | + POP r1 | |
87 | + POP r2 | |
88 | + POP r3 | |
89 | + POP r4 | |
90 | + POP r5 | |
91 | + POP r6 | |
92 | + POP r7 | |
93 | + POP r8 | |
94 | + POP r9 | |
95 | + POP r10 | |
96 | + POP r11 | |
97 | + | |
98 | + POP blink | |
99 | + POPAX lp_end | |
100 | + POPAX lp_start | |
101 | + | |
102 | + POP r9 | |
103 | + mov lp_count, r9 | |
104 | + | |
105 | + add sp, sp, 12 ; skip JLI, LDI, EI | |
106 | + ld.as r9, [sp, -10] ; reload r9 which got clobbered | |
107 | +.endif | |
108 | +#endif | |
109 | + | |
110 | .endm | |
111 | ||
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 ####### | |
119 | ||
120 | debug_marker_l1: | |
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 | |
125 | ||
126 | .Lisr_ret_fast_path: | |
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) | |
133 | ||
134 | *(unsigned int *)&ictrl = 0; | |
135 | ||
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 */ | |
142 | +#endif | |
143 | ||
144 | WRITE_AUX(AUX_IRQ_CTRL, ictrl); | |
145 | ||
146 | diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig | |
147 | index fcc9a9e27e9c..8fb1600b29b7 100644 | |
148 | --- a/arch/arc/plat-hsdk/Kconfig | |
149 | +++ b/arch/arc/plat-hsdk/Kconfig | |
150 | @@ -9,5 +9,6 @@ menuconfig ARC_SOC_HSDK | |
151 | bool "ARC HS Development Kit SOC" | |
152 | depends on ISA_ARCV2 | |
153 | select ARC_HAS_ACCL_REGS | |
154 | + select ARC_IRQ_NO_AUTOSAVE | |
155 | select CLK_HSDK | |
156 | select RESET_HSDK | |
157 | -- | |
158 | 2.19.1 | |
159 |