Skip to content

Commit abeccfe

Browse files
williamtcdnsdkalowsk
authored andcommitted
xtensa: support for more than 32 interrupts
This change add support for using more than 32 interrupts. Signed-off-by: William Tambe <williamt@cadence.com>
1 parent dcdc7d3 commit abeccfe

File tree

19 files changed

+564
-113
lines changed

19 files changed

+564
-113
lines changed

arch/xtensa/core/irq_manage.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,59 @@ void z_irq_spurious(const void *arg)
7474
__asm__ volatile("rsr.intenable %0" : "=r"(ie));
7575
LOG_ERR(" ** Spurious INTERRUPT(s) %p, INTENABLE = %p",
7676
(void *)irqs, (void *)ie);
77+
78+
#if XCHAL_NUM_INTERRUPTS > 32
79+
__asm__ volatile("rsr.interrupt1 %0" : "=r"(irqs));
80+
__asm__ volatile("rsr.intenable1 %0" : "=r"(ie));
81+
LOG_ERR(" ** Spurious INTERRUPT1(s) %p, INTENABLE1 = %p",
82+
(void *)irqs, (void *)ie);
83+
#endif
84+
85+
#if XCHAL_NUM_INTERRUPTS > 64
86+
__asm__ volatile("rsr.interrupt2 %0" : "=r"(irqs));
87+
__asm__ volatile("rsr.intenable2 %0" : "=r"(ie));
88+
LOG_ERR(" ** Spurious INTERRUPT2(s) %p, INTENABLE2 = %p",
89+
(void *)irqs, (void *)ie);
90+
#endif
91+
92+
#if XCHAL_NUM_INTERRUPTS > 96
93+
__asm__ volatile("rsr.interrupt3 %0" : "=r"(irqs));
94+
__asm__ volatile("rsr.intenable3 %0" : "=r"(ie));
95+
LOG_ERR(" ** Spurious INTERRUPT3(s) %p, INTENABLE3 = %p",
96+
(void *)irqs, (void *)ie);
97+
#endif
98+
7799
xtensa_fatal_error(K_ERR_SPURIOUS_IRQ, NULL);
78100
}
79101

80102
int xtensa_irq_is_enabled(unsigned int irq)
81103
{
82104
uint32_t ie;
83105

106+
#if XCHAL_NUM_INTERRUPTS > 32
107+
switch (irq >> 5) {
108+
case 0:
109+
__asm__ volatile("rsr.intenable %0" : "=r"(ie));
110+
break;
111+
case 1:
112+
__asm__ volatile("rsr.intenable1 %0" : "=r"(ie));
113+
break;
114+
#if XCHAL_NUM_INTERRUPTS > 64
115+
case 2:
116+
__asm__ volatile("rsr.intenable2 %0" : "=r"(ie));
117+
break;
118+
#endif
119+
#if XCHAL_NUM_INTERRUPTS > 96
120+
case 3:
121+
__asm__ volatile("rsr.intenable3 %0" : "=r"(ie));
122+
break;
123+
#endif
124+
default:
125+
break;
126+
}
127+
#else
84128
__asm__ volatile("rsr.intenable %0" : "=r"(ie));
129+
#endif
85130

86-
return (ie & (1 << irq)) != 0U;
131+
return (ie & (1 << (irq & 31U))) != 0U;
87132
}

arch/xtensa/core/irq_offload.c

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,63 @@ void arch_irq_offload(irq_offload_routine_t routine, const void *parameter)
3131
offload_params[cpu_id].fn = routine;
3232
offload_params[cpu_id].arg = parameter;
3333

34-
__asm__ volatile("rsr %0, INTENABLE" : "=r"(intenable));
35-
intenable |= BIT(ZSR_IRQ_OFFLOAD_INT);
36-
__asm__ volatile("wsr %0, INTENABLE; wsr %0, INTSET; rsync"
37-
:: "r"(intenable), "r"(BIT(ZSR_IRQ_OFFLOAD_INT)));
34+
#if XCHAL_NUM_INTERRUPTS > 32
35+
switch ((ZSR_IRQ_OFFLOAD_INT) >> 5) {
36+
case 0:
37+
__asm__ volatile("rsr.intenable %0" : "=r"(intenable));
38+
break;
39+
case 1:
40+
__asm__ volatile("rsr.intenable1 %0" : "=r"(intenable));
41+
break;
42+
#if XCHAL_NUM_INTERRUPTS > 64
43+
case 2:
44+
__asm__ volatile("rsr.intenable2 %0" : "=r"(intenable));
45+
break;
46+
#endif
47+
#if XCHAL_NUM_INTERRUPTS > 96
48+
case 3:
49+
__asm__ volatile("rsr.intenable3 %0" : "=r"(intenable));
50+
break;
51+
#endif
52+
default:
53+
break;
54+
}
55+
#else
56+
__asm__ volatile("rsr.intenable %0" : "=r"(intenable));
57+
#endif
58+
59+
intenable |= BIT((ZSR_IRQ_OFFLOAD_INT & 31U));
60+
61+
#if XCHAL_NUM_INTERRUPTS > 32
62+
switch ((ZSR_IRQ_OFFLOAD_INT) >> 5) {
63+
case 0:
64+
__asm__ volatile("wsr.intenable %0; wsr.intset %0; rsync"
65+
:: "r"(intenable), "r"(BIT((ZSR_IRQ_OFFLOAD_INT & 31U))));
66+
break;
67+
case 1:
68+
__asm__ volatile("wsr.intenable1 %0; wsr.intset1 %0; rsync"
69+
:: "r"(intenable), "r"(BIT((ZSR_IRQ_OFFLOAD_INT & 31U))));
70+
break;
71+
#if XCHAL_NUM_INTERRUPTS > 64
72+
case 2:
73+
__asm__ volatile("wsr.intenable2 %0; wsr.intset2 %0; rsync"
74+
:: "r"(intenable), "r"(BIT((ZSR_IRQ_OFFLOAD_INT & 31U))));
75+
break;
76+
#endif
77+
#if XCHAL_NUM_INTERRUPTS > 96
78+
case 3:
79+
__asm__ volatile("wsr.intenable3 %0; wsr.intset3 %0; rsync"
80+
:: "r"(intenable), "r"(BIT((ZSR_IRQ_OFFLOAD_INT & 31U))));
81+
break;
82+
#endif
83+
default:
84+
break;
85+
}
86+
#else
87+
__asm__ volatile("wsr.intenable %0; wsr.intset %0; rsync"
88+
:: "r"(intenable), "r"(BIT((ZSR_IRQ_OFFLOAD_INT & 31U))));
89+
#endif
90+
3891
arch_irq_unlock(key);
3992
}
4093

arch/xtensa/core/startup/reset_vector.S

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,16 @@ _ResetHandler:
150150
/* make sure that interrupts are shut off (*before* we lower
151151
* PS.INTLEVEL and PS.EXCM!)
152152
*/
153-
wsr a0, INTENABLE
153+
wsr.intenable a0
154+
#if (XCHAL_NUM_INTERRUPTS > 32)
155+
wsr.intenable1 a0
156+
#endif
157+
#if (XCHAL_NUM_INTERRUPTS > 64)
158+
wsr.intenable2 a0
159+
#endif
160+
#if (XCHAL_NUM_INTERRUPTS > 96)
161+
wsr.intenable3 a0
162+
#endif
154163
#endif
155164

156165
#if !XCHAL_HAVE_FULL_RESET

arch/xtensa/core/vector_handlers.c

Lines changed: 107 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,20 +286,116 @@ static inline void *return_to(void *interrupted)
286286
* This may be unused depending on number of interrupt levels
287287
* supported by the SoC.
288288
*/
289-
#define DEF_INT_C_HANDLER(l) \
290-
__unused void *xtensa_int##l##_c(void *interrupted_stack) \
291-
{ \
292-
uint32_t irqs, intenable, m; \
293-
usage_stop(); \
294-
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
289+
290+
#if XCHAL_NUM_INTERRUPTS <= 32
291+
#define DEF_INT_C_HANDLER(l) \
292+
__unused void *xtensa_int##l##_c(void *interrupted_stack) \
293+
{ \
294+
uint32_t irqs, intenable, m; \
295+
usage_stop(); \
296+
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
295297
__asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \
296-
irqs &= intenable; \
297-
while ((m = _xtensa_handle_one_int##l(irqs))) { \
298-
irqs ^= m; \
298+
irqs &= intenable; \
299+
while ((m = _xtensa_handle_one_int##l(0, irqs))) { \
300+
irqs ^= m; \
299301
__asm__ volatile("wsr.intclear %0" : : "r"(m)); \
300-
} \
301-
return return_to(interrupted_stack); \
302+
} \
303+
return return_to(interrupted_stack); \
304+
}
305+
#endif /* XCHAL_NUM_INTERRUPTS <= 32 */
306+
307+
#if XCHAL_NUM_INTERRUPTS > 32 && XCHAL_NUM_INTERRUPTS <= 64
308+
#define DEF_INT_C_HANDLER(l) \
309+
__unused void *xtensa_int##l##_c(void *interrupted_stack) \
310+
{ \
311+
uint32_t irqs, intenable, m; \
312+
usage_stop(); \
313+
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
314+
__asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \
315+
irqs &= intenable; \
316+
while ((m = _xtensa_handle_one_int##l(0, irqs))) { \
317+
irqs ^= m; \
318+
__asm__ volatile("wsr.intclear %0" : : "r"(m)); \
319+
} \
320+
__asm__ volatile("rsr.interrupt1 %0" : "=r"(irqs)); \
321+
__asm__ volatile("rsr.intenable1 %0" : "=r"(intenable)); \
322+
irqs &= intenable; \
323+
while ((m = _xtensa_handle_one_int##l(1, irqs))) { \
324+
irqs ^= m; \
325+
__asm__ volatile("wsr.intclear1 %0" : : "r"(m)); \
326+
} \
327+
return return_to(interrupted_stack); \
328+
}
329+
#endif /* XCHAL_NUM_INTERRUPTS > 32 && XCHAL_NUM_INTERRUPTS <= 64 */
330+
331+
#if XCHAL_NUM_INTERRUPTS > 64 && XCHAL_NUM_INTERRUPTS <= 96
332+
#define DEF_INT_C_HANDLER(l) \
333+
__unused void *xtensa_int##l##_c(void *interrupted_stack) \
334+
{ \
335+
uint32_t irqs, intenable, m; \
336+
usage_stop(); \
337+
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
338+
__asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \
339+
irqs &= intenable; \
340+
while ((m = _xtensa_handle_one_int##l(0, irqs))) { \
341+
irqs ^= m; \
342+
__asm__ volatile("wsr.intclear %0" : : "r"(m)); \
343+
} \
344+
__asm__ volatile("rsr.interrupt1 %0" : "=r"(irqs)); \
345+
__asm__ volatile("rsr.intenable1 %0" : "=r"(intenable)); \
346+
irqs &= intenable; \
347+
while ((m = _xtensa_handle_one_int##l(1, irqs))) { \
348+
irqs ^= m; \
349+
__asm__ volatile("wsr.intclear1 %0" : : "r"(m)); \
350+
} \
351+
__asm__ volatile("rsr.interrupt2 %0" : "=r"(irqs)); \
352+
__asm__ volatile("rsr.intenable2 %0" : "=r"(intenable)); \
353+
irqs &= intenable; \
354+
while ((m = _xtensa_handle_one_int##l(2, irqs))) { \
355+
irqs ^= m; \
356+
__asm__ volatile("wsr.intclear2 %0" : : "r"(m)); \
357+
} \
358+
return return_to(interrupted_stack); \
359+
}
360+
#endif /* XCHAL_NUM_INTERRUPTS > 64 && XCHAL_NUM_INTERRUPTS <= 96 */
361+
362+
#if XCHAL_NUM_INTERRUPTS > 96
363+
#define DEF_INT_C_HANDLER(l) \
364+
__unused void *xtensa_int##l##_c(void *interrupted_stack) \
365+
{ \
366+
uint32_t irqs, intenable, m; \
367+
usage_stop(); \
368+
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
369+
__asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \
370+
irqs &= intenable; \
371+
while ((m = _xtensa_handle_one_int##l(0, irqs))) { \
372+
irqs ^= m; \
373+
__asm__ volatile("wsr.intclear %0" : : "r"(m)); \
374+
} \
375+
__asm__ volatile("rsr.interrupt1 %0" : "=r"(irqs)); \
376+
__asm__ volatile("rsr.intenable1 %0" : "=r"(intenable)); \
377+
irqs &= intenable; \
378+
while ((m = _xtensa_handle_one_int##l(1, irqs))) { \
379+
irqs ^= m; \
380+
__asm__ volatile("wsr.intclear1 %0" : : "r"(m)); \
381+
} \
382+
__asm__ volatile("rsr.interrupt2 %0" : "=r"(irqs)); \
383+
__asm__ volatile("rsr.intenable2 %0" : "=r"(intenable)); \
384+
irqs &= intenable; \
385+
while ((m = _xtensa_handle_one_int##l(2, irqs))) { \
386+
irqs ^= m; \
387+
__asm__ volatile("wsr.intclear2 %0" : : "r"(m)); \
388+
} \
389+
__asm__ volatile("rsr.interrupt3 %0" : "=r"(irqs)); \
390+
__asm__ volatile("rsr.intenable3 %0" : "=r"(intenable)); \
391+
irqs &= intenable; \
392+
while ((m = _xtensa_handle_one_int##l(3, irqs))) { \
393+
irqs ^= m; \
394+
__asm__ volatile("wsr.intclear3 %0" : : "r"(m)); \
395+
} \
396+
return return_to(interrupted_stack); \
302397
}
398+
#endif /* XCHAL_NUM_INTERRUPTS > 96 */
303399

304400
#if XCHAL_HAVE_NMI
305401
#define MAX_INTR_LEVEL XCHAL_NMILEVEL

arch/xtensa/core/xtensa_intgen.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ def emit_int_handler(ints):
117117

118118
# Emit the handlers
119119
for lvl in ints_by_lvl:
120-
cprint("static inline int _xtensa_handle_one_int" + str(lvl) + "(unsigned int mask)")
120+
cprint("static inline int _xtensa_handle_one_int" +
121+
str(lvl) + "(unsigned int set, unsigned int mask)")
121122
cprint("{")
122123

123124
if not ints_by_lvl[lvl]:
@@ -128,11 +129,14 @@ def emit_int_handler(ints):
128129
cprint("int irq;")
129130
print("")
130131

131-
emit_int_handler(sorted(ints_by_lvl[lvl]))
132+
if int(len(ints_by_lvl[lvl])) > 32:
133+
emit_int_handler((sorted(ints_by_lvl[lvl]))[0:31])
134+
else:
135+
emit_int_handler(sorted(ints_by_lvl[lvl]))
132136

133137
cprint("return 0;")
134138
cprint("handle_irq:")
135-
cprint("_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);")
139+
cprint("_sw_isr_table[set * 32 + irq].isr(_sw_isr_table[set * 32 + irq].arg);")
136140
cprint("return mask;")
137141
cprint("}")
138142
cprint("")

0 commit comments

Comments
 (0)