summaryrefslogtreecommitdiff
path: root/source/application/hal/platforms/bare-metal/bsp/cmsis-device
diff options
context:
space:
mode:
Diffstat (limited to 'source/application/hal/platforms/bare-metal/bsp/cmsis-device')
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c122
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h31
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h54
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c261
4 files changed, 468 insertions, 0 deletions
diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c
new file mode 100644
index 0000000..c9cf53d
--- /dev/null
+++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+#include "cmsis.h"
+
+extern void *__Vectors; /* see irqs.c */
+
+/*----------------------------------------------------------------------------*\
+ * Define clocks (uses OSC1 ACLK) *
+\*----------------------------------------------------------------------------*/
+#define __XTAL (25000000) /* Oscillator frequency */
+#define __SYSTEM_CLOCK (__XTAL)
+
+#define STR(x) #x
+#define RESET_REG(n) __ASM volatile("MOV " STR(r##n) ", #0" : : : STR(r##n))
+
+#if defined(CPU_CORTEX_M55)
+#define CCR_DL (1 << 19)
+#else
+#error "Invalid CPU; This file only services Cortex-M55 CPUs"
+#endif /* (CPU_CORTEX_M55) */
+
+/*----------------------------------------------------------------------------
+ System Core Clock Variable (Core Clock)
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = __SYSTEM_CLOCK;
+
+
+/*----------------------------------------------------------------------------
+ Clock functions
+ *----------------------------------------------------------------------------*/
+/**
+ * @brief Updates the SystemCoreClock variable with current core Clock
+ * retrieved from cpu registers.
+ */
+void SystemCoreClockUpdate(void)
+{
+ /* Update the SystemCoreClock variable */
+ SystemCoreClock = __SYSTEM_CLOCK;
+}
+
+uint32_t GetSystemCoreClock(void)
+{
+ return SystemCoreClock;
+}
+
+/**
+ * @brief Setup the microcontroller system.
+ * Initialize the System.
+ **/
+void SystemInit(void)
+{
+#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \
+ (defined (__MVE_USED) && (__MVE_USED == 1U))
+ SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */
+ (3U << 11U*2U) );
+#endif
+
+ /* Initialise registers r0-r12 and LR(=r14)
+ * They must have a valid value before being potentially pushed to stack by
+ * C calling convention or by context saving in exception handling
+ */
+ RESET_REG(0);
+ RESET_REG(1);
+ RESET_REG(2);
+ RESET_REG(3);
+ RESET_REG(4);
+ RESET_REG(5);
+ RESET_REG(6);
+ RESET_REG(7);
+ RESET_REG(8);
+ RESET_REG(9);
+ RESET_REG(10);
+ RESET_REG(11);
+ RESET_REG(12);
+ RESET_REG(14);
+
+#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
+ SCB->VTOR = (uint32_t) &__Vectors;
+#endif
+
+ /* Enable hard, bus, mem and usage fault detection in SHCSR, bits 16-18.
+ * Enable stkof, bf, div_0_trp, unalign_trp and usersetm bits in CCR.
+ */
+ SCB->SHCSR = (
+ _VAL2FLD(SCB_SHCSR_USGFAULTENA, 1) |
+ _VAL2FLD(SCB_SHCSR_BUSFAULTENA, 1) |
+ _VAL2FLD(SCB_SHCSR_MEMFAULTENA, 1));
+
+ SCB->CCR = (_VAL2FLD(SCB_CCR_USERSETMPEND, 1) |
+ _VAL2FLD(SCB_CCR_DIV_0_TRP, 1) |
+ _VAL2FLD(SCB_CCR_BFHFNMIGN, 1) |
+ _VAL2FLD(SCB_CCR_STKOFHFNMIGN, 1));
+#ifdef UNALIGNED_SUPPORT_DISABLE
+ SCB->CCR |= _VAL2FLD(SCB_CCR_UNALIGN_TRP, 1);
+#endif
+
+ SCB->CCR |= CCR_DL;
+
+ /* Reset pipeline. */
+ __DSB();
+ __ISB();
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+ SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
+#endif
+
+ SystemCoreClock = __SYSTEM_CLOCK;
+}
diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h
new file mode 100644
index 0000000..969db15
--- /dev/null
+++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+#ifndef BAREMETAL_CMSIS_H
+#define BAREMETAL_CMSIS_H
+
+#include "ARMCM55.h" /* Cortex M system header file from CMSIS. */
+#include "irqs.h" /* Interrupt definitions file. */
+
+/* Addition to template functions should be mentioned here. */
+
+/**
+ * @brief Gets the internal processor clock.
+ * @return Clock frequency as unsigned 32 bit value.
+ **/
+uint32_t GetSystemCoreClock(void);
+
+#endif /* BAREMETAL_CMSIS_H */
diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h
new file mode 100644
index 0000000..0d8dec6
--- /dev/null
+++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+#ifndef IRQS_H
+#define IRQS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "peripheral_irqs.h"
+
+#include <stdint.h>
+
+/* Interrupt handler function type. */
+typedef void (*const irq_vec_type)(void);
+
+/**
+ * @brief Reset interrupt handler and also, the starting
+ * point of the application.
+ **/
+extern void Reset_Handler(void);
+
+/**
+ * @brief Gets the system tick triggered cycle counter for the CPU.
+ * @return 64-bit counter value.
+ **/
+extern uint64_t Get_SysTick_Cycle_Count(void);
+
+/**
+ * @brief Initialises the system tick registers.
+ * @return Error code return from sys tick configuration function
+ * (0 = no error).
+ **/
+extern int Init_SysTick(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IRQS_H */
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 <stdio.h>
+
+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