diff --git a/core/embed/sys/linker/inc/sys/linker_utils.h b/core/embed/sys/linker/inc/sys/linker_utils.h
index 9975fc8372..7286584b5d 100644
--- a/core/embed/sys/linker/inc/sys/linker_utils.h
+++ b/core/embed/sys/linker/inc/sys/linker_utils.h
@@ -31,15 +31,6 @@ extern uint8_t _stack_section_end;
// to reinitialize these sections if necessary.
void init_linker_sections(void);
-// Clears the unused portion of the stack.
-//
-// This includes memory between the start of the stack
-// and the current stack pointer (SP).
-//
-// It's safe to call this function at any time, but it's
-// recommended to call it only during the startup sequence.
-void clear_unused_stack(void);
-
// Maximum number of memory blocks in a memory region
#define MEMREGION_MAX_BLOCKS 8
diff --git a/core/embed/sys/linker/linker_utils.c b/core/embed/sys/linker/linker_utils.c
index 84419ed12b..bd3770088c 100644
--- a/core/embed/sys/linker/linker_utils.c
+++ b/core/embed/sys/linker/linker_utils.c
@@ -54,21 +54,6 @@ void init_linker_sections(void) {
}
}
-__attribute((naked, no_stack_protector)) void clear_unused_stack(void) {
- __asm__ volatile(
- " MOV R0, #0 \n"
- " LDR R1, =%[sstack] \n"
- "1: \n"
- " STR R0, [R1], #4 \n"
- " CMP R1, SP \n"
- " BNE 1b \n"
- " BX LR \n"
- : // no output
- : [sstack] "i"((uint32_t)&_stack_section_start)
- : // no clobber
- );
-}
-
static void memregion_remove_block(memregion_t* region, int idx) {
if (idx < 0 || idx >= MEMREGION_MAX_BLOCKS) {
return;
diff --git a/core/embed/sys/stack/inc/sys/stack_utils.h b/core/embed/sys/stack/inc/sys/stack_utils.h
new file mode 100644
index 0000000000..e18f677fb7
--- /dev/null
+++ b/core/embed/sys/stack/inc/sys/stack_utils.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+// Clears the unused portion of the stack.
+//
+// This includes memory between the start of the stack
+// and the current stack pointer (SP).
+//
+// It's safe to call this function at any time, but it's
+// recommended to call it only during the startup sequence.
+void clear_unused_stack(void);
diff --git a/core/embed/sys/stack/stm32/stack_utils.c b/core/embed/sys/stack/stm32/stack_utils.c
new file mode 100644
index 0000000000..a9fc4da6b1
--- /dev/null
+++ b/core/embed/sys/stack/stm32/stack_utils.c
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+
+__attribute((naked, no_stack_protector)) void clear_unused_stack(void) {
+ __asm__ volatile(
+ " MOV R0, #0 \n"
+ " LDR R1, =%[sstack] \n"
+ "1: \n"
+ " STR R0, [R1], #4 \n"
+ " CMP R1, SP \n"
+ " BNE 1b \n"
+ " BX LR \n"
+ : // no output
+ : [sstack] "i"((uint32_t)&_stack_section_start)
+ : // no clobber
+ );
+}
diff --git a/core/embed/sys/startup/stm32/bootutils.c b/core/embed/sys/startup/stm32/bootutils.c
index 8fe025f668..aeae943ac9 100644
--- a/core/embed/sys/startup/stm32/bootutils.c
+++ b/core/embed/sys/startup/stm32/bootutils.c
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/core/embed/sys/startup/stm32f4/startup_init.c b/core/embed/sys/startup/stm32f4/startup_init.c
index b6429a76c0..f095c73fdd 100644
--- a/core/embed/sys/startup/stm32f4/startup_init.c
+++ b/core/embed/sys/startup/stm32f4/startup_init.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/core/embed/sys/startup/stm32u5/startup_init.c b/core/embed/sys/startup/stm32u5/startup_init.c
index 524c8baffc..727a15a111 100644
--- a/core/embed/sys/startup/stm32u5/startup_init.c
+++ b/core/embed/sys/startup/stm32u5/startup_init.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#ifdef KERNEL_MODE
diff --git a/core/embed/sys/task/stm32/system.c b/core/embed/sys/task/stm32/system.c
index 1c940d630c..d484524dfb 100644
--- a/core/embed/sys/task/stm32/system.c
+++ b/core/embed/sys/task/stm32/system.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/core/site_scons/models/stm32f4_common.py b/core/site_scons/models/stm32f4_common.py
index 498803b1d1..f1b744df41 100644
--- a/core/site_scons/models/stm32f4_common.py
+++ b/core/site_scons/models/stm32f4_common.py
@@ -22,6 +22,7 @@ def stm32f4_common_files(env, defines, sources, paths):
"embed/sys/mpu/inc",
"embed/sys/pvd/inc",
"embed/sec/secret/inc",
+ "embed/sys/stack/inc",
"embed/sys/startup/inc",
"embed/sys/syscall/inc",
"embed/sys/task/inc",
@@ -70,6 +71,7 @@ def stm32f4_common_files(env, defines, sources, paths):
"embed/sys/linker/linker_utils.c",
"embed/sys/mpu/stm32f4/mpu.c",
"embed/sys/pvd/stm32/pvd.c",
+ "embed/sys/stack/stm32/stack_utils.c",
"embed/sys/startup/stm32/bootutils.c",
"embed/sys/startup/stm32/sysutils.c",
"embed/sys/startup/stm32f4/reset_flags.c",
diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py
index dbf1ac3801..0d4b7844e1 100644
--- a/core/site_scons/models/stm32u5_common.py
+++ b/core/site_scons/models/stm32u5_common.py
@@ -23,6 +23,7 @@ def stm32u5_common_files(env, defines, sources, paths):
"embed/sys/linker/inc",
"embed/sys/mpu/inc",
"embed/sys/pvd/inc",
+ "embed/sys/stack/inc",
"embed/sys/startup/inc",
"embed/sys/syscall/inc",
"embed/sys/tamper/inc",
@@ -88,6 +89,7 @@ def stm32u5_common_files(env, defines, sources, paths):
"embed/sys/linker/linker_utils.c",
"embed/sys/mpu/stm32u5/mpu.c",
"embed/sys/pvd/stm32/pvd.c",
+ "embed/sys/stack/stm32/stack_utils.c",
"embed/sys/startup/stm32/bootutils.c",
"embed/sys/startup/stm32/sysutils.c",
"embed/sys/startup/stm32u5/reset_flags.c",