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/arm/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 : register uint32_t r0 __asm__("r0") = reason_p; \ 57 : do { \ 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_ */