blob: 2ecd4d5f06e8a780c2ec0ea954548e621657dcf5 [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001/*
2 * Copyright (c) 2021 Arm Limited. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#ifdef __cplusplus
18extern "C"
19{
20#endif
21
22#include "irqs.h"
23#include "cmsis.h"
24
25#include <stdio.h>
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010026#include <inttypes.h>
alexander3c798932021-03-26 21:42:19 +000027
alexander3c798932021-03-26 21:42:19 +000028/**
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010029 * External references
30 */
31extern uint32_t __INITIAL_SP;
32extern uint32_t __STACK_LIMIT;
33
34#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
35 extern uint32_t __STACK_SEAL;
36#endif
37
38extern __NO_RETURN void __PROGRAM_START(void);
39
40/**
alexander3c798932021-03-26 21:42:19 +000041 * @brief Dump core registers on stdout
42 */
43static void LogCoreCPURegisters(void)
44{
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010045 printf("CTRL : 0x%08" PRIx32 "\n", __get_CONTROL());
46 printf("IPSR : 0x%08" PRIx32 "\n", __get_IPSR());
47 printf("APSR : 0x%08" PRIx32 "\n", __get_APSR());
48 printf("xPSR : 0x%08" PRIx32 "\n", __get_xPSR());
49 printf("PSP : 0x%08" PRIx32 "\n", __get_PSP());
50 printf("MSP : 0x%08" PRIx32 "\n", __get_MSP());
51 printf("PRIMASK : 0x%08" PRIx32 "\n", __get_PRIMASK());
52 printf("BASEPRI : 0x%08" PRIx32 "\n", __get_BASEPRI());
53 printf("FAULTMSK: 0x%08" PRIx32 "\n", __get_FAULTMASK());
alexander3c798932021-03-26 21:42:19 +000054}
55
56/**
57 * @brief Default interrupt handler - an infinite loop.
58 **/
59__attribute__((noreturn)) static void DefaultHandler(void)
60{
61 LogCoreCPURegisters();
62 while (1) {
63 /* Without the following line, armclang may optimize away the
64 * infinite loop because it'd be without side effects and thus
65 * undefined behaviour. */
66 __ASM volatile("");
67 }
68}
69
70#define DEFAULT_HANDLER_CALL(type) \
71 do { \
Kshitij Sisodia3c8256d2021-05-24 16:12:40 +010072 printf("\n"); \
73 printf("%s caught by function %s\n", \
alexander3c798932021-03-26 21:42:19 +000074 type, __FUNCTION__); \
75 DefaultHandler(); \
76 } while (0)
77
78#define DEFAULT_ERROR_HANDLER_CALL() \
79 DEFAULT_HANDLER_CALL("Exception")
80
81#define DEFAULT_IRQ_HANDLER_CALL() \
82 DEFAULT_HANDLER_CALL("Interrupt")
83
84/**
85 * Dummy Exception Handlers for core interrupts.
86 *
87 * Weak definitions provided to be used if the user chooses not
88 * to override them.
89 **/
90
91/**
92 * @brief Non maskable interrupt handler.
93 **/
94 __attribute__((weak)) void NMI_Handler(void)
95{
96 DEFAULT_ERROR_HANDLER_CALL();
97}
98
99/**
100 * @brief Hardfault interrupt handler.
101 **/
102 __attribute__((weak)) void HardFault_Handler(void)
103{
104 DEFAULT_ERROR_HANDLER_CALL();
105}
106
107/**
108 * @brief Memory management interrupt handler.
109 **/
110__attribute__((weak)) void MemManage_Handler(void)
111{
112 DEFAULT_IRQ_HANDLER_CALL();
113}
114
115/**
116 * @brief Bus fault interrupt handler.
117 **/
118__attribute__((weak)) void BusFault_Handler(void)
119{
120 DEFAULT_ERROR_HANDLER_CALL();
121}
122
123/**
124 * @brief Usage fault interrupt handler.
125 **/
126__attribute__((weak)) void UsageFault_Handler(void)
127{
128 DEFAULT_ERROR_HANDLER_CALL();
129}
130
131/**
132 * @brief Secure access fault interrupt handler.
133 **/
134__attribute__((weak)) void SecureFault_Handler(void)
135{
136 DEFAULT_ERROR_HANDLER_CALL();
137}
138
139/**
140 * @brief Supervisor call interrupt handler.
141 **/
142__attribute__((weak)) void SVC_Handler(void)
143{
144 DEFAULT_IRQ_HANDLER_CALL();
145}
146
147/**
148 * @brief Debug monitor interrupt handler.
149 **/
150__attribute__((weak)) void DebugMon_Handler(void)
151{
152 DEFAULT_IRQ_HANDLER_CALL();
153}
154
155/**
156 * @brief Pending SV call interrupt handler.
157 */
158__attribute__((weak)) void PendSV_Handler(void)
159{
160 DEFAULT_IRQ_HANDLER_CALL();
161}
162
163/**
164 * @brief System tick interrupt handler.
165 **/
Kshitij Sisodiaa1256e32022-02-23 14:40:45 +0000166__attribute__((weak)) void SysTick_Handler(void)
alexander3c798932021-03-26 21:42:19 +0000167{
Kshitij Sisodiaa1256e32022-02-23 14:40:45 +0000168 DEFAULT_IRQ_HANDLER_CALL();
alexander3c798932021-03-26 21:42:19 +0000169}
170
alexander3c798932021-03-26 21:42:19 +0000171/**
172 * Interrupt vector table.
173 */
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100174irq_vec_type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
175 (irq_vec_type)(&__INITIAL_SP), /* Initial Stack Pointer */
176 Reset_Handler , /* 1 Initial PC, set to entry point */
alexander3c798932021-03-26 21:42:19 +0000177
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100178 NMI_Handler , /* 2 (-14) NMI Handler */
179 HardFault_Handler , /* 3 (-13) Hard Fault Handler */
180 MemManage_Handler , /* 4 (-12) MPU Fault Handler */
181 BusFault_Handler , /* 5 (-11) Bus Fault Handler */
182 UsageFault_Handler , /* 6 (-10) Usage Fault Handler */
183 SecureFault_Handler, /* 7 ( -9) Secure Fault Handler */
alexander3c798932021-03-26 21:42:19 +0000184 0 , /* 8 ( -8) Reserved */
185 0 , /* 9 ( -7) Reserved */
186 0 , /* 10 ( -6) Reserved */
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100187 SVC_Handler , /* 11 ( -5) SVCall Handler */
188 DebugMon_Handler , /* 12 ( -4) Debug Monitor Handler */
alexander3c798932021-03-26 21:42:19 +0000189 0 , /* 13 ( -3) Reserved */
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100190 PendSV_Handler , /* 14 ( -2) PendSV Handler */
191 SysTick_Handler , /* 15 ( -1) SysTick Handler */
alexander3c798932021-03-26 21:42:19 +0000192
193 /* External sources to be populated by user. */
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 16 */
195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 32 */
196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 - 48 */
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 48 - 64 */
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 64 - 80 */
199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 96 */
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 96 - 112 */
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 112 - 128 */
202};
203
alexander3c798932021-03-26 21:42:19 +0000204/* Reset handler - starting point of our application. */
205__attribute__((used)) void Reset_Handler(void)
206{
207 /* Initialise system. */
208 SystemInit();
209
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100210 /* cmsis supplied entry point. */
211 __PROGRAM_START();
alexander3c798932021-03-26 21:42:19 +0000212}
213
214#ifdef __cplusplus
215}
216#endif