1/* 2 * Copyright (c) 2013-2014 Wind River Systems, Inc. 3 * Copyright (c) 2017-2019 Nordic Semiconductor ASA. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8/** 9 * @file 10 * @brief Fault handlers for ARM Cortex-M 11 * 12 * Fault handlers for ARM Cortex-M processors. 13 */ 14 15#include <zephyr/toolchain.h> 16#include <zephyr/linker/sections.h> 17 18_ASM_FILE_PROLOGUE 19 20GTEXT(z_arm_fault) 21 22GTEXT(z_arm_hard_fault) 23#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 24/* HardFault is used for all fault conditions on ARMv6-M. */ 25#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 26GTEXT(z_arm_mpu_fault) 27GTEXT(z_arm_bus_fault) 28GTEXT(z_arm_usage_fault) 29#if defined(CONFIG_ARM_SECURE_FIRMWARE) 30GTEXT(z_arm_secure_fault) 31#endif /* CONFIG_ARM_SECURE_FIRMWARE*/ 32WTEXT(z_arm_debug_monitor) 33#else 34#error Unknown ARM architecture 35#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ 36GTEXT(z_arm_exc_spurious) 37 38/** 39 * 40 * @brief Fault handler installed in the fault vectors 41 * 42 * Entry point for the HardFault, MemManageFault, BusFault, UsageFault, 43 * SecureFault and Debug Monitor exceptions. 44 * 45 * The function supplies the values of 46 * - the MSP 47 * - the PSP 48 * - the EXC_RETURN value 49 * - callee saved register state (r4-r11, psp) 50 * as parameters to the z_arm_fault() C function that will perform the 51 * rest of the fault handling: 52 * (i.e. z_arm_fault(MSP, PSP, EXC_RETURN, CALLEE_REGS)). 53 * Provides these symbols: 54 * 55 * z_arm_hard_fault 56 * z_arm_mpu_fault 57 * z_arm_bus_fault 58 * z_arm_usage_fault 59 * z_arm_secure_fault 60 * z_arm_debug_monitor 61 * z_arm_exc_spurious 62 */ 63 64SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_hard_fault) 65#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 66/* HardFault is used for all fault conditions on ARMv6-M. */ 67#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 68SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_mpu_fault) 69SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_bus_fault) 70SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_usage_fault) 71#if defined(CONFIG_ARM_SECURE_FIRMWARE) 72SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_secure_fault) 73#endif /* CONFIG_ARM_SECURE_FIRMWARE */ 74SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_debug_monitor) 75#else 76#error Unknown ARM architecture 77#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ 78SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_exc_spurious) 79 80 mrs r0, MSP 81 mrs r1, PSP 82 push {r0, lr} 83#if defined(CONFIG_EXTRA_EXCEPTION_INFO) 84 /* Build _callee_saved_t. To match the struct 85 * definition we push the psp & then r11-r4 86 */ 87 push { r1, r2 } 88#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 89 mov r3, r11 90 mov r2, r10 91 push {r2, r3} 92 mov r3, r9 93 mov r2, r8 94 push {r2, r3} 95 push {r4-r7} 96#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 97 push {r4-r11} 98#endif 99 mov r3, sp /* pointer to _callee_saved_t */ 100#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ 101 mov r2, lr /* EXC_RETURN */ 102 bl z_arm_fault 103#if defined(CONFIG_EXTRA_EXCEPTION_INFO) 104 /* We do not need to restore any register state here 105 * because we did not use any callee-saved registers 106 * in this routine. Therefore, we can just reset 107 * the MSP to its value prior to entering the function 108 */ 109 add sp, #40 110#endif 111 pop {r0, pc} 112 113 .end 114