aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2024-01-20 19:30:21 -0500
committerKevin O'Connor <kevin@koconnor.net>2024-01-25 11:02:49 -0500
commit55e46aa6250382367af30d3a5e005e919d772d32 (patch)
tree561cc3137705e51a3c30b7c0fa393b7f30151392
parent43a9685c581a46ea161faa297c0a29f3bcd7194e (diff)
downloadkutter-55e46aa6250382367af30d3a5e005e919d772d32.tar.gz
kutter-55e46aa6250382367af30d3a5e005e919d772d32.tar.xz
kutter-55e46aa6250382367af30d3a5e005e919d772d32.zip
armcm_boot: Avoid invoking functions in reset_handler_stage_two()
Avoid calling memset() and memcpy() prior to copying the ram and clearing the bss. Also, place both ResetHandler() and reset_handler_stage_two() in an explicit ".text.armcm_boot" linker section. These changes make it easier to support targets that want to run all code in ram. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/generic/armcm_boot.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/generic/armcm_boot.c b/src/generic/armcm_boot.c
index f83ca60d..9d2ce0bb 100644
--- a/src/generic/armcm_boot.c
+++ b/src/generic/armcm_boot.c
@@ -22,7 +22,31 @@ extern uint32_t _stack_end;
* Basic interrupt handlers
****************************************************************/
-static void __noreturn
+// Inlined version of memset (to avoid function calls during intial boot code)
+static void __always_inline
+boot_memset(void *s, int c, size_t n)
+{
+ volatile uint32_t *p = s;
+ while (n) {
+ *p++ = c;
+ n -= sizeof(*p);
+ }
+}
+
+// Inlined version of memcpy (to avoid function calls during intial boot code)
+static void __always_inline
+boot_memcpy(void *dest, const void *src, size_t n)
+{
+ const uint32_t *s = src;
+ volatile uint32_t *d = dest;
+ while (n) {
+ *d++ = *s++;
+ n -= sizeof(*d);
+ }
+}
+
+// Main initialization code (called from ResetHandler below)
+static void __noreturn __section(".text.armcm_boot.stage_two")
reset_handler_stage_two(void)
{
int i;
@@ -60,10 +84,10 @@ reset_handler_stage_two(void)
// Copy global variables from flash to ram
uint32_t count = (&_data_end - &_data_start) * 4;
- __builtin_memcpy(&_data_start, &_data_flash, count);
+ boot_memcpy(&_data_start, &_data_flash, count);
// Clear the bss segment
- __builtin_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4);
+ boot_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4);
barrier();
@@ -80,7 +104,7 @@ reset_handler_stage_two(void)
// Initial code entry point - invoked by the processor after a reset
// Reset interrupts and stack to take control from bootloaders
-void
+void __section(".text.armcm_boot.stage_one")
ResetHandler(void)
{
__disable_irq();