Skip to content

Commit 5386f41

Browse files
arch: arm: cortex_m: generalizing SRAM vector table relocation
Allow to place the vector table section in SRAM with CONFIG_SRAM_VECTOR_TABLE option for all cortex-m architecture that have VTOR register. Signed-off-by: Martin Hoff <[email protected]>
1 parent 68a0e25 commit 5386f41

File tree

5 files changed

+75
-0
lines changed

5 files changed

+75
-0
lines changed

arch/arm/core/cortex_m/CMakeLists.txt

+10
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,13 @@ zephyr_linker_sources(
6161
vt_pointer_section.ld
6262
)
6363
endif()
64+
65+
if (CONFIG_CPU_CORTEX_M_HAS_VTOR)
66+
zephyr_linker_sources_ifdef(CONFIG_SRAM_VECTOR_TABLE
67+
RAM_SECTIONS
68+
# Maybe need to be changed in order to be placed at the beginning of RAM
69+
# (conflict with code relocation script)
70+
SORT_KEY 0
71+
ram_vector_table.ld
72+
)
73+
endif()

arch/arm/core/cortex_m/prep_c.c

+10
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) void *_vector_table
3939

4040
#ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR
4141

42+
#ifdef CONFIG_SRAM_VECTOR_TABLE
43+
#define VECTOR_ADDRESS ((uintptr_t)_sram_vector_start)
44+
#else
4245
#define VECTOR_ADDRESS ((uintptr_t)_vector_start)
46+
#endif
4347

4448
/* In some Cortex-M3 implementations SCB_VTOR bit[29] is called the TBLBASE bit */
4549
#ifdef SCB_VTOR_TBLBASE_Msk
@@ -50,6 +54,12 @@ Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) void *_vector_table
5054

5155
void __weak relocate_vector_table(void)
5256
{
57+
#ifdef CONFIG_SRAM_VECTOR_TABLE
58+
/* Copy vector table to its location in SRAM */
59+
size_t vector_size = (size_t)_vector_end - (size_t)_vector_start;
60+
61+
z_early_memcpy(_sram_vector_start, _vector_start, vector_size);
62+
#endif
5363
SCB->VTOR = VECTOR_ADDRESS & VTOR_MASK;
5464
barrier_dsync_fence_full();
5565
barrier_isync_fence_full();
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2025 Silicon Laboratories Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/* Vector table is not necessarily at the start of the RAM region: in the case where Zephyr code
8+
* relocation is used, the vector table is placed after the relocated code.
9+
* Relocated code is always placed at the start of the RAM SECTION because of the hard-coded value
10+
* generated by "gen_relocate_app.py" in the file. It can create quite a big gap and lose about the
11+
* size of alignment in RAM space.
12+
*/
13+
14+
SECTION_PROLOGUE(.sram_vt,,)
15+
{
16+
/* Heritage of vector table alignment in flash (see vector_table.ld in arch/arm/core/) */
17+
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
18+
. = ALIGN( 1 << LOG2CEIL(4 * 64) );
19+
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
20+
. = ALIGN( 1 << LOG2CEIL(4 * 32) );
21+
#else
22+
#error "Unsupported architecture variant"
23+
#endif
24+
25+
. = ALIGN( 1 << LOG2CEIL(4 * (16 + CONFIG_NUM_IRQS)) );
26+
27+
_sram_vector_start = .;
28+
. += _vector_end - _vector_start;
29+
MPU_ALIGN(_sram_vector_size);
30+
_sram_vector_end = .;
31+
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
32+
_sram_vector_size = _sram_vector_end - _sram_vector_start;

arch/arm/core/mpu/arm_core_mpu.c

+17
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ extern char __ram_text_reloc_start[];
6363
extern char __ram_text_reloc_size[];
6464
#endif
6565

66+
#if defined(CONFIG_SRAM_VECTOR_TABLE)
67+
extern char _sram_vector_start[];
68+
extern char _sram_vector_size[];
69+
#endif
70+
6671
static const struct z_arm_mpu_partition static_regions[] = {
6772
#if defined(CONFIG_COVERAGE_GCOV) && defined(CONFIG_USERSPACE)
6873
{
@@ -106,6 +111,18 @@ static const struct z_arm_mpu_partition static_regions[] = {
106111
#endif
107112
},
108113
#endif /* CONFIG_CODE_DATA_RELOCATION_SRAM */
114+
#if defined(CONFIG_SRAM_VECTOR_TABLE)
115+
{
116+
/* Vector table in SRAM */
117+
.start = (uint32_t)&_sram_vector_start,
118+
.size = (uint32_t)&_sram_vector_size,
119+
#if defined(CONFIG_ARM_MPU_PXN) && defined(CONFIG_USERSPACE)
120+
.attr = K_MEM_PARTITION_P_R_U_RX,
121+
#else
122+
.attr = K_MEM_PARTITION_P_RO_U_RO,
123+
#endif
124+
},
125+
#endif /* CONFIG_SRAM_VECTOR_TABLE */
109126
#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_MPU_STACK_GUARD)
110127
/* Main stack MPU guard to detect overflow.
111128
* Note:

include/zephyr/linker/linker-defs.h

+6
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ extern char _vector_end[];
154154
extern char __vector_relay_table[];
155155
#endif
156156

157+
#ifdef CONFIG_SRAM_VECTOR_TABLE
158+
extern char _sram_vector_start[];
159+
extern char _sram_vector_end[];
160+
extern char _sram_vector_size[];
161+
#endif
162+
157163
#ifdef CONFIG_COVERAGE_GCOV
158164
extern char __gcov_bss_start[];
159165
extern char __gcov_bss_end[];

0 commit comments

Comments
 (0)