-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
natmod: Add RV64 native modules support. #18428
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
base: master
Are you sure you want to change the base?
Conversation
This commit lets the persistent code loader to load natmods even if
there is no emitter being present for the platform in use.
Native modules loading does not need an emitter being available, and
until the addition of RV64 to the architectures list there was no
platform without an associated native code emitter. This also means
that native module loading for RV64 could not happen until a matching
emitter is written for it.
Still, that can be worked around by adding a new configuration define
("MICROPY_LOAD_NATIVE_MODULES") to short-circuit the define checks that
bring in native code loading to also be enabled if natmod support is
explicitly enabled. The changes are a bit all over the place but this
seems to make it work for RV64.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit fixes the implementation of the R_RISCV_GOT32_PCREL RISC-V relocation type when linking native modules for RV32IMC. The previous implementation of R_RISCV_GOT32_PCREL ended up not being fully updated when the initial RV32 support was checked in. Said relocation was not emitted in the sample natmods that ship with the MicroPython source tree, and since they're the testbed for CI jobs that should check RV32 natmod support, this was not caught. On the other hand, nobody raised an issue about this problem yet, so hopefully it didn't cause much trouble. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
|
Code size report: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #18428 +/- ##
==========================================
+ Coverage 98.38% 98.41% +0.03%
==========================================
Files 171 171
Lines 22294 22965 +671
==========================================
+ Hits 21933 22602 +669
- Misses 361 363 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This commit adds the ability to compile native modules for the RV64 platform, using "rv64imc" as its architecture name (eg. "make ARCH=rv64imc" should build a RV64 natmod). The rest of 64-bits relocations needed to build a native module are now implemented, and all sample native modules build without errors and warnings. The same Picolibc caveats on RV32 also apply on RV64, thus the documentation was updated accordingly. RV64 are also built as part of the CI process, but not yet executed as the QEMU port is not yet able to load and run native modules. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit extends the natmod test runner to also recognise the RV64 architecture when reported by the feature check script. However, said script bases its findings on the output of "sys.implementation._mpy", and the platform identifier reported in that tuple depends on whether a native emitter is present or not. Since natmod loading has been made independent of the presence of a native emitter, RV64 needs a platform-specific definition check to provide the correct value to "MPY_FEATURE_ARCH", and thus let the test runner accept that architecture. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit lets the QEMU port's VIRT_RV64 board load and run native modules, via the appropriate configuration changes in mpconfigport.h. Now the CI test job for the QEMU/RV64 port can also run natmods and see whether they actually work, so the CI tasks script has been updated to bring RV64 to parity with RV32 as far as CI checks go. Documentation was also updated, since now all supported boards in the QEMU port should be able to run natmod tests. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
|
Thanks for this, it's a good addition. I did myself want to tackle this issue of emitting vs loading native code. The way you approached it with If you want to go for a more long term solution, I would suggest opening a separate PR that does a refactoring of the configuration options as follows:
Then once that PR is merged, come back to this one. |
|
Thank you for the suggestions. I went for the long-term solution using your hints as a base,
Anyway, there's plenty of work to do on this it seems... The changes I've made are here if you want to take a look when you've got some time: https://github.com/agatti/micropython/tree/natmod-load-without-emitter I'll mark this PR as draft as it's not yet ready. Edit: parent PR is ready (#18596) |
Summary
This PR adds natmod support for RV64, including the necessary changes to MicroPython's core, enabling this feature in the QEMU port, and test the feature as part of the CI jobs set.
Now, the interesting part. Natmod file loading has historically been tied to the presence of a native emitter, since there was no architecture that did not have such a thing. This, however, stopped being true with the introduction of RV64 support as no native emitter is available for said architecture.
Loading native modules shouldn't really depend on emitting code, since all the code to load is already there. For certain scenarios where native modules loading is needed, this could be something worthwhile, as the interpreter may be made smaller with all native code support generation not shipping with the main firmware image. The changes in this PR can selectively enable the code blocks needed to load and run native modules without the rest of the emitter framework being there, as needed for the RV64 architecture.
The native modules loader changes can also make possible supporting AArch64 without having to write a brand-new emitter, just like for RV64.
Along with core changes,
tools/mpy_ld.pynow has support for all needed relocation types (and got a bug fixed too!), therv64imcvalue is recognised bypy/dynruntime.mk'sARCHvariable checks, the natmod test runner was updated to recognise RV64 as part of the potential targets, and the documentation plus the example natmods have been updated to mention the new architecture.The Unix port hasn't been updated to load natmods when running the RV64 binary as I haven't done any on-device testing, I'll get around to that as soon as I remember where I put my MilkV-Duo board.
Testing
Besides manual testing on QEMU, the QEMU/RV64 CI job was updated to build and run natmods on RV64, just like RV32. RV64 tasks don't fail on my repo's branch, so hopefully they should work on this one too.
Trade-offs and Alternatives
I'm not really happy about the changes in
py/related toMICROPY_LOAD_NATIVE_MODULES, but I didn't really find any other obvious way to get that done with fewer code changes. I'm sure this can be done better, and I'm open to suggestions for this.The same applies to the change made in
py/persistentcode.hto letsys.implementation._mpyreport that it's running on RV64. The target architecture in that tuple is based on what kind of native emitter is enabled, which may have been correct before, but it is not the case anymore.I thought about factoring out the platform detection used in
py/nlr.hand apply that to defineMPY_FEATURE_ARCH, but that's a bit too much code to touch and it may break something else. I'd like some feedback about that - changing the relevant commit to do that instead isn't an issue at all.