-
Notifications
You must be signed in to change notification settings - Fork 187
riscv-rt: Preserve a0-a2 in startup only when startup functions are expected
#326
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
Conversation
riscv-rt/CHANGELOG.md
Outdated
|
|
||
| - Removed usage of the stack before `_start_rust`. This was unsound, as in the `.init` | ||
| section RAM is still uninitialized. | ||
| - Now, `a1` and `a2` are **not** preserved during the startup process. New documentation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think clobbering a1 at startup is a good idea. For instance, if riscv-rt code is being run as a kernel-like SBI payload, a1 stores the address location of the DeviceTree.
I think this is just a convention, so not a hard requirement. I'm not aware of any conventions requiring preservation of the a2 register.
Edit: after reviewing the startup code, it doesn't look like a1 is clobbered, unless implicitly by a function return. If that's the case, it may be worth storing it in one of the higher numbered a* registers, since we don't have other s* or t* registers available in RV32E contexts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In RVI, we can store a0-a2 in s1-s3. We can even use s0-s2 and initialize the frame pointer later, as proposed in the other PR. But im RVE we only have s0-s1, so we need to use a4 and/or a5. Using aX registers for preservation is not part of the ABI, so we must document it to avoid misuse.
Here, while we are not preserving a1-a2, we clearly specify in the documentation for _mp_hook and __preinit that these registers are reserved and must not be used.
Let me know what you prefer and I'll try it.
Note that registers can get dirty only when using _mp_hook and __pre_init, which is not always the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can even use s0-s2 and initialize the frame pointer later, as proposed in the other PR. But im RVE we only have s0-s1, so we need to use a4 and/or a5. Using aX registers for preservation is not part of the ABI, so we must document it to avoid misuse.
I was wondering about the framepointer init, since that frees up s0 for storing a0, and s1 for a1. Which would still leave a2 to maybe be preserved in higher-number a* registers, which may not be necessary if we just make note of a2 being reserved, like you mention.
In my opinion, as long as we hold the invariants in our default _mp_hook and __preinit impls, i.e. not clobbering reserved registers, we should be fine with documentation for users that want custom implementations.
Let me know what you prefer and I'll try it.
If the framepointer late-init is workable, that sounds like the simplest solution to me. If it ends up being to complicated, maybe we store in stack after doing the RAM init (.bss clearing), and store on the stack like in your other PR?
654fcc4 to
df61545
Compare
|
@hegza can you check this PR too? Which one do you prefer? |
riscv-rt: Preserve only a0 in startupriscv-rt: Preserve a0-a2 in startup only when startup functions are expected
|
Still compiles on RVE. I have no preference whatsoever, both work. One nice thing about this is that the only implementation that gets a bit of unreasonable extra complexity is the mythical multicore RVE. I'm pretty sure that if anyone's going to build one anytime soon it's going to be our lab 😅 |
Alternative to #325 . This is simpler, as it reduces register preservation to the minimum. New documentation specifies that registers
a1anda2must not be modified during_mp_hookand__pre_init.I personally prefer this over #325, but let me know your opinion.
Closes #315