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) \
103 : union { \
104 : uint32_t name1, name2; \
105 : }
106 :
107 : struct arch_esf {
108 : struct __basic_sf {
109 0 : sys_define_gpr_with_alias(a1, r0);
110 0 : sys_define_gpr_with_alias(a2, r1);
111 0 : sys_define_gpr_with_alias(a3, r2);
112 0 : sys_define_gpr_with_alias(a4, r3);
113 0 : sys_define_gpr_with_alias(ip, r12);
114 0 : sys_define_gpr_with_alias(lr, r14);
115 0 : sys_define_gpr_with_alias(pc, r15);
116 : uint32_t xpsr;
117 : } basic;
118 : #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
119 : struct __fpu_sf fpu;
120 : #endif
121 : #if defined(CONFIG_EXTRA_EXCEPTION_INFO)
122 : struct __extra_esf_info extra_info;
123 : #endif
124 : };
125 :
126 : extern uint32_t z_arm_coredump_fault_sp;
127 :
128 : extern void z_arm_exc_exit(void);
129 :
130 : #ifdef __cplusplus
131 : }
132 : #endif
133 :
134 : #endif /* _ASMLANGUAGE */
135 :
136 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXCEPTION_H_ */
|