1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Description:
8 * ARM-M exception handlers.
9 */
10
11 #include "arch_exceptions.h"
12
13 #include <fwk_attributes.h>
14
15 #include <fmw_cmsis.h>
16
17 #include <stdint.h>
18 #include <string.h>
19
20 #ifdef __NEWLIB__
21 /*
22 * This function overloads a weak definition provided by Newlib. It is called
23 * during initialization of the C runtime just after .bss has been zeroed.
24 */
software_init_hook(void)25 void software_init_hook(void)
26 {
27 extern char __data_load__;
28 extern char __data_start__;
29 extern char __data_end__;
30
31 char *load = &__data_load__;
32 char *start = &__data_start__;
33 char *end = &__data_end__;
34
35 if (load != start) {
36 (void)memcpy(start, load, (size_t)(end - start));
37 }
38 }
39 #endif
40
41 #ifdef __ARMCC_VERSION
42 extern char Image$$ARM_LIB_STACKHEAP$$ZI$$Limit;
43
44 # define arch_exception_stack (&Image$$ARM_LIB_STACKHEAP$$ZI$$Limit)
45 #else
46 extern char __stackheap_end__;
47
48 # define arch_exception_stack (&__stackheap_end__)
49 #endif
50
51 /*
52 * Set up the exception table. The structure below is added to the
53 * .exceptions section which will be explicitly placed at the beginning of the
54 * binary by the linker script.
55 */
56
57 const struct {
58 uintptr_t stack;
59 uintptr_t exceptions[NVIC_USER_IRQ_OFFSET - 1];
60 } arch_exceptions FWK_SECTION(".exceptions") = {
61 .stack = (uintptr_t)(arch_exception_stack),
62 .exceptions = {
63 [NVIC_USER_IRQ_OFFSET + Reset_IRQn - 1] =
64 (uintptr_t)(arch_exception_reset),
65 [NonMaskableInt_IRQn + (NVIC_USER_IRQ_OFFSET - 1)] =
66 (uintptr_t)(arch_exception_invalid),
67 [NVIC_USER_IRQ_OFFSET + HardFault_IRQn - 1] =
68 (uintptr_t)(arch_exception_invalid),
69 [NVIC_USER_IRQ_OFFSET + MemoryManagement_IRQn - 1] =
70 (uintptr_t)(arch_exception_invalid),
71 [NVIC_USER_IRQ_OFFSET + BusFault_IRQn - 1] =
72 (uintptr_t)(arch_exception_invalid),
73 [NVIC_USER_IRQ_OFFSET + UsageFault_IRQn - 1] =
74 (uintptr_t)(arch_exception_invalid),
75 #ifdef ARMV8M
76 [NVIC_USER_IRQ_OFFSET + SecureFault_IRQn - 1] =
77 (uintptr_t)(arch_exception_invalid),
78 #endif
79 [NVIC_USER_IRQ_OFFSET + DebugMonitor_IRQn - 1] =
80 (uintptr_t)(arch_exception_invalid),
81
82 [NVIC_USER_IRQ_OFFSET + SVCall_IRQn - 1] =
83 (uintptr_t)(arch_exception_invalid),
84 [NVIC_USER_IRQ_OFFSET + PendSV_IRQn - 1] =
85 (uintptr_t)(arch_exception_invalid),
86 [NVIC_USER_IRQ_OFFSET + SysTick_IRQn - 1] =
87 (uintptr_t)(arch_exception_invalid),
88 },
89 };
90