summaryrefslogtreecommitdiff
path: root/source/application/hal/platforms/bare-metal/bsp
diff options
context:
space:
mode:
Diffstat (limited to 'source/application/hal/platforms/bare-metal/bsp')
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/bsp-core/retarget.c277
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/device_mps3.c4
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/timer_mps3.c12
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/uart_stdout.c5
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c22
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c90
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.ld246
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.sct10
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.ld246
-rw-r--r--source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.sct58
10 files changed, 744 insertions, 226 deletions
diff --git a/source/application/hal/platforms/bare-metal/bsp/bsp-core/retarget.c b/source/application/hal/platforms/bare-metal/bsp/bsp-core/retarget.c
index cf31a53..29c2023 100644
--- a/source/application/hal/platforms/bare-metal/bsp/bsp-core/retarget.c
+++ b/source/application/hal/platforms/bare-metal/bsp/bsp-core/retarget.c
@@ -14,177 +14,188 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "uart_stdout.h"
#include "bsp_core_log.h"
-#if defined (MPS3_PLATFORM)
-#include "smm_mps3.h"
-#endif /* MPS3_PLATFORM */
-
#include <stdio.h>
#include <string.h>
#include <time.h>
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
+/* Arm compiler re-targeting */
+
#include <rt_misc.h>
#include <rt_sys.h>
/* Standard IO device handles. */
-#define STDIN 0x8001
-#define STDOUT 0x8002
-#define STDERR 0x8003
+#define STDIN 0x8001
+#define STDOUT 0x8002
+#define STDERR 0x8003
-/* Standard IO device name defines. */
-const char __stdin_name[] = "STDIN";
-const char __stdout_name[] = "STDOUT";
-const char __stderr_name[] = "STDERR";
+#define RETARGET(fun) _sys##fun
-int fputc(int ch, FILE *f)
-{
- UNUSED(f);
- return (UartPutc(ch));
-}
+#else
+/* GNU compiler re-targeting */
-int fgetc(FILE *f)
-{
- UNUSED(f);
- return (UartPutc(UartGetc()));
-}
+/*
+ * This type is used by the _ I/O functions to denote an open
+ * file.
+ */
+typedef int FILEHANDLE;
-int ferror(FILE *f)
-{
- UNUSED(f);
- /* Your implementation of ferror */
- return EOF;
-}
+/*
+ * Open a file. May return -1 if the file failed to open.
+ */
+extern FILEHANDLE _open(const char * /*name*/, int /*openmode*/);
-void _ttywrch(int ch)
-{
- UartPutc(ch);
+/* Standard IO device handles. */
+#define STDIN 0x00
+#define STDOUT 0x01
+#define STDERR 0x02
+
+#define RETARGET(fun) fun
+
+#endif
+
+/* Standard IO device name defines. */
+const char __stdin_name[] __attribute__((aligned(4))) = "STDIN";
+const char __stdout_name[] __attribute__((aligned(4))) = "STDOUT";
+const char __stderr_name[] __attribute__((aligned(4))) = "STDERR";
+
+void _ttywrch(int ch) {
+ (void)fputc(ch, stdout);
}
-FILEHANDLE _sys_open(const char *name, int openmode)
+FILEHANDLE RETARGET(_open)(const char *name, int openmode)
{
UNUSED(openmode);
- /* Register standard Input Output devices. */
- if (strcmp(name, "STDIN") == 0)
- {
+ if (strcmp(name, __stdin_name) == 0) {
return (STDIN);
}
- if (strcmp(name, "STDOUT") == 0)
- {
+
+ if (strcmp(name, __stdout_name) == 0) {
return (STDOUT);
}
- if (strcmp(name, "STDERR") == 0)
- {
+
+ if (strcmp(name, __stderr_name) == 0) {
return (STDERR);
}
- return (-1);
-}
-int _sys_close(FILEHANDLE fh)
-{
- if (fh > 0x8000)
- {
- return (0);
- }
- return (-1);
+ return -1;
}
-int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned int len, int mode)
+int RETARGET(_write)(FILEHANDLE fh, const unsigned char *buf, unsigned int len, int mode)
{
UNUSED(mode);
- if (fh == STDOUT || fh == STDERR )
- {
- /* Standard Output device. */
- for (; len; len--)
- {
- UartPutc(*buf++);
+
+ switch (fh) {
+ case STDOUT:
+ case STDERR: {
+ int c;
+
+ while (len-- > 0) {
+ c = fputc(*buf++, stdout);
+ if (c == EOF) {
+ return EOF;
+ }
}
- return (0);
- }
- if (fh > 0x8000)
- {
- return (-1);
+ return 0;
+ }
+ default:
+ return EOF;
}
- return (-1);
}
-int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode)
+int RETARGET(_read)(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode)
{
UNUSED(mode);
- if (fh == STDIN)
- {
- /* Standard Input device. */
- for (; len; len--)
- {
- *buf++ = UartGetc();
+
+ switch (fh) {
+ case STDIN: {
+ int c;
+
+ while (len-- > 0) {
+ c = fgetc(stdin);
+ if (c == EOF) {
+ return EOF;
+ }
+
+ *buf++ = (unsigned char)c;
}
- return (0);
+
+ return 0;
+ }
+ default:
+ return EOF;
}
+}
- if (fh > 0x8000)
- {
- return (-1);
+int RETARGET(_istty)(FILEHANDLE fh)
+{
+ switch (fh) {
+ case STDIN:
+ case STDOUT:
+ case STDERR:
+ return 1;
+ default:
+ return 0;
}
- return (-1);
}
-int _sys_istty(FILEHANDLE fh)
+int RETARGET(_close)(FILEHANDLE fh)
{
- if (fh > 0x8000)
- {
- return (1);
+ if (RETARGET(_istty(fh))) {
+ return 0;
}
- return (0);
+
+ return -1;
}
-int _sys_seek(FILEHANDLE fh, long pos)
+int RETARGET(_seek)(FILEHANDLE fh, long pos)
{
+ UNUSED(fh);
UNUSED(pos);
- if (fh > 0x8000)
- {
- return (-1);
- }
- return (-1);
+
+ return -1;
}
-int _sys_ensure(FILEHANDLE fh)
+int RETARGET(_ensure)(FILEHANDLE fh)
{
- if (fh > 0x8000)
- {
- return (-1);
- }
- return (-1);
+ UNUSED(fh);
+
+ return -1;
}
-long _sys_flen(FILEHANDLE fh)
+long RETARGET(_flen)(FILEHANDLE fh)
{
- if (fh > 0x8000)
- {
- return (0);
+ if (RETARGET(_istty)(fh)) {
+ return 0;
}
- return (-1);
+
+ return -1;
}
-int _sys_tmpnam(char *name, int sig, unsigned maxlen)
+int RETARGET(_tmpnam)(char *name, int sig, unsigned int maxlen)
{
UNUSED(name);
UNUSED(sig);
UNUSED(maxlen);
- return (1);
+
+ return 1;
}
-char *_sys_command_string(char *cmd, int len)
+char *RETARGET(_command_string)(char *cmd, int len)
{
UNUSED(len);
- return (cmd);
+
+ return cmd;
}
-void _sys_exit(int return_code)
+void RETARGET(_exit)(int return_code)
{
UartEndSimulation(return_code);
}
@@ -192,44 +203,66 @@ void _sys_exit(int return_code)
int system(const char *cmd)
{
UNUSED(cmd);
- return (0);
+
+ return 0;
}
time_t time(time_t *timer)
{
time_t current;
-#if defined (MPS3_PLATFORM)
- current = MPS3_FPGAIO->COUNTER;
-#else /* MPS3_PLATFORM */
- current = 0; /* No RTC implementation available. */
-#endif /* MPS3_PLATFORM */
+ current = 0; // To Do !! No RTC implemented
if (timer != NULL) {
*timer = current;
}
- return (current);
+ return current;
}
-#else /* #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) */
+void _clock_init(void) {}
-/******************************************************************************/
-/* Retarget functions for GNU Tools for ARM Embedded Processors */
-/******************************************************************************/
-#include <stdio.h>
-#include <sys/stat.h>
+clock_t clock(void)
+{
+ return (clock_t)-1;
+}
+
+int remove(const char *arg) {
+ UNUSED(arg);
-extern unsigned char UartPutc(unsigned char my_ch);
+ return 0;
+}
-__attribute__((used)) int _write(int fd, char *ptr, int len)
+int rename(const char *oldn, const char *newn)
{
- size_t i;
- for (i = 0; i < len; i++)
- {
- UartPutc(ptr[i]); /* call character output function. */
- }
- return len;
+ UNUSED(oldn);
+ UNUSED(newn);
+
+ return 0;
+}
+
+int fputc(int ch, FILE *f)
+{
+ UNUSED(f);
+
+ return UartPutc(ch);
+}
+
+int fgetc(FILE *f)
+{
+ UNUSED(f);
+
+ return UartPutc(UartGetc());
+}
+
+#ifndef ferror
+
+/* arm-none-eabi-gcc with newlib uses a define for ferror */
+int ferror(FILE *f)
+{
+ UNUSED(f);
+
+ return EOF;
}
-#endif /* #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) */
+#endif /* #ifndef ferror */
diff --git a/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/device_mps3.c b/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/device_mps3.c
index f4f2e6b..7040cf3 100644
--- a/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/device_mps3.c
+++ b/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/device_mps3.c
@@ -19,6 +19,8 @@
#include "bsp_core_log.h"
#include "smm_mps3.h"
+#include <inttypes.h>
+
uint32_t GetMPS3CoreClock(void)
{
const uint32_t default_clock = 32000000;
@@ -28,7 +30,7 @@ uint32_t GetMPS3CoreClock(void)
}
if (!warned_once) {
- warn("MPS3_SCC->CFG_ACLK reads 0. Assuming default clock of %u\n",
+ warn("MPS3_SCC->CFG_ACLK reads 0. Assuming default clock of %" PRIu32 "\n",
default_clock);
warned_once = 1;
}
diff --git a/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/timer_mps3.c b/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/timer_mps3.c
index 0a3a8b1..a72103c 100644
--- a/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/timer_mps3.c
+++ b/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/timer_mps3.c
@@ -19,6 +19,8 @@
#include "bsp_core_log.h"
#include "device_mps3.h"
+#include <inttypes.h>
+
void timer_reset(void)
{
MPS3_FPGAIO->CLK1HZ = 0;
@@ -39,11 +41,11 @@ mps3_time_counter get_time_counter(void)
.counter_fpga = MPS3_FPGAIO->COUNTER,
.counter_systick = Get_SysTick_Cycle_Count()
};
- debug("Timestamp:\
- \n\tCounter 1 Hz: %u\
- \n\tCounter 100 Hz: %u\
- \n\tCounter FPGA: %u\
- \n\tCounter CPU: %llu\n",
+ debug("Timestamp:"
+ "\n\tCounter 1 Hz: %" PRIu32
+ "\n\tCounter 100 Hz: %" PRIu32
+ "\n\tCounter FPGA: %" PRIu32
+ "\n\tCounter CPU: %" PRIu64 "\n",
t.counter_1Hz, t.counter_100Hz, t.counter_fpga, t.counter_systick);
return t;
}
diff --git a/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/uart_stdout.c b/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/uart_stdout.c
index 1bf8291..ed12c8b 100644
--- a/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/uart_stdout.c
+++ b/source/application/hal/platforms/bare-metal/bsp/bsp-packs/mps3/uart_stdout.c
@@ -107,10 +107,11 @@ bool GetLine(char *lp, unsigned int len)
return false;
case CR: /* CR - done, stop editing line. */
- *lp = c;
+ UartPutc (*lp = c); /* Echo and store character. */
lp++; /* Increment line pointer */
cnt++; /* and count. */
c = LF;
+ break;
default:
UartPutc (*lp = c); /* Echo and store character. */
fflush (stdout);
@@ -124,7 +125,7 @@ bool GetLine(char *lp, unsigned int len)
return true;
}
-void UartEndSimulation(int code)
+__attribute__((noreturn)) void UartEndSimulation(int code)
{
UartPutc((char) 0x4); /* End of simulation */
UartPutc((char) code); /* End of simulation */
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
index c9cf53d..b7f318c 100644
--- a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c
+++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c
@@ -24,9 +24,6 @@ extern void *__Vectors; /* see irqs.c */
#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
@@ -69,25 +66,6 @@ void SystemInit(void)
(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
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
index c6f54b1..7c9f4b8 100644
--- a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c
+++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c
@@ -23,24 +23,36 @@ extern "C"
#include "cmsis.h"
#include <stdio.h>
+#include <inttypes.h>
static uint64_t cpu_cycle_count = 0;
/**
+ * External references
+ */
+extern uint32_t __INITIAL_SP;
+extern uint32_t __STACK_LIMIT;
+
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+ extern uint32_t __STACK_SEAL;
+#endif
+
+extern __NO_RETURN void __PROGRAM_START(void);
+
+/**
* @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());
+ printf("CTRL : 0x%08" PRIx32 "\n", __get_CONTROL());
+ printf("IPSR : 0x%08" PRIx32 "\n", __get_IPSR());
+ printf("APSR : 0x%08" PRIx32 "\n", __get_APSR());
+ printf("xPSR : 0x%08" PRIx32 "\n", __get_xPSR());
+ printf("PSP : 0x%08" PRIx32 "\n", __get_PSP());
+ printf("MSP : 0x%08" PRIx32 "\n", __get_MSP());
+ printf("PRIMASK : 0x%08" PRIx32 "\n", __get_PRIMASK());
+ printf("BASEPRI : 0x%08" PRIx32 "\n", __get_BASEPRI());
+ printf("FAULTMSK: 0x%08" PRIx32 "\n", __get_FAULTMASK());
}
/**
@@ -158,6 +170,9 @@ void SysTick_Handler(void)
cpu_cycle_count += SysTick->LOAD + 1;
}
+/**
+ * Gets the current SysTick derived counter value
+ */
uint64_t Get_SysTick_Cycle_Count(void)
{
uint32_t systick_val;
@@ -169,47 +184,27 @@ uint64_t Get_SysTick_Cycle_Count(void)
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 */
+irq_vec_type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
+ (irq_vec_type)(&__INITIAL_SP), /* Initial Stack Pointer */
+ 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 */
+ 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 */
+ 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 */
@@ -222,6 +217,9 @@ irq_vec_type __Vectors[] __attribute__((section("RESET"), used)) = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 112 - 128 */
};
+/**
+ * SysTick initialisation
+ */
int Init_SysTick(void)
{
const uint32_t ticks_10ms = GetSystemCoreClock()/100 + 1;
@@ -252,8 +250,8 @@ __attribute__((used)) void Reset_Handler(void)
/* Configure the system tick. */
Init_SysTick();
- /* libcxx supplied entry point. */
- __main();
+ /* cmsis supplied entry point. */
+ __PROGRAM_START();
}
#ifdef __cplusplus
diff --git a/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.ld b/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.ld
new file mode 100644
index 0000000..8bb99cd
--- /dev/null
+++ b/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.ld
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+__STACK_SIZE = 0x00060000;
+__HEAP_SIZE = 0x000f0000;
+
+/* System memory brief */
+MEMORY
+{
+ ITCM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
+ DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00080000
+ BRAM (rwx) : ORIGIN = 0x11000000, LENGTH = 0x00200000
+ SRAM (rwx) : ORIGIN = 0x31000000, LENGTH = 0x00400000
+ DDR (rwx) : ORIGIN = 0x70000000, LENGTH = 0x02000000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions ITCM 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
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .text.at_itcm :
+ {
+ 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)
+
+ KEEP(*(.eh_frame*))
+ } > ITCM
+
+ .ARM.extab.at_itcm :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > ITCM
+
+ __exidx_start = .;
+ .ARM.exidx.at_itcm :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > ITCM
+ __exidx_end = .;
+
+ .zero.table.at_itcm :
+ {
+ . = ALIGN(4);
+ __zero_table_start__ = .;
+
+ LONG (__bss_start__)
+ LONG ((__bss_end__ - __bss_start__)/4) /* Size is in 32-bit words */
+
+ __zero_table_end__ = .;
+ } > ITCM
+
+ .copy.table.at_itcm :
+ {
+ . = ALIGN(4);
+ __copy_table_start__ = .;
+
+ /* Section to be copied - part 1: any data to be placed in BRAM */
+ LONG (__etext)
+ LONG (__data_start__)
+ LONG ((__data_end__ - __data_start__)/4) /* Size is in 32-bit words */
+
+ /* Section to be copied - part 2: RO data for for DTCM */
+ LONG (__etext2)
+ LONG (__ro_data_start__)
+ LONG ((__ro_data_end__ - __ro_data_start__)/4) /* Size is in 32-bit words */
+
+ __copy_table_end__ = .;
+ } > ITCM
+
+ __itcm_total = ALIGN(4);
+
+ ASSERT( __itcm_total < (ORIGIN(ITCM) + LENGTH(ITCM)), "ITCM overflow")
+
+ .sram :
+ {
+ . = ALIGN(16);
+ *(.bss.NoInit.activation_buf)
+ . = ALIGN(16);
+ } > SRAM AT > SRAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > DTCM AT > DTCM
+
+ .stack (ORIGIN(DTCM) + LENGTH(DTCM) - __STACK_SIZE) (COPY) :
+ {
+ . = ALIGN(8);
+ __StackLimit = .;
+ . = . + __STACK_SIZE;
+ . = ALIGN(8);
+ __StackTop = .;
+ } > DTCM
+ PROVIDE(__stack = __StackTop);
+ ASSERT(
+ (__STACK_SIZE + __bss_end__ - __bss_start__) <= LENGTH(DTCM),
+ "DTCM overflow")
+
+ .ddr.at_ddr :
+ {
+ /* __attribute__((aligned(16))) is not handled by the CMSIS startup code.
+ * Force the alignment here as a workaround */
+ . = ALIGN(16);
+ *(ifm)
+ . = ALIGN(16);
+ *(nn_model)
+ . = ALIGN (16);
+ *(labels)
+ . = ALIGN (16);
+ *(activation_buf)
+ . = ALIGN (16);
+ } > DDR AT > DDR
+
+ /**
+ * 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 DTCM
+ * which must be 4byte aligned
+ */
+ __etext = ALIGN (4);
+
+ .bram.at_ddr : AT (__etext)
+ {
+ __data_start__ = .;
+ *(vtable)
+ *(.data)
+ *(.data.*)
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+
+ __data_end__ = .;
+ } > BRAM
+
+ __etext2 = __etext + (__data_end__ - __data_start__);
+
+ .data.at_ddr : AT (__etext2)
+ {
+ . = ALIGN(4);
+ __ro_data_start__ = .;
+
+ *(.rodata*)
+ . = ALIGN(4);
+ * (npu_driver_version)
+ . = ALIGN(4);
+ * (npu_driver_arch_version)
+ . = ALIGN(4);
+
+ __ro_data_end__ = .;
+ } > BRAM
+
+ .heap (COPY) :
+ {
+ . = ALIGN(8);
+ __end__ = .;
+ PROVIDE(end = .);
+ . = . + __HEAP_SIZE;
+ . = ALIGN(8);
+ __HeapLimit = .;
+ } > BRAM
+
+ ASSERT (
+ (__ro_data_end__ - __ro_data_start__)
+ + (__data_end__ - __data_start__)
+ + __HEAP_SIZE <= LENGTH(BRAM),
+ "BRAM overflow")
+}
diff --git a/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.sct b/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.sct
index 327d511..55ed5d7 100644
--- a/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.sct
+++ b/source/application/hal/platforms/bare-metal/bsp/mem_layout/mps3-sse-300.sct
@@ -78,12 +78,12 @@ LOAD_REGION_0 0x00000000 0x00080000
LOAD_REGION_1 0x70000000 0x02000000
{
;-----------------------------------------------------
- ; 32 MiB of DRAM space for neural network model,
+ ; 32 MiB of DDR space for neural network model,
; input vectors and labels. If the activation buffer
; size required by the network is bigger than the
; SRAM size available, it is accommodated here.
;-----------------------------------------------------
- dram.bin 0x70000000 ALIGN 16 0x02000000
+ ddr.bin 0x70000000 ALIGN 16 0x02000000
{
; nn model's baked in input matrices
*.o (ifm)
@@ -110,9 +110,9 @@ LOAD_REGION_1 0x70000000 0x02000000
}
;-----------------------------------------------------
- ; Remaining part of the 2MiB BRAM used as heap space.
- ; 0x00200000 - 0x00040000 = 0x001C0000 (1.75 MiB)
+ ; 960 KiB of remaining part of the 2MiB BRAM used as
+ ; heap space. 0x000F0000 of 0x0x001C0000 available.
;-----------------------------------------------------
- ARM_LIB_HEAP 0x11040000 EMPTY ALIGN 8 0x001C0000
+ ARM_LIB_HEAP 0x11040000 EMPTY ALIGN 8 0x000F0000
{}
}
diff --git a/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.ld b/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.ld
new file mode 100644
index 0000000..8bb99cd
--- /dev/null
+++ b/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.ld
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+__STACK_SIZE = 0x00060000;
+__HEAP_SIZE = 0x000f0000;
+
+/* System memory brief */
+MEMORY
+{
+ ITCM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
+ DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00080000
+ BRAM (rwx) : ORIGIN = 0x11000000, LENGTH = 0x00200000
+ SRAM (rwx) : ORIGIN = 0x31000000, LENGTH = 0x00400000
+ DDR (rwx) : ORIGIN = 0x70000000, LENGTH = 0x02000000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions ITCM 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
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .text.at_itcm :
+ {
+ 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)
+
+ KEEP(*(.eh_frame*))
+ } > ITCM
+
+ .ARM.extab.at_itcm :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > ITCM
+
+ __exidx_start = .;
+ .ARM.exidx.at_itcm :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > ITCM
+ __exidx_end = .;
+
+ .zero.table.at_itcm :
+ {
+ . = ALIGN(4);
+ __zero_table_start__ = .;
+
+ LONG (__bss_start__)
+ LONG ((__bss_end__ - __bss_start__)/4) /* Size is in 32-bit words */
+
+ __zero_table_end__ = .;
+ } > ITCM
+
+ .copy.table.at_itcm :
+ {
+ . = ALIGN(4);
+ __copy_table_start__ = .;
+
+ /* Section to be copied - part 1: any data to be placed in BRAM */
+ LONG (__etext)
+ LONG (__data_start__)
+ LONG ((__data_end__ - __data_start__)/4) /* Size is in 32-bit words */
+
+ /* Section to be copied - part 2: RO data for for DTCM */
+ LONG (__etext2)
+ LONG (__ro_data_start__)
+ LONG ((__ro_data_end__ - __ro_data_start__)/4) /* Size is in 32-bit words */
+
+ __copy_table_end__ = .;
+ } > ITCM
+
+ __itcm_total = ALIGN(4);
+
+ ASSERT( __itcm_total < (ORIGIN(ITCM) + LENGTH(ITCM)), "ITCM overflow")
+
+ .sram :
+ {
+ . = ALIGN(16);
+ *(.bss.NoInit.activation_buf)
+ . = ALIGN(16);
+ } > SRAM AT > SRAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > DTCM AT > DTCM
+
+ .stack (ORIGIN(DTCM) + LENGTH(DTCM) - __STACK_SIZE) (COPY) :
+ {
+ . = ALIGN(8);
+ __StackLimit = .;
+ . = . + __STACK_SIZE;
+ . = ALIGN(8);
+ __StackTop = .;
+ } > DTCM
+ PROVIDE(__stack = __StackTop);
+ ASSERT(
+ (__STACK_SIZE + __bss_end__ - __bss_start__) <= LENGTH(DTCM),
+ "DTCM overflow")
+
+ .ddr.at_ddr :
+ {
+ /* __attribute__((aligned(16))) is not handled by the CMSIS startup code.
+ * Force the alignment here as a workaround */
+ . = ALIGN(16);
+ *(ifm)
+ . = ALIGN(16);
+ *(nn_model)
+ . = ALIGN (16);
+ *(labels)
+ . = ALIGN (16);
+ *(activation_buf)
+ . = ALIGN (16);
+ } > DDR AT > DDR
+
+ /**
+ * 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 DTCM
+ * which must be 4byte aligned
+ */
+ __etext = ALIGN (4);
+
+ .bram.at_ddr : AT (__etext)
+ {
+ __data_start__ = .;
+ *(vtable)
+ *(.data)
+ *(.data.*)
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+
+ __data_end__ = .;
+ } > BRAM
+
+ __etext2 = __etext + (__data_end__ - __data_start__);
+
+ .data.at_ddr : AT (__etext2)
+ {
+ . = ALIGN(4);
+ __ro_data_start__ = .;
+
+ *(.rodata*)
+ . = ALIGN(4);
+ * (npu_driver_version)
+ . = ALIGN(4);
+ * (npu_driver_arch_version)
+ . = ALIGN(4);
+
+ __ro_data_end__ = .;
+ } > BRAM
+
+ .heap (COPY) :
+ {
+ . = ALIGN(8);
+ __end__ = .;
+ PROVIDE(end = .);
+ . = . + __HEAP_SIZE;
+ . = ALIGN(8);
+ __HeapLimit = .;
+ } > BRAM
+
+ ASSERT (
+ (__ro_data_end__ - __ro_data_start__)
+ + (__data_end__ - __data_start__)
+ + __HEAP_SIZE <= LENGTH(BRAM),
+ "BRAM overflow")
+}
diff --git a/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.sct b/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.sct
index a1ffb49..deb4214 100644
--- a/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.sct
+++ b/source/application/hal/platforms/bare-metal/bsp/mem_layout/simple_platform.sct
@@ -36,35 +36,36 @@ LOAD_REGION_0 0x00000000 0x00080000
}
;-----------------------------------------------------
- ; BRAM or FPGA data SRAM region worth 2MiB
- ;-----------------------------------------------------
- bram.bin 0x11000000 UNINIT ALIGN 16 0x00200000
- {
- ; activation buffers a.k.a tensor arena
- *.o (.bss.NoInit.activation_buf)
- }
-
- ;-----------------------------------------------------
- ; 128kiB of 512kiB bank is used for any other RW or ZI
+ ; 128kiB of 512kiB DTCM is used for any other RW or ZI
; data. Note: this region is internal to the Cortex-M
- ; CPU
+ ; CPU.
;-----------------------------------------------------
dtcm.bin 0x20000000 0x00020000
{
+ ; Any R/W and/or zero initialised data
.ANY(+RW +ZI)
}
;-----------------------------------------------------
- ; 128kiB of stack space within the DTCM region
+ ; 384kiB of stack space within the DTCM region. See
+ ; `dtcm.bin` for the first section. Note: by virtue of
+ ; being part of DTCM, this region is only accessible
+ ; from Cortex-M55.
;-----------------------------------------------------
- ARM_LIB_STACK 0x20020000 EMPTY ALIGN 8 0x00020000
+ ARM_LIB_STACK 0x20020000 EMPTY ALIGN 8 0x00060000
{}
;-----------------------------------------------------
- ; 256kiB of heap space within the DTCM region
+ ; SSE-300's internal SRAM of 4MiB - reserved for
+ ; activation buffers.
+ ; This region should have 3 cycle read latency from
+ ; both Cortex-M55 and Ethos-U55
;-----------------------------------------------------
- ARM_LIB_HEAP 0x20040000 EMPTY ALIGN 8 0x00040000
- {}
+ isram.bin 0x31000000 UNINIT ALIGN 16 0x00400000
+ {
+ ; activation buffers a.k.a tensor arena
+ *.o (.bss.NoInit.activation_buf)
+ }
}
;---------------------------------------------------------
@@ -73,9 +74,12 @@ LOAD_REGION_0 0x00000000 0x00080000
LOAD_REGION_1 0x70000000 0x02000000
{
;-----------------------------------------------------
- ; 32 MiB of DRAM space for nn model and input vectors
+ ; 32 MiB of DDR space for neural network model,
+ ; input vectors and labels. If the activation buffer
+ ; size required by the network is bigger than the
+ ; SRAM size available, it is accommodated here.
;-----------------------------------------------------
- dram.bin 0x70000000 ALIGN 16 0x02000000
+ ddr.bin 0x70000000 ALIGN 16 0x02000000
{
; nn model's baked in input matrices
*.o (ifm)
@@ -83,20 +87,28 @@ LOAD_REGION_1 0x70000000 0x02000000
; nn model
*.o (nn_model)
+ ; labels
+ *.o (labels)
+
; if the activation buffer (tensor arena) doesn't
; fit in the SRAM region, we accommodate it here
*.o (activation_buf)
}
;-----------------------------------------------------
- ; SSE-300's internal SRAM of 2MiB - reserved for
- ; activation buffers.
- ; This region should have 3 cycle read latency from
- ; both Cortex-M55 and Ethos-U55
+ ; First 256kiB of BRAM (FPGA SRAM) used for RO data.
+ ; Note: Total BRAM size available is 2MiB.
;-----------------------------------------------------
- isram.bin 0x31000000 0x00080000
+ bram.bin 0x11000000 ALIGN 8 0x00040000
{
; RO data (incl. unwinding tables for debugging)
.ANY (+RO-DATA)
}
+
+ ;-----------------------------------------------------
+ ; 960 KiB of remaining part of the 2MiB BRAM used as
+ ; heap space. 0x000F0000 of 0x0x001C0000 available.
+ ;-----------------------------------------------------
+ ARM_LIB_HEAP 0x11040000 EMPTY ALIGN 8 0x000F0000
+ {}
}