Line data Source code
1 1 : /*
2 : * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 : * Copyright (c) 2023 Arm Limited
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : /**
9 : * @file
10 : * @brief ARM AArch32 public error handling
11 : *
12 : * ARM AArch32-specific kernel error handling interface. Included by
13 : * arm/arch.h.
14 : */
15 :
16 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_
17 : #define ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_
18 :
19 : #include <zephyr/arch/arm/syscall.h>
20 : #include <zephyr/arch/exception.h>
21 : #include <stdbool.h>
22 :
23 : #ifdef __cplusplus
24 : extern "C" {
25 : #endif
26 :
27 : #if defined(CONFIG_CPU_CORTEX_M)
28 : /* ARMv6 will hard-fault if SVC is called with interrupts locked. Just
29 : * force them unlocked, the thread is in an undefined state anyway
30 : *
31 : * On ARMv7m we won't get a HardFault, but if interrupts were locked the
32 : * thread will continue executing after the exception and forbid PendSV to
33 : * schedule a new thread until they are unlocked which is not what we want.
34 : * Force them unlocked as well.
35 : */
36 : #define ARCH_EXCEPT(reason_p) \
37 : do {\
38 : arch_irq_unlock(0); \
39 : __asm__ volatile( \
40 : "mov r0, %[_reason]\n" \
41 : "svc %[id]\n" \
42 : :: [_reason] "r" (reason_p), [id] "i" (_SVC_CALL_RUNTIME_EXCEPT) \
43 : : "r0", "memory"); \
44 : } while (false)
45 : #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \
46 : || defined(CONFIG_ARMV7_A)
47 : /*
48 : * In order to support using svc for an exception while running in an
49 : * isr, stack $lr_svc before calling svc. While exiting the isr,
50 : * z_check_stack_sentinel is called. $lr_svc contains the return address.
51 : * If the sentinel is wrong, it calls svc to cause an oops. This svc
52 : * call will overwrite $lr_svc, losing the return address from the
53 : * z_check_stack_sentinel call if it is not stacked before the svc.
54 : */
55 : #define ARCH_EXCEPT(reason_p) \
56 : do { \
57 : register uint32_t r0 __asm__("r0") = reason_p; \
58 : __asm__ volatile ( \
59 : "push {lr}\n\t" \
60 : "cpsie i\n\t" \
61 : "svc %[id]\n\t" \
62 : "pop {lr}\n\t" \
63 : : \
64 : : "r" (r0), [id] "i" (_SVC_CALL_RUNTIME_EXCEPT) \
65 : : "memory"); \
66 : } while (false)
67 : #else
68 : #error Unknown ARM architecture
69 : #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
70 :
71 : #ifdef __cplusplus
72 : }
73 : #endif
74 :
75 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_ */
|