From a0a03d7597fa59939369bf3b5fd634e464d8af38 Mon Sep 17 00:00:00 2001 From: Ioannis Glaropoulos Date: Tue, 6 Feb 2018 23:47:58 +0100 Subject: [PATCH] arch: arm: common Armv8-M support This PR includes the required changes in order to support conditional compilation for Armv8-M architecture. Two variants of the Armv8-M architecture are defined: - the Armv8-M Baseline (backwards compatible with ARMv6-M), - the Armv8-M Mainline (backwards compatible with ARMv7-M). Signed-off-by: Ioannis Glaropoulos --- arch/arm/core/cortex_m/Kconfig | 41 +++++++++++++----- arch/arm/core/cortex_m/reset.S | 6 +-- arch/arm/core/cortex_m/vector_table.S | 6 +-- arch/arm/core/cortex_m/vector_table.h | 6 +-- arch/arm/core/cpu_idle.S | 12 +++--- arch/arm/core/exc_exit.S | 8 ++-- arch/arm/core/fault.c | 32 +++++++------- arch/arm/core/fault_s.S | 20 +++++---- arch/arm/core/irq_manage.c | 12 +++--- arch/arm/core/irq_offload.c | 4 +- arch/arm/core/isr_wrapper.S | 22 +++++----- arch/arm/core/swap.S | 42 +++++++++---------- arch/arm/include/cortex_m/exc.h | 12 +++--- arch/arm/include/kernel_arch_func.h | 6 +-- dts/arm/armv8-m.dtsi | 25 +++++++++++ .../interrupt-controller/arm,v8m-nvic.yaml | 32 ++++++++++++++ include/arch/arm/cortex_m/asm_inline_gcc.h | 12 +++--- include/arch/arm/cortex_m/cmsis.h | 4 +- include/arch/arm/cortex_m/error.h | 6 +-- .../kernel/arm_irq_vector_table/testcase.yaml | 2 +- tests/kernel/gen_isr_table/testcase.yaml | 2 +- 21 files changed, 197 insertions(+), 115 deletions(-) create mode 100644 dts/arm/armv8-m.dtsi create mode 100644 dts/bindings/interrupt-controller/arm,v8m-nvic.yaml diff --git a/arch/arm/core/cortex_m/Kconfig b/arch/arm/core/cortex_m/Kconfig index 85c534c0fa2..63eaba70184 100644 --- a/arch/arm/core/cortex_m/Kconfig +++ b/arch/arm/core/cortex_m/Kconfig @@ -65,16 +65,26 @@ config CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP This option signifies the Cortex-M0 has some mechanisms that can map the vector table to SRAM -config ARMV6_M +config ARMV6_M_ARMV8_M_BASELINE bool # Omit prompt to signify "hidden" option default n select ATOMIC_OPERATIONS_C select ISA_THUMB2 help - This option signifies the use of an ARMv6-M processor implementation. + This option signifies the use of an ARMv6-M processor + implementation, or the use of an ARMv8-M processor + supporting the Baseline implementation. -config ARMV7_M + Notes: + - A Processing Element (PE) without the Main Extension + is also referred to as a Baseline Implementation. A + Baseline implementation has a subset of the instructions, + registers, and features, of a Mainline implementation. + - ARMv6-M compatibility is provided by all ARMv8-M + implementations. + +config ARMV7_M_ARMV8_M_MAINLINE bool # Omit prompt to signify "hidden" option default n @@ -84,40 +94,51 @@ config ARMV7_M select CPU_CORTEX_M_HAS_VTOR select CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS help - This option signifies the use of an ARMv7-M processor implementation. + This option signifies the use of an ARMv7-M processor + implementation, or the use of an ARMv8-M processor + implementation supporting the Main Extension. + + Notes: + - A Processing Element (PE) with the Main Extension is also + referred to as a Mainline Implementation. + - ARMv7-M compatibility requires the Main Extension. + + From https://developer.arm.com/products/architecture/m-profile: + The Main Extension provides backwards compatibility + with ARMv7-M. config CPU_CORTEX_M0 bool # Omit prompt to signify "hidden" option - select ARMV6_M + select ARMV6_M_ARMV8_M_BASELINE help This option signifies the use of a Cortex-M0 CPU config CPU_CORTEX_M0PLUS bool # Omit prompt to signify "hidden" option - select ARMV6_M + select ARMV6_M_ARMV8_M_BASELINE help This option signifies the use of a Cortex-M0+ CPU config CPU_CORTEX_M3 bool # Omit prompt to signify "hidden" option - select ARMV7_M + select ARMV7_M_ARMV8_M_MAINLINE help This option signifies the use of a Cortex-M3 CPU config CPU_CORTEX_M4 bool # Omit prompt to signify "hidden" option - select ARMV7_M + select ARMV7_M_ARMV8_M_MAINLINE help This option signifies the use of a Cortex-M4 CPU config CPU_CORTEX_M7 bool # Omit prompt to signify "hidden" option - select ARMV7_M + select ARMV7_M_ARMV8_M_MAINLINE default n help This option signifies the use of a Cortex-M7 CPU @@ -177,7 +198,7 @@ config XIP endmenu menu "ARM Cortex-M0/M0+/M3/M4/M7 options" - depends on ARMV6_M || ARMV7_M + depends on ARMV6_M_ARMV8_M_BASELINE || ARMV7_M_ARMV8_M_MAINLINE config GEN_ISR_TABLES default y diff --git a/arch/arm/core/cortex_m/reset.S b/arch/arm/core/cortex_m/reset.S index 0cf37bf059e..752b2928df8 100644 --- a/arch/arm/core/cortex_m/reset.S +++ b/arch/arm/core/cortex_m/reset.S @@ -58,14 +58,14 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__reset) SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) /* lock interrupts: will get unlocked when switch to main task */ -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) cpsid i -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) movs.n r0, #_EXC_IRQ_DEFAULT_PRIO msr BASEPRI, r0 #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ #ifdef CONFIG_WDOG_INIT /* board-specific watchdog initialization is necessary */ diff --git a/arch/arm/core/cortex_m/vector_table.S b/arch/arm/core/cortex_m/vector_table.S index 5a65b747d88..99092df24b9 100644 --- a/arch/arm/core/cortex_m/vector_table.S +++ b/arch/arm/core/cortex_m/vector_table.S @@ -39,7 +39,7 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) .word __nmi .word __hard_fault -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) .word __reserved .word __reserved .word __reserved @@ -49,7 +49,7 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) .word __reserved .word __svc .word __reserved -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) .word __mpu_fault .word __bus_fault .word __usage_fault @@ -61,7 +61,7 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) .word __debug_monitor #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ .word __reserved .word __pendsv #if defined(CONFIG_CORTEX_M_SYSTICK) diff --git a/arch/arm/core/cortex_m/vector_table.h b/arch/arm/core/cortex_m/vector_table.h index d15d9808ad1..4d696e1092d 100644 --- a/arch/arm/core/cortex_m/vector_table.h +++ b/arch/arm/core/cortex_m/vector_table.h @@ -38,9 +38,9 @@ GTEXT(_vector_table) GTEXT(__reset) GTEXT(__nmi) GTEXT(__hard_fault) -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) GTEXT(__svc) -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) GTEXT(__mpu_fault) GTEXT(__bus_fault) GTEXT(__usage_fault) @@ -48,7 +48,7 @@ GTEXT(__svc) GTEXT(__debug_monitor) #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ GTEXT(__pendsv) GTEXT(__reserved) diff --git a/arch/arm/core/cpu_idle.S b/arch/arm/core/cpu_idle.S index 79fd6b9bf2a..622a3f4b0e7 100644 --- a/arch/arm/core/cpu_idle.S +++ b/arch/arm/core/cpu_idle.S @@ -120,15 +120,15 @@ SECTION_FUNC(TEXT, k_cpu_idle) mov lr, r0 #endif -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) cpsie i -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* clear BASEPRI so wfi is awakened by incoming interrupts */ eors.n r0, r0 msr BASEPRI, r0 #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ wfi @@ -177,7 +177,7 @@ SECTION_FUNC(TEXT, k_cpu_atomic_idle) /* r0: interrupt mask from caller */ -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* No BASEPRI, call wfe directly (SEVONPEND set in _CpuIdleInit()) */ wfe @@ -186,7 +186,7 @@ SECTION_FUNC(TEXT, k_cpu_atomic_idle) cpsie i _irq_disabled: -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* r1: zero, for setting BASEPRI (needs a register) */ eors.n r1, r1 @@ -199,5 +199,5 @@ _irq_disabled: cpsie i #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ bx lr diff --git a/arch/arm/core/exc_exit.S b/arch/arm/core/exc_exit.S index fd46560a1c7..b7363e6b0df 100644 --- a/arch/arm/core/exc_exit.S +++ b/arch/arm/core/exc_exit.S @@ -90,12 +90,12 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, _ExcExit) #ifdef CONFIG_TIMESLICING push {lr} bl _update_time_slice_before_swap -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0} mov lr, r0 #else pop {lr} -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ #endif /* CONFIG_TIMESLICING */ /* context switch required, pend the PendSV exception */ @@ -111,12 +111,12 @@ _EXIT_EXC: #ifdef CONFIG_STACK_SENTINEL push {lr} bl _check_stack_sentinel -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0} mov lr, r0 #else pop {lr} -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ #endif /* CONFIG_STACK_SENTINEL */ bx lr diff --git a/arch/arm/core/fault.c b/arch/arm/core/fault.c index b10d760f861..987d3b62837 100644 --- a/arch/arm/core/fault.c +++ b/arch/arm/core/fault.c @@ -59,8 +59,8 @@ void _FaultDump(const NANO_ESF *esf, int fault) k_current_get(), esf->pc); -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) int escalation = 0; if (3 == fault) { /* hard fault */ @@ -92,7 +92,7 @@ void _FaultDump(const NANO_ESF *esf, int fault) SCB->CFSR |= SCB_CFSR_USGFAULTSR_Msk; #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ } #endif @@ -112,8 +112,9 @@ static void _FaultThreadShow(const NANO_ESF *esf) k_current_get(), esf->pc); } -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +/* HardFault is used for all fault conditions on ARMv6-M. */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /** * @@ -240,7 +241,7 @@ static void _DebugMonitor(const NANO_ESF *esf) #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /** * @@ -254,9 +255,9 @@ static void _HardFault(const NANO_ESF *esf) { PR_EXC("***** HARD FAULT *****\n"); -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) _FaultThreadShow(esf); -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) { PR_EXC(" Bus fault on vector table read\n"); } else if (SCB->HFSR & SCB_HFSR_FORCED_Msk) { @@ -271,7 +272,7 @@ static void _HardFault(const NANO_ESF *esf) } #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ } /** @@ -316,8 +317,9 @@ static void _FaultDump(const NANO_ESF *esf, int fault) case 3: _HardFault(esf); break; -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + /* HardFault is used for all fault conditions on ARMv6-M. */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) case 4: _MpuFault(esf, 0); break; @@ -332,7 +334,7 @@ static void _FaultDump(const NANO_ESF *esf, int fault) break; #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ default: _ReservedException(esf, fault); break; @@ -375,10 +377,10 @@ void _Fault(const NANO_ESF *esf) */ void _FaultInit(void) { -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ } diff --git a/arch/arm/core/fault_s.S b/arch/arm/core/fault_s.S index e0c84ac5fe2..1615acf468a 100644 --- a/arch/arm/core/fault_s.S +++ b/arch/arm/core/fault_s.S @@ -20,15 +20,16 @@ _ASM_FILE_PROLOGUE GTEXT(_Fault) GTEXT(__hard_fault) -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +/* HardFault is used for all fault conditions on ARMv6-M. */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) GTEXT(__mpu_fault) GTEXT(__bus_fault) GTEXT(__usage_fault) GTEXT(__debug_monitor) #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ GTEXT(__reserved) /** @@ -55,18 +56,19 @@ GTEXT(__reserved) */ SECTION_SUBSEC_FUNC(TEXT,__fault,__hard_fault) -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +/* HardFault is used for all fault conditions on ARMv6-M. */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) SECTION_SUBSEC_FUNC(TEXT,__fault,__mpu_fault) SECTION_SUBSEC_FUNC(TEXT,__fault,__bus_fault) SECTION_SUBSEC_FUNC(TEXT,__fault,__usage_fault) SECTION_SUBSEC_FUNC(TEXT,__fault,__debug_monitor) #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ SECTION_SUBSEC_FUNC(TEXT,__fault,__reserved) -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* force unlock interrupts */ cpsie i @@ -83,7 +85,7 @@ _stack_frame_msp: mrs r0, MSP _stack_frame_endif: -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* force unlock interrupts */ eors.n r0, r0 msr BASEPRI, r0 @@ -102,7 +104,7 @@ _stack_frame_endif: * frame is on the PSP */ #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ push {lr} bl _Fault diff --git a/arch/arm/core/irq_manage.c b/arch/arm/core/irq_manage.c index e865ae4468c..323f0642fe8 100644 --- a/arch/arm/core/irq_manage.c +++ b/arch/arm/core/irq_manage.c @@ -146,12 +146,12 @@ void _irq_spurious(void *unused) #ifdef CONFIG_SYS_POWER_MANAGEMENT void _arch_isr_direct_pm(void) { -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) int key; /* irq_lock() does what we wan for this CPU */ key = irq_lock(); -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* Lock all interrupts. irq_lock() will on this CPU only disable those * lower than BASEPRI, which is not what we want. See comments in * arch/arm/core/isr_wrapper.S @@ -159,7 +159,7 @@ void _arch_isr_direct_pm(void) __asm__ volatile("cpsid i" : : : "memory"); #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ if (_kernel.idle) { s32_t idle_val = _kernel.idle; @@ -168,13 +168,13 @@ void _arch_isr_direct_pm(void) _sys_power_save_idle_exit(idle_val); } -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) irq_unlock(key); -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) __asm__ volatile("cpsie i" : : : "memory"); #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ } #endif diff --git a/arch/arm/core/irq_offload.c b/arch/arm/core/irq_offload.c index 1508405c4ff..12e3cc93324 100644 --- a/arch/arm/core/irq_offload.c +++ b/arch/arm/core/irq_offload.c @@ -22,7 +22,7 @@ void _irq_do_offload(void) void irq_offload(irq_offload_routine_t routine, void *parameter) { -#if defined(CONFIG_ARMV6_M) && defined(CONFIG_ASSERT) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && defined(CONFIG_ASSERT) /* Cortex M0 hardfaults if you make a SVC call with interrupts * locked. */ @@ -30,7 +30,7 @@ void irq_offload(irq_offload_routine_t routine, void *parameter) __asm__ volatile("mrs %0, PRIMASK;" : "=r" (key) : : "memory"); __ASSERT(key == 0, "irq_offload called with interrupts locked\n"); -#endif +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE && CONFIG_ASSERT */ k_sched_lock(); offload_routine = routine; diff --git a/arch/arm/core/isr_wrapper.S b/arch/arm/core/isr_wrapper.S index 83556f8337c..b1563df2f74 100644 --- a/arch/arm/core/isr_wrapper.S +++ b/arch/arm/core/isr_wrapper.S @@ -72,7 +72,7 @@ SECTION_FUNC(TEXT, _isr_wrapper) ldr r0, [r2, #_kernel_offset_to_idle] cmp r0, #0 -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) beq _idle_state_cleared movs.n r1, #0 /* clear kernel idle state */ @@ -80,7 +80,7 @@ SECTION_FUNC(TEXT, _isr_wrapper) blx _sys_power_save_idle_exit _idle_state_cleared: -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) ittt ne movne r1, #0 /* clear kernel idle state */ @@ -88,22 +88,22 @@ _idle_state_cleared: blxne _sys_power_save_idle_exit #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ cpsie i /* re-enable interrupts (PRIMASK = 0) */ #endif mrs r0, IPSR /* get exception number */ -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) ldr r1, =16 subs r0, r1 /* get IRQ number */ lsls r0, #3 /* table is 8-byte wide */ -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) sub r0, r0, #16 /* get IRQ number */ lsl r0, r0, #3 /* table is 8-byte wide */ #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ ldr r1, =_sw_isr_table add r1, r1, r0 /* table entry: ISRs must have their MSB set to stay * in thumb mode */ @@ -113,24 +113,24 @@ _idle_state_cleared: stm sp!,{r0-r3} /* Save r0 to r4 into stack */ push {lr} bl read_timer_end_of_isr -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r3} mov lr,r3 #else pop {lr} -#endif +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ ldm sp!,{r0-r3} /* Restore r0 to r4 regs */ #endif blx r3 /* call ISR */ -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r3} mov lr, r3 -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) pop {lr} #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /* exception return is done in _IntExit() */ b _IntExit diff --git a/arch/arm/core/swap.S b/arch/arm/core/swap.S index d90dd24d67c..f4a575d1296 100644 --- a/arch/arm/core/swap.S +++ b/arch/arm/core/swap.S @@ -46,12 +46,12 @@ SECTION_FUNC(TEXT, __pendsv) /* Register the context switch */ push {lr} bl _sys_k_event_logger_context_switch -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0} mov lr, r0 #else pop {lr} -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ #endif /* CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH */ /* load _kernel into r1 and current k_thread into r2 */ @@ -65,7 +65,7 @@ SECTION_FUNC(TEXT, __pendsv) /* save callee-saved + psp in thread */ mrs ip, PSP -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* Store current r4-r7 */ stmea r0!, {r4-r7} /* copy r8-r12 into r3-r7 */ @@ -76,7 +76,7 @@ SECTION_FUNC(TEXT, __pendsv) mov r7, ip /* store r8-12 */ stmea r0!, {r3-r7} -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) stmia r0, {v1-v8, ip} #ifdef CONFIG_FP_SHARING add r0, r2, #_thread_offset_to_preempt_float @@ -84,7 +84,7 @@ SECTION_FUNC(TEXT, __pendsv) #endif /* CONFIG_FP_SHARING */ #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /* * Prepare to clear PendSV with interrupts unlocked, but @@ -97,14 +97,14 @@ SECTION_FUNC(TEXT, __pendsv) ldr v3, =_SCS_ICSR_UNPENDSV /* protect the kernel state while we play with the thread lists */ -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) cpsid i -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) movs.n r0, #_EXC_IRQ_DEFAULT_PRIO msr BASEPRI, r0 #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /* _kernel is still in r1 */ @@ -130,7 +130,7 @@ SECTION_FUNC(TEXT, __pendsv) movs.n r3, #0 str r3, [r2, #_thread_offset_to_basepri] -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* BASEPRI not available, previous interrupt disable state * maps to PRIMASK. * @@ -158,7 +158,7 @@ _thread_irq_disabled: /* restore r4-r7, go back 9*4 bytes to the start of the stored block */ subs r0, #36 ldmia r0!, {r4-r7} -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* restore BASEPRI for the incoming thread */ msr BASEPRI, r0 @@ -188,7 +188,7 @@ _thread_irq_disabled: ldmia r0, {v1-v8, ip} #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ msr PSP, ip @@ -197,19 +197,19 @@ _thread_irq_disabled: push {lr} bl read_timer_end_of_swap -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r3} mov lr,r3 #else pop {lr} -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ ldm sp!,{r0-r3} /* Load back regs ro to r4 */ #endif /* CONFIG_EXECUTION_BENCHMARKING */ /* exc return */ bx lr -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) SECTION_FUNC(TEXT, __svc) /* Use EXC_RETURN state to find out if stack frame is on the * MSP or PSP @@ -256,7 +256,7 @@ _oops: blx _do_kernel_oops pop {pc} -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /** * * @brief Service call handler @@ -326,7 +326,7 @@ _oops: #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /** * @@ -370,12 +370,12 @@ SECTION_FUNC(TEXT, __swap) #ifdef CONFIG_EXECUTION_BENCHMARKING push {lr} bl read_timer_start_of_swap -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r3} mov lr,r3 #else pop {lr} -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ #endif /* CONFIG_EXECUTION_BENCHMARKING */ ldr r1, =_kernel ldr r2, [r1, #_kernel_offset_to_current] @@ -389,7 +389,7 @@ SECTION_FUNC(TEXT, __swap) ldr r1, [r1] str r1, [r2, #_thread_offset_to_swap_return_value] -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* No priority-based interrupt masking on M0/M0+, * pending PendSV is used instead of svc */ @@ -403,11 +403,11 @@ SECTION_FUNC(TEXT, __swap) * of a higher priority pending. */ cpsie i -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) svc #0 #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /* coming back from exception, r2 still holds the pointer to _current */ ldr r0, [r2, #_thread_offset_to_swap_return_value] diff --git a/arch/arm/include/cortex_m/exc.h b/arch/arm/include/cortex_m/exc.h index 3ca85926d50..a4fd88791fa 100644 --- a/arch/arm/include/cortex_m/exc.h +++ b/arch/arm/include/cortex_m/exc.h @@ -55,12 +55,12 @@ static ALWAYS_INLINE int _IsInIsr(void) /* Only non-NULL if currently running an offloaded function */ || offload_routine != NULL #endif -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* On ARMv6-M there is no nested execution bit, so we check * exception 3, hard fault, to a detect a nested exception. */ || (vector == 3) -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* If not in thread mode, and if RETTOBASE bit in ICSR is 0, * then there are preempted active exceptions to execute. */ @@ -75,7 +75,7 @@ static ALWAYS_INLINE int _IsInIsr(void) #endif /* CONFIG_BOARD_QEMU_CORTEX_M3 */ #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ ; } @@ -119,8 +119,8 @@ static ALWAYS_INLINE void _ExcSetup(void) */ static ALWAYS_INLINE void _ClearFaults(void) { -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* Reset all faults */ SCB->CFSR = SCB_CFSR_USGFAULTSR_Msk | SCB_CFSR_MEMFAULTSR_Msk | @@ -130,7 +130,7 @@ static ALWAYS_INLINE void _ClearFaults(void) SCB->HFSR = 0xffffffff; #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ } #endif /* _ASMLANGUAGE */ diff --git a/arch/arm/include/kernel_arch_func.h b/arch/arm/include/kernel_arch_func.h index 72720ab84c2..c352005a03f 100644 --- a/arch/arm/include/kernel_arch_func.h +++ b/arch/arm/include/kernel_arch_func.h @@ -59,14 +59,14 @@ _arch_switch_to_main_thread(struct k_thread *main_thread, "msr PSP, %0 \t\n" /* unlock interrupts */ -#ifdef CONFIG_ARMV6_M +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) "cpsie i \t\n" -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) "movs %%r1, #0 \n\t" "msr BASEPRI, %%r1 \n\t" #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ /* branch to _thread_entry(_main, 0, 0, 0) */ "mov %%r0, %1 \n\t" diff --git a/dts/arm/armv8-m.dtsi b/dts/arm/armv8-m.dtsi new file mode 100644 index 00000000000..8c4437d62b2 --- /dev/null +++ b/dts/arm/armv8-m.dtsi @@ -0,0 +1,25 @@ +#include "skeleton.dtsi" + +/ { + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&nvic>; + ranges; + + nvic: interrupt-controller@e000e100 { + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + }; +}; + diff --git a/dts/bindings/interrupt-controller/arm,v8m-nvic.yaml b/dts/bindings/interrupt-controller/arm,v8m-nvic.yaml new file mode 100644 index 00000000000..d09427ffc62 --- /dev/null +++ b/dts/bindings/interrupt-controller/arm,v8m-nvic.yaml @@ -0,0 +1,32 @@ +--- +title: ARMv8-M NVIC Interrupt Controller +version: 0.1 + +description: > + This binding describes the ARMv8-M Nested Vectored Interrupt Controller. + +properties: + compatible: + category: required + type: string + description: compatible strings + constraint: "arm,v8m-nvic" + + reg: + category: required + type: int + description: mmio register space + generation: define + + arm,num-irq-priority-bits: + category: required + type: int + description: number of bits of IRQ priorities + generation: define + +cell_string: IRQ + +"#cells": + - irq + - priority +... diff --git a/include/arch/arm/cortex_m/asm_inline_gcc.h b/include/arch/arm/cortex_m/asm_inline_gcc.h index 6dcbc9fac02..d64bf7902b2 100644 --- a/include/arch/arm/cortex_m/asm_inline_gcc.h +++ b/include/arch/arm/cortex_m/asm_inline_gcc.h @@ -118,13 +118,13 @@ static ALWAYS_INLINE unsigned int _arch_irq_lock(void) { unsigned int key; -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) __asm__ volatile("mrs %0, PRIMASK;" "cpsid i" : "=r" (key) : : "memory"); -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) unsigned int tmp; __asm__ volatile( @@ -136,7 +136,7 @@ static ALWAYS_INLINE unsigned int _arch_irq_lock(void) : "memory"); #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ return key; } @@ -163,16 +163,16 @@ static ALWAYS_INLINE unsigned int _arch_irq_lock(void) static ALWAYS_INLINE void _arch_irq_unlock(unsigned int key) { -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) if (key) { return; } __asm__ volatile("cpsie i" : : : "memory"); -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) __asm__ volatile("msr BASEPRI, %0" : : "r"(key) : "memory"); #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ } diff --git a/include/arch/arm/cortex_m/cmsis.h b/include/arch/arm/cortex_m/cmsis.h index aad213b9451..fa1d389398f 100644 --- a/include/arch/arm/cortex_m/cmsis.h +++ b/include/arch/arm/cortex_m/cmsis.h @@ -94,11 +94,11 @@ typedef enum { Reset_IRQn = -15, NonMaskableInt_IRQn = -14, HardFault_IRQn = -13, -#if defined(CONFIG_ARMV7_M) +#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) MemoryManagement_IRQn = -12, BusFault_IRQn = -11, UsageFault_IRQn = -10, -#endif /* CONFIG_ARMV7_M */ +#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ SVCall_IRQn = -5, DebugMonitor_IRQn = -4, PendSV_IRQn = -2, diff --git a/include/arch/arm/cortex_m/error.h b/include/arch/arm/cortex_m/error.h index b3cd064843f..d245b543cf6 100644 --- a/include/arch/arm/cortex_m/error.h +++ b/include/arch/arm/cortex_m/error.h @@ -34,7 +34,7 @@ extern void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *esf); #define _SVC_CALL_IRQ_OFFLOAD 1 #define _SVC_CALL_RUNTIME_EXCEPT 2 -#if defined(CONFIG_ARMV6_M) +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) /* ARMv6 will hard-fault if SVC is called with interrupts locked. Just * force them unlocked, the thread is in an undefined state anyway * @@ -53,7 +53,7 @@ extern void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *esf); : "memory"); \ CODE_UNREACHABLE; \ } while (0) -#elif defined(CONFIG_ARMV7_M) +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) #define _ARCH_EXCEPT(reason_p) do { \ __asm__ volatile ( \ "eors.n r0, r0\n\t" \ @@ -67,7 +67,7 @@ extern void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *esf); } while (0) #else #error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ +#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ #ifdef __cplusplus } diff --git a/tests/kernel/arm_irq_vector_table/testcase.yaml b/tests/kernel/arm_irq_vector_table/testcase.yaml index bf0629d24a1..9a5b5a0aaa5 100644 --- a/tests/kernel/arm_irq_vector_table/testcase.yaml +++ b/tests/kernel/arm_irq_vector_table/testcase.yaml @@ -1,4 +1,4 @@ tests: test: - filter: CONFIG_ARMV7_M + filter: CONFIG_ARMV7_M_ARMV8_M_MAINLINE tags: core bat_commit diff --git a/tests/kernel/gen_isr_table/testcase.yaml b/tests/kernel/gen_isr_table/testcase.yaml index a59a7496054..2c84c3925d8 100644 --- a/tests/kernel/gen_isr_table/testcase.yaml +++ b/tests/kernel/gen_isr_table/testcase.yaml @@ -1,4 +1,4 @@ tests: test: - filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV7_M + filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV7_M_ARMV8_M_MAINLINE tags: core