New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cortex-M cores: pendSV handler need to modify the auto stacked XPSR value to clear LDM/STM progress #3842

Open
RockySong opened this Issue Jun 5, 2018 · 4 comments

Comments

Projects
None yet
3 participants
@RockySong

RockySong commented Jun 5, 2018

If pendSV is serviced during an LDM/STM instruction, which is interruptible and uses XPSR "ICI/IT" bitfield to save load/store progress, it may causes INVSTATE type hardfault when CPU finally returns to nlr_jump().
This is because on exception return, the Cortex-M core is expecting to resume LDM/STM when it sees the valid progress information in unstacked ICI/IT field of XPSR register
However, pendSV returns to nlr_jump(). So there is no LDM/STM instruction and the Cortex-M CPU generates hardfault with INVSTATE.
My workaround, insert below instructions in the beginning of PendSV_Handler:
"mov r2, #0x01000000 \n"
"str r2, [sp, #28] \n" // modify stacked XPSR to make sure possible LDM/STM progress is cleared

So when nlr_jump() is entered, it always has XPSR unstacked to a "clean" state.

Note: This may have something to do with the INVSTATE hardfault found in openMV project.

@iabdalkader

This comment has been minimized.

Show comment
Hide comment
@iabdalkader

iabdalkader Jun 5, 2018

Contributor

Is this going to break multithreading ? BTW another solution is to disable interruption of multicycle instructions:

DISMCYCINT : Disables interruption of multi-cycle instructions. This increases the interrupt latency of the processor because load/store and multiply/divide operations complete before interrupt stacking occurs

I'm almost sure I tried this before but didn't work (maybe I didn't upload the right fw image when testing)

Contributor

iabdalkader commented Jun 5, 2018

Is this going to break multithreading ? BTW another solution is to disable interruption of multicycle instructions:

DISMCYCINT : Disables interruption of multi-cycle instructions. This increases the interrupt latency of the processor because load/store and multiply/divide operations complete before interrupt stacking occurs

I'm almost sure I tried this before but didn't work (maybe I didn't upload the right fw image when testing)

@RockySong

This comment has been minimized.

Show comment
Hide comment
@RockySong

RockySong Jun 6, 2018

I did captured real case that LDM/STM is interrupted and ICI field saved its progress. I think DISMCYCINT should also work as it makes LDM/STM can't be interrupted, but only if the core implemented that bit field. From R1P1 Cortex-M7's technical reference manual, bit0 of ACTLR is reserved, maybe this feature is not implemented on Cortex-M7 up to R1P1 revision.

RockySong commented Jun 6, 2018

I did captured real case that LDM/STM is interrupted and ICI field saved its progress. I think DISMCYCINT should also work as it makes LDM/STM can't be interrupted, but only if the core implemented that bit field. From R1P1 Cortex-M7's technical reference manual, bit0 of ACTLR is reserved, maybe this feature is not implemented on Cortex-M7 up to R1P1 revision.

@iabdalkader

This comment has been minimized.

Show comment
Hide comment
@iabdalkader

iabdalkader Jun 9, 2018

Contributor

@dpgeorge Any comment on this issue ?

Contributor

iabdalkader commented Jun 9, 2018

@dpgeorge Any comment on this issue ?

@dpgeorge

This comment has been minimized.

Show comment
Hide comment
@dpgeorge

dpgeorge Jun 13, 2018

Contributor

modify stacked XPSR to make sure possible LDM/STM progress is cleared

This sounds like it needs to be done. But, as mentioned above, we'd need to check how it interacts with threading and make sure that still works as before.

The only case where this can happen is if a ctrl-C comes in (via USB or UART) a second time and triggers the pendsv NLR jump. An alternative solution/workaround is to simple disable this behaviour and only allow the first ctrl-C, which does a "soft break" because the VM must explicitly check for the pending exception and then raise it itself.

Contributor

dpgeorge commented Jun 13, 2018

modify stacked XPSR to make sure possible LDM/STM progress is cleared

This sounds like it needs to be done. But, as mentioned above, we'd need to check how it interacts with threading and make sure that still works as before.

The only case where this can happen is if a ctrl-C comes in (via USB or UART) a second time and triggers the pendsv NLR jump. An alternative solution/workaround is to simple disable this behaviour and only allow the first ctrl-C, which does a "soft break" because the VM must explicitly check for the pending exception and then raise it itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment