diff --git a/core/embed/projects/firmware/main.c b/core/embed/projects/firmware/main.c index 3f2094ea61..6561ad66fb 100644 --- a/core/embed/projects/firmware/main.c +++ b/core/embed/projects/firmware/main.c @@ -41,6 +41,10 @@ #include "zkp_context.h" #endif +// symbols defined in the linker script +extern uint8_t _stack_section_start; +extern uint8_t _stack_section_end; + int main(uint32_t cmd, void *arg) { if (cmd == 1) { systask_postmortem_t *info = (systask_postmortem_t *)arg; @@ -57,8 +61,9 @@ int main(uint32_t cmd, void *arg) { printf("CORE: Preparing stack\n"); // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. - mp_stack_set_top(&_estack); - mp_stack_set_limit((char *)&_estack - (char *)&_sstack - 1024); + mp_stack_set_top(&_stack_section_end); + mp_stack_set_limit((char *)&_stack_section_end - + (char *)&_stack_section_start - 1024); #if MICROPY_ENABLE_PYSTACK static mp_obj_t pystack[1024]; diff --git a/core/embed/sys/linker/stm32f4/boardloader.ld b/core/embed/sys/linker/stm32f4/boardloader.ld index fbdaf5ed8c..a12041c2a3 100644 --- a/core/embed/sys/linker/stm32f4/boardloader.ld +++ b/core/embed/sys/linker/stm32f4/boardloader.ld @@ -11,9 +11,8 @@ MEMORY { AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32f4/bootloader.ld b/core/embed/sys/linker/stm32f4/bootloader.ld index 41b96dae5c..5b3b66e619 100644 --- a/core/embed/sys/linker/stm32f4/bootloader.ld +++ b/core/embed/sys/linker/stm32f4/bootloader.ld @@ -11,9 +11,8 @@ MEMORY { AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32f4/firmware.ld b/core/embed/sys/linker/stm32f4/firmware.ld index d2c909ada7..cf27f7f442 100644 --- a/core/embed/sys/linker/stm32f4/firmware.ld +++ b/core/embed/sys/linker/stm32f4/firmware.ld @@ -9,10 +9,9 @@ MEMORY { AUX2_RAM (wal) : ORIGIN = K_AUX2_RAM_START, LENGTH = K_AUX2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; -_stack_size = SIZEOF(.stack); +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); +_stack_section_size = SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32f4/kernel.ld b/core/embed/sys/linker/stm32f4/kernel.ld index dd87d0e1ea..001a01f3a2 100644 --- a/core/embed/sys/linker/stm32f4/kernel.ld +++ b/core/embed/sys/linker/stm32f4/kernel.ld @@ -11,9 +11,8 @@ MEMORY { DMABUF (wal) : ORIGIN = DMABUF_RAM_START, LENGTH = DMABUF_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32f4/prodtest.ld b/core/embed/sys/linker/stm32f4/prodtest.ld index 0a1d4598f7..ecf0a94ed4 100644 --- a/core/embed/sys/linker/stm32f4/prodtest.ld +++ b/core/embed/sys/linker/stm32f4/prodtest.ld @@ -11,9 +11,8 @@ MEMORY { AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u58/boardloader.ld b/core/embed/sys/linker/stm32u58/boardloader.ld index e048d11bd0..df21f7c8cb 100644 --- a/core/embed/sys/linker/stm32u58/boardloader.ld +++ b/core/embed/sys/linker/stm32u58/boardloader.ld @@ -14,9 +14,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u58/bootloader.ld b/core/embed/sys/linker/stm32u58/bootloader.ld index b2e4bb27a3..d140114c41 100644 --- a/core/embed/sys/linker/stm32u58/bootloader.ld +++ b/core/embed/sys/linker/stm32u58/bootloader.ld @@ -13,9 +13,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u58/firmware.ld b/core/embed/sys/linker/stm32u58/firmware.ld index 6c09d9364b..212ad22bff 100644 --- a/core/embed/sys/linker/stm32u58/firmware.ld +++ b/core/embed/sys/linker/stm32u58/firmware.ld @@ -8,10 +8,9 @@ MEMORY { AUX2_RAM (wal) : ORIGIN = AUX2_RAM_START, LENGTH = AUX2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; -_stack_size = SIZEOF(.stack); +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); +_stack_section_size = SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u58/kernel.ld b/core/embed/sys/linker/stm32u58/kernel.ld index 88cc18beda..4a0fd08e7c 100644 --- a/core/embed/sys/linker/stm32u58/kernel.ld +++ b/core/embed/sys/linker/stm32u58/kernel.ld @@ -12,9 +12,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); ustack_base = ADDR(.udata) + 512; _sustack = ADDR(.udata) + 256; diff --git a/core/embed/sys/linker/stm32u58/prodtest.ld b/core/embed/sys/linker/stm32u58/prodtest.ld index 33e1479da1..985e71a706 100644 --- a/core/embed/sys/linker/stm32u58/prodtest.ld +++ b/core/embed/sys/linker/stm32u58/prodtest.ld @@ -13,9 +13,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u5g/boardloader.ld b/core/embed/sys/linker/stm32u5g/boardloader.ld index f9ec3c1610..ce6be59f39 100644 --- a/core/embed/sys/linker/stm32u5g/boardloader.ld +++ b/core/embed/sys/linker/stm32u5g/boardloader.ld @@ -14,9 +14,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u5g/bootloader.ld b/core/embed/sys/linker/stm32u5g/bootloader.ld index 75bfeb458e..aafcd5ea0b 100644 --- a/core/embed/sys/linker/stm32u5g/bootloader.ld +++ b/core/embed/sys/linker/stm32u5g/bootloader.ld @@ -13,9 +13,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u5g/firmware.ld b/core/embed/sys/linker/stm32u5g/firmware.ld index 499be37ac9..a806612422 100644 --- a/core/embed/sys/linker/stm32u5g/firmware.ld +++ b/core/embed/sys/linker/stm32u5g/firmware.ld @@ -7,10 +7,9 @@ MEMORY { AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; -_stack_size = SIZEOF(.stack); +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); +_stack_section_size = SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/linker/stm32u5g/kernel.ld b/core/embed/sys/linker/stm32u5g/kernel.ld index 6ed802c874..924413bd27 100644 --- a/core/embed/sys/linker/stm32u5g/kernel.ld +++ b/core/embed/sys/linker/stm32u5g/kernel.ld @@ -12,9 +12,9 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); + ustack_base = ADDR(.udata) + 512; _sustack = ADDR(.udata) + 256; diff --git a/core/embed/sys/linker/stm32u5g/prodtest.ld b/core/embed/sys/linker/stm32u5g/prodtest.ld index eb721427ed..17190dcfcf 100644 --- a/core/embed/sys/linker/stm32u5g/prodtest.ld +++ b/core/embed/sys/linker/stm32u5g/prodtest.ld @@ -13,9 +13,8 @@ MEMORY { FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } -main_stack_base = ADDR(.stack) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ -_sstack = ADDR(.stack); -_estack = main_stack_base; +_stack_section_start = ADDR(.stack); +_stack_section_end = ADDR(.stack) + SIZEOF(.stack); /* used by the startup code to populate variables used by the C code */ data_lma = LOADADDR(.data); diff --git a/core/embed/sys/startup/stm32f4/vectortable.S b/core/embed/sys/startup/stm32f4/vectortable.S index 89f5dcb7b0..1dd7c4082c 100644 --- a/core/embed/sys/startup/stm32f4/vectortable.S +++ b/core/embed/sys/startup/stm32f4/vectortable.S @@ -20,7 +20,7 @@ default_handler: // Section B1.5 - ARMv7-M Architecture Reference Manual .section .vector_table, "a" vector_table: - .word main_stack_base // defined in linker script + .word _stack_section_end // defined in linker script add_handler reset_handler add_handler NMI_Handler add_handler HardFault_Handler @@ -132,8 +132,8 @@ vector_table: .section .vector_table, "a" vector_table: - .word _sstack - .word _stack_size + .word _stack_section_start + .word _stack_section_size .word reset_handler diff --git a/core/embed/sys/startup/stm32u5/startup_stage_0.s b/core/embed/sys/startup/stm32u5/startup_stage_0.s index 8473911bdc..7c27989319 100644 --- a/core/embed/sys/startup/stm32u5/startup_stage_0.s +++ b/core/embed/sys/startup/stm32u5/startup_stage_0.s @@ -6,7 +6,7 @@ .type reset_handler, STT_FUNC reset_handler: // set the stack protection - ldr r0, =_sstack + ldr r0, =_stack_section_start add r0, r0, #128 // safety margin for the exception frame msr MSPLIM, r0 diff --git a/core/embed/sys/startup/stm32u5/startup_stage_1.s b/core/embed/sys/startup/stm32u5/startup_stage_1.s index b1a785a8a5..e8e0ed37e4 100644 --- a/core/embed/sys/startup/stm32u5/startup_stage_1.s +++ b/core/embed/sys/startup/stm32u5/startup_stage_1.s @@ -6,7 +6,7 @@ .type reset_handler, STT_FUNC reset_handler: // set the stack protection - ldr r0, =_sstack + ldr r0, =_stack_section_start add r0, r0, #128 // safety margin for the exception frame msr MSPLIM, r0 diff --git a/core/embed/sys/startup/stm32u5/startup_stage_2.s b/core/embed/sys/startup/stm32u5/startup_stage_2.s index 2130afe463..20355ff8ed 100644 --- a/core/embed/sys/startup/stm32u5/startup_stage_2.s +++ b/core/embed/sys/startup/stm32u5/startup_stage_2.s @@ -6,7 +6,7 @@ .type reset_handler, STT_FUNC reset_handler: // set the stack protection - ldr r0, =_sstack + ldr r0, =_stack_section_start add r0, r0, #128 // safety margin for the exception frame msr MSPLIM, r0 diff --git a/core/embed/sys/startup/stm32u5/vectortable.S b/core/embed/sys/startup/stm32u5/vectortable.S index 497ed72b8f..a7059829a6 100644 --- a/core/embed/sys/startup/stm32u5/vectortable.S +++ b/core/embed/sys/startup/stm32u5/vectortable.S @@ -20,7 +20,7 @@ default_handler: // Section B1.5 - ARMv7-M Architecture Reference Manual .section .vector_table, "a" vector_table: - .word main_stack_base // defined in linker script + .word _stack_section_end // defined in linker script add_handler reset_handler add_handler NMI_Handler add_handler HardFault_Handler @@ -180,8 +180,8 @@ vector_table: .section .vector_table, "a" vector_table: - .word _sstack - .word _stack_size + .word _stack_section_start + .word _stack_section_size .word reset_handler #endif diff --git a/core/embed/sys/task/stm32/systask.c b/core/embed/sys/task/stm32/systask.c index 12d0ec699e..2c459b67e6 100644 --- a/core/embed/sys/task/stm32/systask.c +++ b/core/embed/sys/task/stm32/systask.c @@ -55,8 +55,8 @@ typedef struct { } systask_scheduler_t; // Kernel stack base pointer defined in linker script -extern uint8_t _sstack; -extern uint8_t _estack; +extern uint8_t _stack_section_start; +extern uint8_t _stack_section_end; // Global task manager state static systask_scheduler_t g_systask_scheduler = { @@ -65,7 +65,7 @@ static systask_scheduler_t g_systask_scheduler = { .active_task = &g_systask_scheduler.kernel_task, .waiting_task = &g_systask_scheduler.kernel_task, .kernel_task = { - .sp_lim = (uint32_t)&_sstack, + .sp_lim = (uint32_t)&_stack_section_start, }}; void systask_scheduler_init(systask_error_handler_t error_handler) { @@ -77,7 +77,7 @@ void systask_scheduler_init(systask_error_handler_t error_handler) { scheduler->active_task = &scheduler->kernel_task; scheduler->waiting_task = scheduler->active_task; - scheduler->kernel_task.sp_lim = (uint32_t)&_sstack; + scheduler->kernel_task.sp_lim = (uint32_t)&_stack_section_start; // SVCall priority should be the lowest since it is // generally a blocking operation @@ -541,7 +541,7 @@ __attribute__((naked, no_stack_protector)) void HardFault_Handler(void) { "MOV R0, #1 \n" // R0 = 1 (Privileged) "B systask_exit_fault \n" // Exit task with fault : - : [estack] "i"(&_estack) + : [estack] "i"(&_stack_section_end) : "memory"); } @@ -565,7 +565,9 @@ __attribute__((naked, no_stack_protector)) void MemManage_Handler(void) { #endif "B systask_exit_fault \n" // Exit task with fault : - : [estack] "i"(&_estack), [sstack] "i"((uint32_t)&_sstack + 256) + : [estack] "i"(&_stack_section_end), [sstack] "i"( + (uint32_t)&_stack_section_start + + 256) : "memory"); } @@ -600,7 +602,7 @@ __attribute__((naked, no_stack_protector)) void UsageFault_Handler(void) { "MOV R0, #1 \n" // R0 = 1 (Privileged) "B systask_exit_fault \n" // Exit task with fault : - : [estack] "i"(&_estack) + : [estack] "i"(&_stack_section_end) : "memory"); } diff --git a/core/embed/sys/task/stm32/system.c b/core/embed/sys/task/stm32/system.c index d21866b848..4fbb91c0c9 100644 --- a/core/embed/sys/task/stm32/system.c +++ b/core/embed/sys/task/stm32/system.c @@ -41,6 +41,10 @@ #ifdef KERNEL_MODE +// Kernel stack base pointer defined in linker script +extern uint8_t _stack_section_start; +extern uint8_t _stack_section_end; + void system_init(systask_error_handler_t error_handler) { #if defined(TREZOR_MODEL_T2T1) && (!defined(BOARDLOADER)) // Early boardloader versions on Model T initialized the CPU clock to 168MHz. @@ -198,10 +202,10 @@ __attribute((naked, no_stack_protector)) void system_emergency_rescue( // Setup new stack // -------------------------------------------------------------- - "LDR R0, =_estack \n" // Setup new stack + "LDR R0, =%[estack] \n" // Setup new stack "MSR MSP, R0 \n" // Set MSP #if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) - "LDR R0, =_sstack \n" + "LDR R0, =%[sstack] \n" "ADD R0, R0, #256 \n" // Add safety margin "MSR MSPLIM, R0 \n" // Set MSPLIM #endif @@ -331,7 +335,8 @@ __attribute((naked, no_stack_protector)) void system_emergency_rescue( "BX LR \n" : // no output : [PMINFO_SIZE] "i"(sizeof(systask_postmortem_t)), - [STK_GUARD] "i"(&__stack_chk_guard) + [STK_GUARD] "i"(&__stack_chk_guard), [estack] "i"(&_stack_section_end), + [sstack] "i"((uint32_t)&_stack_section_start) : // no clobber ); }