Line data Source code
1 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 Cortex-M public exception handling 10 : */ 11 : 12 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXCEPTION_H_ 13 : #define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXCEPTION_H_ 14 : 15 : #include <zephyr/devicetree.h> 16 : 17 : #include <zephyr/arch/arm/cortex_m/nvic.h> 18 : 19 : /* for assembler, only works with constants */ 20 : #define Z_EXC_PRIO(pri) (((pri) << (8 - NUM_IRQ_PRIO_BITS)) & 0xff) 21 : 22 : /* 23 : * In architecture variants with non-programmable fault exceptions 24 : * (e.g. Cortex-M Baseline variants), hardware ensures processor faults 25 : * are given the highest interrupt priority level. SVCalls are assigned 26 : * the highest configurable priority level (level 0); note, however, that 27 : * this interrupt level may be shared with HW interrupts. 28 : * 29 : * In Cortex variants with programmable fault exception priorities we 30 : * assign the highest interrupt priority level (level 0) to processor faults 31 : * with configurable priority. 32 : * The highest priority level may be shared with either Zero-Latency IRQs (if 33 : * support for the feature is enabled) or with SVCall priority level. 34 : * Regular HW IRQs are always assigned priority levels lower than the priority 35 : * levels for SVCalls, Zero-Latency IRQs and processor faults. 36 : * 37 : * PendSV IRQ (which is used in Cortex-M variants to implement thread 38 : * context-switching) is assigned the lowest IRQ priority level. 39 : */ 40 : #if defined(CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS) 41 : #define _EXCEPTION_RESERVED_PRIO 1 42 : #else 43 : #define _EXCEPTION_RESERVED_PRIO 0 44 : #endif 45 : 46 : #define _EXC_FAULT_PRIO 0 47 : #define _EXC_ZERO_LATENCY_IRQS_PRIO 0 48 : #define _EXC_SVC_PRIO COND_CODE_1(CONFIG_ZERO_LATENCY_IRQS, \ 49 : (CONFIG_ZERO_LATENCY_LEVELS), (0)) 50 : #define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO) 51 0 : #define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1) 52 : 53 : #define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET) 54 : 55 : /* Use lowest possible priority level for PendSV */ 56 : #define _EXC_PENDSV_PRIO 0xff 57 : #define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO) 58 : 59 : #ifdef _ASMLANGUAGE 60 : GTEXT(z_arm_exc_exit); 61 : #else 62 : #include <zephyr/types.h> 63 : 64 : #ifdef __cplusplus 65 : extern "C" { 66 : #endif 67 : 68 : #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) 69 : 70 : /* Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine calls. 71 : * 72 : * Registers s0-s15 (d0-d7, q0-q3) do not have to be preserved (and can be used 73 : * for passing arguments or returning results in standard procedure-call variants). 74 : * 75 : * Registers d16-d31 (q8-q15), do not have to be preserved. 76 : */ 77 : struct __fpu_sf { 78 : uint32_t s[16]; /* s0~s15 (d0-d7) */ 79 : #ifdef CONFIG_VFP_FEATURE_REGS_S64_D32 80 : uint64_t d[16]; /* d16~d31 */ 81 : #endif 82 : uint32_t fpscr; 83 : uint32_t undefined; 84 : }; 85 : #endif 86 : 87 : /* Additional register state that is not stacked by hardware on exception 88 : * entry. 89 : * 90 : * These fields are ONLY valid in the ESF copy passed into z_arm_fatal_error(). 91 : * When information for a member is unavailable, the field is set to zero. 92 : */ 93 : #if defined(CONFIG_EXTRA_EXCEPTION_INFO) 94 : struct __extra_esf_info { 95 : _callee_saved_t *callee; 96 : uint32_t msp; 97 : uint32_t exc_return; 98 : }; 99 : #endif /* CONFIG_EXTRA_EXCEPTION_INFO */ 100 : 101 : /* ARM GPRs are often designated by two different names */ 102 0 : #define sys_define_gpr_with_alias(name1, name2) union { uint32_t name1, name2; } 103 : 104 : struct arch_esf { 105 : struct __basic_sf { 106 0 : sys_define_gpr_with_alias(a1, r0); 107 0 : sys_define_gpr_with_alias(a2, r1); 108 0 : sys_define_gpr_with_alias(a3, r2); 109 0 : sys_define_gpr_with_alias(a4, r3); 110 0 : sys_define_gpr_with_alias(ip, r12); 111 0 : sys_define_gpr_with_alias(lr, r14); 112 0 : sys_define_gpr_with_alias(pc, r15); 113 : uint32_t xpsr; 114 : } basic; 115 : #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) 116 : struct __fpu_sf fpu; 117 : #endif 118 : #if defined(CONFIG_EXTRA_EXCEPTION_INFO) 119 : struct __extra_esf_info extra_info; 120 : #endif 121 : }; 122 : 123 : extern uint32_t z_arm_coredump_fault_sp; 124 : 125 : extern void z_arm_exc_exit(void); 126 : 127 : #ifdef __cplusplus 128 : } 129 : #endif 130 : 131 : #endif /* _ASMLANGUAGE */ 132 : 133 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXCEPTION_H_ */