Skip to content

Commit a034e86

Browse files
committed
arch: arm: Separate common irq_manage and isr_wrapper code
There are too many differences between Cortex-A/R and Cortex-M on irq code, e.g. Cortex-A/R use GIC and Cortex-M uses NVIC. For reducing the complexity and easier to maintain, this commit separates irq_manage.c and isr_wrapper.S into two different parts based on the architecture. This commit also Removes the part related to the option 'CONFIG_ARM_SECURE_FIRMWARE' in 'cortex_a_r/irq_manage.c' because this code is written for the Cortex-M architecture. Signed-off-by: Huifeng Zhang <[email protected]>
1 parent 26597a3 commit a034e86

File tree

7 files changed

+292
-138
lines changed

7 files changed

+292
-138
lines changed

arch/arm/core/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ zephyr_library()
55
zephyr_library_sources(
66
cpu_idle.S
77
fatal.c
8-
irq_manage.c
98
nmi.c
109
nmi_on_reset.S
1110
prep_c.c
1211
thread.c
1312
)
1413

15-
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)
1614
zephyr_library_sources_ifdef(CONFIG_CPP __aeabi_atexit.c)
1715
zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c)
1816
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c)

arch/arm/core/cortex_a_r/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ zephyr_library_sources(
1414
vector_table.S
1515
swap.c
1616
swap_helper.S
17+
irq_manage.c
1718
)
1819

20+
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)
1921
zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c)
2022
zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c)
2123
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S)
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright (c) 2013-2014 Wind River Systems, Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file
9+
* @brief ARM Cortex-A and Cortex-R interrupt management
10+
*
11+
*
12+
* Interrupt management: enabling/disabling and dynamic ISR
13+
* connecting/replacing. SW_ISR_TABLE_DYNAMIC has to be enabled for
14+
* connecting ISRs at runtime.
15+
*/
16+
17+
#include <zephyr/kernel.h>
18+
#include <zephyr/arch/cpu.h>
19+
#include <zephyr/drivers/interrupt_controller/gic.h>
20+
#include <zephyr/sys/__assert.h>
21+
#include <zephyr/sys/barrier.h>
22+
#include <zephyr/toolchain.h>
23+
#include <zephyr/linker/sections.h>
24+
#include <zephyr/sw_isr_table.h>
25+
#include <zephyr/irq.h>
26+
#include <zephyr/tracing/tracing.h>
27+
#include <zephyr/pm/pm.h>
28+
29+
extern void z_arm_reserved(void);
30+
31+
/*
32+
* For Cortex-A and Cortex-R cores, the default interrupt controller is the ARM
33+
* Generic Interrupt Controller (GIC) and therefore the architecture interrupt
34+
* control functions are mapped to the GIC driver interface.
35+
*
36+
* When a custom interrupt controller is used (i.e.
37+
* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER is enabled), the architecture
38+
* interrupt control functions are mapped to the SoC layer in
39+
* `include/arch/arm/irq.h`.
40+
*/
41+
42+
#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
43+
void arch_irq_enable(unsigned int irq)
44+
{
45+
arm_gic_irq_enable(irq);
46+
}
47+
48+
void arch_irq_disable(unsigned int irq)
49+
{
50+
arm_gic_irq_disable(irq);
51+
}
52+
53+
int arch_irq_is_enabled(unsigned int irq)
54+
{
55+
return arm_gic_irq_is_enabled(irq);
56+
}
57+
58+
/**
59+
* @internal
60+
*
61+
* @brief Set an interrupt's priority
62+
*
63+
* The priority is verified if ASSERT_ON is enabled. The maximum number
64+
* of priority levels is a little complex, as there are some hardware
65+
* priority levels which are reserved: three for various types of exceptions,
66+
* and possibly one additional to support zero latency interrupts.
67+
*/
68+
void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
69+
{
70+
arm_gic_irq_set_priority(irq, prio, flags);
71+
}
72+
#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
73+
74+
void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf);
75+
76+
/**
77+
*
78+
* @brief Spurious interrupt handler
79+
*
80+
* Installed in all _sw_isr_table slots at boot time. Throws an error if
81+
* called.
82+
*
83+
*/
84+
void z_irq_spurious(const void *unused)
85+
{
86+
ARG_UNUSED(unused);
87+
88+
z_arm_fatal_error(K_ERR_SPURIOUS_IRQ, NULL);
89+
}
90+
91+
#ifdef CONFIG_PM
92+
void _arch_isr_direct_pm(void)
93+
{
94+
unsigned int key;
95+
96+
/* irq_lock() does what we want for this CPU */
97+
key = irq_lock();
98+
99+
if (_kernel.idle) {
100+
_kernel.idle = 0;
101+
z_pm_save_idle_exit();
102+
}
103+
104+
irq_unlock(key);
105+
}
106+
#endif
107+
108+
#ifdef CONFIG_DYNAMIC_INTERRUPTS
109+
#ifdef CONFIG_GEN_ISR_TABLES
110+
int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
111+
void (*routine)(const void *parameter),
112+
const void *parameter, uint32_t flags)
113+
{
114+
z_isr_install(irq, routine, parameter);
115+
z_arm_irq_priority_set(irq, priority, flags);
116+
return irq;
117+
}
118+
#endif /* CONFIG_GEN_ISR_TABLES */
119+
120+
#ifdef CONFIG_DYNAMIC_DIRECT_INTERRUPTS
121+
static inline void z_arm_irq_dynamic_direct_isr_dispatch(void)
122+
{
123+
uint32_t irq = __get_IPSR() - 16;
124+
125+
if (irq < IRQ_TABLE_SIZE) {
126+
struct _isr_table_entry *isr_entry = &_sw_isr_table[irq];
127+
128+
isr_entry->isr(isr_entry->arg);
129+
}
130+
}
131+
132+
ISR_DIRECT_DECLARE(z_arm_irq_direct_dynamic_dispatch_reschedule)
133+
{
134+
z_arm_irq_dynamic_direct_isr_dispatch();
135+
136+
return 1;
137+
}
138+
139+
ISR_DIRECT_DECLARE(z_arm_irq_direct_dynamic_dispatch_no_reschedule)
140+
{
141+
z_arm_irq_dynamic_direct_isr_dispatch();
142+
143+
return 0;
144+
}
145+
146+
#endif /* CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
147+
148+
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

arch/arm/core/isr_wrapper.S renamed to arch/arm/core/cortex_a_r/isr_wrapper.S

Lines changed: 1 addition & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
/**
99
* @file
10-
* @brief ARM Cortex-A, Cortex-M and Cortex-R wrapper for ISRs with parameter
10+
* @brief ARM Cortex-A and Cortex-R wrapper for ISRs with parameter
1111
*
1212
* Wrapper installed in vector table for handling dynamic interrupts that accept
1313
* a parameter.
@@ -45,10 +45,6 @@ GTEXT(z_arm_int_exit)
4545
*/
4646
SECTION_FUNC(TEXT, _isr_wrapper)
4747

48-
#if defined(CONFIG_CPU_CORTEX_M)
49-
push {r0,lr} /* r0, lr are now the first items on the stack */
50-
#elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A)
51-
5248
#if defined(CONFIG_USERSPACE)
5349
/* See comment below about svc stack usage */
5450
cps #MODE_SVC
@@ -147,7 +143,6 @@ _vfp_not_enabled:
147143
ldr r0, [r2, #_kernel_offset_to_nested]
148144
add r0, r0, #1
149145
str r0, [r2, #_kernel_offset_to_nested]
150-
#endif /* CONFIG_CPU_CORTEX_M */
151146

152147
#ifdef CONFIG_TRACING_ISR
153148
bl sys_trace_isr_enter
@@ -163,65 +158,21 @@ _vfp_not_enabled:
163158
* is called with interrupts disabled.
164159
*/
165160

166-
#if defined(CONFIG_CPU_CORTEX_M)
167-
/*
168-
* Disable interrupts to prevent nesting while exiting idle state. This
169-
* is only necessary for the Cortex-M because it is the only ARM
170-
* architecture variant that automatically enables interrupts when
171-
* entering an ISR.
172-
*/
173-
cpsid i /* PRIMASK = 1 */
174-
#endif
175-
176161
/* is this a wakeup from idle ? */
177162
ldr r2, =_kernel
178163
/* requested idle duration, in ticks */
179164
ldr r0, [r2, #_kernel_offset_to_idle]
180165
cmp r0, #0
181166

182-
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
183-
beq _idle_state_cleared
184-
movs.n r1, #0
185-
/* clear kernel idle state */
186-
str r1, [r2, #_kernel_offset_to_idle]
187-
bl z_pm_save_idle_exit
188-
_idle_state_cleared:
189-
190-
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
191-
ittt ne
192-
movne r1, #0
193-
/* clear kernel idle state */
194-
strne r1, [r2, #_kernel_offset_to_idle]
195-
blne z_pm_save_idle_exit
196-
#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \
197-
|| defined(CONFIG_ARMV7_A)
198167
beq _idle_state_cleared
199168
movs r1, #0
200169
/* clear kernel idle state */
201170
str r1, [r2, #_kernel_offset_to_idle]
202171
bl z_pm_save_idle_exit
203172
_idle_state_cleared:
204-
#else
205-
#error Unknown ARM architecture
206-
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
207-
208-
#if defined(CONFIG_CPU_CORTEX_M)
209-
cpsie i /* re-enable interrupts (PRIMASK = 0) */
210-
#endif
211173

212174
#endif /* CONFIG_PM */
213175

214-
#if defined(CONFIG_CPU_CORTEX_M)
215-
mrs r0, IPSR /* get exception number */
216-
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
217-
ldr r1, =16
218-
subs r0, r1 /* get IRQ number */
219-
lsls r0, #3 /* table is 8-byte wide */
220-
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
221-
sub r0, r0, #16 /* get IRQ number */
222-
lsl r0, r0, #3 /* table is 8-byte wide */
223-
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
224-
#elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A)
225176
/* Get active IRQ number from the interrupt controller */
226177
#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
227178
bl arm_gic_get_active
@@ -230,11 +181,7 @@ _idle_state_cleared:
230181
#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
231182
push {r0, r1}
232183
lsl r0, r0, #3 /* table is 8-byte wide */
233-
#else
234-
#error Unknown ARM architecture
235-
#endif /* CONFIG_CPU_CORTEX_M */
236184

237-
#if !defined(CONFIG_CPU_CORTEX_M)
238185
/*
239186
* Enable interrupts to allow nesting.
240187
*
@@ -254,7 +201,6 @@ _idle_state_cleared:
254201
lsl r1, r1, #3
255202
cmp r0, r1
256203
bge spurious_continue
257-
#endif /* !CONFIG_CPU_CORTEX_M */
258204

259205
ldr r1, =_sw_isr_table
260206
add r1, r1, r0 /* table entry: ISRs must have their MSB set to stay
@@ -263,7 +209,6 @@ _idle_state_cleared:
263209
ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */
264210
blx r3 /* call ISR */
265211

266-
#if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A)
267212
spurious_continue:
268213
/* Signal end-of-interrupt */
269214
pop {r0, r1}
@@ -272,29 +217,11 @@ spurious_continue:
272217
#else
273218
bl z_soc_irq_eoi
274219
#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
275-
#endif /* CONFIG_CPU_AARCH32_CORTEX_R || CONFIG_CPU_AARCH32_CORTEX_A */
276220

277221
#ifdef CONFIG_TRACING_ISR
278222
bl sys_trace_isr_exit
279223
#endif
280224

281-
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
282-
pop {r0, r3}
283-
mov lr, r3
284-
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
285-
pop {r0, lr}
286-
#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \
287-
|| defined(CONFIG_ARMV7_A)
288-
/*
289-
* r0 and lr_irq were saved on the process stack since a swap could
290-
* happen. exc_exit will handle getting those values back
291-
* from the process stack to return to the correct location
292-
* so there is no need to do anything here.
293-
*/
294-
#else
295-
#error Unknown ARM architecture
296-
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
297-
298225
/* Use 'bx' instead of 'b' because 'bx' can jump further, and use
299226
* 'bx' instead of 'blx' because exception return is done in
300227
* z_arm_int_exit() */

arch/arm/core/cortex_m/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ zephyr_library_sources(
1414
vector_table.S
1515
swap.c
1616
swap_helper.S
17+
irq_manage.c
1718
)
1819

20+
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)
1921
zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c)
2022
zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c)
2123
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S)

0 commit comments

Comments
 (0)