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 <devicetree.h>
20 
21 #include <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, (1), (0))
53 #define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO)
54 #define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1)
55 
56 #define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET)
57 
58 /* Use lowest possible priority level for PendSV */
59 #define _EXC_PENDSV_PRIO 0xff
60 #define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO)
61 #endif /* CONFIG_CPU_CORTEX_M */
62 
63 #ifdef _ASMLANGUAGE
64 GTEXT(z_arm_exc_exit);
65 #else
66 #include <zephyr/types.h>
67 
68 #ifdef __cplusplus
69 extern "C" {
70 #endif
71 
72 /* Additional register state that is not stacked by hardware on exception
73  * entry.
74  *
75  * These fields are ONLY valid in the ESF copy passed into z_arm_fatal_error().
76  * When information for a member is unavailable, the field is set to zero.
77  */
78 #if defined(CONFIG_EXTRA_EXCEPTION_INFO)
79 struct __extra_esf_info {
80 	_callee_saved_t *callee;
81 	uint32_t msp;
82 	uint32_t exc_return;
83 };
84 #endif /* CONFIG_EXTRA_EXCEPTION_INFO */
85 
86 struct __esf {
87 	struct __basic_sf {
88 		sys_define_gpr_with_alias(a1, r0);
89 		sys_define_gpr_with_alias(a2, r1);
90 		sys_define_gpr_with_alias(a3, r2);
91 		sys_define_gpr_with_alias(a4, r3);
92 		sys_define_gpr_with_alias(ip, r12);
93 		sys_define_gpr_with_alias(lr, r14);
94 		sys_define_gpr_with_alias(pc, r15);
95 		uint32_t xpsr;
96 	} basic;
97 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
98 	float s[16];
99 	uint32_t fpscr;
100 	uint32_t undefined;
101 #endif
102 #if defined(CONFIG_EXTRA_EXCEPTION_INFO)
103 	struct __extra_esf_info extra_info;
104 #endif
105 };
106 
107 extern uint32_t z_arm_coredump_fault_sp;
108 
109 typedef struct __esf z_arch_esf_t;
110 
111 #ifdef CONFIG_CPU_CORTEX_M
112 extern void z_arm_exc_exit(void);
113 #else
114 extern void z_arm_exc_exit(bool fatal);
115 #endif
116 
117 #ifdef __cplusplus
118 }
119 #endif
120 
121 #endif /* _ASMLANGUAGE */
122 
123 #endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_EXC_H_ */
124