cancel
Showing results for 
Search instead for 
Did you mean: 

Confused by Run* state of STMH7 and the startup code that jumps to ExitRun0Mode

Torsten_Robitzki
Associate II

According to RM0433 Rev 8:

The Run* mode is entered after a POR reset and a wakeup from Standby. In Run*
mode, the performance is limited and the system supply configuration shall be
programmed in PWR control register 3 (PWR_CR3). The system enters Run
mode only when the ACTVOSRDY bit in PWR control status register 1
(PWR_CSR1) is set to 1.

and

As long as ACTVOSRDY indicates that voltage levels are invalid, the system is in
Run* mode, write accesses to the RAMs are not permitted and VOS shall not be
changed.

Now, the startup code first jumps (bl ExitRun0Mode) to the C function `ExitRun0Mode()` which probably might involves writes to stack.

Is this construct (calling a C function from ASM) just relying on the compiler not touching the stack or am I'm reading the docs wrongly?

best regards

Torsten

Bootloader off-the-shelf
1 ACCEPTED SOLUTION

Accepted Solutions
Saket_Om
ST Employee

Hello @Torsten_Robitzki 

Thank you for bringing this issue to our attention.

I reported this internally.

Internal ticket number: 222757 (This is an internal tracking number and is not accessible or usable by customers).

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

View solution in original post

11 REPLIES 11
KnarfB
Super User

The bl instruction places the return address in the lr register. If ExitRun0Mode is a leaf function (does not call other functions), there is no need for the compiler to save lr on the stack, but just to generate a bx lr instruction for return. The current implementation is indeed a leaf function that just sets PWR->CR3 and waits for the PWR_CSR1_ACTVOSRDY condition. No need to touch the stack.

But, interestingly, when compiled in Debug configuration (-O0 optimization), it will use the stack for saving r7 (callers frame pointer):

08000434 <ExitRun0Mode>:
 8000434:	b480      	push	{r7}
 8000436:	af00      	add	r7, sp, #0
 8000438:	4b09      	ldr	r3, [pc, #36]	@ (8000460 <ExitRun0Mode+0x2c>)
 800043a:	68db      	ldr	r3, [r3, #12]
 800043c:	4a08      	ldr	r2, [pc, #32]	@ (8000460 <ExitRun0Mode+0x2c>)
 800043e:	f023 0302 	bic.w	r3, r3, #2
 8000442:	60d3      	str	r3, [r2, #12]
 8000444:	bf00      	nop
 8000446:	4b06      	ldr	r3, [pc, #24]	@ (8000460 <ExitRun0Mode+0x2c>)
 8000448:	685b      	ldr	r3, [r3, #4]
 800044a:	f403 5300 	and.w	r3, r3, #8192	@ 0x2000
 800044e:	2b00      	cmp	r3, #0
 8000450:	d0f9      	beq.n	8000446 <ExitRun0Mode+0x12>
 8000452:	bf00      	nop
 8000454:	bf00      	nop
 8000456:	46bd      	mov	sp, r7
 8000458:	f85d 7b04 	ldr.w	r7, [sp], #4
 800045c:	4770      	bx	lr
 800045e:	bf00      	nop
 8000460:	58024800 	.word	0x58024800

This is pointless as the caller is the startup code that does not use r7 at that time.

Hmm.

hth

KnarfB

I think it's not surprising, that the compiler generate sub-optimal code without any optimization.

Do you think, I read the documentation correctly and the startup code is broken?

Bootloader off-the-shelf

No no surprise, but it looks like you found a bug.

I don't know the internals, but the cited RM explicitely forbids such access.

Maybe @mƎALLEm can help here.

As a quick workaround, you may add #pragma GCC optimize("O3") to the source code.

hth

KnarfB

 

Hello all,

@Torsten_Robitzki your interpretation is correct. That's why ExitRun0Mode() has been introduced and implemented, I think starting from the CubeH7 package V1.7.0 (if I'm not mistaken).

@KnarfB that's and interesting finding. When in level -O3, do you have the access to the stack?

@Saket_Om : could you please check? at this stage the RAM memory should not be accessible.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

-Os -O1 and better are fine:

080006e8 <ExitRun0Mode>:
 80006e8:	4b04      	ldr	r3, [pc, #16]	@ (80006fc <ExitRun0Mode+0x14>)
 80006ea:	68da      	ldr	r2, [r3, #12]
 80006ec:	f042 0202 	orr.w	r2, r2, #2
 80006f0:	60da      	str	r2, [r3, #12]
 80006f2:	685a      	ldr	r2, [r3, #4]
 80006f4:	0492      	lsls	r2, r2, #18
 80006f6:	d5fc      	bpl.n	80006f2 <ExitRun0Mode+0xa>
 80006f8:	4770      	bx	lr
 80006fa:	bf00      	nop
 80006fc:	58024800 	.word	0x58024800

 But there is no guarantee for future/alternate toolchains.

hth

KnarfB


08000434 <ExitRun0Mode>:
 8000434:	b480      	push	{r7}
 8000436:	af00      	add	r7, sp, #0
 8000438:	4b09      	ldr	r3, [pc, #36]	@ (8000460 <ExitRun0Mode+0x2c>)
 800043a:	68db      	ldr	r3, [r3, #12]
 800043c:	4a08      	ldr	r2, [pc, #32]	@ (8000460 <ExitRun0Mode+0x2c>)
 800043e:	f023 0302 	bic.w	r3, r3, #2
 8000442:	60d3      	str	r3, [r2, #12]
 8000444:	bf00      	nop
 8000446:	4b06      	ldr	r3, [pc, #24]	@ (8000460 <ExitRun0Mode+0x2c>)
 8000448:	685b      	ldr	r3, [r3, #4]
 800044a:	f403 5300 	and.w	r3, r3, #8192	@ 0x2000
 800044e:	2b00      	cmp	r3, #0
 8000450:	d0f9      	beq.n	8000446 <ExitRun0Mode+0x12>
 8000452:	bf00      	nop
 8000454:	bf00      	nop
 8000456:	46bd      	mov	sp, r7
 8000458:	f85d 7b04 	ldr.w	r7, [sp], #4
 800045c:	4770      	bx	lr
 800045e:	bf00      	nop
 8000460:	58024800 	.word	0x58024800

That assembly code was generated by CubeIDE?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
STM32CubeIDE for VS Code 3.6.4 using
"name": "gnu-tools-for-stm32",
"version": "13.3.1+st.9"

Hi @KnarfB ,

I may found a solution to that unwanted access to the stack by replacing:

void ExitRun0Mode(void)

by

void __attribute__((naked)) ExitRun0Mode(void)

But this is applicable only for GCC.

With the "naked" attribute: no SP is called:

mALLEm_3-1764337510982.png

without "naked" attribute: SP is called:

mALLEm_2-1764337452906.png

Could you test from your side?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om
ST Employee

Hello @Torsten_Robitzki 

Thank you for bringing this issue to our attention.

I reported this internally.

Internal ticket number: 222757 (This is an internal tracking number and is not accessible or usable by customers).

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om