From 3c79893217bc632c9b0efa815091bef3c779490c Mon Sep 17 00:00:00 2001 From: alexander Date: Fri, 26 Mar 2021 21:42:19 +0000 Subject: Opensource ML embedded evaluation kit Change-Id: I12e807f19f5cacad7cef82572b6dd48252fd61fd --- .../platforms/bare-metal/bsp/cmsis-device/irqs.c | 261 +++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c (limited to 'source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c') diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c new file mode 100644 index 0000000..c6f54b1 --- /dev/null +++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "irqs.h" +#include "cmsis.h" + +#include + +static uint64_t cpu_cycle_count = 0; + +/** + * @brief Dump core registers on stdout + */ +static void LogCoreCPURegisters(void) +{ + printf("CTRL : 0x%08x\n", __get_CONTROL()); + printf("IPSR : 0x%08x\n", __get_IPSR()); + printf("APSR : 0x%08x\n", __get_APSR()); + printf("xPSR : 0x%08x\n", __get_xPSR()); + printf("PSP : 0x%08x\n", __get_PSP()); + printf("MSP : 0x%08x\n", __get_MSP()); + printf("PRIMASK : 0x%08x\n", __get_PRIMASK()); + printf("BASEPRI : 0x%08x\n", __get_BASEPRI()); + printf("FAULTMSK: 0x%08x\n", __get_FAULTMASK()); + printf("PC : 0x%08x\n", __current_pc()); +} + +/** + * @brief Default interrupt handler - an infinite loop. + **/ +__attribute__((noreturn)) static void DefaultHandler(void) +{ + LogCoreCPURegisters(); + while (1) { + /* Without the following line, armclang may optimize away the + * infinite loop because it'd be without side effects and thus + * undefined behaviour. */ + __ASM volatile(""); + } +} + +#define DEFAULT_HANDLER_CALL(type) \ + do { \ + printf("\n%s caught by function %s\n", \ + type, __FUNCTION__); \ + DefaultHandler(); \ + } while (0) + +#define DEFAULT_ERROR_HANDLER_CALL() \ + DEFAULT_HANDLER_CALL("Exception") + +#define DEFAULT_IRQ_HANDLER_CALL() \ + DEFAULT_HANDLER_CALL("Interrupt") + +/** + * Dummy Exception Handlers for core interrupts. + * + * Weak definitions provided to be used if the user chooses not + * to override them. + **/ + +/** + * @brief Non maskable interrupt handler. + **/ + __attribute__((weak)) void NMI_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Hardfault interrupt handler. + **/ + __attribute__((weak)) void HardFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Memory management interrupt handler. + **/ +__attribute__((weak)) void MemManage_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief Bus fault interrupt handler. + **/ +__attribute__((weak)) void BusFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Usage fault interrupt handler. + **/ +__attribute__((weak)) void UsageFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Secure access fault interrupt handler. + **/ +__attribute__((weak)) void SecureFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Supervisor call interrupt handler. + **/ +__attribute__((weak)) void SVC_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief Debug monitor interrupt handler. + **/ +__attribute__((weak)) void DebugMon_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief Pending SV call interrupt handler. + */ +__attribute__((weak)) void PendSV_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief System tick interrupt handler. + **/ +void SysTick_Handler(void) +{ + /* Increment the cycle counter based on load value. */ + cpu_cycle_count += SysTick->LOAD + 1; +} + +uint64_t Get_SysTick_Cycle_Count(void) +{ + uint32_t systick_val; + + NVIC_DisableIRQ(SysTick_IRQn); + systick_val = SysTick->VAL & SysTick_VAL_CURRENT_Msk; + NVIC_EnableIRQ(SysTick_IRQn); + + return cpu_cycle_count + (SysTick->LOAD - systick_val); +} + + +/** + * These symbols are provided by the ARM lib - needs the stack and heap + * regions in the scatter file. + */ +extern void Image$$ARM_LIB_STACK$$ZI$$Base(); +extern void Image$$ARM_LIB_STACK$$ZI$$Limit(); +extern void Image$$ARM_LIB_HEAP$$ZI$$Base(); +extern void Image$$ARM_LIB_HEAP$$ZI$$Limit(); +extern __attribute__((noreturn)) void __main(); + +__attribute__((naked, used)) void __user_setup_stackheap() +{ + __ASM volatile("LDR r0, =Image$$ARM_LIB_HEAP$$ZI$$Base"); + __ASM volatile("LDR r1, =Image$$ARM_LIB_STACK$$ZI$$Limit"); + __ASM volatile("LDR r2, =Image$$ARM_LIB_HEAP$$ZI$$Limit"); + __ASM volatile("LDR r3, =Image$$ARM_LIB_STACK$$ZI$$Base"); + __ASM volatile("bx lr"); +} + +/** + * Interrupt vector table. + */ +irq_vec_type __Vectors[] __attribute__((section("RESET"), used)) = { + &Image$$ARM_LIB_STACK$$ZI$$Limit, /* 0 Initial SP */ + &Reset_Handler , /* 1 Initial PC, set to entry point */ + + &NMI_Handler , /* 2 (-14) NMI Handler */ + &HardFault_Handler , /* 3 (-13) Hard Fault Handler */ + &MemManage_Handler , /* 4 (-12) MPU Fault Handler */ + &BusFault_Handler , /* 5 (-11) Bus Fault Handler */ + &UsageFault_Handler , /* 6 (-10) Usage Fault Handler */ + &SecureFault_Handler, /* 7 ( -9) Secure Fault Handler */ + 0 , /* 8 ( -8) Reserved */ + 0 , /* 9 ( -7) Reserved */ + 0 , /* 10 ( -6) Reserved */ + &SVC_Handler , /* 11 ( -5) SVCall Handler */ + &DebugMon_Handler , /* 12 ( -4) Debug Monitor Handler */ + 0 , /* 13 ( -3) Reserved */ + &PendSV_Handler , /* 14 ( -2) PendSV Handler */ + &SysTick_Handler , /* 15 ( -1) SysTick Handler */ + + /* External sources to be populated by user. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 32 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 - 48 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 48 - 64 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 64 - 80 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 96 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 96 - 112 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 112 - 128 */ +}; + +int Init_SysTick(void) +{ + const uint32_t ticks_10ms = GetSystemCoreClock()/100 + 1; + int err = 0; + + /* Reset CPU cycle count value. */ + cpu_cycle_count = 0; + + /* Changing configuration for sys tick => guard from being + * interrupted. */ + NVIC_DisableIRQ(SysTick_IRQn); + + /* SysTick init - this will enable interrupt too. */ + err = SysTick_Config(ticks_10ms); + + /* Enable interrupt again. */ + NVIC_EnableIRQ(SysTick_IRQn); + + return err; +} + +/* Reset handler - starting point of our application. */ +__attribute__((used)) void Reset_Handler(void) +{ + /* Initialise system. */ + SystemInit(); + + /* Configure the system tick. */ + Init_SysTick(); + + /* libcxx supplied entry point. */ + __main(); +} + +#ifdef __cplusplus +} +#endif -- cgit v1.2.1