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 AArch32 public exception handling 10 * 11 * ARM AArch32-specific kernel exception handling interface. Included by 12 * arm/arch.h. 13 */ 14 15 #ifndef ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_EXC_H_ 16 #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_EXC_H_ 17 18 #if defined(CONFIG_CPU_CORTEX_M) 19 #include <zephyr/devicetree.h> 20 21 #include <zephyr/arch/arm/aarch32/cortex_m/nvic.h> 22 23 /* for assembler, only works with constants */ 24 #define Z_EXC_PRIO(pri) (((pri) << (8 - NUM_IRQ_PRIO_BITS)) & 0xff) 25 26 /* 27 * In architecture variants with non-programmable fault exceptions 28 * (e.g. Cortex-M Baseline variants), hardware ensures processor faults 29 * are given the highest interrupt priority level. SVCalls are assigned 30 * the highest configurable priority level (level 0); note, however, that 31 * this interrupt level may be shared with HW interrupts. 32 * 33 * In Cortex variants with programmable fault exception priorities we 34 * assign the highest interrupt priority level (level 0) to processor faults 35 * with configurable priority. 36 * The highest priority level may be shared with either Zero-Latency IRQs (if 37 * support for the feature is enabled) or with SVCall priority level. 38 * Regular HW IRQs are always assigned priority levels lower than the priority 39 * levels for SVCalls, Zero-Latency IRQs and processor faults. 40 * 41 * PendSV IRQ (which is used in Cortex-M variants to implement thread 42 * context-switching) is assigned the lowest IRQ priority level. 43 */ 44 #if defined(CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS) 45 #define _EXCEPTION_RESERVED_PRIO 1 46 #else 47 #define _EXCEPTION_RESERVED_PRIO 0 48 #endif 49 50 #define _EXC_FAULT_PRIO 0 51 #define _EXC_ZERO_LATENCY_IRQS_PRIO 0 52 #define _EXC_SVC_PRIO COND_CODE_1(CONFIG_ZERO_LATENCY_IRQS, \ 53 (CONFIG_ZERO_LATENCY_LEVELS), (0)) 54 #define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO) 55 #define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1) 56 57 #define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET) 58 59 /* Use lowest possible priority level for PendSV */ 60 #define _EXC_PENDSV_PRIO 0xff 61 #define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO) 62 #endif /* CONFIG_CPU_CORTEX_M */ 63 64 #ifdef _ASMLANGUAGE 65 GTEXT(z_arm_exc_exit); 66 #else 67 #include <zephyr/types.h> 68 69 #ifdef __cplusplus 70 extern "C" { 71 #endif 72 73 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) 74 struct __fpu_sf { 75 float s[16]; 76 uint32_t fpscr; 77 uint32_t undefined; 78 }; 79 #endif 80 81 /* Additional register state that is not stacked by hardware on exception 82 * entry. 83 * 84 * These fields are ONLY valid in the ESF copy passed into z_arm_fatal_error(). 85 * When information for a member is unavailable, the field is set to zero. 86 */ 87 #if defined(CONFIG_EXTRA_EXCEPTION_INFO) 88 struct __extra_esf_info { 89 _callee_saved_t *callee; 90 uint32_t msp; 91 uint32_t exc_return; 92 }; 93 #endif /* CONFIG_EXTRA_EXCEPTION_INFO */ 94 95 #if defined(CONFIG_CPU_CORTEX_M) 96 97 struct __esf { 98 struct __basic_sf { 99 sys_define_gpr_with_alias(a1, r0); 100 sys_define_gpr_with_alias(a2, r1); 101 sys_define_gpr_with_alias(a3, r2); 102 sys_define_gpr_with_alias(a4, r3); 103 sys_define_gpr_with_alias(ip, r12); 104 sys_define_gpr_with_alias(lr, r14); 105 sys_define_gpr_with_alias(pc, r15); 106 uint32_t xpsr; 107 } basic; 108 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) 109 struct __fpu_sf fpu; 110 #endif 111 #if defined(CONFIG_EXTRA_EXCEPTION_INFO) 112 struct __extra_esf_info extra_info; 113 #endif 114 }; 115 116 #else 117 118 struct __esf { 119 #if defined(CONFIG_EXTRA_EXCEPTION_INFO) 120 struct __extra_esf_info extra_info; 121 #endif 122 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) 123 struct __fpu_sf fpu; 124 #endif 125 struct __basic_sf { 126 sys_define_gpr_with_alias(a1, r0); 127 sys_define_gpr_with_alias(a2, r1); 128 sys_define_gpr_with_alias(a3, r2); 129 sys_define_gpr_with_alias(a4, r3); 130 sys_define_gpr_with_alias(ip, r12); 131 sys_define_gpr_with_alias(lr, r14); 132 sys_define_gpr_with_alias(pc, r15); 133 uint32_t xpsr; 134 } basic; 135 }; 136 137 #endif 138 139 extern uint32_t z_arm_coredump_fault_sp; 140 141 typedef struct __esf z_arch_esf_t; 142 143 #ifdef CONFIG_CPU_CORTEX_M 144 extern void z_arm_exc_exit(void); 145 #else 146 extern void z_arm_exc_exit(bool fatal); 147 #endif 148 149 #ifdef __cplusplus 150 } 151 #endif 152 153 #endif /* _ASMLANGUAGE */ 154 155 #endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_EXC_H_ */ 156