arch: arm: cortex-m: support custom interrupt controllers
This change adds support for the CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER option on Cortex-M platforms. While all Cortex-M platforms have a NVIC controller some custom SoCs may have additional IRQ controllers or custom handling. This change allows those SoCs to modify this bahaviour without having to place platform specific logic inside applications or drivers. Signed-off-by: Corey Wharton <xodus7@cwharton.com>
This commit is contained in:
parent
c4ffadb0b6
commit
4e5868faaf
|
@ -16,23 +16,23 @@ config CPU_CORTEX
|
|||
|
||||
config ARM_CUSTOM_INTERRUPT_CONTROLLER
|
||||
bool
|
||||
depends on !CPU_CORTEX_M
|
||||
help
|
||||
This option indicates that the ARM CPU is connected to a custom (i.e.
|
||||
non-GIC) interrupt controller.
|
||||
non-GIC or NVIC) interrupt controller.
|
||||
|
||||
A number of Cortex-A and Cortex-R cores (Cortex-A5, Cortex-R4/5, ...)
|
||||
allow interfacing to a custom external interrupt controller and this
|
||||
option must be selected when such cores are connected to an interrupt
|
||||
controller that is not the ARM Generic Interrupt Controller (GIC).
|
||||
controller that is not the ARM Generic Interrupt Controller (GIC) or
|
||||
the Cortex-M ARM Nested Vectored Interrupt Controller (NVIC).
|
||||
|
||||
When this option is selected, the architecture interrupt control
|
||||
functions are mapped to the SoC interrupt control interface, which is
|
||||
implemented at the SoC level.
|
||||
|
||||
N.B. This option is only applicable to the Cortex-A and Cortex-R
|
||||
family cores. The Cortex-M family cores are always equipped with
|
||||
the ARM Nested Vectored Interrupt Controller (NVIC).
|
||||
N.B. Since all Cortex-M cores have a NVIC, if this option is selected it
|
||||
is assumed that the custom interrupt control interface implementation
|
||||
assumes responsibility for handling the NVIC.
|
||||
|
||||
config CODE_DATA_RELOCATION_SRAM
|
||||
bool "Relocate code/data sections to SRAM"
|
||||
|
|
|
@ -7,7 +7,6 @@ zephyr_library_sources(
|
|||
fault.c
|
||||
fault_s.S
|
||||
fpu.c
|
||||
irq_init.c
|
||||
reset.S
|
||||
scb.c
|
||||
thread_abort.c
|
||||
|
@ -20,6 +19,7 @@ zephyr_library_sources(
|
|||
cpu_idle.S
|
||||
)
|
||||
|
||||
zephyr_library_sources_ifndef(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER irq_init.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)
|
||||
zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S)
|
||||
|
|
|
@ -32,6 +32,8 @@ extern void z_arm_reserved(void);
|
|||
#define REG_FROM_IRQ(irq) (irq / NUM_IRQS_PER_REG)
|
||||
#define BIT_FROM_IRQ(irq) (irq % NUM_IRQS_PER_REG)
|
||||
|
||||
#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
|
||||
|
||||
void arch_irq_enable(unsigned int irq)
|
||||
{
|
||||
NVIC_EnableIRQ((IRQn_Type)irq);
|
||||
|
@ -90,6 +92,8 @@ void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
|
|||
NVIC_SetPriority((IRQn_Type)irq, prio);
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) */
|
||||
|
||||
void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf);
|
||||
|
||||
/**
|
||||
|
|
|
@ -97,13 +97,24 @@ _idle_state_cleared:
|
|||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
|
||||
bl z_soc_irq_get_active
|
||||
#else
|
||||
mrs r0, IPSR /* get exception number */
|
||||
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
|
||||
|
||||
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
|
||||
ldr r1, =16
|
||||
subs r0, r1 /* get IRQ number */
|
||||
#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
|
||||
push {r0}
|
||||
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
|
||||
lsls r0, #3 /* table is 8-byte wide */
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
sub r0, r0, #16 /* get IRQ number */
|
||||
#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
|
||||
push {r0}
|
||||
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
|
||||
lsl r0, r0, #3 /* table is 8-byte wide */
|
||||
#else
|
||||
#error Unknown ARM architecture
|
||||
|
@ -116,6 +127,11 @@ _idle_state_cleared:
|
|||
ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */
|
||||
blx r3 /* call ISR */
|
||||
|
||||
#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
|
||||
pop {r0}
|
||||
bl z_soc_irq_eoi
|
||||
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
|
||||
|
||||
#ifdef CONFIG_TRACING_ISR
|
||||
bl sys_trace_isr_exit
|
||||
#endif
|
||||
|
|
|
@ -187,7 +187,12 @@ void z_arm_prep_c(void)
|
|||
#endif
|
||||
z_bss_zero();
|
||||
z_data_copy();
|
||||
#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
|
||||
/* Invoke SoC-specific interrupt controller initialization */
|
||||
z_soc_irq_init();
|
||||
#else
|
||||
z_arm_interrupt_init();
|
||||
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
|
||||
z_cstart();
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue