blob: 7d8aa06d92c9c951be5df16dea3d15257deaa5b9 [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
28static uint64_t cpu_cycle_count = 0;
29
30/**
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010031 * External references
32 */
33extern uint32_t __INITIAL_SP;
34extern uint32_t __STACK_LIMIT;
35
36#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
37 extern uint32_t __STACK_SEAL;
38#endif
39
40extern __NO_RETURN void __PROGRAM_START(void);
41
42/**
alexander3c798932021-03-26 21:42:19 +000043 * @brief Dump core registers on stdout
44 */
45static void LogCoreCPURegisters(void)
46{
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010047 printf("CTRL : 0x%08" PRIx32 "\n", __get_CONTROL());
48 printf("IPSR : 0x%08" PRIx32 "\n", __get_IPSR());
49 printf("APSR : 0x%08" PRIx32 "\n", __get_APSR());
50 printf("xPSR : 0x%08" PRIx32 "\n", __get_xPSR());
51 printf("PSP : 0x%08" PRIx32 "\n", __get_PSP());
52 printf("MSP : 0x%08" PRIx32 "\n", __get_MSP());
53 printf("PRIMASK : 0x%08" PRIx32 "\n", __get_PRIMASK());
54 printf("BASEPRI : 0x%08" PRIx32 "\n", __get_BASEPRI());
55 printf("FAULTMSK: 0x%08" PRIx32 "\n", __get_FAULTMASK());
alexander3c798932021-03-26 21:42:19 +000056}
57
58/**
59 * @brief Default interrupt handler - an infinite loop.
60 **/
61__attribute__((noreturn)) static void DefaultHandler(void)
62{
63 LogCoreCPURegisters();
64 while (1) {
65 /* Without the following line, armclang may optimize away the
66 * infinite loop because it'd be without side effects and thus
67 * undefined behaviour. */
68 __ASM volatile("");
69 }
70}
71
72#define DEFAULT_HANDLER_CALL(type) \
73 do { \
Kshitij Sisodia3c8256d2021-05-24 16:12:40 +010074 printf("\n"); \
75 printf("%s caught by function %s\n", \
alexander3c798932021-03-26 21:42:19 +000076 type, __FUNCTION__); \
77 DefaultHandler(); \
78 } while (0)
79
80#define DEFAULT_ERROR_HANDLER_CALL() \
81 DEFAULT_HANDLER_CALL("Exception")
82
83#define DEFAULT_IRQ_HANDLER_CALL() \
84 DEFAULT_HANDLER_CALL("Interrupt")
85
86/**
87 * Dummy Exception Handlers for core interrupts.
88 *
89 * Weak definitions provided to be used if the user chooses not
90 * to override them.
91 **/
92
93/**
94 * @brief Non maskable interrupt handler.
95 **/
96 __attribute__((weak)) void NMI_Handler(void)
97{
98 DEFAULT_ERROR_HANDLER_CALL();
99}
100
101/**
102 * @brief Hardfault interrupt handler.
103 **/
104 __attribute__((weak)) void HardFault_Handler(void)
105{
106 DEFAULT_ERROR_HANDLER_CALL();
107}
108
109/**
110 * @brief Memory management interrupt handler.
111 **/
112__attribute__((weak)) void MemManage_Handler(void)
113{
114 DEFAULT_IRQ_HANDLER_CALL();
115}
116
117/**
118 * @brief Bus fault interrupt handler.
119 **/
120__attribute__((weak)) void BusFault_Handler(void)
121{
122 DEFAULT_ERROR_HANDLER_CALL();
123}
124
125/**
126 * @brief Usage fault interrupt handler.
127 **/
128__attribute__((weak)) void UsageFault_Handler(void)
129{
130 DEFAULT_ERROR_HANDLER_CALL();
131}
132
133/**
134 * @brief Secure access fault interrupt handler.
135 **/
136__attribute__((weak)) void SecureFault_Handler(void)
137{
138 DEFAULT_ERROR_HANDLER_CALL();
139}
140
141/**
142 * @brief Supervisor call interrupt handler.
143 **/
144__attribute__((weak)) void SVC_Handler(void)
145{
146 DEFAULT_IRQ_HANDLER_CALL();
147}
148
149/**
150 * @brief Debug monitor interrupt handler.
151 **/
152__attribute__((weak)) void DebugMon_Handler(void)
153{
154 DEFAULT_IRQ_HANDLER_CALL();
155}
156
157/**
158 * @brief Pending SV call interrupt handler.
159 */
160__attribute__((weak)) void PendSV_Handler(void)
161{
162 DEFAULT_IRQ_HANDLER_CALL();
163}
164
165/**
166 * @brief System tick interrupt handler.
167 **/
168void SysTick_Handler(void)
169{
170 /* Increment the cycle counter based on load value. */
171 cpu_cycle_count += SysTick->LOAD + 1;
172}
173
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100174/**
175 * Gets the current SysTick derived counter value
176 */
alexander3c798932021-03-26 21:42:19 +0000177uint64_t Get_SysTick_Cycle_Count(void)
178{
179 uint32_t systick_val;
180
181 NVIC_DisableIRQ(SysTick_IRQn);
182 systick_val = SysTick->VAL & SysTick_VAL_CURRENT_Msk;
183 NVIC_EnableIRQ(SysTick_IRQn);
184
185 return cpu_cycle_count + (SysTick->LOAD - systick_val);
186}
187
alexander3c798932021-03-26 21:42:19 +0000188/**
189 * Interrupt vector table.
190 */
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100191irq_vec_type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
192 (irq_vec_type)(&__INITIAL_SP), /* Initial Stack Pointer */
193 Reset_Handler , /* 1 Initial PC, set to entry point */
alexander3c798932021-03-26 21:42:19 +0000194
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100195 NMI_Handler , /* 2 (-14) NMI Handler */
196 HardFault_Handler , /* 3 (-13) Hard Fault Handler */
197 MemManage_Handler , /* 4 (-12) MPU Fault Handler */
198 BusFault_Handler , /* 5 (-11) Bus Fault Handler */
199 UsageFault_Handler , /* 6 (-10) Usage Fault Handler */
200 SecureFault_Handler, /* 7 ( -9) Secure Fault Handler */
alexander3c798932021-03-26 21:42:19 +0000201 0 , /* 8 ( -8) Reserved */
202 0 , /* 9 ( -7) Reserved */
203 0 , /* 10 ( -6) Reserved */
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100204 SVC_Handler , /* 11 ( -5) SVCall Handler */
205 DebugMon_Handler , /* 12 ( -4) Debug Monitor Handler */
alexander3c798932021-03-26 21:42:19 +0000206 0 , /* 13 ( -3) Reserved */
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100207 PendSV_Handler , /* 14 ( -2) PendSV Handler */
208 SysTick_Handler , /* 15 ( -1) SysTick Handler */
alexander3c798932021-03-26 21:42:19 +0000209
210 /* External sources to be populated by user. */
211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 16 */
212 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 32 */
213 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 - 48 */
214 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 48 - 64 */
215 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 64 - 80 */
216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 96 */
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 96 - 112 */
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 112 - 128 */
219};
220
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100221/**
222 * SysTick initialisation
223 */
alexander3c798932021-03-26 21:42:19 +0000224int Init_SysTick(void)
225{
226 const uint32_t ticks_10ms = GetSystemCoreClock()/100 + 1;
227 int err = 0;
228
229 /* Reset CPU cycle count value. */
230 cpu_cycle_count = 0;
231
232 /* Changing configuration for sys tick => guard from being
233 * interrupted. */
234 NVIC_DisableIRQ(SysTick_IRQn);
235
236 /* SysTick init - this will enable interrupt too. */
237 err = SysTick_Config(ticks_10ms);
238
239 /* Enable interrupt again. */
240 NVIC_EnableIRQ(SysTick_IRQn);
241
Kshitij Sisodia3c8256d2021-05-24 16:12:40 +0100242 /* Wait for SysTick to kick off */
243 while (!err && !SysTick->VAL) {
244 __NOP();
245 }
246
alexander3c798932021-03-26 21:42:19 +0000247 return err;
248}
249
250/* Reset handler - starting point of our application. */
251__attribute__((used)) void Reset_Handler(void)
252{
253 /* Initialise system. */
254 SystemInit();
255
256 /* Configure the system tick. */
257 Init_SysTick();
258
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100259 /* cmsis supplied entry point. */
260 __PROGRAM_START();
alexander3c798932021-03-26 21:42:19 +0000261}
262
263#ifdef __cplusplus
264}
265#endif