From 00368be949ddafce512de40a56bac29b8555180f Mon Sep 17 00:00:00 2001 From: Christophe Favergeon Date: Wed, 14 Apr 2021 09:24:14 +0200 Subject: [PATCH] CMSIS-DSP: Improvement to gcc+FVP support in test framework. --- .../ARMv81MML/LinkScripts/GCC/lnk.ld | 317 ++++++++++++++++++ .../ARMv81MML/LinkScripts/GCC/mem_ARMv81MML.h | 38 +++ .../ARMv81MML/Startup/GCC/startup_ARMv81MML.c | 189 +++++++++++ .../Startup/GCC/startup_asm_ARMv81MML.S | 41 +++ .../NORMALFVP/ARMv81MML/Startup/GCC/support.c | 36 ++ Platforms/NORMALFVP/platform.cmake | 2 + 6 files changed, 623 insertions(+) create mode 100755 Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/lnk.ld create mode 100755 Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/mem_ARMv81MML.h create mode 100755 Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_ARMv81MML.c create mode 100755 Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_asm_ARMv81MML.S create mode 100755 Platforms/NORMALFVP/ARMv81MML/Startup/GCC/support.c diff --git a/Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/lnk.ld b/Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/lnk.ld new file mode 100755 index 00000000..51ddb41a --- /dev/null +++ b/Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/lnk.ld @@ -0,0 +1,317 @@ +/****************************************************************************** + * @file gcc_arm.ld + * @brief GNU Linker Script for Cortex-M based device + * @version V2.2.0 + * @date 16. December 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 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 + * + * 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. + */ + +/* + *-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- + */ + +/*---------------------- Flash Configuration ---------------------------------- + Flash Configuration + Flash Base Address <0x0-0xFFFFFFFF:8> + Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> + + -----------------------------------------------------------------------------*/ +__ROM_BASE = 0x10000000; +__ROM_SIZE = 0x00100000; + +/*--------------------- Embedded RAM Configuration ---------------------------- + RAM Configuration + RAM Base Address <0x0-0xFFFFFFFF:8> + RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> + + -----------------------------------------------------------------------------*/ +__RAM_BASE = 0x30000000; +__RAM_SIZE = 0x00200000; + +/*--------------------- Stack / Heap Configuration ---------------------------- + Stack / Heap Configuration + Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> + Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> + + -----------------------------------------------------------------------------*/ +__STACK_SIZE = 0x00002000; +__HEAP_SIZE = 0x00100000; + +/* + *-------------------- <<< end of configuration section >>> ------------------- + */ + +/* ARMv8-M stack sealing: + to use ARMv8-M stack sealing set __STACKSEAL_SIZE to 8 otherwise keep 0 + */ +__STACKSEAL_SIZE = 0; + + +MEMORY +{ + FLASH (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE + RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __StackSeal (only if ARMv8-M stack sealing is used) + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + /* + * SG veneers: + * All SG veneers are placed in the special output section .gnu.sgstubs. Its start address + * must be set, either with the command line option ‘--section-start’ or in a linker script, + * to indicate where to place these veneers in memory. + */ +/* + .gnu.sgstubs : + { + . = ALIGN(32); + } > FLASH +*/ + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + LONG (__etext) + LONG (__data_start__) + LONG ((__data_end__ - __data_start__) / 4) + + /* Add each additional data section here */ +/* + LONG (__etext2) + LONG (__data2_start__) + LONG ((__data2_end__ - __data2_start__) / 4) +*/ + __copy_table_end__ = .; + } > FLASH + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + /* Add each additional bss section here */ +/* + LONG (__bss2_start__) + LONG ((__bss2_end__ - __bss2_start__) / 4) +*/ + __zero_table_end__ = .; + } > FLASH + + /** + * Location counter can end up 2byte aligned with narrow Thumb code but + * __etext is assumed by startup code to be the LMA of a section in RAM + * which must be 4byte aligned + */ + __etext = ALIGN (4); + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data) + *(.data.*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + /* + * Secondary data section, optional + * + * Remember to add each additional data section + * to the .copy.table above to asure proper + * initialization during startup. + */ +/* + __etext2 = ALIGN (4); + + .data2 : AT (__etext2) + { + . = ALIGN(4); + __data2_start__ = .; + *(.data2) + *(.data2.*) + . = ALIGN(4); + __data2_end__ = .; + + } > RAM2 +*/ + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM AT > RAM + + /* + * Secondary bss section, optional + * + * Remember to add each additional bss section + * to the .zero.table above to asure proper + * initialization during startup. + */ +/* + .bss2 : + { + . = ALIGN(4); + __bss2_start__ = .; + *(.bss2) + *(.bss2.*) + . = ALIGN(4); + __bss2_end__ = .; + } > RAM2 AT > RAM2 +*/ + + .heap (COPY) : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + . = . + __HEAP_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + PROVIDE(HeapBase = end); + + .stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE - __STACKSEAL_SIZE) (COPY) : + { + . = ALIGN(8); + __StackLimit = .; + . = . + __STACK_SIZE; + . = ALIGN(8); + __StackTop = .; + } > RAM + PROVIDE(__stack = __StackTop); + + /* ARMv8-M stack sealing: + to use ARMv8-M stack sealing uncomment '.stackseal' section + */ +/* + .stackseal (ORIGIN(RAM) + LENGTH(RAM) - __STACKSEAL_SIZE) (COPY) : + { + . = ALIGN(8); + __StackSeal = .; + . = . + 8; + . = ALIGN(8); + } > RAM +*/ + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/mem_ARMv81MML.h b/Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/mem_ARMv81MML.h new file mode 100755 index 00000000..84a1ff1d --- /dev/null +++ b/Platforms/NORMALFVP/ARMv81MML/LinkScripts/GCC/mem_ARMv81MML.h @@ -0,0 +1,38 @@ +/**************************************************************************//** + * @file mem_ARMCM7.h + * @brief Memory base and size definitions (used in scatter file) + * @version V1.1.0 + * @date 15. May 2019 + * + * @note + * + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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 + * + * 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 __MEM_ARMCM7_H +#define __MEM_ARMCM7_H + + + +#define STACK_SIZE 0x00003000 +#define HEAP_SIZE 0x00100000 + + + +#endif /* __MEM_ARMCM7_H */ diff --git a/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_ARMv81MML.c b/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_ARMv81MML.c new file mode 100755 index 00000000..3f259c56 --- /dev/null +++ b/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_ARMv81MML.c @@ -0,0 +1,189 @@ +/****************************************************************************** + * @file startup_ARMCM7.c + * @brief CMSIS-Core(M) Device Startup File for a Cortex-M7 Device + * @version V2.0.3 + * @date 31. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 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 + * + * 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. + */ + +#if defined (ARMv81MML_DSP_DP_MVE_FP) + #include "ARMv81MML_DSP_DP_MVE_FP.h" +#else + #error device not specified! +#endif + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +extern __NO_RETURN void __PROGRAM_START(void); + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +__NO_RETURN void Reset_Handler (void); + void Default_Handler(void); + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +/* Exceptions */ +void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler (void) __attribute__ ((weak)); +void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); + +void Interrupt0_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt1_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt2_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt3_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt4_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt5_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt6_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt7_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt8_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void Interrupt9_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); + + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[240]; + const pFunc __VECTOR_TABLE[240] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14 NMI Handler */ + HardFault_Handler, /* -13 Hard Fault Handler */ + MemManage_Handler, /* -12 MPU Fault Handler */ + BusFault_Handler, /* -11 Bus Fault Handler */ + UsageFault_Handler, /* -10 Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5 SVCall Handler */ + DebugMon_Handler, /* -4 Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2 PendSV Handler */ + SysTick_Handler, /* -1 SysTick Handler */ + + /* Interrupts */ + Interrupt0_Handler, /* 0 Interrupt 0 */ + Interrupt1_Handler, /* 1 Interrupt 1 */ + Interrupt2_Handler, /* 2 Interrupt 2 */ + Interrupt3_Handler, /* 3 Interrupt 3 */ + Interrupt4_Handler, /* 4 Interrupt 4 */ + Interrupt5_Handler, /* 5 Interrupt 5 */ + Interrupt6_Handler, /* 6 Interrupt 6 */ + Interrupt7_Handler, /* 7 Interrupt 7 */ + Interrupt8_Handler, /* 8 Interrupt 8 */ + Interrupt9_Handler /* 9 Interrupt 9 */ + /* Interrupts 10 .. 223 are left out */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + + + +extern void _start(void) __NO_RETURN; + + +extern void _ttywrch(char c); +extern void _sys_exit(); + +int _write(int file, + char *ptr, + int len) +{ + int i; + (void)file; + + for(i=0; i < len;i++) + { + _ttywrch(*ptr++); + } + return len; +} + +void _exit(int return_code) +{ + (void)return_code; + _sys_exit(); + while(1); +} + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +__NO_RETURN void ResetC_Handler(void) +{ + __set_PSP((uint32_t)(&__INITIAL_SP)); + + __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); + __set_PSPLIM((uint32_t)(&__STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + + __PROGRAM_START(); + + //_start(); +} + + + +/*---------------------------------------------------------------------------- + Hard Fault Handler + *----------------------------------------------------------------------------*/ +void HardFault_Handler(void) +{ + + while(1); +} + +/*---------------------------------------------------------------------------- + Default Handler for Exceptions / Interrupts + *----------------------------------------------------------------------------*/ +void Default_Handler(void) +{ + + while(1); +} + + + diff --git a/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_asm_ARMv81MML.S b/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_asm_ARMv81MML.S new file mode 100755 index 00000000..9c0c53ec --- /dev/null +++ b/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/startup_asm_ARMv81MML.S @@ -0,0 +1,41 @@ + .global Reset_Handler + .global __StackLimit + .global _ttywrch + .global _sys_exit + .syntax unified + .text + .thumb + .thumb_func + .align 2 + .global Reset_Handler + + + .type _ttywrch, %function + + _ttywrch: + PUSH {r3,lr} + MOV r1,sp + STRB r0,[sp,#0] + MOVS r0,#3 + BKPT #0xab + POP {r3,pc} + MOVS r0,r0 + + .type _sys_exit, %function + +_sys_exit: + LDR r1,=0x20026 + MOVS r0,#0x18 + BKPT #0xab +loop: B loop + + .type Reset_Handler, %function + +Reset_Handler: + + + + LDR R0,=ResetC_Handler + BLX R0 + + .end \ No newline at end of file diff --git a/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/support.c b/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/support.c new file mode 100755 index 00000000..e284cd95 --- /dev/null +++ b/Platforms/NORMALFVP/ARMv81MML/Startup/GCC/support.c @@ -0,0 +1,36 @@ + +#ifdef __cplusplus +extern "C" +{ +#endif + +char * _sbrk(int incr); + +void __malloc_lock() ; +void __malloc_unlock(); + +char __HeapBase, __HeapLimit; // make sure to define these symbols in linker command file +#ifdef __cplusplus +} +#endif + +static int totalBytesProvidedBySBRK = 0; +/* +//! sbrk/_sbrk version supporting reentrant newlib (depends upon above symbols defined by linker control file). +char * sbrk(int incr) { + static char *currentHeapEnd = &__HeapBase; + char *previousHeapEnd = currentHeapEnd; + if (currentHeapEnd + incr > &__HeapLimit) { + return (char *)-1; // the malloc-family routine that called sbrk will return 0 + } + currentHeapEnd += incr; + + totalBytesProvidedBySBRK += incr; + + return (char *) previousHeapEnd; +} +//! Synonym for sbrk. +char * _sbrk(int incr) { return sbrk(incr); }; +*/ +void __malloc_lock() { }; +void __malloc_unlock() { }; \ No newline at end of file diff --git a/Platforms/NORMALFVP/platform.cmake b/Platforms/NORMALFVP/platform.cmake index b39377ca..b0b8baee 100755 --- a/Platforms/NORMALFVP/platform.cmake +++ b/Platforms/NORMALFVP/platform.cmake @@ -1,5 +1,7 @@ function(configure_platform PROJECTNAME ROOT CORE PLATFORMFOLDER) if (GCC) target_sources(${PROJECTNAME} PRIVATE ${PLATFORMFOLDER}/${CORE}/Startup/GCC/startup_asm_${CORE}.S) + # target_link_options(${PROJECTNAME} PRIVATE "-lrdimon;-lc") + endif() endfunction() \ No newline at end of file