-
-
Notifications
You must be signed in to change notification settings - Fork 17
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
Is there a mechanism to emulate only CAS operations? #123
Comments
Is this an officially recognized bug? If not, it is not very clear whether it is a bug in the chip or a bug in your environment. For example, I have seen several cases where there is a bug in the linker script, resulting in misalignment (mvdnes/spin-rs#154 (comment), rust-lang/rust#86693, etc.). Atomic instructions require proper alignment, so I would not be surprised if some atomic instructions caused exceptions in such cases. Could you check to see if the pointer is aligned correctly? If this is really a bug in the chip, I can consider providing a way to work around it in some way. |
It is not a bug, it is a (very annoying) feature. The microcontroller datasheet explicitly mentions that it supports atomic operations except CAS, which raise a LoadFault/StoreFault exception. |
Thanks for the clarification.
As far as I know, at least both LLVM and GCC treat RISC-V with the A extension as if all instructions in the A extension are available (godbolt). So, compiling as riscv32imac for this CPU should usually be considered unsound because it is impossible to safely run a binary that is compiled as riscv32imac, even though it claims to be riscv32imac (unless you can ensure that the instructions causing the problem are not used by auditing the standard library, all dependencies, and the C library to which it is linked). So, we should compile as riscv32imc for this CPU, which supports some instructions of the A extension.
RISC-V A extension does not actually have CAS instructions and has LR/SC and AMO (CAS is implemented by using LR/SC), but the actual situation here is more complicated:
Considering the above, the implementation would be in the form of:
Any thoughts? |
Sorry for not being precise. The instructions that are missing in E310x are LR and SC. I agree with your approach:
|
Filed #124 to implement this. |
#124 has been published in 1.5.0. |
This feature seems to have been ratified as Zaamo a few month ago.
I plan to make force-amo feature available via |
Support for Zaamo feature (and various improvements) are published in 1.8.0. |
Hi @taiki-e I have been playing around with the |
zaamo only covers some atomic operations. so there is no way to support this in core::sync::atomic (which supports load store only or all atomic operations). (a, zalrsc, or zacas is needed) portable-atomic unsafe-assume-single-core can support this because it can use alternative implementation that compatible with zaamo for operations that not covered by zaamo. |
I thought core would support all atomic operations covered by zaamo and leave the others undefined. In this way, portable-atomic would only be needed for non-zaamo operations. I guess this is not possible (yet), but future versions of Rust might implement it. |
I think it's relatively easy in portable-atomic with unsafe-assume-single-core/critical-section disabled, but I think it's (technically possible but) much harder in core. In addition to the fact that it basically always requires -Zbuild-std, in RISC-V without a extension there are various patterns for atomic support based on target features: the operations that zaamo can support depend on its width (not only its kind), it also depends on the presence or absence of zabha or zacas (or zalrsc). |
Now I'm trying to compile a project for a Zaamo target with portable-atomic and using In [dependencies]
# portable-atomic = { version = "1.8", default-features = false, features = ["unsafe-assume-single-core", "force-amo"] }
portable-atomic = { version = "1.8", default-features = false } I compile my toy project with: RUSTFLAGS="-C target-feature=+zaamo" cargo build --target riscv32imc-unknown-none-elf But compilation fails:
How can I use the new Zaamo support properly? PS: the compilation also raises a warning about the Zaamo feature:
Sounds like Rust is still not 100% compatible with this target feature, even in Nightly. |
unsafe-assume-single-core + zaamo is supported, but no unsafe-assume-single-core + zaamo is not yet supported (internally supported but not exposed). That said, it should be relatively easy to support as mentioned above by adjusting the cfg. UPDATE: will be supported by #185 |
I'm working with the SparkFun RED-V RedBoard, which contains an E310g002 RISC-V microcontroller. This microcontroller is supposed to support atomic operations, and therefore I can compile projects targeting
riscv32imac-unknown-none-elf
. However, this microcontroller always raises an exception for CAS instructions (i.e., in practice onlyamoxxx
instructions are allowed).Is there any mechanism to configure
portable-atomic
to only emulate CAS instructions while natively executing the other atomic operations? Or am I doomed to compiling forriscv32imc-unknown-none-elf
and forgetting about native atomic support?Thanks in advance!
The text was updated successfully, but these errors were encountered: