Skip to content

Commit dfe31af

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 86f349e commit dfe31af

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ 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+
select RETAINED_MEM_INIT_LEVEL_PRE_KERNEL_1
45+
select RETENTION_INIT_LEVEL_PRE_KERNEL_1
46+
help
47+
Enable support for jumping into the STM32 when the bootmode is set.
48+
4149
config STM32_ENABLE_DEBUG_SLEEP_STOP
4250
bool "Allow debugger attach in stop/sleep Mode"
4351
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 1
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: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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+
LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH);
39+
40+
jmp = (void (*)(void))(void (*)(void))(*((uint32_t *)((bootloader + 4))));
41+
42+
/*
43+
* We need to clear a few things set by the Zephyr early startup code
44+
*/
45+
__set_CONTROL(0);
46+
#if !defined(CONFIG_CPU_CORTEX_M0)
47+
__set_BASEPRI(0);
48+
#endif
49+
50+
__set_MSP(*(uint32_t *)bootloader);
51+
52+
__enable_irq();
53+
54+
jmp();
55+
56+
CODE_UNREACHABLE;
57+
}
58+
59+
static int bootloader_check_boot_init(void)
60+
{
61+
if (bootmode_check(BOOT_MODE_TYPE_BOOTLOADER) > 0) {
62+
bootmode_clear();
63+
jump_to_bootloader();
64+
}
65+
66+
return 0;
67+
}
68+
69+
SYS_INIT(bootloader_check_boot_init, PRE_KERNEL_1, 3);

0 commit comments

Comments
 (0)