This repository has been archived by the owner on Jan 24, 2022. It is now read-only.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I'm opening this PR for discussion after today's meeting, I'm not really sure I want it to be merged but I thought it might be helpful to see what it could look like.
VTOR
The VTOR register offsets the vector table from the default 0x0000_0000 to a user-provided address, which is required if the user's vector table is not at the start of memory (for example, because a bootloader is present).
We occasionally get people asking for help because none of their interrupts are working and it turns out their bootloader does not set VTOR, so interrupts were not taking the right vector. Typically this is on platforms with manufacturer or vendor bootloaders rather than ones the user has installed, so they may not even be aware the bootloader is running.
It's a hard problem to debug and we could resolve it by having cortex-m-rt always write VTOR at startup, since it knows what the vector table address is. On ARMv6-M the VTOR register is optional, but if not present it must be RAZ/WI, which means it's safe to write to it even though it won't have any effect. On ARMv7-M and ARMv8-M VTOR is always implemented. In practice no Cortex-M0 core has VTOR, but many Cortex-M0+ cores do.
However, this write is useless for the vast majority of applications, using up flash space and boot time without any benefit. I think bootloaders should always be responsible for setting VTOR, and for example this document from Arm agrees, but clearly not all bootloader authors read it.
SP
This seems even rarer, but we have also had reports of debuggers resetting the chip by jumping to the reset vector without setting SP (the stack pointer, which is normally set to the first word of the vector table by the CPU at boot). I don't know what else those debuggers aren't setting, but from reports it sounds like setting SP is enough to get some basic functionality. This seems even more cursed (what else should we set, if we can't rely even on this?) but again is pretty easy to include if we wanted to. It's possible some bootloaders also fail to set SP before jumping to user code, although I don't recall hearing about that and it seems even more egregious. It would probably be helpful to have some more specific references to situations where this is necessary (see related issues).
Making this optional
At the moment the reset vector is pre-built and distributed as a binary, so there's no simple way to control this behaviour with feature gates (except for shipping a lot of different binaries, one for each architecture for each set of features). In the future when
global_asm!
becomes stable, it will probably be easy to feature-gate this functionality, and then it could be pretty easily enabled by users who need it and not others. Since many of the common use cases are for specific platforms which typically have a commonly-used HAL, those HALs could enable the feature for their users, so many users would not need to know about VTOR.So, one (good?) option is to wait for
global_asm!
and then revisit this.Before or after pre_init?
I've put the new instructions before
pre_init
so that user code callingpre_init
could choose to override them. I don't think it's likely any user code would need to run before these instructions: there's only 5 of them, so it's unlikely e.g. a watchdog would fire, and they don't access RAM, so it's unlikely RAM would need enabling, and they only set up the chip to a state it should normally be in after boot (well, VTOR is usually 0, but what we write should be equivalent).Related issues
These topics have been requested/discussed before:
And besides those issues, it comes up occasionally on the Matrix chat.