Skip to content

Riscv64 support? #218

Closed
Closed

Description

@lachlansneff

Apparently llvm has Risc-V64 support now, so is there a timeline on supporting a riscv64 toolchain for rust?

Activity

  1. japaric commented on Sep 27, 2018

    @japaric
    Member

    cc @rust-embedded/riscv

    What kind of target do you have in mind? Bare metal or Linux?

    A bare metal target like riscv32imc-unknown-none-elf needs less things from LLVM. For example, it's OK if the LLVM backend doesn't fully support atomics.

    A Linux target needs, off the top of my head, fully working support for atomics and ELF TLS in the LLVM backend. Also, the standard libraries contains pieces of C code that need to be cross compiled to riscv64 using gcc: maybe unwinding support, backtrace support, jemalloc, etc. some you may be able to omit depending on which libc you use (gnu or musl).

  2. lachlansneff commented on Sep 27, 2018

    @lachlansneff
    Author

    I'm looking into porting nebulet to risvc64, which would require riscv64imac-unknown-none-elf.

  3. japaric commented on Sep 27, 2018

    @japaric
    Member

    In that case the required work would involve:

    • Upgrading the LLVM submodule if the current version rustc is using doesn't have the riscv64 support you need. This is the hardest part.

    • Adding a built-in target. See this commit.

    • Enabling builds of the rust-std component (pre-compiled core and compiler-builtins) for the new target iff the target is stable enough (no LLVM errors when compiling core and other crates). See this commit.

    If someone volunteers to do the job I can review a PR that does steps 2 and 3. I can't, however, help with step 1; you are best asking the compiler team for help on that one.

  4. xxuejie commented on Oct 26, 2018

    @xxuejie

    Hey I dig into this problem a little bit, and after some trials I got a working prototype at here: https://github.com/xxuejie/rust/tree/riscv64

    The first issue I encountered, is that Rust's current LLVM version has too strict checking: https://github.com/rust-lang/llvm/blob/caddcd9b9dc9479a20908d93c3e47c49b021379e/lib/Target/RISCV/RISCVISelLowering.cpp#L301. Luckily, this problem has been resolved in upstream LLVM: llvm-mirror/llvm@22abcbc#diff-e08aaff1bcaf5b99c78106d5d7d2f2e5. So updating LLVM submodule version used in Rust could solve this. In my prototype, I just cherry-picked the needed commits.

    After that, another problem is that there're still instructions unimplemented even in upstream LLVM: https://github.com/llvm-mirror/llvm/blob/master/lib/Target/RISCV/RISCVInstrInfo.td#L477-L481. It seems the relevant part in this patch: https://github.com/lowRISC/riscv-llvm/blob/master/0044-RISCV-Add-initial-RV64I-codegen-support.patch is left out when merging to upstream. I guess maybe we will need a little help from @asb on the current status. In the meantime for my prototype I just copy over the code from the patch: xxuejie/llvm@8f01ea4, and the result is a Rust version that can compile to RISCV64.

    So the above are 2 issues we need to solve to make Rust work. If you guys think this is a legit path I can start working on getting those changes into proper PRs for upstreams.

  5. asb commented on Oct 26, 2018

    @asb

    Thanks for tagging me - I'm the code owner and primary author of the upstream RISC-V LLVM backend.

    I've been working on getting RV64 support upstream. I recently authored an RFC to get feedback on the implementation approach: http://lists.llvm.org/pipermail/llvm-dev/2018-October/126690.html

    I've followed that up with a stream of patches currently under review on Phabricator. These implement RV64IMAFD (and we get 'C' support for free based on the current upstream code). Note that in these in-flight patches, codegen for atomic cmpxchg isn't implemented on RV64, as I'm blocked on final review of my RV32A cmpxchg patch (see my RFC on safe atomics lowering for more background if interested).

    Codegen quality is much better than the proof of concept patch previously shared.

    See:

    I just updated a bunch of these after getting back from the LLVM Dev Meeting last week, so hopefully the review process will start to move forwards and we can get these merged.

    I'm really excited to see interest in RV64 support in Rust and I'm keen to do what I can to support you in this. The immediate priority is pretty clear - get these patches merged upstream. Beyond that, please keep tagging me in issues that I can help with and of course file bug reports on bugs.llvm.org when appropriate.

  6. xxuejie commented on Oct 26, 2018

    @xxuejie

    Thanks @asb for your reply and awesome work! It's great to hear that RV64 support is in progress. We are also interested in contributing as much as we can to support RV64 port in Rust(and maybe also help test LLVM code for RV64 :P). In the meantime I guess we will wait for the new patches to land in upstream, and see how we can work from there.

  7. jethrogb commented on Dec 11, 2018

    @jethrogb
  8. tarcieri commented on Dec 12, 2018

    @tarcieri

    Great news @asb!

    What kind of target do you have in mind? Bare metal or Linux?

    For me, initially a riscv64-unknown-linux-gnu or thereabouts target would be useful to me as I'm targeting the HiFive Unleashed, which comes preinstalled with Linux.

    Eventually I'll be interested in non-Linux targets.

  9. memoryruins commented on Jan 26, 2019

    @memoryruins

    Status of patches as of January 26, 2019 🎉

    title status
    Refactoring in preparation for immediate lowering merged
    Immediate lowering merged
    RV64I merged
    New target hook to improve codegen merged
    RV64M merged
    RV64A (minus cmpxchg) merged
    RV64F needs review
    RV64D accepted
  10. fintelia commented on Jan 26, 2019

    @fintelia

    If I understand correctly this means that rustc could now support a riscv64imac-unknown-none-elftarget?

  11. xxuejie commented on Jan 27, 2019

    @xxuejie

    I just did a check, it seems Rust team has just recently updated LLVM with changes till Jan 16. That means all the merged PRs above has landed in Rust's LLVM except RV64A, which was merged on Jan 17.

    I think that means we can at least prepare a riscv64imc-unknown-none-elf rustc target now.

  12. asb commented on Jan 27, 2019

    @asb

    The RV64A patch was actually updated to include cmpxchg prior to merging (the only reason it didn't have it originally was that RV32 cmpxchg / the new target hooks for late cmpxchg expansion were still under review).

    For RV64I, you might want to cherry-pick the simple fix r351806 or the better fix r352169.

  13. fintelia commented on Jan 30, 2019

    @fintelia

    @xxuejie What needs to be done to prepare that target?

  14. dvc94ch commented on Jan 30, 2019

    @dvc94ch
    Member
  15. 13 remaining items

  16. fintelia commented on Feb 17, 2019

    @fintelia

    That limitation is rather unfortunate, particularly for targets that have all of their memory above 0x8000_0000. It makes it very hard to write for qemu's virt machine type, or any application that needs to place code at specific virtual addresses. Do you know which component lacks support for relocations? Is it something Rust related or a more fundamental problem with LLVM?

    Edit: I wonder if position independent code could help. It isn't really a matter of needing more than 2GB of code+data but rather that the address range has to start at address zero.

  17. Disasm commented on Feb 17, 2019

    @Disasm
    Member

    @fintelia,

    It makes it very hard to write for qemu's virt machine type, or any application that needs to place code at specific virtual addresses.

    What's wrong with qemu? I thought that you can set any base address for RAM in your machine definition. Other workarounds may involve using virtual memory region [-2GB;+2GB) for your application.

    Do you know which component lacks support for relocations? Is it something Rust related or a more fundamental problem with LLVM?

    It's not a fundamental problem, but you need LLVM support to generate relocatable code with pc-based addressing. Aside from this, Rust uses static relocation model for many if not all embedded targets. I don't know what is the reason, but it can be a problem because you need to set the relocation model to pic in order to enable relocatable code generation in LLVM.

  18. fintelia commented on Feb 17, 2019

    @fintelia

    What's wrong with qemu? I thought that you can set any base address for RAM in your machine definition. Other workarounds may involve using virtual memory region [-2GB;+2GB) for your application.

    This is possible in spike, but I'm not sure of any way to configure this in qemu. It is hard coded here and I'm not aware of any way to change that without patching/recompiling qemu. My application is also a bit tricky because I'm trying to build a classic hypervisor. That means that even once early boot is over and I've installed page tables (negating issues with the physical location of DRAM) I still ideally need to pick virtual address for code+data that the guest kernel/userspace isn't using.

    It's not a fundamental problem, but you need LLVM support to generate relocatable code with pc-based addressing. Aside from this, Rust uses static relocation model for many if not all embedded targets.

    I'd be interested in digging into this more. Long term I think there is a push to make riscv more than just an embedded target and use it for larger systems (this is my interest) which would make the need for using larger virtual addresses and relocatable code more pressing. @asb do you know if LLVM has any targets or timelines for these features?

  19. Disasm commented on Feb 17, 2019

    @Disasm
    Member

    @fintelia Yes, you have to recompile qemu with another address, however it's not difficult. If you are trying to implement a hypervisor, you need to execute (at least some of) your code in M mode without virtual addresses. You can write this M-mode part in assembly with relocatable code.

  20. fintelia commented on Apr 8, 2019

    @fintelia

    It seems that LLVM now has support for mcmodel=medium (which is equivalent to GCC's mcmodel=medany). It should now be possible to cherry pick the relevant commits and expose support from Rust.

  21. Disasm commented on Apr 8, 2019

    @Disasm
    Member

    @fintelia Wow! Thank you for the information. I'm not sure I'll be able to cherry-pick commits this time, maybe we need some help from the Rust team. I tried to cherry-pick useful commits two weeks ago and failed: I couldn't even figure out "maximum" commit set.

  22. memoryruins commented on Apr 11, 2019

    @memoryruins

    riscv64imac-unknown-none-elf and riscv64gc-unknown-none-elf targets are now on stable rustc 1.34.0 :) https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1340-2019-04-11

  23. sequencer commented on May 11, 2019

    @sequencer

    #218 (comment)
    May I ask when will mcmodel become ready in rust?
    RISC-V is deprecating bbl, using opensbi as a replacement, which won't set paging from bootloader, so if _start don't start from 0x8000_000 will lead to pure rust can't write a bare metal entry.

  24. Disasm commented on May 11, 2019

    @Disasm
    Member

    @sequencer Unfortunately, I don't have an answer to this question. Someone has to merge corresponding patches from upstream LLVM to Rust LLVM tree. I'm busy at the moment, but I hope I will be able to start dealing with this soon.

  25. sequencer commented on May 11, 2019

    @sequencer

    Oh thank you!
    A demo kernel by @wangrunji0408 give a solution of sv39 paging in _start written by Rust.

  26. Disasm commented on Jun 23, 2019

    @Disasm
    Member

    Good news! This patch arrived 12 days ago: llvm/llvm-project@a524036

    Now it's possible to build C programs like this one:

    unsigned int a;
    void *f() {
        return &a;
    }
    f:                                      # @f
    .LBB0_1:                                # Label of block must be emitted
            auipc   a0, %pcrel_hi(a)
            addi    a0, a0, %pcrel_lo(.LBB0_1)
            ret
    

    UPD: rust-lang/rust#62281

  27. added a commit that references this issue on Jul 6, 2019
  28. added a commit that references this issue on Jul 7, 2019
  29. Disasm commented on Jul 9, 2019

    @Disasm
    Member

    Closing this because the major addressing problem is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions