Skip to content

Commit 741435c

Browse files
committed
soc: arm: stm32: Add ROM bootloader support
Add jump to ROM bootloader for STM32 when bootmode is set via retention boot mode feature. Signed-off-by: Peter Johanson <[email protected]>
1 parent f8322ef commit 741435c

File tree

5 files changed

+112
-0
lines changed

5 files changed

+112
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Peter Johanson
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: ST STM32 ROM Bootloader Details
5+
6+
compatible: "st,stm32-bootloader"
7+
8+
include: base.yaml
9+
10+
properties:
11+
reg:
12+
required: true

soc/st/stm32/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ config STM32_BACKUP_SRAM_INIT_PRIORITY
3838
help
3939
STM32 Backup SRAM device initialization priority.
4040

41+
config STM32_BOOTLOADER
42+
bool "STM32 Bootloader Support"
43+
depends on RETENTION_BOOT_MODE && DT_HAS_ST_STM32_BOOTLOADER_ENABLED
44+
help
45+
Enable support for jumping into the STM32 bootloader when the
46+
bootmode is set.
47+
48+
config STM32_BOOTLOADER_INIT_PRIORITY
49+
int "STM32 bootloader check init priority"
50+
default 3
51+
help
52+
STM32 bootloader check initialization priority (must be higher than init
53+
priorities for retention/retained memory drivers).
54+
4155
config STM32_ENABLE_DEBUG_SLEEP_STOP
4256
bool "Allow debugger attach in stop/sleep Mode"
4357
help

soc/st/stm32/Kconfig.defconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ config CLOCK_CONTROL_INIT_PRIORITY
8181
default 1
8282
depends on CLOCK_CONTROL
8383

84+
if STM32_BOOTLOADER
85+
86+
config RETAINED_MEM_INIT_PRIORITY
87+
default 1
88+
89+
config RETENTION_INIT_PRIORITY
90+
default 2
91+
92+
endif
93+
8494
# Get flash configuration for NS image from dts flash partition
8595
config USE_DT_CODE_PARTITION
8696
default y if TRUSTED_EXECUTION_NONSECURE

soc/st/stm32/common/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ endif()
1919
zephyr_sources_ifdef(CONFIG_STM32_BACKUP_SRAM stm32_backup_sram.c)
2020
zephyr_linker_sources_ifdef(CONFIG_STM32_BACKUP_SRAM SECTIONS stm32_backup_sram.ld)
2121

22+
zephyr_sources_ifdef(CONFIG_STM32_BOOTLOADER stm32_bootloader.c)
23+
2224
if (NOT CONFIG_DEBUG AND CONFIG_PM)
2325
zephyr_sources_ifdef(CONFIG_DT_HAS_SWJ_CONNECTOR_ENABLED pm_debug_swj.c)
2426
endif()
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2020 Google LLC.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <soc.h>
8+
#include <zephyr/init.h>
9+
#include <zephyr/retention/retention.h>
10+
#include <zephyr/retention/bootmode.h>
11+
#include <stm32_ll_system.h>
12+
13+
#if defined(CONFIG_ARM_MPU)
14+
extern void arm_core_mpu_disable(void);
15+
#endif
16+
17+
static const uint32_t bootloader = DT_REG_ADDR(DT_INST(0, st_stm32_bootloader));
18+
static FUNC_NORETURN void jump_to_bootloader(void)
19+
{
20+
int i;
21+
void (*jmp)(void);
22+
23+
__disable_irq();
24+
25+
for (i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
26+
NVIC->ICER[i] = 0xFFFFFFFF;
27+
NVIC->ICPR[i] = 0xFFFFFFFF;
28+
}
29+
30+
#if defined(CONFIG_ARM_MPU)
31+
/*
32+
* Needed to allow the bootloader to erase/write to flash, and the MPU
33+
* is set up in the arch init phase.
34+
*/
35+
arm_core_mpu_disable();
36+
#endif
37+
38+
/*
39+
* Disable SysTick before jumping, to keep the bootloader happy
40+
*/
41+
SysTick->CTRL = 0;
42+
43+
LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH);
44+
45+
jmp = (void (*)(void))(void (*)(void))(*((uint32_t *)((bootloader + 4))));
46+
47+
/*
48+
* We need to clear a few things set by the Zephyr early startup code
49+
*/
50+
__set_CONTROL(0);
51+
#if !defined(CONFIG_CPU_CORTEX_M0)
52+
__set_BASEPRI(0);
53+
#endif
54+
55+
__set_MSP(*(uint32_t *)bootloader);
56+
57+
__enable_irq();
58+
59+
jmp();
60+
61+
CODE_UNREACHABLE;
62+
}
63+
64+
static int bootloader_check_boot_init(void)
65+
{
66+
if (bootmode_check(BOOT_MODE_TYPE_BOOTLOADER) > 0) {
67+
bootmode_clear();
68+
jump_to_bootloader();
69+
}
70+
71+
return 0;
72+
}
73+
74+
SYS_INIT(bootloader_check_boot_init, POST_KERNEL, CONFIG_STM32_BOOTLOADER_INIT_PRIORITY);

0 commit comments

Comments
 (0)