-
Notifications
You must be signed in to change notification settings - Fork 170
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
riscv-rt: Add mtvec-align features for the vector table alignment #259
base: master
Are you sure you want to change the base?
Conversation
The RISC-V Privileged Specification (version 1.11) for mtvec CSR says: > The value in the BASE field must always be aligned on a 4-byte boundary, and the MODE setting may > impose additional alignment constraints on the value in the BASE field. > [...] > An implementation may have different alignment constraints for different modes. In particular, > MODE=Vectored may have stricter alignment constraints than MODE=Direct. The Ibex Reference Guide for mtvec CSR says[^1]: > The trap-vector base address, always aligned to 256 bytes I'm not sure how we can parametrize mtvec alignment without cargo features, so this PR simply uses the stricter alignment. If a cargo feature is preferred, I can add `mtvec-align-256`. Note that multiple `mtvec-align-N` features are additive because the stricter one wins. [^1]: https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html#machine-trap-vector-base-address-mtvec
Truly, each interrupt controller has its own alignment requirements. For instance, the riscv-fast-interrupt specification (CLIC) specifies 4-byte alignment in CLINT mode and 64-byte alignment in CLIC mode. This has been an issue for us at https://github.com/soc-hub-fi/atalanta working on an Ibex-based CPU design as well, as not being able to parameterize this forces us to flag out & write the trap vector ourselves. I'd be in favor of a flag such as |
I think the best approach is using a linker symbol, such as _heap_size, for instance. By default, the symbol should be 4. PACs can overwrite it according to their particular needs. The linker script should check that the alignment is a power of 2, I guess (and greater than 4) |
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'm not sure how we can parametrize mtvec alignment without cargo features, so this PR simply uses the stricter alignment.
One possibility is to use const generics to parameterize the Mtvec::set_address
function directly, or offer another Mtvec::set_address_aligned<const N: usize>
.
Something like:
impl Mtvec {
pub fn set_address_aligned<const N: usize>(&mut self, address: usize) {
// check alignment does not violate spec requirements
const _: () = assert!(N >= 4);
const _: () = assert_eq!(N % 4, 0);
const MASK: usize = usize::MAX & !((1usize << N) - 1);
self.set_address(address & MASK);
}
}
The above could also obviously be made into a fallible try_set_address_aligned
, just used this one for brevity.
For the actual alignment of the trap vector function, I think @romancardenas approach is the right way to go.
It kind of scales thanks to the I used the values 4 (default), 16, 64, and 256, since 4, 64, and 256 are used, and 16 is the missing power of 2 with an even exponent.
I don't think this works?
This seems unrelated. This PR is about letting users configure the alignment of the vector table in |
Perhaps another option is using a procedural macro with environment variables (e.g., Line 44 in b391a48
PACs would set the mtvec alignment as part of their (I'm not against the approach of this PR, but I'd rather have something more configurable that would not potentially lead to more features etc.) |
THe Line 277 in b391a48
We can make a new version of this macro that also allows to define the alignment of the vector table and use it in |
The good thing about the |
This looks much better! I've updated the PR. |
Ah, I've seen this too late. I'll update the PR to reuse it. |
Actually, I don't think we can reuse it without creating a separate library for proc-macro helpers (or possibly making |
Good (and delicate) question. Creating a new I personally don't want Any thoughts/suggestions/concerns? |
A proc-macro cannot depend on another proc-macro as a library. So it would only be I updated the PR. |
Line 380 in cfb7128
Line 386 in cfb7128
They are only necessary when the I think the way to go is:
|
Actually, the first action point is not that immediate. In other words ,the macro should only add feature gates when this condition is met: Line 399 in cfb7128
|
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.
Minor nit, removes the need for a mutable align
variable.
I updated the PR accordingly (also gating the |
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.
LGTM! I added a minor documentation suggestion.
I think we should add a directive toriscv-rt
's build script to re-compile the crate if RISCV_MTVEC_ALIGN
changes its value, right after this:
Line 49 in b391a48
println!("cargo:rerun-if-env-changed=RISCV_RT_LLVM_ARCH_PATCH"); |
We can opt-out this check if the v-trap
vector is disabled (no vector table at all) or if the no-interrupts
feature is enabled (i.e., a PAC is implementing its custom core interrupt vector).
PACs with custom core interrupt vectors (i.e., those that use riscv::pac_enum(CoreInterruptNumber)
must also include a similar directive to their build.rs
. We can also include this in the docs.
riscv-rt/src/interrupts.rs
Outdated
@@ -14,64 +14,7 @@ | |||
//! code to adapt for the target needs. In this case, you may need to opt out this module. |
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.
Could you add a few lines of documentation for vectored mode about the RISCV_MTVEC_ALIGN
environment variable and why it is necessary? You should also mention that, in most of the cases, this environment variable must be handled by the PAC crate, not users directly
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'm not good at documentation, so I attempted something. Feel free to suggest an alternative.
The RISC-V Privileged Specification (version 1.11) for mtvec CSR says:
The Ibex Reference Guide for mtvec CSR says1:
Other implementations have yet other alignment constraints (see #259 (comment)).
This PR introduces the
mtvec-align-{16,64,256}
cargo features to let users choose the alignment constraint appropriate to their implementation.Footnotes
https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html#machine-trap-vector-base-address-mtvec ↩