Is it possible to build a single toolchain for RV32* & RV64*

2,159 views
Skip to first unread message

Tommy Murphy

unread,
Mar 29, 2017, 1:14:58 PM3/29/17
to RISC-V SW Dev
OK - here goes and hopefully this makes sense and somebody can advise me ... :-)

Is it possible to build a single (bare metal) toolchain for RV32* & RV64*
Where * means all possible combinations of extensions - e.g. I, M, A, G, C, F, D, Q etc.

At the moment when I build with, say, --with-arch=rv32im and --with-arch=rv64im then I get two separate toolchains - riscv32-unknown-elf-* and riscv64-unknown-elf-*.
Is it possible to build a single toolchain (either riscv64-unknown-elf-* or riscv-unknown-elf-*) that supports both 32 and 64 bit?
If not is this due to limitations of the build process or something inherent in the tools?
Similarly is it possible to have a single toolchain that supports all possible extensions so that the single toolchain can be called with, say, -march=rv32im or -march=rv32g or -march=64imafdq etc.?
Again, if not, why not?
Lastly I presume that --enable-multilib when configuring the tools is relevant here but does it work and if so what exactly does it do?

If any clarification of my questions is needed please let me know.
Thanks a lot.

Richard Herveille

unread,
Mar 29, 2017, 3:38:50 PM3/29/17
to Tommy Murphy, RISC-V SW Dev
I have the same question. 
I use only the riscv64-unknown-elf toolchain and use -march= to specify the actual feature set. This seems to work (I checked the generated code). 

I currently don't rely on/use newlib, but want to use it. What does 'multilib' do? The way I understand it, is that there are multiple newlib versions and the toolchain picks the relevant one based on the march= option. I also heard this feature is currently broken. 

Richard 

Sent from my iPad
--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/a5a88dc3-22c8-4fa5-9516-25fc37fca7e4%40groups.riscv.org.

Palmer Dabbelt

unread,
Mar 29, 2017, 5:26:24 PM3/29/17
to tommy_...@hotmail.com, sw-...@groups.riscv.org
See also my posts in this thread
https://groups.google.com/a/groups.riscv.org/d/msg/sw-dev/8dae3T-fS8A/z2NHToMlBgAJ

On Wed, 29 Mar 2017 10:14:57 PDT (-0700), tommy_...@hotmail.com wrote:
> OK - here goes and hopefully this makes sense and somebody can advise me
> ... :-)
>
> Is it possible to build a single (bare metal) toolchain for RV32* & RV64*
> Where * means all possible combinations of extensions - e.g. I, M, A, G, C,
> F, D, Q etc.

Depends on what "bare metal" means.

> At the moment when I build with, say, --with-arch=rv32im and
> --with-arch=rv64im then I get two separate toolchains -
> riscv32-unknown-elf-* and riscv64-unknown-elf-*.
> Is it possible to build a single toolchain (either riscv64-unknown-elf-* or
> riscv-unknown-elf-*) that supports both 32 and 64 bit?

Regardless of the configure-time arguments passed to
riscv-gnu-toolchain/configure, binutils and GCC always support all -march/-mabi
combinations. All passing "--with-arch" to riscv-gnu-toolchain/configure does
is:

* Set the default values for -march and -mabi for both GCC and binutils.

* Choose the tuple (as riscv32 or riscv64).

So if you're not worried about libraries then you're all set. If "bare metal"
means you want libraries (either libc or libgcc), then there's some more work
you have to do...

> If not is this due to limitations of the build process or something
> inherent in the tools?
> Similarly is it possible to have a single toolchain that supports all
> possible extensions so that the single toolchain can be called with, say,
> -march=rv32im or -march=rv32g or -march=64imafdq etc.?
> Again, if not, why not?
> Lastly I presume that --enable-multilib when configuring the tools is
> relevant here but does it work and if so what exactly does it do?

Passing "--enable-multilib" to riscv-gnu-toolchain/configure changes how GCC
and libc (either glibc or newlib) are built. This also has two effects:

* GCC gets an additional make fragment, this one for the ELF (newlib)
toolchain <https://github.com/riscv/riscv-gcc/blob/riscv-next/gcc/config/riscv/t-elf-multilib>.

* The C library gets built multiple times. newlib has internal support for
this, so that's a bit magic. glibc is explicitly configured and built
multiple times based on this list
<https://github.com/riscv/riscv-gnu-toolchain/blob/master/configure.ac#L100>.

We chose the set of multilibs to encompass systems that seemed reasonable to
build, so they're different between the embedded (newlib/ELF) and Linux (glibc)
targets -- our view is that picking this list is really a distribution problem,
so we just picked a sensible default.

If you're OK with the default lists, then simply passing "--enable-multilib" to
riscv-gnu-toolchain/configure should be sufficient to get everything working.
If you're not, then you'll have to change the lists.

I'd be amenable to allowing some sort of "--with-multilib-list=..." flag to
riscv-gnu-toolchain/configure that lets users pick which multilibs should be
configured, but there'd also need to be some support in GCC for this. It's not
trivial because of the fallback mechanism for multilibs, but it's mostly
scripted so it shouldn't be too hard.

Tommy Murphy

unread,
Mar 29, 2017, 5:43:44 PM3/29/17
to RISC-V SW Dev, tommy_...@hotmail.com, pal...@sifive.com
Thanks Palmer - that helps a lot.
Just to clarify - by "bare metal" I meant not linux but just the tools + newlib.
I will try a new build run using --enable-multilib and see how it goes.
From what you're saying it sounds like it should all work.
I didn't expect that because as far as I recall some people posted here in recent times about multilib being broken.

Tommy Murphy

unread,
Mar 29, 2017, 6:09:48 PM3/29/17
to RISC-V SW Dev, tommy_...@hotmail.com, pal...@sifive.com
I don't see rv32ima on the list so would I have to do something to have that supported?
Do you know what?
Thanks.

Vania Joloboff

unread,
Mar 31, 2017, 2:47:50 AM3/31/17
to sw-...@groups.riscv.org
In the specs Volume II: RISC-V Privileged Architectures version 1.9
there are Machine Counter-Delta Registers such as

mucycle delta, cycle counter delta, mutime delta at addresses 0x700-0x78A

In version 1.9.1 of the specs, these registers have disappeared.

Is this an omission, or the delta registers have been deliberately
discarded ?


--
Best Regards,

Vania Joloboff
INRIA Bretagne Atlantique
Campus de Beaulieu
35042 Rennes Cedex
Tél: +33 (0)2 9984 7100
Fax: +33 (0)2 9984 7171

Stefan O'Rear

unread,
Mar 31, 2017, 2:52:18 AM3/31/17
to Vania Joloboff, RISC-V SW Dev
On Thu, Mar 30, 2017 at 11:47 PM, Vania Joloboff
<vania.j...@inria.fr> wrote:
> In the specs Volume II: RISC-V Privileged Architectures version 1.9
> there are Machine Counter-Delta Registers such as
>
> mucycle delta, cycle counter delta, mutime delta at addresses 0x700-0x78A
>
> In version 1.9.1 of the specs, these registers have disappeared.
>
> Is this an omission, or the delta registers have been deliberately discarded
> ?

The 1.9.1 spec has a preface which enumerates the deliberate changes.

https://github.com/riscv/riscv-isa-manual/blob/master/src/priv-preface.tex#L77-L79

https://content.riscv.org/wp-content/uploads/2016/11/riscv-privileged-v1.9.1.pdf#page=5

"Simplified the handling of existing hardware counters, removing
privileged versions of the counters and the corresponding delta
registers."

-s

Vania Joloboff

unread,
Mar 31, 2017, 7:59:11 AM3/31/17
to sw-...@groups.riscv.org

I just don't understand how after the machine has been booted in M-mode
it can boot the hypervisor or supervisor and switch to H or S mode.

My understanding is:
The ECALL instruction is provided to call a higher privilege mode from a
lower one
after it has been booted

The M/H/S/U-RET instruction is returning from such trap invoked by ECALL

But I don't see how to start lower privilege software from a higher level
the first time, how the register file can be initialized in that case
and how to specify the pc where the lower level should start
and what to do l if I want to jump directly from M-level to S-level
because there is no hypervisor.

Unconditional jumps cannot change privilege level...

Bruce Hoult

unread,
Mar 31, 2017, 8:08:56 AM3/31/17
to Vania Joloboff, RISC-V SW Dev
The usual way, on any kind of CPU, generally, is to set up a fake exception structure on the stack or in dedicated registers (as ECALL would do), set up the user-level registers how you want them (the normal registers, or shadow registers, or saved on the stack depending on the CPU), and then do an exception return.


--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Vania Joloboff

unread,
Mar 31, 2017, 8:34:29 AM3/31/17
to Bruce Hoult, RISC-V SW Dev
On 03/31/2017 02:08 PM, Bruce Hoult wrote:
> The usual way, on any kind of CPU, generally, is to set up a fake
> exception structure on the stack or in dedicated registers (as ECALL
> would do), set up the user-level registers how you want them (the
> normal registers, or shadow registers, or saved on the stack depending
> on the CPU), and then do an exception return.
>
>
So it is implementation dependent.
I mean hardware implementation dependent , as this is not part of the
MRET spec.
> <mailto:sw-dev%2Bunsu...@groups.riscv.org>.
> To post to this group, send email to sw-...@groups.riscv.org
> <mailto:sw-...@groups.riscv.org>.
> <https://groups.google.com/a/groups.riscv.org/group/sw-dev/>.
> <https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/a5891e63-9d93-4bf9-c077-f49719671c14%40inria.fr>.

Bruce Hoult

unread,
Mar 31, 2017, 9:09:23 AM3/31/17
to Vania Joloboff, RISC-V SW Dev
Hopefully someone more knowledgeable will come along .. I haven't looked into this as the RISC-V hardware I have is M-mode only.

There are RISC-V Linux kernels that run on qemu or riscvemu. They have source code :-) e.g. https://github.com/riscv/riscv-linux

On Fri, Mar 31, 2017 at 3:34 PM, Vania Joloboff <vania.j...@inria.fr> wrote:
On 03/31/2017 02:08 PM, Bruce Hoult wrote:
The usual way, on any kind of CPU, generally, is to set up a fake exception structure on the stack or in dedicated registers (as ECALL would do), set up the user-level registers how you want them (the normal registers, or shadow registers, or saved on the stack depending on the CPU), and then do an exception return.


So it is implementation dependent.
I mean hardware implementation dependent , as this is not part of the MRET spec.



--
Best Regards,

Vania Joloboff
INRIA Bretagne Atlantique
Campus de Beaulieu
35042 Rennes Cedex
Tél: +33 (0)2 9984 7100
Fax: +33 (0)2 9984 7171

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/273a22cc-5119-4e5e-2f41-d776d959753f%40inria.fr.

Vania Joloboff

unread,
Mar 31, 2017, 9:41:02 AM3/31/17
to RISC-V SW Dev

What happens if a dumb program in M-mode is issuing an ECALL instruction?
Is this a NOP or an illegal instruction raising some exception ?
Or this is implementation defined ?

Wei Song

unread,
Mar 31, 2017, 9:42:46 AM3/31/17
to Bruce Hoult, Vania Joloboff, RISC-V SW Dev

On 03/31/2017 02:08 PM, Bruce Hoult wrote:
The usual way, on any kind of CPU, generally, is to set up a fake exception structure on the stack or in dedicated registers (as ECALL would do), set up the user-level registers how you want them (the normal registers, or shadow registers, or saved on the stack depending on the CPU), and then do an exception return.


So it is implementation dependent.
I mean hardware implementation dependent , as this is not part of the MRET spec.


Too some extent it is implementation dependent as some processor may choose implementing just machine mode.
However, as long as other modes are implemented, such as supervisor/user modes, the way to transfer control form higher mode to lower mode is defined by the privilege spec, related to the MSTATUS, MEPC and SEPC.

There are simple examples in the isa regression tests.

Transfer from machine to supervisor mode:
https://github.com/riscv/riscv-test-env/blob/9e219c9ca70459bfda9067d637bb8bf52c5f0326/p/riscv_test.h

# line 61 Set MSTATUS

#define RVTEST_ENABLE_SUPERVISOR                                        \
  li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1);                              \
  csrs mstatus, a0;                                                     \
  li a0, SIP_SSIP | SIP_STIP;                                           \
  csrs mideleg, a0;                                                     \


# line 148 jump to supervisor mode



        la t0, 1f;                                                      \
        csrw mepc, t0;                                                  \
        csrr a0, mhartid;                                               \
        mret;                                                           \
1:

Similar example of jump from machine to user mode can be find in:

line 73
https://github.com/riscv/riscv-test-env/blob/9e219c9ca70459bfda9067d637bb8bf52c5f0326/v/entry.S

line 222, 241, 242
https://github.com/riscv/riscv-test-env/blob/9e219c9ca70459bfda9067d637bb8bf52c5f0326/v/vm.c


-Wei

Stefan O'Rear

unread,
Mar 31, 2017, 12:10:04 PM3/31/17
to Vania Joloboff, RISC-V SW Dev
On Fri, Mar 31, 2017 at 4:59 AM, Vania Joloboff <vania.j...@inria.fr> wrote:
>
> I just don't understand how after the machine has been booted in M-mode
> it can boot the hypervisor or supervisor and switch to H or S mode.
>
> My understanding is:
> The ECALL instruction is provided to call a higher privilege mode from a
> lower one
> after it has been booted
>
> The M/H/S/U-RET instruction is returning from such trap invoked by ECALL
>
> But I don't see how to start lower privilege software from a higher level
> the first time,

FYI none of this is specific to RISC-V - what I'm about to tell you is
exactly as applicable, up to small details, when writing an ARM or x86
kernel.

Switching from M-mode to a lower privilege mode, the first time and
every subsequent time, is always done with MRET.

> how the register file can be initialized in that case

Ordinary registers keep their value across privilege transitions. You
can just set them (e.g. using load instructions; you WILL need a block
of assembly code for this) prior to the MRET.

> and how to specify the pc where the lower level should start

MRET sets the PC to the value of the MEPC CSR as described on page 37
of priv 1.9.1.

You set MEPC using a CSRW instruction prior to MRET. Setting CSRs
requires the use of general registers, so do all of your CSR setting
first, load general registers second, and issue MRET third.

> and what to do l if I want to jump directly from M-level to S-level
> because there is no hypervisor.

H-mode has been removed.

MRET can transfer control to any privilege level.

The description of MRET: "In addition to manipulating the privilege
stack as described in Section 3.1.7,"

§3.1.7 explains the privilege level transitions as follows: "When
executing an xRET instruction, supposing xPP holds the value y, y IE
is set to xPIE; the privilege mode is changed to y; xPIE is set to 1;
and xPP is set to U (or M if user-mode is not supported)."

In other words, if you are in M-mode and want to enter S-mode, set
MSTATUS.MPP (bits 11 and 12) to S (01) before executing MRET.

If you wanted to enter U-mode instead, you would set MPP to U (00).

Hope this helps! Any other questions?

-s

Stefan O'Rear

unread,
Mar 31, 2017, 12:11:53 PM3/31/17
to Vania Joloboff, Bruce Hoult, RISC-V SW Dev
On Fri, Mar 31, 2017 at 5:34 AM, Vania Joloboff <vania.j...@inria.fr> wrote:
> On 03/31/2017 02:08 PM, Bruce Hoult wrote:
>>
>> The usual way, on any kind of CPU, generally, is to set up a fake
>> exception structure on the stack or in dedicated registers (as ECALL would
>> do), set up the user-level registers how you want them (the normal
>> registers, or shadow registers, or saved on the stack depending on the CPU),
>> and then do an exception return.
>>
>>
> So it is implementation dependent.
> I mean hardware implementation dependent , as this is not part of the MRET
> spec.

It's absolutely part of the MRET spec and documented in the privileged
architecture document.

What "depending on the CPU" means is that the fine details are
different by *architecture* - you don't use the mstatus register on
x86, but the basic theme of "fake an exception return" is the same.

-s

Tommy Murphy

unread,
Mar 31, 2017, 12:30:41 PM3/31/17
to RISC-V SW Dev, tommy_...@hotmail.com, pal...@sifive.com
Sorry for bumping this but does anybody have any idea how a new target (e.g. rv32ima) can be added to the multlib list?
I can probably guess most of it by copying and pasting but I'm not exactly sure what I'm doing here so would appreciate guidance. 
Thanks.

Stefan O'Rear

unread,
Mar 31, 2017, 12:53:29 PM3/31/17
to Vania Joloboff, RISC-V SW Dev
On Fri, Mar 31, 2017 at 6:40 AM, Vania Joloboff <vania.j...@inria.fr> wrote:
>
> What happens if a dumb program in M-mode is issuing an ECALL instruction?
> Is this a NOP or an illegal instruction raising some exception ?
> Or this is implementation defined ?

I would assume that it generates exception cause 11, "Environment call
from M-mode", per privileged spec page 36. ECALL in S-mode and U-mode
generates exception causes 9 and 8 respectively.

-s

Richard Herveille

unread,
Apr 3, 2017, 5:03:14 AM4/3/17
to Stefan O'Rear, Richard Herveille, Vania Joloboff, RISC-V SW Dev
That’s how I implemented it …

Richard



ROA LOGIC
Design Services and Silicon Proven IP

Richard Herveille
Managing Director
Cell +31 (6) 5207 2230




--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Tommy Murphy

unread,
Apr 3, 2017, 5:37:02 AM4/3/17
to RISC-V SW Dev, tommy_...@hotmail.com, pal...@sifive.com
Hi there - anybody got any ideas?
The default list is here:


I guess that I need to add...

march=rv32i to MULTILIB_OPTIONS
rv32ima to MULTILIB_DIRNAMES
march=rv32im/mabi=ilp32 to MULTILIB_REQUIRED


but it's unclear to me what, if anything, I need to add to MULTILIB_REUSE.
Or should I be running .../riscv-gcc/gcc/config/riscv/multilib-generator with an additional argument?
If so what should that argument be?
rv32ima-ilp32--c perhaps?

Thanks a lot.

Richard Herveille

unread,
May 3, 2017, 7:20:47 AM5/3/17
to Tommy Murphy, Richard Herveille, RISC-V SW Dev, pal...@sifive.com
Hi Tommy,

Did you ever figure this out?

Richard



Richard Herveille
Managing Director
Cell +31 (6) 5207 2230




-- 
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Tommy Murphy

unread,
May 3, 2017, 9:28:36 AM5/3/17
to RISC-V SW Dev, tommy_...@hotmail.com, richard....@roalogic.com, pal...@sifive.com
Yes - simply doing this works for me:

git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
cd riscv
-gnu-toolchain
./configure --prefix=... --enable-multilib
make

The resulting riscv64-unknown-elf-* tools support 32 and 64 bit and the default set of multilibs listed here:

.../riscv-gnu-toolchain/riscv-gnu-toolchain/riscv-gcc/gcc/config/riscv/t-elf-multilib

I haven't tried varying this list yet.

If you want to build the latest GCC 7.1 RC version then see here - I haven't tried this yet:


Hope this helps.
Reply all
Reply to author
Forward
0 new messages